From 2f7f612b6fe411533d91b9d68c13af2336171d29 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 5 Jul 2026 20:31:45 +0200 Subject: [PATCH 01/83] refactor(server): extract Electron-free engine + wire contract into packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splits the engine from the Electron shell into two workspace packages so any transport (Electron IPC today, JSON-RPC over SSH next) can drive it — the foundation for remote/SSH-reachable operation. - @ateam/protocol: the wire contract (AteamApi, CH, DTOs, event payloads), dependency-free, shared by renderer, main, and the future server. - @ateam/server: the whole engine (git worktrees, agent PTYs, board state machine, hooks, loops, merge queue), Electron-free. createEngine() emits abstract events instead of webContents.send; createDispatcher() exposes the 26 engine methods as handle(method, args). - Desktop main shrinks to a shell (547->363 lines): builds the engine, forwards its events to the renderer, bridges ipcMain -> dispatcher, and keeps only the 4 client-native handlers (dialog/clipboard). ipc.ts 620->83 lines. Engine + loop tests move with their code into @ateam/server; adds a dispatcher unit test over an in-memory bun:sqlite db. All package typechecks, the production build, and the full suite (96 pass) are green. Behaviorally identical: handler bodies and the board state machine were relocated verbatim. Not yet exercised via a live Electron launch (no binary in this worktree). --- apps/desktop/electron.vite.config.ts | 6 +- apps/desktop/package.json | 2 + apps/desktop/src/main/index.ts | 231 +------ apps/desktop/src/main/ipc.ts | 583 +----------------- apps/desktop/src/preload/index.ts | 2 +- apps/desktop/src/renderer/src/App.tsx | 2 +- .../renderer/src/components/CleanupDialog.tsx | 2 +- .../renderer/src/components/LoopsPanel.tsx | 2 +- .../src/components/NewTaskComposer.tsx | 2 +- apps/desktop/src/renderer/src/global.d.ts | 2 +- apps/desktop/tsconfig.node.json | 1 - apps/desktop/tsconfig.web.json | 2 +- bun.lock | 25 +- packages/protocol/package.json | 10 + .../protocol/src/index.ts | 6 +- packages/protocol/tsconfig.json | 5 + packages/server/package.json | 22 + .../server/src}/agent-setup/index.ts | 0 packages/server/src/dispatcher.ts | 518 ++++++++++++++++ packages/server/src/engine.ts | 265 ++++++++ .../server/src}/hooks/board-mcp.ts | 0 .../server/src}/hooks/hook-server.ts | 0 packages/server/src/index.ts | 12 + .../server/src}/loops/agent-loop.ts | 0 .../server/src}/loops/agent-loops.design.md | 0 .../server/src}/loops/board-organizer.ts | 0 .../server/src}/loops/board-reconciler.ts | 0 .../server/src}/loops/board-signals.ts | 0 .../server/src}/loops/runner.ts | 2 +- .../server/src}/loops/session-liveness.ts | 0 .../server/src}/loops/templates.ts | 0 .../server/src}/loops/types.ts | 0 .../server/src}/loops/worktree-triage.ts | 0 .../server/src}/merge-queue.ts | 0 .../server/src}/pty/pty-client.ts | 0 .../main => packages/server/src}/services.ts | 2 +- .../server}/test/agent-loop.test.ts | 2 +- .../server}/test/board-mcp.test.ts | 2 +- .../server}/test/board-organizer.test.ts | 2 +- .../server}/test/board-signals.test.ts | 4 +- packages/server/test/dispatcher.test.ts | 84 +++ .../server}/test/loops-runner.test.ts | 6 +- .../server}/test/worktree-triage.test.ts | 2 +- packages/server/tsconfig.json | 5 + 44 files changed, 1020 insertions(+), 791 deletions(-) create mode 100644 packages/protocol/package.json rename apps/desktop/src/shared/types.ts => packages/protocol/src/index.ts (96%) create mode 100644 packages/protocol/tsconfig.json create mode 100644 packages/server/package.json rename {apps/desktop/src/main => packages/server/src}/agent-setup/index.ts (100%) create mode 100644 packages/server/src/dispatcher.ts create mode 100644 packages/server/src/engine.ts rename {apps/desktop/src/main => packages/server/src}/hooks/board-mcp.ts (100%) rename {apps/desktop/src/main => packages/server/src}/hooks/hook-server.ts (100%) create mode 100644 packages/server/src/index.ts rename {apps/desktop/src/main => packages/server/src}/loops/agent-loop.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/agent-loops.design.md (100%) rename {apps/desktop/src/main => packages/server/src}/loops/board-organizer.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/board-reconciler.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/board-signals.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/runner.ts (99%) rename {apps/desktop/src/main => packages/server/src}/loops/session-liveness.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/templates.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/types.ts (100%) rename {apps/desktop/src/main => packages/server/src}/loops/worktree-triage.ts (100%) rename {apps/desktop/src/main => packages/server/src}/merge-queue.ts (100%) rename {apps/desktop/src/main => packages/server/src}/pty/pty-client.ts (100%) rename {apps/desktop/src/main => packages/server/src}/services.ts (95%) rename {apps/desktop => packages/server}/test/agent-loop.test.ts (98%) rename {apps/desktop => packages/server}/test/board-mcp.test.ts (98%) rename {apps/desktop => packages/server}/test/board-organizer.test.ts (99%) rename {apps/desktop => packages/server}/test/board-signals.test.ts (97%) create mode 100644 packages/server/test/dispatcher.test.ts rename {apps/desktop => packages/server}/test/loops-runner.test.ts (96%) rename {apps/desktop => packages/server}/test/worktree-triage.test.ts (98%) create mode 100644 packages/server/tsconfig.json diff --git a/apps/desktop/electron.vite.config.ts b/apps/desktop/electron.vite.config.ts index 22d4fac..f926109 100644 --- a/apps/desktop/electron.vite.config.ts +++ b/apps/desktop/electron.vite.config.ts @@ -14,6 +14,8 @@ export default defineConfig({ "@ateam/db", "@ateam/agents", "@ateam/panes", + "@ateam/protocol", + "@ateam/server", ], }), ], @@ -28,7 +30,9 @@ export default defineConfig({ }, }, preload: { - plugins: [externalizeDepsPlugin()], + // Bundle @ateam/protocol (raw TS, and CH is used at runtime here); keep + // real npm deps externalized as usual. + plugins: [externalizeDepsPlugin({ exclude: ["@ateam/protocol"] })], build: { rollupOptions: { input: { index: resolve(__dirname, "src/preload/index.ts") }, diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 21b61c9..d2f3eb1 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -22,6 +22,8 @@ "@ateam/db": "workspace:*", "@ateam/git-core": "workspace:*", "@ateam/panes": "workspace:*", + "@ateam/protocol": "workspace:*", + "@ateam/server": "workspace:*", "@electron/notarize": "^3.1.1", "@electron/rebuild": "^3.7.1", "@types/node": "^22.10.5", diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 1836526..00519fc 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -1,39 +1,18 @@ import { execFileSync } from "node:child_process"; -import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs"; -import { homedir } from "node:os"; +import { readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; -import { createDb, repo } from "@ateam/db"; import { app, BrowserWindow, dialog, Menu } from "electron"; import { autoUpdater } from "electron-updater"; -import { type AgentStatus, CH, type KanbanColumn, type MergeStrategy } from "../shared/types"; -import { ensureGhShim, ensureNotifyScript } from "./agent-setup"; +import { CH } from "@ateam/protocol"; +import { createDispatcher, createEngine, type Engine } from "@ateam/server"; import { APP_NAME } from "./app-name"; -import { type HookEvent, HookServer, type MergeRequestEvent } from "./hooks/hook-server"; import { registerIpc } from "./ipc"; -import { createBoardReconciler } from "./loops/board-reconciler"; -import { applySetStatus, buildBoardView } from "./loops/board-signals"; -import { LoopRunner } from "./loops/runner"; -import { MergeQueue } from "./merge-queue"; -import { PtyClient } from "./pty/pty-client"; -import { type Services, toTaskDTO } from "./services"; let win: BrowserWindow | null = null; -let services: Services | null = null; +let engine: Engine | null = null; const SMOKE = process.env.ATEAM_SMOKE === "1"; -function mapEventToStatus(eventType: string): AgentStatus { - if (eventType === "PermissionRequest") return "awaiting_input"; - if (eventType === "Stop") return "idle"; - return "running"; -} - -function mapEventToColumn(eventType: string): KanbanColumn { - if (eventType === "PermissionRequest") return "needs_attention"; - if (eventType === "Stop") return "review"; - return "running"; -} - /** * GUI apps on macOS launch with a minimal PATH (/usr/bin:/bin:…), so agent * binaries in ~/.local/bin or /opt/homebrew/bin look "not installed" and @@ -275,171 +254,6 @@ function buildAppMenu(): void { Menu.setApplicationMenu(Menu.buildFromTemplate(template)); } -function sendTaskUpdated(taskId: string): void { - if (!services) return; - const task = repo.getTask(services.db, taskId); - if (task) win?.webContents.send(CH.evtTaskUpdated, toTaskDTO(task)); -} - -function sendLoopsUpdated(): void { - if (!services) return; - win?.webContents.send(CH.evtLoopsUpdated, services.loopRunner.describe()); -} - -async function initServices(): Promise { - const userDataDir = app.getPath("userData"); - // One-time migration from the pre-rename database filename. - const dbPath = join(userDataDir, "ateam.sqlite"); - if (!existsSync(dbPath) && existsSync(join(userDataDir, "grove.sqlite"))) { - for (const suffix of ["", "-wal", "-shm"]) { - const old = join(userDataDir, `grove.sqlite${suffix}`); - if (existsSync(old)) renameSync(old, `${dbPath}${suffix}`); - } - } - const db = createDb(dbPath); - // The detached PTY daemon survives app restarts; out/main/daemon.js is run via - // the Electron binary as node (ELECTRON_RUN_AS_NODE) so node-pty's ABI matches. - const pty = new PtyClient( - join(__dirname, "daemon.js"), - join(homedir(), ".ateam", "pty-daemon.sock"), - process.execPath, - ); - const hooks = new HookServer(); - const hookPort = await hooks.start(repo.getSettings(db).hookPort ?? undefined); - const notifyScriptPath = await ensureNotifyScript(userDataDir); - await ensureGhShim(userDataDir); - const hooksDir = join(userDataDir, "hooks"); - repo.updateSettings(db, { hookPort }); - - const mergeQueue = new MergeQueue({ db, onTaskUpdated: sendTaskUpdated }); - const loopRunner = new LoopRunner({ - db, - onTaskUpdated: sendTaskUpdated, - log: (line) => console.log(line), - mergeQueue, - }); - loopRunner.register(createBoardReconciler()); - - // Board Organizer tools: the organizer loop's headless `claude -p` turn reads - // the board and proposes moves through these, guarded by validateSetStatus. - hooks.setBoardHandlers({ - get: () => buildBoardView(db), - setStatus: async (req) => applySetStatus(db, req, sendTaskUpdated), - }); - - const svc: Services = { - db, - pty, - hooks, - userDataDir, - hooksDir, - notifyScriptPath, - hookPort, - mergeQueue, - loopRunner, - }; - - // PTY output/exit → renderer. - pty.on("data", (e) => win?.webContents.send(CH.evtPtyData, e)); - pty.on("exit", (e) => { - win?.webContents.send(CH.evtPtyExit, e); - // Record the exit in the DB so a session is never left looking "running" - // after its process is gone — the gap that previously stranded cards in - // the running column (the board reconciler is the backstop for exits we - // miss entirely, e.g. while the app was closed). - const session = repo.getSessionByTerminal(db, e.terminalId); - if (!session) return; - if (session.exitedAt == null) { - repo.updateSession(db, session.id, { - status: "stopped", - exitedAt: Date.now(), - }); - } - const task = repo.getTask(db, session.taskId); - if (task && task.column === "running") { - repo.updateTask(db, task.id, { - agentStatus: "stopped", - column: - task.prNumber != null || (task.gitStatus?.ahead ?? 0) > 0 ? "review" : "needs_attention", - isUnread: true, - }); - sendTaskUpdated(task.id); - } - }); - - // Agent status hooks → update session/task, drive the kanban column. - hooks.on("hook", (e: HookEvent) => { - const session = repo.getSessionByTerminal(db, e.terminalId); - if (!session) return; - const status = mapEventToStatus(e.eventType); - repo.updateSession(db, session.id, { - status, - lastEventAt: Date.now(), - }); - // "Working" fires on every tool use — too chatty for the append-only - // event log; it only needs to drive status/column. - if (e.eventType !== "Working") { - repo.recordEvent(db, { - sessionId: session.id, - terminalId: e.terminalId, - eventType: e.eventType, - rawAgentSessionId: e.sessionId ?? null, - }); - } - const task = repo.getTask(db, session.taskId); - if (task) { - const column = mapEventToColumn(e.eventType); - // Subagents fire PreToolUse too, so a Working event must never mask a - // pending question — only an explicit user reply (UserReply), Stop, or - // a fresh Start may move a task out of needs_attention. - if (e.eventType === "Working" && task.column === "needs_attention") { - return; - } - // Skip no-op Working updates so the renderer isn't pinged per tool use. - if (e.eventType === "Working" && task.column === column && task.agentStatus === status) { - return; - } - repo.updateTask(db, task.id, { - agentStatus: status, - column, - lastEventAt: Date.now(), - // Working/Start mean the user just interacted or launched — the - // task isn't "unread"; Stop/PermissionRequest are news for them. - isUnread: e.eventType === "Stop" || e.eventType === "PermissionRequest", - }); - sendTaskUpdated(task.id); - } - }); - - // Agent ran `gh pr merge` in its terminal → the gh shim routed it here. - // Resolve the task from the terminal and enqueue, so terminal merges and the - // in-app Merge button share one serialized queue per base branch. - hooks.on("merge-request", (e: MergeRequestEvent) => { - const session = repo.getSessionByTerminal(db, e.terminalId); - if (!session) return; - const task = repo.getTask(db, session.taskId); - if (!task) return; - const project = repo.getProject(db, task.projectId); - if (!project) return; - const settings = repo.getSettings(db); - const requested = e.strategy ?? ""; - const strategy = ( - ["merge", "squash", "rebase"].includes(requested) - ? requested - : (settings.defaultMergeStrategy ?? "squash") - ) as MergeStrategy; - void mergeQueue.enqueue({ - task, - repoPath: project.repoPath, - strategy, - updateStrategy: settings.defaultUpdateStrategy ?? "merge", - deleteRemoteBranch: settings.deleteRemoteBranchOnMerge ?? false, - }); - }); - - return svc; -} - function createWindow(): void { win = new BrowserWindow({ width: 1400, @@ -487,20 +301,25 @@ app.whenReady().then(async () => { } } - services = await initServices(); - registerIpc({ - services, - sendTaskUpdated, - mergeQueue: services.mergeQueue, - loopRunner: services.loopRunner, - sendLoopsUpdated, + engine = await createEngine({ + dataDir: app.getPath("userData"), + // The detached PTY daemon (out/main/daemon.js) is run via the Electron + // binary as node (ELECTRON_RUN_AS_NODE) so node-pty's ABI matches. + daemonPath: join(__dirname, "daemon.js"), + execPath: process.execPath, }); + // Forward the engine's transport-agnostic events to the renderer. + engine.on("taskUpdated", (task) => win?.webContents.send(CH.evtTaskUpdated, task)); + engine.on("loopsUpdated", (loops) => win?.webContents.send(CH.evtLoopsUpdated, loops)); + engine.on("ptyData", (e) => win?.webContents.send(CH.evtPtyData, e)); + engine.on("ptyExit", (e) => win?.webContents.send(CH.evtPtyExit, e)); + registerIpc(createDispatcher(engine)); if (SMOKE) { - // Headless boot check: prove services init (db, hook server, notify + // Headless boot check: prove the engine inits (db, hook server, notify // script) without opening a window or the daemon, then exit cleanly. - console.log(`ATEAM_READY hookPort=${services.hookPort}`); - services.hooks.stop(); + console.log(`ATEAM_READY hookPort=${engine.services.hookPort}`); + engine.stopHooks(); app.exit(0); return; } @@ -508,7 +327,7 @@ app.whenReady().then(async () => { // Connect to (or launch) the PTY daemon and learn which sessions are still // alive from a previous run, so the renderer can re-attach to them. try { - await services.pty.connect(); + await engine.connectPty(); } catch (err) { console.error("[ateam] PTY daemon connect failed:", err); } @@ -517,7 +336,7 @@ app.whenReady().then(async () => { buildAppMenu(); // Start the board reconciler (and any other registered loops) once the // window exists, so the first pass can push corrections to the renderer. - services.loopRunner.start(); + engine.startLoops(); setupAutoUpdate(); app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); @@ -537,10 +356,8 @@ app.whenReady().then(async () => { }); app.on("window-all-closed", () => { - // Do NOT kill PTYs — the daemon keeps them alive across restarts. Just - // disconnect; the daemon stays running with the sessions. - services?.pty.disconnect(); - services?.hooks.stop(); - services?.loopRunner.stop(); + // Do NOT kill PTYs — the daemon keeps them alive across restarts. engine.stop + // just disconnects the client and stops hooks/loops; the daemon stays running. + engine?.stop(); if (process.platform !== "darwin") app.quit(); }); diff --git a/apps/desktop/src/main/ipc.ts b/apps/desktop/src/main/ipc.ts index db60b0e..ce6948f 100644 --- a/apps/desktop/src/main/ipc.ts +++ b/apps/desktop/src/main/ipc.ts @@ -1,93 +1,6 @@ -import { randomUUID } from "node:crypto"; -import { readFileSync } from "node:fs"; -import { basename, join } from "node:path"; -import { agentCommand, getAgent, listAgents } from "@ateam/agents"; -import { repo } from "@ateam/db"; -import { - commit, - detectMerged, - diff, - errorMessage, - fileDiff, - createTask as gitCreateTask, - gitFor, - removeTask as gitRemoveTask, - initRepository, - push, - registerProject, - trackingStatus, - updateFromBase, -} from "@ateam/git-core"; import { clipboard, dialog, ipcMain, nativeImage } from "electron"; -import { - CH, - type CreateLoopInput, - type GitStatusSnapshot, - type KanbanColumn, - type MergeStrategy, -} from "../shared/types"; -import { buildAgentEnv, ensureClaudeHooks, ensureCodexHooks } from "./agent-setup"; -import type { LoopRunner } from "./loops/runner"; -import { LOOP_TEMPLATES } from "./loops/templates"; -import type { MergeQueue } from "./merge-queue"; -import { type Services, toProjectDTO, toSessionDTO, toTaskDTO } from "./services"; - -export interface IpcContext { - services: Services; - sendTaskUpdated: (taskId: string) => void; - mergeQueue: MergeQueue; - loopRunner: LoopRunner; - /** Push the current loop list to the renderer. */ - sendLoopsUpdated: () => void; -} - -/** Project display name from the repo's README H1 (md or HTML), if present. */ -function readmeTitle(repoPath: string): string | null { - const clean = (s: string) => - s - .replace(/<[^>]+>/g, "") - .replace(/[*_`#]/g, "") - .trim() - .slice(0, 60); - for (const f of ["README.md", "readme.md", "Readme.md"]) { - try { - const txt = readFileSync(join(repoPath, f), "utf8").slice(0, 4000); - const md = txt.match(/^#\s+(.+?)\s*$/m); - if (md?.[1]) return clean(md[1]) || null; - const html = txt.match(/]*>([\s\S]*?)<\/h1>/i); - if (html?.[1]) return clean(html[1]) || null; - } catch { - /* no readme at this casing */ - } - } - return null; -} - -function requireTask(services: Services, taskId: string) { - const task = repo.getTask(services.db, taskId); - if (!task) throw new Error(`Task not found: ${taskId}`); - return task; -} - -function requireProjectFor(services: Services, projectId: string) { - const project = repo.getProject(services.db, projectId); - if (!project) throw new Error(`Project not found: ${projectId}`); - return project; -} - -async function computeGitStatus( - worktreePath: string, - baseBranch: string, -): Promise { - const tracking = await trackingStatus(worktreePath); - const d = await diff({ worktreePath, baseBranch }); - return { - ahead: tracking?.ahead ?? 0, - behind: tracking?.behind ?? 0, - dirty: d.files.length, - updatedAt: Date.now(), - }; -} +import { CH } from "@ateam/protocol"; +import type { Dispatcher } from "@ateam/server"; /** * Load an image file and put it on the clipboard as a real bitmap, so a @@ -103,11 +16,25 @@ function stageImageOnClipboard(path: string | null): boolean { return true; } -export function registerIpc(ctx: IpcContext): void { - const { services, sendTaskUpdated, mergeQueue, loopRunner, sendLoopsUpdated } = ctx; - const { db } = services; +// Channels the renderer calls with `ipcRenderer.send` (fire-and-forget) rather +// than `invoke` — they take no reply, so they bridge to ipcMain.on. +const SEND_CHANNELS = new Set([CH.ptyWrite, CH.ptyResize]); + +/** + * Bridge Electron IPC to the transport-agnostic engine dispatcher. Every engine + * method flows through `dispatcher.handle`; only the handful of handlers that + * need Electron's native dialog/clipboard live here directly. + */ +export function registerIpc(dispatcher: Dispatcher): void { + for (const method of dispatcher.methods) { + if (SEND_CHANNELS.has(method)) { + ipcMain.on(method, (_e, ...args: unknown[]) => void dispatcher.handle(method, args)); + } else { + ipcMain.handle(method, (_e, ...args: unknown[]) => dispatcher.handle(method, args)); + } + } - // ---- projects ---- + // ---- client-native handlers (need Electron dialog/clipboard) ---- ipcMain.handle(CH.projectsPick, async () => { const res = await dialog.showOpenDialog({ properties: ["openDirectory"], @@ -116,302 +43,6 @@ export function registerIpc(ctx: IpcContext): void { return res.canceled ? null : (res.filePaths[0] ?? null); }); - ipcMain.handle(CH.projectsRegister, async (_e, repoPath: string, opts?: { init?: boolean }) => { - // "Create a repository here instead" (GitHub-Desktop-style), after the - // renderer asked the user. - if (opts?.init) await initRepository(repoPath); - const info = await registerProject(repoPath); - const row = repo.upsertProject(db, { - repoPath: info.repoPath, - name: readmeTitle(info.repoPath) ?? basename(info.repoPath), - defaultBranch: info.defaultBranch, - githubOwner: info.githubRepo?.owner ?? null, - githubName: info.githubRepo?.name ?? null, - }); - return toProjectDTO(row!); - }); - - ipcMain.handle(CH.projectsList, async () => - repo - .listProjects(db) - .map((p) => toProjectDTO({ ...p, name: readmeTitle(p.repoPath) ?? p.name })), - ); - - ipcMain.handle(CH.projectsRemove, async (_e, id: string) => { - repo.deleteProject(db, id); - }); - - // ---- tasks ---- - ipcMain.handle(CH.tasksList, async (_e, projectId: string) => - repo.listTasks(db, projectId).map(toTaskDTO), - ); - - ipcMain.handle( - CH.tasksCreate, - async (_e, input: { projectId: string; name: string; baseBranch?: string }) => { - const project = requireProjectFor(services, input.projectId); - const created = await gitCreateTask({ - repoPath: project.repoPath, - name: input.name, - baseBranch: input.baseBranch ?? project.defaultBranch ?? undefined, - worktreesRoot: project.worktreesRoot ?? undefined, - }); - const row = repo.createTask(db, { - projectId: project.id, - name: input.name, - slug: created.slug, - branch: created.branch, - baseBranch: created.baseBranch, - worktreePath: created.worktreePath, - }); - return toTaskDTO(row); - }, - ); - - ipcMain.handle( - CH.tasksRemove, - async (_e, input: { id: string; deleteBranch?: boolean; force?: boolean }) => { - const task = requireTask(services, input.id); - const project = requireProjectFor(services, task.projectId); - // Tear down any live agent/shell sessions in this worktree first. - for (const s of repo.listSessionsByTask(db, task.id)) { - services.pty.kill(s.terminalId); - } - await gitRemoveTask({ - repoPath: project.repoPath, - worktreePath: task.worktreePath, - branch: task.branch, - deleteBranch: input.deleteBranch, - force: input.force, - }); - repo.deleteTask(db, task.id); - }, - ); - - ipcMain.handle(CH.tasksSetColumn, async (_e, id: string, column: KanbanColumn) => { - const row = repo.updateTask(db, id, { column }); - // Broadcast so every view (board, sidebar) reflects the move — e.g. the - // "Done" button under the terminal that sends a review task to merged. - sendTaskUpdated(id); - return toTaskDTO(row!); - }); - - // ---- cleanup: remove only merged + idle + clean worktrees ---- - // Classify a project's tasks into removable vs kept (with a reason). A task - // is removable ONLY when it merged, has no live agent session, and its - // working tree is clean. Everything else is kept — never deleting unmerged - // work or a task an agent is still using. - async function classifyForCleanup(projectId: string) { - const allTasks = repo.listTasks(db, projectId); - const removable: typeof allTasks = []; - const kept: { task: (typeof allTasks)[number]; reason: string }[] = []; - for (const task of allTasks) { - const isMerged = task.column === "merged" || task.prState === "merged"; - if (!isMerged) { - kept.push({ task, reason: "not merged" }); - continue; - } - const live = repo.listSessionsByTask(db, task.id).some((s) => services.pty.has(s.terminalId)); - if (live) { - kept.push({ task, reason: "agent still active" }); - continue; - } - const dirty = - ( - await gitFor(task.worktreePath) - .raw(["status", "--porcelain"]) - .catch(() => "") - ).trim() !== ""; - if (dirty) { - kept.push({ task, reason: "uncommitted/untracked changes" }); - continue; - } - removable.push(task); - } - return { removable, kept }; - } - - // Candidates for the interactive cleanup dialog: every task that isn't - // actively running (idle / stopped / merged / no activity). Each carries a - // live terminalId when its PTY is still around, so the dialog can show the - // conversation and let the user continue it instead of deleting. - ipcMain.handle(CH.tasksCleanupCandidates, async (_e, projectId: string) => { - const out: { - id: string; - name: string; - branch: string; - worktreePath: string; - reason: string; - terminalId: string | null; - agentStatus: string | null; - }[] = []; - for (const task of repo.listTasks(db, projectId)) { - const busy = task.agentStatus === "running" || task.agentStatus === "awaiting_input"; - // Done tasks are always proposed — merged work is cleanup material - // even when its agent session is technically still alive. - if (busy && task.column !== "merged") continue; - const live = repo.listSessionsByTask(db, task.id).find((s) => services.pty.has(s.terminalId)); - const reason = - task.column === "merged" - ? "merged" - : task.agentStatus === "idle" || task.agentStatus === "stopped" - ? "agent idle" - : "no recent activity"; - out.push({ - id: task.id, - name: task.name, - branch: task.branch, - worktreePath: task.worktreePath, - reason, - terminalId: live?.terminalId ?? null, - agentStatus: task.agentStatus ?? null, - }); - } - return out; - }); - - ipcMain.handle(CH.tasksCleanupPreview, async (_e, projectId: string) => { - const { removable, kept } = await classifyForCleanup(projectId); - return { - removed: removable.map((t) => ({ - id: t.id, - name: t.name, - branch: t.branch, - })), - kept: kept.map((k) => ({ - id: k.task.id, - name: k.task.name, - branch: k.task.branch, - reason: k.reason, - })), - }; - }); - - ipcMain.handle(CH.tasksCleanup, async (_e, projectId: string) => { - const project = requireProjectFor(services, projectId); - const { removable, kept } = await classifyForCleanup(projectId); - const removed: { id: string; name: string; branch: string }[] = []; - for (const task of removable) { - try { - // force:false → git refuses if the tree somehow became dirty between - // classify and now; deleteBranch:true (branch -d refuses unmerged). - await gitRemoveTask({ - repoPath: project.repoPath, - worktreePath: task.worktreePath, - branch: task.branch, - deleteBranch: true, - force: false, - }); - repo.deleteTask(db, task.id); - removed.push({ id: task.id, name: task.name, branch: task.branch }); - } catch (err) { - kept.push({ task, reason: errorMessage(err) }); - } - } - return { - removed, - kept: kept.map((k) => ({ - id: k.task.id, - name: k.task.name, - branch: k.task.branch, - reason: k.reason, - })), - }; - }); - - // ---- git ---- - ipcMain.handle(CH.gitCommit, async (_e, taskId: string, message: string) => { - const task = requireTask(services, taskId); - return commit({ worktreePath: task.worktreePath, message }); - }); - - ipcMain.handle(CH.gitPush, async (_e, taskId: string) => { - const task = requireTask(services, taskId); - await push({ worktreePath: task.worktreePath, branch: task.branch }); - }); - - ipcMain.handle(CH.gitUpdate, async (_e, taskId: string) => { - const task = requireTask(services, taskId); - const settings = repo.getSettings(db); - const result = await updateFromBase({ - worktreePath: task.worktreePath, - baseBranch: task.baseBranch, - strategy: settings.defaultUpdateStrategy ?? "merge", - }); - return result; - }); - - ipcMain.handle(CH.gitMerge, async (_e, taskId: string, strategy: MergeStrategy) => { - const task = requireTask(services, taskId); - const project = requireProjectFor(services, task.projectId); - const settings = repo.getSettings(db); - // Serialize through the merge queue: two branches targeting the same - // base never race; each absorbs the freshly-merged base before merging. - return mergeQueue.enqueue({ - task, - repoPath: project.repoPath, - strategy, - updateStrategy: settings.defaultUpdateStrategy ?? "merge", - deleteRemoteBranch: settings.deleteRemoteBranchOnMerge ?? false, - }); - }); - - ipcMain.handle(CH.gitDiff, async (_e, taskId: string) => { - const task = requireTask(services, taskId); - return diff({ worktreePath: task.worktreePath, baseBranch: task.baseBranch }); - }); - - ipcMain.handle(CH.gitFileDiff, async (_e, taskId: string, file: string) => { - const task = requireTask(services, taskId); - return fileDiff({ - worktreePath: task.worktreePath, - file, - baseBranch: task.baseBranch, - }); - }); - - // Detect merges done OUTSIDE Ateam (the agent ran `gh pr merge` in its - // terminal, or the PR was merged on github.com) and move the task to Done. - // Throttled per task; fire-and-forget so status replies stay fast. - const mergeCheckedAt = new Map(); - const detectExternalMerge = async (taskId: string): Promise => { - if (Date.now() - (mergeCheckedAt.get(taskId) ?? 0) < 60_000) return; - mergeCheckedAt.set(taskId, Date.now()); - const task = repo.getTask(db, taskId); - if (!task || task.column === "merged") return; - // Done only when the conversation ended on a plain text reply: the agent - // fired Stop (idle/stopped) and is not waiting on a question/permission. - // A merge mid-conversation must NOT yank the card to Done. - const finished = - task.agentStatus == null || task.agentStatus === "idle" || task.agentStatus === "stopped"; - if (!finished || task.column === "needs_attention") return; - try { - const res = await detectMerged({ - worktreePath: task.worktreePath, - branch: task.branch, - baseBranch: task.baseBranch, - }); - if (!res.merged) return; - repo.updateTask(db, task.id, { - column: "merged", - prState: "merged", - prNumber: res.prNumber ?? task.prNumber ?? null, - prUrl: res.prUrl ?? task.prUrl ?? null, - }); - sendTaskUpdated(task.id); - } catch { - /* offline or gh unavailable — retried on a later refresh */ - } - }; - - ipcMain.handle(CH.gitStatus, async (_e, taskId: string) => { - const task = requireTask(services, taskId); - const snapshot = await computeGitStatus(task.worktreePath, task.baseBranch); - repo.updateTask(db, task.id, { gitStatus: snapshot }); - if (task.column !== "merged") void detectExternalMerge(task.id); - return snapshot; - }); - // Native file picker for the terminal toolbar's "+ → Files…" action; the // renderer types the chosen paths into the PTY like a drag-and-drop would. ipcMain.handle(CH.utilPickFiles, async () => { @@ -446,177 +77,7 @@ export function registerIpc(ctx: IpcContext): void { }); // Paste/drop of a copied image *file*: stage its bytes as a real bitmap so the - // renderer's following Ctrl+V attaches the pixels. Typing the path only - // attaches when the agent runs typed-path detection, and a bare Ctrl+V on a - // file copy grabs the file's generic icon — staging the bytes is the reliable - // path. Returns false (renderer then falls back to typing the path) if the - // file isn't a decodable image. + // renderer's following Ctrl+V attaches the pixels. Returns false (renderer + // then falls back to typing the path) if the file isn't a decodable image. ipcMain.handle(CH.utilStageImagePath, async (_e, path: string) => stageImageOnClipboard(path)); - - // ---- agents ---- - ipcMain.handle(CH.agentsList, async () => { - const agents = await listAgents(); - return agents.map((a) => ({ - id: a.id, - label: a.label, - description: a.description, - available: a.available, - })); - }); - - // ---- loops (periodic reconcilers) ---- - ipcMain.handle(CH.loopsList, () => loopRunner.describe()); - ipcMain.handle(CH.loopsSetEnabled, (_e, id: string, enabled: boolean) => { - loopRunner.setEnabled(id, enabled); - sendLoopsUpdated(); - return loopRunner.describe(); - }); - ipcMain.handle(CH.loopsRunNow, async (_e, id: string) => { - await loopRunner.runNow(id); - sendLoopsUpdated(); - return loopRunner.describe(); - }); - ipcMain.handle(CH.loopsTemplates, () => - LOOP_TEMPLATES.map((t) => ({ - id: t.id, - title: t.title, - description: t.description, - params: t.params, - })), - ); - ipcMain.handle(CH.loopsCreate, (_e, input: CreateLoopInput) => { - const loops = loopRunner.createUserLoop(input); - sendLoopsUpdated(); - return loops; - }); - ipcMain.handle(CH.loopsDelete, (_e, id: string) => { - const loops = loopRunner.deleteUserLoop(id); - sendLoopsUpdated(); - return loops; - }); - - // ---- pty ---- - const shell = process.env.SHELL || "/bin/zsh"; - - ipcMain.handle( - CH.ptySpawnAgent, - async ( - _e, - input: { - taskId: string; - agentId: string; - yolo?: boolean; - resume?: boolean; - prompt?: string; - files?: string[]; - }, - ) => { - const task = requireTask(services, input.taskId); - const agent = getAgent(input.agentId); - if (!agent) throw new Error(`Unknown agent: ${input.agentId}`); - - const terminalId = randomUUID(); - repo.createSession(db, { - taskId: task.id, - agentId: agent.id, - terminalId, - cwd: task.worktreePath, - }); - - if (agent.id === "claude") { - await ensureClaudeHooks(task.worktreePath, services.notifyScriptPath); - } else if (agent.id === "codex") { - await ensureCodexHooks(task.worktreePath, services.notifyScriptPath); - } - - const env = buildAgentEnv({ - terminalId, - agentId: agent.id, - hookPort: services.hookPort, - hooksDir: services.hooksDir, - }); - // Run the agent in a login shell, then drop to an interactive shell so - // the pane stays usable after the agent exits. YOLO appends the bypass - // flag; resume relaunches the agent's most recent conversation here. - // Attached files ride along in the prompt as absolute paths under a - // header — the agent reads them with its own Read tool (nothing is - // copied into the worktree). Skip on resume, which ignores the prompt. - let prompt = input.prompt; - if (input.files?.length) { - const list = input.files.map((f) => `- ${f}`).join("\n"); - prompt = prompt ? `${prompt}\n\nAttached files:\n${list}` : `Attached files:\n${list}`; - } - let agentCmd = agentCommand(agent, { - yolo: input.yolo, - resume: input.resume, - prompt, - }); - if (agent.id === "codex") { - // Codex has no hooks, but `notify` invokes a program with a JSON - // payload on turn completion — our script maps it to Stop. Injected - // per-launch via -c so the user's ~/.codex/config.toml is untouched. - const codexNotify = join(services.hooksDir, "codex-notify.sh"); - agentCmd = agentCmd.replace(/^codex/, `codex -c 'notify=["sh","${codexNotify}"]'`); - } - const command = `${agentCmd}; exec ${shell} -l`; - services.pty.spawn({ - terminalId, - shell, - args: ["-l", "-c", command], - cwd: task.worktreePath, - env, - }); - - repo.updateTask(db, task.id, { - column: "running", - agentStatus: "running", - agentId: agent.id, - }); - sendTaskUpdated(task.id); - return { terminalId }; - }, - ); - - ipcMain.handle(CH.ptySpawnShell, async (_e, input: { taskId: string }) => { - const task = requireTask(services, input.taskId); - const terminalId = randomUUID(); - repo.createSession(db, { - taskId: task.id, - agentId: "shell", - terminalId, - cwd: task.worktreePath, - }); - services.pty.spawn({ - terminalId, - shell, - args: ["-l"], - cwd: task.worktreePath, - env: { ...process.env }, - }); - return { terminalId }; - }); - - ipcMain.on(CH.ptyWrite, (_e, terminalId: string, data: string) => { - services.pty.write(terminalId, data); - }); - - ipcMain.on(CH.ptyResize, (_e, terminalId: string, cols: number, rows: number) => { - services.pty.resize(terminalId, cols, rows); - }); - - ipcMain.handle(CH.ptyKill, async (_e, terminalId: string) => { - services.pty.kill(terminalId); - }); - - ipcMain.handle(CH.ptySnapshot, async (_e, terminalId: string) => - services.pty.snapshot(terminalId), - ); - - ipcMain.handle(CH.ptyListForTask, async (_e, taskId: string) => { - // Return the task's sessions that still have a live PTY. - return repo - .listSessionsByTask(db, taskId) - .filter((s) => services.pty.has(s.terminalId)) - .map(toSessionDTO); - }); } diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index cdbf025..1350b46 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -8,7 +8,7 @@ import { type PtyDataEvent, type PtyExitEvent, type TaskDTO, -} from "../shared/types"; +} from "@ateam/protocol"; const api: AteamApi = { projects: { diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index 756d363..e426d4b 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -46,7 +46,7 @@ import type { KanbanColumn, ProjectDTO, TaskDTO, -} from "../../shared/types"; +} from "@ateam/protocol"; import { AgentIcon } from "./components/AgentIcon"; import { CleanupDialog } from "./components/CleanupDialog"; import { FileDiffView } from "./components/FileDiffView"; diff --git a/apps/desktop/src/renderer/src/components/CleanupDialog.tsx b/apps/desktop/src/renderer/src/components/CleanupDialog.tsx index 2aebc10..d75fe51 100644 --- a/apps/desktop/src/renderer/src/components/CleanupDialog.tsx +++ b/apps/desktop/src/renderer/src/components/CleanupDialog.tsx @@ -1,6 +1,6 @@ import { MessageSquare, Trash2, X } from "lucide-react"; import { useEffect, useState } from "react"; -import type { CleanupCandidate } from "../../../shared/types"; +import type { CleanupCandidate } from "@ateam/protocol"; import { IconButton } from "./IconButton"; import { TerminalView } from "./Terminal"; diff --git a/apps/desktop/src/renderer/src/components/LoopsPanel.tsx b/apps/desktop/src/renderer/src/components/LoopsPanel.tsx index a707fea..da11ab2 100644 --- a/apps/desktop/src/renderer/src/components/LoopsPanel.tsx +++ b/apps/desktop/src/renderer/src/components/LoopsPanel.tsx @@ -1,6 +1,6 @@ import { AlertTriangle, CheckCircle2, Play, Plus, RefreshCw, Trash2, X } from "lucide-react"; import { useEffect, useState } from "react"; -import type { LoopDTO, LoopTemplateDTO, ProjectDTO } from "../../../shared/types"; +import type { LoopDTO, LoopTemplateDTO, ProjectDTO } from "@ateam/protocol"; /** "in 45s" / "in 2m" / "now", or "—" when no next run is scheduled. */ function untilLabel(nextRunAt: number | null, now: number): string { diff --git a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx index 8af47b6..ab87140 100644 --- a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx +++ b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx @@ -1,6 +1,6 @@ import { ArrowUp, Paperclip, X, Zap } from "lucide-react"; import { useState } from "react"; -import type { AgentDTO } from "../../../shared/types"; +import type { AgentDTO } from "@ateam/protocol"; /** Last path segment, for a compact chip label. */ function baseName(p: string): string { diff --git a/apps/desktop/src/renderer/src/global.d.ts b/apps/desktop/src/renderer/src/global.d.ts index ef84630..32ba60d 100644 --- a/apps/desktop/src/renderer/src/global.d.ts +++ b/apps/desktop/src/renderer/src/global.d.ts @@ -1,4 +1,4 @@ -import type { AteamApi } from "../../shared/types"; +import type { AteamApi } from "@ateam/protocol"; declare global { interface Window { diff --git a/apps/desktop/tsconfig.node.json b/apps/desktop/tsconfig.node.json index aa919ad..7029dd1 100644 --- a/apps/desktop/tsconfig.node.json +++ b/apps/desktop/tsconfig.node.json @@ -10,7 +10,6 @@ "src/main/**/*.ts", "src/daemon/**/*.ts", "src/preload/**/*.ts", - "src/shared/**/*.ts", "electron.vite.config.ts" ] } diff --git a/apps/desktop/tsconfig.web.json b/apps/desktop/tsconfig.web.json index 524caa9..0e1775d 100644 --- a/apps/desktop/tsconfig.web.json +++ b/apps/desktop/tsconfig.web.json @@ -6,5 +6,5 @@ "jsx": "react-jsx", "noEmit": true }, - "include": ["src/renderer/**/*.ts", "src/renderer/**/*.tsx", "src/shared/**/*.ts"] + "include": ["src/renderer/**/*.ts", "src/renderer/**/*.tsx"] } diff --git a/bun.lock b/bun.lock index 894e88c..72c3d00 100644 --- a/bun.lock +++ b/bun.lock @@ -12,7 +12,7 @@ }, "apps/desktop": { "name": "@ateam/desktop", - "version": "0.1.13", + "version": "0.1.25", "dependencies": { "better-sqlite3": "^11.8.1", "electron-updater": "^6.8.3", @@ -23,6 +23,8 @@ "@ateam/db": "workspace:*", "@ateam/git-core": "workspace:*", "@ateam/panes": "workspace:*", + "@ateam/protocol": "workspace:*", + "@ateam/server": "workspace:*", "@electron/notarize": "^3.1.1", "@electron/rebuild": "^3.7.1", "@types/node": "^22.10.5", @@ -73,6 +75,23 @@ "name": "@ateam/panes", "version": "0.0.0", }, + "packages/protocol": { + "name": "@ateam/protocol", + "version": "0.0.0", + }, + "packages/server": { + "name": "@ateam/server", + "version": "0.0.0", + "dependencies": { + "@ateam/agents": "workspace:*", + "@ateam/db": "workspace:*", + "@ateam/git-core": "workspace:*", + "@ateam/protocol": "workspace:*", + }, + "devDependencies": { + "drizzle-orm": "^0.38.4", + }, + }, }, "packages": { "7zip-bin": ["7zip-bin@5.2.0", "", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], @@ -87,6 +106,10 @@ "@ateam/panes": ["@ateam/panes@workspace:packages/panes"], + "@ateam/protocol": ["@ateam/protocol@workspace:packages/protocol"], + + "@ateam/server": ["@ateam/server@workspace:packages/server"], + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], diff --git a/packages/protocol/package.json b/packages/protocol/package.json new file mode 100644 index 0000000..444a11b --- /dev/null +++ b/packages/protocol/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ateam/protocol", + "version": "0.0.0", + "private": true, + "type": "module", + "main": "./src/index.ts", + "types": "./src/index.ts", + "exports": { ".": "./src/index.ts" }, + "scripts": { "typecheck": "tsc --noEmit" } +} diff --git a/apps/desktop/src/shared/types.ts b/packages/protocol/src/index.ts similarity index 96% rename from apps/desktop/src/shared/types.ts rename to packages/protocol/src/index.ts index a9e0612..9573f05 100644 --- a/apps/desktop/src/shared/types.ts +++ b/packages/protocol/src/index.ts @@ -1,5 +1,7 @@ -// Plain DTOs crossing the IPC boundary. Kept dependency-free so the renderer -// never imports node/electron/db internals. +// The Ateam wire contract: plain DTOs, channel names, event payloads, and the +// AteamApi surface. Dependency-free by design so every consumer — the desktop +// renderer, the Electron main process, and the (future) headless @ateam/server +// over SSH — shares one definition without pulling in node/electron/db internals. export type KanbanColumn = "todo" | "running" | "needs_attention" | "review" | "merged"; diff --git a/packages/protocol/tsconfig.json b/packages/protocol/tsconfig.json new file mode 100644 index 0000000..4e0e7f6 --- /dev/null +++ b/packages/protocol/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { "rootDir": "." }, + "include": ["src/**/*.ts"] +} diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 0000000..c455658 --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,22 @@ +{ + "name": "@ateam/server", + "version": "0.0.0", + "private": true, + "type": "module", + "main": "./src/index.ts", + "types": "./src/index.ts", + "exports": { ".": "./src/index.ts" }, + "scripts": { + "test": "bun test", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@ateam/agents": "workspace:*", + "@ateam/db": "workspace:*", + "@ateam/git-core": "workspace:*", + "@ateam/protocol": "workspace:*" + }, + "devDependencies": { + "drizzle-orm": "^0.38.4" + } +} diff --git a/apps/desktop/src/main/agent-setup/index.ts b/packages/server/src/agent-setup/index.ts similarity index 100% rename from apps/desktop/src/main/agent-setup/index.ts rename to packages/server/src/agent-setup/index.ts diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts new file mode 100644 index 0000000..ffb2735 --- /dev/null +++ b/packages/server/src/dispatcher.ts @@ -0,0 +1,518 @@ +// Transport-agnostic request/response dispatcher for the ~26 engine methods +// (everything the renderer's window.ateam calls except the 4 client-native ones +// that need Electron's dialog/clipboard). Lifted verbatim from the desktop's +// ipcMain handlers; the desktop now adapts ipcMain → handle(), and the SSH +// server will adapt a JSON-RPC channel → handle(). One body, many transports. +import { randomUUID } from "node:crypto"; +import { readFileSync } from "node:fs"; +import { basename, join } from "node:path"; +import { agentCommand, getAgent, listAgents } from "@ateam/agents"; +import { repo } from "@ateam/db"; +import { + commit, + detectMerged, + diff, + errorMessage, + fileDiff, + createTask as gitCreateTask, + gitFor, + removeTask as gitRemoveTask, + initRepository, + push, + registerProject, + trackingStatus, + updateFromBase, +} from "@ateam/git-core"; +import { + CH, + type CreateLoopInput, + type GitStatusSnapshot, + type KanbanColumn, + type MergeStrategy, +} from "@ateam/protocol"; +import { buildAgentEnv, ensureClaudeHooks, ensureCodexHooks } from "./agent-setup"; +import type { Engine } from "./engine"; +import { LOOP_TEMPLATES } from "./loops/templates"; +import { type Services, toProjectDTO, toSessionDTO, toTaskDTO } from "./services"; + +/** Project display name from the repo's README H1 (md or HTML), if present. */ +function readmeTitle(repoPath: string): string | null { + const clean = (s: string) => + s + .replace(/<[^>]+>/g, "") + .replace(/[*_`#]/g, "") + .trim() + .slice(0, 60); + for (const f of ["README.md", "readme.md", "Readme.md"]) { + try { + const txt = readFileSync(join(repoPath, f), "utf8").slice(0, 4000); + const md = txt.match(/^#\s+(.+?)\s*$/m); + if (md?.[1]) return clean(md[1]) || null; + const html = txt.match(/]*>([\s\S]*?)<\/h1>/i); + if (html?.[1]) return clean(html[1]) || null; + } catch { + /* no readme at this casing */ + } + } + return null; +} + +function requireTask(services: Services, taskId: string) { + const task = repo.getTask(services.db, taskId); + if (!task) throw new Error(`Task not found: ${taskId}`); + return task; +} + +function requireProjectFor(services: Services, projectId: string) { + const project = repo.getProject(services.db, projectId); + if (!project) throw new Error(`Project not found: ${projectId}`); + return project; +} + +async function computeGitStatus( + worktreePath: string, + baseBranch: string, +): Promise { + const tracking = await trackingStatus(worktreePath); + const d = await diff({ worktreePath, baseBranch }); + return { + ahead: tracking?.ahead ?? 0, + behind: tracking?.behind ?? 0, + dirty: d.files.length, + updatedAt: Date.now(), + }; +} + +export interface Dispatcher { + /** Method names this dispatcher handles (the non-native CH.* channels). */ + readonly methods: string[]; + /** Invoke a method with its positional args; throws on unknown method. */ + handle(method: string, args: unknown[]): Promise; +} + +export function createDispatcher(engine: Engine): Dispatcher { + const { services } = engine; + const { db, mergeQueue, loopRunner } = services; + const shell = process.env.SHELL || "/bin/zsh"; + + // ---- cleanup: remove only merged + idle + clean worktrees ---- + // A task is removable ONLY when it merged, has no live agent session, and its + // working tree is clean. Everything else is kept — never deleting unmerged + // work or a task an agent is still using. + async function classifyForCleanup(projectId: string) { + const allTasks = repo.listTasks(db, projectId); + const removable: typeof allTasks = []; + const kept: { task: (typeof allTasks)[number]; reason: string }[] = []; + for (const task of allTasks) { + const isMerged = task.column === "merged" || task.prState === "merged"; + if (!isMerged) { + kept.push({ task, reason: "not merged" }); + continue; + } + const live = repo.listSessionsByTask(db, task.id).some((s) => services.pty.has(s.terminalId)); + if (live) { + kept.push({ task, reason: "agent still active" }); + continue; + } + const dirty = + ( + await gitFor(task.worktreePath) + .raw(["status", "--porcelain"]) + .catch(() => "") + ).trim() !== ""; + if (dirty) { + kept.push({ task, reason: "uncommitted/untracked changes" }); + continue; + } + removable.push(task); + } + return { removable, kept }; + } + + // Detect merges done OUTSIDE Ateam (the agent ran `gh pr merge` in its + // terminal, or the PR was merged on github.com) and move the task to Done. + // Throttled per task; fire-and-forget so status replies stay fast. + const mergeCheckedAt = new Map(); + const detectExternalMerge = async (taskId: string): Promise => { + if (Date.now() - (mergeCheckedAt.get(taskId) ?? 0) < 60_000) return; + mergeCheckedAt.set(taskId, Date.now()); + const task = repo.getTask(db, taskId); + if (!task || task.column === "merged") return; + // Done only when the conversation ended on a plain text reply: the agent + // fired Stop (idle/stopped) and is not waiting on a question/permission. + const finished = + task.agentStatus == null || task.agentStatus === "idle" || task.agentStatus === "stopped"; + if (!finished || task.column === "needs_attention") return; + try { + const res = await detectMerged({ + worktreePath: task.worktreePath, + branch: task.branch, + baseBranch: task.baseBranch, + }); + if (!res.merged) return; + repo.updateTask(db, task.id, { + column: "merged", + prState: "merged", + prNumber: res.prNumber ?? task.prNumber ?? null, + prUrl: res.prUrl ?? task.prUrl ?? null, + }); + engine.sendTaskUpdated(task.id); + } catch { + /* offline or gh unavailable — retried on a later refresh */ + } + }; + + const handlers = { + // ---- projects ---- + [CH.projectsRegister]: async (repoPath: string, opts?: { init?: boolean }) => { + // "Create a repository here instead" (GitHub-Desktop-style), after the + // renderer asked the user. + if (opts?.init) await initRepository(repoPath); + const info = await registerProject(repoPath); + const row = repo.upsertProject(db, { + repoPath: info.repoPath, + name: readmeTitle(info.repoPath) ?? basename(info.repoPath), + defaultBranch: info.defaultBranch, + githubOwner: info.githubRepo?.owner ?? null, + githubName: info.githubRepo?.name ?? null, + }); + return toProjectDTO(row!); + }, + [CH.projectsList]: async () => + repo + .listProjects(db) + .map((p) => toProjectDTO({ ...p, name: readmeTitle(p.repoPath) ?? p.name })), + [CH.projectsRemove]: async (id: string) => { + repo.deleteProject(db, id); + }, + + // ---- tasks ---- + [CH.tasksList]: async (projectId: string) => repo.listTasks(db, projectId).map(toTaskDTO), + [CH.tasksCreate]: async (input: { projectId: string; name: string; baseBranch?: string }) => { + const project = requireProjectFor(services, input.projectId); + const created = await gitCreateTask({ + repoPath: project.repoPath, + name: input.name, + baseBranch: input.baseBranch ?? project.defaultBranch ?? undefined, + worktreesRoot: project.worktreesRoot ?? undefined, + }); + const row = repo.createTask(db, { + projectId: project.id, + name: input.name, + slug: created.slug, + branch: created.branch, + baseBranch: created.baseBranch, + worktreePath: created.worktreePath, + }); + return toTaskDTO(row); + }, + [CH.tasksRemove]: async (input: { id: string; deleteBranch?: boolean; force?: boolean }) => { + const task = requireTask(services, input.id); + const project = requireProjectFor(services, task.projectId); + // Tear down any live agent/shell sessions in this worktree first. + for (const s of repo.listSessionsByTask(db, task.id)) { + services.pty.kill(s.terminalId); + } + await gitRemoveTask({ + repoPath: project.repoPath, + worktreePath: task.worktreePath, + branch: task.branch, + deleteBranch: input.deleteBranch, + force: input.force, + }); + repo.deleteTask(db, task.id); + }, + [CH.tasksSetColumn]: async (id: string, column: KanbanColumn) => { + const row = repo.updateTask(db, id, { column }); + // Broadcast so every view (board, sidebar) reflects the move — e.g. the + // "Done" button under the terminal that sends a review task to merged. + engine.sendTaskUpdated(id); + return toTaskDTO(row!); + }, + + // Candidates for the interactive cleanup dialog: every task that isn't + // actively running. Each carries a live terminalId when its PTY is still + // around, so the dialog can show the conversation and let the user continue. + [CH.tasksCleanupCandidates]: async (projectId: string) => { + const out: { + id: string; + name: string; + branch: string; + worktreePath: string; + reason: string; + terminalId: string | null; + agentStatus: string | null; + }[] = []; + for (const task of repo.listTasks(db, projectId)) { + const busy = task.agentStatus === "running" || task.agentStatus === "awaiting_input"; + // Done tasks are always proposed — merged work is cleanup material + // even when its agent session is technically still alive. + if (busy && task.column !== "merged") continue; + const live = repo + .listSessionsByTask(db, task.id) + .find((s) => services.pty.has(s.terminalId)); + const reason = + task.column === "merged" + ? "merged" + : task.agentStatus === "idle" || task.agentStatus === "stopped" + ? "agent idle" + : "no recent activity"; + out.push({ + id: task.id, + name: task.name, + branch: task.branch, + worktreePath: task.worktreePath, + reason, + terminalId: live?.terminalId ?? null, + agentStatus: task.agentStatus ?? null, + }); + } + return out; + }, + [CH.tasksCleanupPreview]: async (projectId: string) => { + const { removable, kept } = await classifyForCleanup(projectId); + return { + removed: removable.map((t) => ({ id: t.id, name: t.name, branch: t.branch })), + kept: kept.map((k) => ({ + id: k.task.id, + name: k.task.name, + branch: k.task.branch, + reason: k.reason, + })), + }; + }, + [CH.tasksCleanup]: async (projectId: string) => { + const project = requireProjectFor(services, projectId); + const { removable, kept } = await classifyForCleanup(projectId); + const removed: { id: string; name: string; branch: string }[] = []; + for (const task of removable) { + try { + // force:false → git refuses if the tree somehow became dirty between + // classify and now; deleteBranch:true (branch -d refuses unmerged). + await gitRemoveTask({ + repoPath: project.repoPath, + worktreePath: task.worktreePath, + branch: task.branch, + deleteBranch: true, + force: false, + }); + repo.deleteTask(db, task.id); + removed.push({ id: task.id, name: task.name, branch: task.branch }); + } catch (err) { + kept.push({ task, reason: errorMessage(err) }); + } + } + return { + removed, + kept: kept.map((k) => ({ + id: k.task.id, + name: k.task.name, + branch: k.task.branch, + reason: k.reason, + })), + }; + }, + + // ---- git ---- + [CH.gitCommit]: async (taskId: string, message: string) => { + const task = requireTask(services, taskId); + return commit({ worktreePath: task.worktreePath, message }); + }, + [CH.gitPush]: async (taskId: string) => { + const task = requireTask(services, taskId); + await push({ worktreePath: task.worktreePath, branch: task.branch }); + }, + [CH.gitUpdate]: async (taskId: string) => { + const task = requireTask(services, taskId); + const settings = repo.getSettings(db); + return updateFromBase({ + worktreePath: task.worktreePath, + baseBranch: task.baseBranch, + strategy: settings.defaultUpdateStrategy ?? "merge", + }); + }, + [CH.gitMerge]: async (taskId: string, strategy: MergeStrategy) => { + const task = requireTask(services, taskId); + const project = requireProjectFor(services, task.projectId); + const settings = repo.getSettings(db); + // Serialize through the merge queue: two branches targeting the same + // base never race; each absorbs the freshly-merged base before merging. + return mergeQueue.enqueue({ + task, + repoPath: project.repoPath, + strategy, + updateStrategy: settings.defaultUpdateStrategy ?? "merge", + deleteRemoteBranch: settings.deleteRemoteBranchOnMerge ?? false, + }); + }, + [CH.gitDiff]: async (taskId: string) => { + const task = requireTask(services, taskId); + return diff({ worktreePath: task.worktreePath, baseBranch: task.baseBranch }); + }, + [CH.gitFileDiff]: async (taskId: string, file: string) => { + const task = requireTask(services, taskId); + return fileDiff({ worktreePath: task.worktreePath, file, baseBranch: task.baseBranch }); + }, + [CH.gitStatus]: async (taskId: string) => { + const task = requireTask(services, taskId); + const snapshot = await computeGitStatus(task.worktreePath, task.baseBranch); + repo.updateTask(db, task.id, { gitStatus: snapshot }); + if (task.column !== "merged") void detectExternalMerge(task.id); + return snapshot; + }, + + // ---- agents ---- + [CH.agentsList]: async () => { + const agents = await listAgents(); + return agents.map((a) => ({ + id: a.id, + label: a.label, + description: a.description, + available: a.available, + })); + }, + + // ---- loops (periodic reconcilers) ---- + [CH.loopsList]: () => loopRunner.describe(), + [CH.loopsSetEnabled]: (id: string, enabled: boolean) => { + loopRunner.setEnabled(id, enabled); + engine.sendLoopsUpdated(); + return loopRunner.describe(); + }, + [CH.loopsRunNow]: async (id: string) => { + await loopRunner.runNow(id); + engine.sendLoopsUpdated(); + return loopRunner.describe(); + }, + [CH.loopsTemplates]: () => + LOOP_TEMPLATES.map((t) => ({ + id: t.id, + title: t.title, + description: t.description, + params: t.params, + })), + [CH.loopsCreate]: (input: CreateLoopInput) => { + const loops = loopRunner.createUserLoop(input); + engine.sendLoopsUpdated(); + return loops; + }, + [CH.loopsDelete]: (id: string) => { + const loops = loopRunner.deleteUserLoop(id); + engine.sendLoopsUpdated(); + return loops; + }, + + // ---- pty ---- + [CH.ptySpawnAgent]: async (input: { + taskId: string; + agentId: string; + yolo?: boolean; + resume?: boolean; + prompt?: string; + files?: string[]; + }) => { + const task = requireTask(services, input.taskId); + const agent = getAgent(input.agentId); + if (!agent) throw new Error(`Unknown agent: ${input.agentId}`); + + const terminalId = randomUUID(); + repo.createSession(db, { + taskId: task.id, + agentId: agent.id, + terminalId, + cwd: task.worktreePath, + }); + + if (agent.id === "claude") { + await ensureClaudeHooks(task.worktreePath, services.notifyScriptPath); + } else if (agent.id === "codex") { + await ensureCodexHooks(task.worktreePath, services.notifyScriptPath); + } + + const env = buildAgentEnv({ + terminalId, + agentId: agent.id, + hookPort: services.hookPort, + hooksDir: services.hooksDir, + }); + // Run the agent in a login shell, then drop to an interactive shell so + // the pane stays usable after the agent exits. YOLO appends the bypass + // flag; resume relaunches the agent's most recent conversation here. + // Attached files ride along in the prompt as absolute paths under a + // header — the agent reads them with its own Read tool (nothing is + // copied into the worktree). Skip on resume, which ignores the prompt. + let prompt = input.prompt; + if (input.files?.length) { + const list = input.files.map((f) => `- ${f}`).join("\n"); + prompt = prompt ? `${prompt}\n\nAttached files:\n${list}` : `Attached files:\n${list}`; + } + let agentCmd = agentCommand(agent, { yolo: input.yolo, resume: input.resume, prompt }); + if (agent.id === "codex") { + // Codex has no hooks, but `notify` invokes a program with a JSON + // payload on turn completion — our script maps it to Stop. Injected + // per-launch via -c so the user's ~/.codex/config.toml is untouched. + const codexNotify = join(services.hooksDir, "codex-notify.sh"); + agentCmd = agentCmd.replace(/^codex/, `codex -c 'notify=["sh","${codexNotify}"]'`); + } + const command = `${agentCmd}; exec ${shell} -l`; + services.pty.spawn({ + terminalId, + shell, + args: ["-l", "-c", command], + cwd: task.worktreePath, + env, + }); + + repo.updateTask(db, task.id, { + column: "running", + agentStatus: "running", + agentId: agent.id, + }); + engine.sendTaskUpdated(task.id); + return { terminalId }; + }, + [CH.ptySpawnShell]: async (input: { taskId: string }) => { + const task = requireTask(services, input.taskId); + const terminalId = randomUUID(); + repo.createSession(db, { + taskId: task.id, + agentId: "shell", + terminalId, + cwd: task.worktreePath, + }); + services.pty.spawn({ + terminalId, + shell, + args: ["-l"], + cwd: task.worktreePath, + env: { ...process.env }, + }); + return { terminalId }; + }, + [CH.ptyWrite]: (terminalId: string, data: string) => { + services.pty.write(terminalId, data); + }, + [CH.ptyResize]: (terminalId: string, cols: number, rows: number) => { + services.pty.resize(terminalId, cols, rows); + }, + [CH.ptyKill]: async (terminalId: string) => { + services.pty.kill(terminalId); + }, + [CH.ptySnapshot]: async (terminalId: string) => services.pty.snapshot(terminalId), + [CH.ptyListForTask]: async (taskId: string) => + // Return the task's sessions that still have a live PTY. + repo + .listSessionsByTask(db, taskId) + .filter((s) => services.pty.has(s.terminalId)) + .map(toSessionDTO), + } satisfies Record unknown>; + + return { + methods: Object.keys(handlers), + async handle(method: string, args: unknown[]): Promise { + const h = (handlers as Record unknown>)[method]; + if (!h) throw new Error(`Unknown method: ${method}`); + return await h(...args); + }, + }; +} diff --git a/packages/server/src/engine.ts b/packages/server/src/engine.ts new file mode 100644 index 0000000..55e98d0 --- /dev/null +++ b/packages/server/src/engine.ts @@ -0,0 +1,265 @@ +// The Ateam engine: constructs the whole local subsystem (SQLite, PTY daemon +// client, hook server, merge queue, loops) and owns the agent → board state +// machine. It is transport-agnostic — instead of pushing to an Electron +// renderer it EMITS abstract events, so the desktop shell (which forwards them +// to webContents) and the SSH server (which frames them as JSON-RPC +// notifications) drive the exact same engine. +import { EventEmitter } from "node:events"; +import { existsSync, renameSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { createDb, repo } from "@ateam/db"; +import type { + AgentStatus, + KanbanColumn, + LoopDTO, + MergeStrategy, + PtyDataEvent, + PtyExitEvent, + TaskDTO, +} from "@ateam/protocol"; +import { ensureGhShim, ensureNotifyScript } from "./agent-setup"; +import { type HookEvent, HookServer, type MergeRequestEvent } from "./hooks/hook-server"; +import { createBoardReconciler } from "./loops/board-reconciler"; +import { applySetStatus, buildBoardView } from "./loops/board-signals"; +import { LoopRunner } from "./loops/runner"; +import { MergeQueue } from "./merge-queue"; +import { PtyClient } from "./pty/pty-client"; +import { type Services, toTaskDTO } from "./services"; + +export interface EngineOptions { + /** Where the SQLite db, hooks, and notify script live (app userData or ~/.ateam). */ + dataDir: string; + /** Path to the built PTY daemon entry (out/main/daemon.js). */ + daemonPath: string; + /** Binary that runs the detached daemon: the Electron binary as node on the + * desktop, or bun/node on a server. */ + execPath: string; + /** Unix socket for the PTY daemon (defaults to ~/.ateam/pty-daemon.sock). */ + sockPath?: string; + log?: (line: string) => void; +} + +/** Abstract engine events — the transport-neutral superset of what used to be + * `win.webContents.send(...)` calls. */ +interface EngineEventMap { + taskUpdated: [TaskDTO]; + loopsUpdated: [LoopDTO[]]; + ptyData: [PtyDataEvent]; + ptyExit: [PtyExitEvent]; +} + +export interface Engine { + readonly services: Services; + on(event: K, listener: (...args: EngineEventMap[K]) => void): () => void; + /** Re-read a task and emit taskUpdated (used across handlers + loops). */ + sendTaskUpdated(taskId: string): void; + /** Emit the current loop list. */ + sendLoopsUpdated(): void; + /** Connect to (or launch) the detached PTY daemon and learn live sessions. */ + connectPty(): Promise; + /** Start the periodic reconciler loops. */ + startLoops(): void; + /** Detach the client and stop hooks/loops — never kills PTY sessions. */ + stop(): void; + /** Stop just the hook server (used by the headless smoke check). */ + stopHooks(): void; +} + +function mapEventToStatus(eventType: string): AgentStatus { + if (eventType === "PermissionRequest") return "awaiting_input"; + if (eventType === "Stop") return "idle"; + return "running"; +} + +function mapEventToColumn(eventType: string): KanbanColumn { + if (eventType === "PermissionRequest") return "needs_attention"; + if (eventType === "Stop") return "review"; + return "running"; +} + +export async function createEngine(opts: EngineOptions): Promise { + const { dataDir, daemonPath, execPath } = opts; + const emitter = new EventEmitter(); + + // One-time migration from the pre-rename database filename. + const dbPath = join(dataDir, "ateam.sqlite"); + if (!existsSync(dbPath) && existsSync(join(dataDir, "grove.sqlite"))) { + for (const suffix of ["", "-wal", "-shm"]) { + const old = join(dataDir, `grove.sqlite${suffix}`); + if (existsSync(old)) renameSync(old, `${dbPath}${suffix}`); + } + } + const db = createDb(dbPath); + + const sendTaskUpdated = (taskId: string): void => { + const task = repo.getTask(db, taskId); + if (task) emitter.emit("taskUpdated", toTaskDTO(task)); + }; + + // The detached PTY daemon survives restarts; daemonPath is run via execPath as + // node (ELECTRON_RUN_AS_NODE on the desktop) so node-pty's ABI matches. + const pty = new PtyClient( + daemonPath, + opts.sockPath ?? join(homedir(), ".ateam", "pty-daemon.sock"), + execPath, + ); + const hooks = new HookServer(); + const hookPort = await hooks.start(repo.getSettings(db).hookPort ?? undefined); + const notifyScriptPath = await ensureNotifyScript(dataDir); + await ensureGhShim(dataDir); + const hooksDir = join(dataDir, "hooks"); + repo.updateSettings(db, { hookPort }); + + const mergeQueue = new MergeQueue({ db, onTaskUpdated: sendTaskUpdated }); + const loopRunner = new LoopRunner({ + db, + onTaskUpdated: sendTaskUpdated, + log: opts.log ?? ((line) => console.log(line)), + mergeQueue, + }); + loopRunner.register(createBoardReconciler()); + + // Board Organizer tools: the organizer loop's headless `claude -p` turn reads + // the board and proposes moves through these, guarded by validateSetStatus. + hooks.setBoardHandlers({ + get: () => buildBoardView(db), + setStatus: async (req) => applySetStatus(db, req, sendTaskUpdated), + }); + + const services: Services = { + db, + pty, + hooks, + userDataDir: dataDir, + hooksDir, + notifyScriptPath, + hookPort, + mergeQueue, + loopRunner, + }; + + // PTY output/exit → emitted for the transport to forward. + pty.on("data", (e) => emitter.emit("ptyData", e)); + pty.on("exit", (e) => { + emitter.emit("ptyExit", e); + // Record the exit in the DB so a session is never left looking "running" + // after its process is gone — the gap that previously stranded cards in + // the running column (the board reconciler is the backstop for exits we + // miss entirely, e.g. while the app was closed). + const session = repo.getSessionByTerminal(db, e.terminalId); + if (!session) return; + if (session.exitedAt == null) { + repo.updateSession(db, session.id, { + status: "stopped", + exitedAt: Date.now(), + }); + } + const task = repo.getTask(db, session.taskId); + if (task && task.column === "running") { + repo.updateTask(db, task.id, { + agentStatus: "stopped", + column: + task.prNumber != null || (task.gitStatus?.ahead ?? 0) > 0 ? "review" : "needs_attention", + isUnread: true, + }); + sendTaskUpdated(task.id); + } + }); + + // Agent status hooks → update session/task, drive the kanban column. + hooks.on("hook", (e: HookEvent) => { + const session = repo.getSessionByTerminal(db, e.terminalId); + if (!session) return; + const status = mapEventToStatus(e.eventType); + repo.updateSession(db, session.id, { + status, + lastEventAt: Date.now(), + }); + // "Working" fires on every tool use — too chatty for the append-only + // event log; it only needs to drive status/column. + if (e.eventType !== "Working") { + repo.recordEvent(db, { + sessionId: session.id, + terminalId: e.terminalId, + eventType: e.eventType, + rawAgentSessionId: e.sessionId ?? null, + }); + } + const task = repo.getTask(db, session.taskId); + if (task) { + const column = mapEventToColumn(e.eventType); + // Subagents fire PreToolUse too, so a Working event must never mask a + // pending question — only an explicit user reply (UserReply), Stop, or + // a fresh Start may move a task out of needs_attention. + if (e.eventType === "Working" && task.column === "needs_attention") { + return; + } + // Skip no-op Working updates so the renderer isn't pinged per tool use. + if (e.eventType === "Working" && task.column === column && task.agentStatus === status) { + return; + } + repo.updateTask(db, task.id, { + agentStatus: status, + column, + lastEventAt: Date.now(), + // Working/Start mean the user just interacted or launched — the + // task isn't "unread"; Stop/PermissionRequest are news for them. + isUnread: e.eventType === "Stop" || e.eventType === "PermissionRequest", + }); + sendTaskUpdated(task.id); + } + }); + + // Agent ran `gh pr merge` in its terminal → the gh shim routed it here. + // Resolve the task from the terminal and enqueue, so terminal merges and the + // in-app Merge button share one serialized queue per base branch. + hooks.on("merge-request", (e: MergeRequestEvent) => { + const session = repo.getSessionByTerminal(db, e.terminalId); + if (!session) return; + const task = repo.getTask(db, session.taskId); + if (!task) return; + const project = repo.getProject(db, task.projectId); + if (!project) return; + const settings = repo.getSettings(db); + const requested = e.strategy ?? ""; + const strategy = ( + ["merge", "squash", "rebase"].includes(requested) + ? requested + : (settings.defaultMergeStrategy ?? "squash") + ) as MergeStrategy; + void mergeQueue.enqueue({ + task, + repoPath: project.repoPath, + strategy, + updateStrategy: settings.defaultUpdateStrategy ?? "merge", + deleteRemoteBranch: settings.deleteRemoteBranchOnMerge ?? false, + }); + }); + + return { + services, + on(event, listener) { + emitter.on(event, listener as (...a: unknown[]) => void); + return () => emitter.off(event, listener as (...a: unknown[]) => void); + }, + sendTaskUpdated, + sendLoopsUpdated() { + emitter.emit("loopsUpdated", loopRunner.describe()); + }, + async connectPty() { + await pty.connect(); + }, + startLoops() { + loopRunner.start(); + }, + stop() { + pty.disconnect(); + hooks.stop(); + loopRunner.stop(); + }, + stopHooks() { + hooks.stop(); + }, + }; +} diff --git a/apps/desktop/src/main/hooks/board-mcp.ts b/packages/server/src/hooks/board-mcp.ts similarity index 100% rename from apps/desktop/src/main/hooks/board-mcp.ts rename to packages/server/src/hooks/board-mcp.ts diff --git a/apps/desktop/src/main/hooks/hook-server.ts b/packages/server/src/hooks/hook-server.ts similarity index 100% rename from apps/desktop/src/main/hooks/hook-server.ts rename to packages/server/src/hooks/hook-server.ts diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts new file mode 100644 index 0000000..ade22da --- /dev/null +++ b/packages/server/src/index.ts @@ -0,0 +1,12 @@ +// @ateam/server — the Ateam engine: git worktrees, agent PTYs, board state, +// hooks, loops, and the merge queue. Electron-free and transport-agnostic, so +// the desktop shell today and the SSH-reachable server later share one engine. +// +// Public API: build the engine, then a dispatcher over it. Each transport +// (Electron ipcMain today, JSON-RPC over SSH next) forwards the engine's events +// and adapts its own request channel to dispatcher.handle(). +export { createEngine } from "./engine"; +export type { Engine, EngineOptions } from "./engine"; +export { createDispatcher } from "./dispatcher"; +export type { Dispatcher } from "./dispatcher"; +export type { Services } from "./services"; diff --git a/apps/desktop/src/main/loops/agent-loop.ts b/packages/server/src/loops/agent-loop.ts similarity index 100% rename from apps/desktop/src/main/loops/agent-loop.ts rename to packages/server/src/loops/agent-loop.ts diff --git a/apps/desktop/src/main/loops/agent-loops.design.md b/packages/server/src/loops/agent-loops.design.md similarity index 100% rename from apps/desktop/src/main/loops/agent-loops.design.md rename to packages/server/src/loops/agent-loops.design.md diff --git a/apps/desktop/src/main/loops/board-organizer.ts b/packages/server/src/loops/board-organizer.ts similarity index 100% rename from apps/desktop/src/main/loops/board-organizer.ts rename to packages/server/src/loops/board-organizer.ts diff --git a/apps/desktop/src/main/loops/board-reconciler.ts b/packages/server/src/loops/board-reconciler.ts similarity index 100% rename from apps/desktop/src/main/loops/board-reconciler.ts rename to packages/server/src/loops/board-reconciler.ts diff --git a/apps/desktop/src/main/loops/board-signals.ts b/packages/server/src/loops/board-signals.ts similarity index 100% rename from apps/desktop/src/main/loops/board-signals.ts rename to packages/server/src/loops/board-signals.ts diff --git a/apps/desktop/src/main/loops/runner.ts b/packages/server/src/loops/runner.ts similarity index 99% rename from apps/desktop/src/main/loops/runner.ts rename to packages/server/src/loops/runner.ts index 1576cbe..96d0af4 100644 --- a/apps/desktop/src/main/loops/runner.ts +++ b/packages/server/src/loops/runner.ts @@ -1,7 +1,7 @@ import { randomUUID } from "node:crypto"; import type { AteamDb, Loop, LoopCadenceMode } from "@ateam/db"; import { repo } from "@ateam/db"; -import type { LoopDTO } from "../../shared/types"; +import type { LoopDTO } from "@ateam/protocol"; import type { MergeQueue } from "../merge-queue"; import { getTemplate } from "./templates"; import type { LoopCadence, LoopContext, LoopDefinition, LoopOutcome } from "./types"; diff --git a/apps/desktop/src/main/loops/session-liveness.ts b/packages/server/src/loops/session-liveness.ts similarity index 100% rename from apps/desktop/src/main/loops/session-liveness.ts rename to packages/server/src/loops/session-liveness.ts diff --git a/apps/desktop/src/main/loops/templates.ts b/packages/server/src/loops/templates.ts similarity index 100% rename from apps/desktop/src/main/loops/templates.ts rename to packages/server/src/loops/templates.ts diff --git a/apps/desktop/src/main/loops/types.ts b/packages/server/src/loops/types.ts similarity index 100% rename from apps/desktop/src/main/loops/types.ts rename to packages/server/src/loops/types.ts diff --git a/apps/desktop/src/main/loops/worktree-triage.ts b/packages/server/src/loops/worktree-triage.ts similarity index 100% rename from apps/desktop/src/main/loops/worktree-triage.ts rename to packages/server/src/loops/worktree-triage.ts diff --git a/apps/desktop/src/main/merge-queue.ts b/packages/server/src/merge-queue.ts similarity index 100% rename from apps/desktop/src/main/merge-queue.ts rename to packages/server/src/merge-queue.ts diff --git a/apps/desktop/src/main/pty/pty-client.ts b/packages/server/src/pty/pty-client.ts similarity index 100% rename from apps/desktop/src/main/pty/pty-client.ts rename to packages/server/src/pty/pty-client.ts diff --git a/apps/desktop/src/main/services.ts b/packages/server/src/services.ts similarity index 95% rename from apps/desktop/src/main/services.ts rename to packages/server/src/services.ts index cf08b0e..9c7d425 100644 --- a/apps/desktop/src/main/services.ts +++ b/packages/server/src/services.ts @@ -1,5 +1,5 @@ import type { AgentSession, AteamDb, Project, Task } from "@ateam/db"; -import type { ProjectDTO, SessionDTO, TaskDTO } from "../shared/types"; +import type { ProjectDTO, SessionDTO, TaskDTO } from "@ateam/protocol"; import type { HookServer } from "./hooks/hook-server"; import type { LoopRunner } from "./loops/runner"; import type { MergeQueue } from "./merge-queue"; diff --git a/apps/desktop/test/agent-loop.test.ts b/packages/server/test/agent-loop.test.ts similarity index 98% rename from apps/desktop/test/agent-loop.test.ts rename to packages/server/test/agent-loop.test.ts index 7fa2cb4..92a6e65 100644 --- a/apps/desktop/test/agent-loop.test.ts +++ b/packages/server/test/agent-loop.test.ts @@ -5,7 +5,7 @@ import { decideContinuation, HARD_MAX_ITERATIONS, resolveMaxIterations, -} from "../src/main/loops/agent-loop"; +} from "../src/loops/agent-loop"; const cfg = (over: Partial = {}): AgentLoopConfig => ({ prompt: "keep fixing failing tests", diff --git a/apps/desktop/test/board-mcp.test.ts b/packages/server/test/board-mcp.test.ts similarity index 98% rename from apps/desktop/test/board-mcp.test.ts rename to packages/server/test/board-mcp.test.ts index 3830ca3..a57d0cf 100644 --- a/apps/desktop/test/board-mcp.test.ts +++ b/packages/server/test/board-mcp.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "bun:test"; -import { type BoardHandlers, dispatchMcp } from "../src/main/hooks/board-mcp"; +import { type BoardHandlers, dispatchMcp } from "../src/hooks/board-mcp"; // A fake board that records what it was called with. function fakeBoard() { diff --git a/apps/desktop/test/board-organizer.test.ts b/packages/server/test/board-organizer.test.ts similarity index 99% rename from apps/desktop/test/board-organizer.test.ts rename to packages/server/test/board-organizer.test.ts index 1d3080e..5b92303 100644 --- a/apps/desktop/test/board-organizer.test.ts +++ b/packages/server/test/board-organizer.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "bun:test"; -import { type SetStatusRequest, validateSetStatus } from "../src/main/loops/board-organizer"; +import { type SetStatusRequest, validateSetStatus } from "../src/loops/board-organizer"; const req = (over: Partial): SetStatusRequest => ({ taskId: "t1", diff --git a/apps/desktop/test/board-signals.test.ts b/packages/server/test/board-signals.test.ts similarity index 97% rename from apps/desktop/test/board-signals.test.ts rename to packages/server/test/board-signals.test.ts index 27bef79..9612236 100644 --- a/apps/desktop/test/board-signals.test.ts +++ b/packages/server/test/board-signals.test.ts @@ -2,8 +2,8 @@ import { Database } from "bun:sqlite"; import { beforeEach, describe, expect, it } from "bun:test"; import { type AteamDb, bootstrap, repo } from "@ateam/db"; import { drizzle } from "drizzle-orm/bun-sqlite"; -import * as schema from "../../../packages/db/src/schema"; -import { applySetStatus } from "../src/main/loops/board-signals"; +import * as schema from "../../db/src/schema"; +import { applySetStatus } from "../src/loops/board-signals"; function createTestDb(): AteamDb { const sqlite = new Database(":memory:"); diff --git a/packages/server/test/dispatcher.test.ts b/packages/server/test/dispatcher.test.ts new file mode 100644 index 0000000..11c72aa --- /dev/null +++ b/packages/server/test/dispatcher.test.ts @@ -0,0 +1,84 @@ +import { describe, expect, it } from "bun:test"; +import { type AteamDb, repo } from "@ateam/db"; +import { CH } from "@ateam/protocol"; +// Reuse the db package's in-memory bun:sqlite test db (better-sqlite3 can't load +// under Bun). Cross-package test helper — the DRY source of a test AteamDb. +import { createTestDb } from "../../db/test/helpers/test-db"; +import type { Engine } from "../src/engine"; +import { createDispatcher } from "../src/dispatcher"; + +// A minimal fake Engine: a real in-memory db for the DB-backed handlers, stubs +// for the pieces those handlers don't touch, and a spy on taskUpdated so we can +// assert the extraction still emits it. +function makeEngine(db: AteamDb) { + const taskUpdated: string[] = []; + const engine = { + services: { + db, + pty: { has: () => false, kill() {}, write() {}, resize() {} }, + hooks: {}, + mergeQueue: {}, + loopRunner: { describe: () => [] }, + userDataDir: "/tmp", + hooksDir: "/tmp/hooks", + notifyScriptPath: "/tmp/notify.sh", + hookPort: 0, + }, + sendTaskUpdated: (id: string) => taskUpdated.push(id), + sendLoopsUpdated: () => {}, + } as unknown as Engine; + return { engine, taskUpdated }; +} + +describe("createDispatcher", () => { + it("exposes engine methods but not the client-native ones", () => { + const { engine } = makeEngine(createTestDb()); + const d = createDispatcher(engine); + // Representative engine methods are routed… + expect(d.methods).toContain(CH.tasksList); + expect(d.methods).toContain(CH.gitCommit); + expect(d.methods).toContain(CH.ptyWrite); + // …and the Electron-only handlers are NOT (they live in the desktop shell). + expect(d.methods).not.toContain(CH.projectsPick); + expect(d.methods).not.toContain(CH.utilStageImage); + expect(d.methods).not.toContain(CH.utilStageImagePath); + }); + + it("throws on an unknown method", () => { + const { engine } = makeEngine(createTestDb()); + const d = createDispatcher(engine); + expect(d.handle("does:not-exist", [])).rejects.toThrow(/Unknown method/); + }); + + it("lists tasks and moves a card, emitting taskUpdated", async () => { + const db = createTestDb(); + const { engine, taskUpdated } = makeEngine(db); + const d = createDispatcher(engine); + + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A", defaultBranch: "main" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "do a thing", + slug: "do-a-thing", + branch: "do-a-thing", + baseBranch: "main", + worktreePath: "/r/a/.ateam/worktrees/do-a-thing", + }); + + const listed = (await d.handle(CH.tasksList, [project!.id])) as Array<{ id: string }>; + expect(listed.map((t) => t.id)).toEqual([task.id]); + + const moved = (await d.handle(CH.tasksSetColumn, [task.id, "review"])) as { column: string }; + expect(moved.column).toBe("review"); + // The extracted handler must still broadcast the move. + expect(taskUpdated).toContain(task.id); + // …and it persisted. + expect(repo.getTask(db, task.id)?.column).toBe("review"); + }); + + it("registers no project rows for an empty db", async () => { + const { engine } = makeEngine(createTestDb()); + const d = createDispatcher(engine); + expect(await d.handle(CH.projectsList, [])).toEqual([]); + }); +}); diff --git a/apps/desktop/test/loops-runner.test.ts b/packages/server/test/loops-runner.test.ts similarity index 96% rename from apps/desktop/test/loops-runner.test.ts rename to packages/server/test/loops-runner.test.ts index a0c9d0b..4f4289d 100644 --- a/apps/desktop/test/loops-runner.test.ts +++ b/packages/server/test/loops-runner.test.ts @@ -3,9 +3,9 @@ import { beforeEach, describe, expect, it } from "bun:test"; import type { AteamDb } from "@ateam/db"; import { bootstrap, repo } from "@ateam/db"; import { drizzle } from "drizzle-orm/bun-sqlite"; -import * as schema from "../../../packages/db/src/schema"; -import { LoopRunner } from "../src/main/loops/runner"; -import type { LoopDefinition } from "../src/main/loops/types"; +import * as schema from "../../db/src/schema"; +import { LoopRunner } from "../src/loops/runner"; +import type { LoopDefinition } from "../src/loops/types"; function createTestDb(): AteamDb { const sqlite = new Database(":memory:"); diff --git a/apps/desktop/test/worktree-triage.test.ts b/packages/server/test/worktree-triage.test.ts similarity index 98% rename from apps/desktop/test/worktree-triage.test.ts rename to packages/server/test/worktree-triage.test.ts index efd5695..9393006 100644 --- a/apps/desktop/test/worktree-triage.test.ts +++ b/packages/server/test/worktree-triage.test.ts @@ -3,7 +3,7 @@ import { CONVERSATION_GAP_MS, triageWorktree, type WorktreeSignals, -} from "../src/main/loops/worktree-triage"; +} from "../src/loops/worktree-triage"; const NOW = 1_000_000_000_000; const HOUR = 3_600_000; diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 0000000..4e0e7f6 --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { "rootDir": "." }, + "include": ["src/**/*.ts"] +} From e1e7e68bfd50cd334502c6255568518a6c3415e1 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 5 Jul 2026 22:09:32 +0200 Subject: [PATCH 02/83] feat(protocol,server): transport-agnostic JSON-RPC layer for remote clients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the request/response + event framing a remote client (SSH stdio, WebSocket) uses to drive the engine — over the same dispatcher and engine the desktop already runs locally. - @ateam/protocol: RpcRequest/Response/Event frames + createRpcClient (pure, browser-safe) — correlates responses by id, fans out event notifications, rejects in-flight calls on disconnect. - @ateam/server: serveRpc(engine, dispatcher, transport) forwards the engine's four events as notifications and answers requests via the dispatcher; returns dispose() that frees subscriptions when a client drops. Proven with an in-memory transport pair driving the real dispatcher: request roundtrip, unknown-method rejection, event delivery triggered by a call, and silence after dispose. 100 tests pass. The desktop stays on native Electron IPC (the right local transport, already routed through the dispatcher); JSON-RPC is the remote path. The client-side AteamApi builder over createRpcClient lands with the SSH client (Phase 4), where the client-local bits (webUtils.pathForFile) resolve in context. shortcut: createRpcClient has no per-call timeout (onClose rejects in-flight calls); add one with the SSH transport, where a lost reply on a live socket would hang. --- packages/protocol/src/index.ts | 3 + packages/protocol/src/rpc.ts | 91 ++++++++++++++++++++++++ packages/server/src/index.ts | 2 + packages/server/src/rpc.ts | 52 ++++++++++++++ packages/server/test/rpc.test.ts | 117 +++++++++++++++++++++++++++++++ 5 files changed, 265 insertions(+) create mode 100644 packages/protocol/src/rpc.ts create mode 100644 packages/server/src/rpc.ts create mode 100644 packages/server/test/rpc.test.ts diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 9573f05..2e43120 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -337,3 +337,6 @@ export interface AteamApi { stageImagePath(path: string): Promise; }; } + +// Transport-agnostic RPC framing + client (shared by every transport). +export * from "./rpc"; diff --git a/packages/protocol/src/rpc.ts b/packages/protocol/src/rpc.ts new file mode 100644 index 0000000..488f74b --- /dev/null +++ b/packages/protocol/src/rpc.ts @@ -0,0 +1,91 @@ +// Transport-agnostic RPC framing for driving the engine from a client — the +// same wire the desktop's Electron IPC and the SSH stdio channel both carry. +// Requests correlate to responses by id; the server pushes engine events as +// notifications. PTY bytes ride as `evt` payloads (already base64 in the daemon +// protocol), so there is one framed channel, not a special-cased binary lane. + +export interface RpcRequest { + t: "req"; + id: number; + method: string; + args: unknown[]; +} +export type RpcResponse = + | { t: "res"; id: number; ok: true; result: unknown } + | { t: "res"; id: number; ok: false; error: string }; +export interface RpcEvent { + t: "evt"; + event: string; + payload: unknown; +} +/** Frames the server sends to the client. */ +export type ServerFrame = RpcResponse | RpcEvent; +/** Frames the client sends to the server. */ +export type ClientFrame = RpcRequest; + +/** + * The client's view of a bidirectional, whole-frame message channel — Electron + * IPC, an SSH stdio pipe, or a WebSocket. Framing/serialization is the + * transport's job; this layer only deals in decoded frames. + */ +export interface ClientTransport { + send(frame: ClientFrame): void; + onFrame(handler: (frame: ServerFrame) => void): void; + /** Optional: fires when the channel drops, so in-flight calls can reject. */ + onClose?(handler: () => void): void; +} + +export interface RpcClient { + /** Invoke an engine method; resolves with its result or rejects on error. */ + call(method: string, args?: unknown[]): Promise; + /** Subscribe to a server event (taskUpdated, ptyData, …); returns unsubscribe. */ + on(event: string, handler: (payload: unknown) => void): () => void; +} + +export function createRpcClient(transport: ClientTransport): RpcClient { + let nextId = 1; + const pending = new Map void; reject: (e: Error) => void }>(); + const listeners = new Map void>>(); + + transport.onFrame((frame) => { + if (frame.t === "res") { + const p = pending.get(frame.id); + if (!p) return; + pending.delete(frame.id); + if (frame.ok) p.resolve(frame.result); + else p.reject(new Error(frame.error)); + } else { + const set = listeners.get(frame.event); + if (set) for (const l of [...set]) l(frame.payload); + } + }); + + transport.onClose?.(() => { + for (const p of pending.values()) p.reject(new Error("RPC connection closed")); + pending.clear(); + }); + + return { + call(method, args = []) { + const id = nextId++; + return new Promise((resolve, reject) => { + pending.set(id, { resolve, reject }); + // shortcut: no per-call timeout. onClose rejects in-flight calls when + // the channel drops; add a timeout once the SSH transport lands, where + // a lost reply on a still-open socket would otherwise hang forever. + transport.send({ t: "req", id, method, args }); + }); + }, + on(event, handler) { + let set = listeners.get(event); + if (!set) { + set = new Set(); + listeners.set(event, set); + } + set.add(handler); + return () => { + set.delete(handler); + }; + }, + }; +} diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index ade22da..8862d97 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -10,3 +10,5 @@ export type { Engine, EngineOptions } from "./engine"; export { createDispatcher } from "./dispatcher"; export type { Dispatcher } from "./dispatcher"; export type { Services } from "./services"; +export { serveRpc } from "./rpc"; +export type { ServerTransport } from "./rpc"; diff --git a/packages/server/src/rpc.ts b/packages/server/src/rpc.ts new file mode 100644 index 0000000..96306af --- /dev/null +++ b/packages/server/src/rpc.ts @@ -0,0 +1,52 @@ +// Serve one client connection: forward the engine's events as notifications and +// answer its requests through the dispatcher. Transport-agnostic — the desktop +// hands it an Electron-IPC connection, the SSH server an stdio one — so every +// client drives the identical engine + dispatcher. +import { errorMessage } from "@ateam/git-core"; +import type { ClientFrame, ServerFrame } from "@ateam/protocol"; +import type { Dispatcher } from "./dispatcher"; +import type { Engine } from "./engine"; + +/** The server's view of a bidirectional, whole-frame message channel. */ +export interface ServerTransport { + send(frame: ServerFrame): void; + onFrame(handler: (frame: ClientFrame) => void): void; + /** Optional: fires when the client disconnects, so subscriptions are freed. */ + onClose?(handler: () => void): void; +} + +/** + * Wire an engine + dispatcher to one client connection. Returns a cleanup that + * removes the event subscriptions — call it (or fire the transport's onClose) + * when the client goes away, so a dropped client never leaks listeners or keeps + * pushing into a dead channel. The engine and its PTY sessions live on. + */ +export function serveRpc( + engine: Engine, + dispatcher: Dispatcher, + transport: ServerTransport, +): () => void { + const forward = (event: string) => (payload: unknown) => + transport.send({ t: "evt", event, payload }); + const unsubscribe = [ + engine.on("taskUpdated", forward("taskUpdated")), + engine.on("loopsUpdated", forward("loopsUpdated")), + engine.on("ptyData", forward("ptyData")), + engine.on("ptyExit", forward("ptyExit")), + ]; + const dispose = () => { + for (const u of unsubscribe) u(); + }; + + transport.onFrame(async (frame) => { + if (frame.t !== "req") return; + try { + const result = await dispatcher.handle(frame.method, frame.args); + transport.send({ t: "res", id: frame.id, ok: true, result }); + } catch (err) { + transport.send({ t: "res", id: frame.id, ok: false, error: errorMessage(err) }); + } + }); + transport.onClose?.(dispose); + return dispose; +} diff --git a/packages/server/test/rpc.test.ts b/packages/server/test/rpc.test.ts new file mode 100644 index 0000000..6f86d13 --- /dev/null +++ b/packages/server/test/rpc.test.ts @@ -0,0 +1,117 @@ +import { EventEmitter } from "node:events"; +import { describe, expect, it } from "bun:test"; +import { type AteamDb, repo } from "@ateam/db"; +import { CH, type ClientFrame, createRpcClient, type ServerFrame } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; + +// In-memory transport pair: whatever one side sends, the other receives — the +// stand-in for Electron IPC / SSH stdio, proving the layer is transport-neutral. +function makePair() { + let toClient: ((f: ServerFrame) => void) | null = null; + let toServer: ((f: ClientFrame) => void) | null = null; + const server = { + send: (f: ServerFrame) => toClient?.(f), + onFrame: (cb: (f: ClientFrame) => void) => { + toServer = cb; + }, + onClose: () => {}, + }; + const client = { + send: (f: ClientFrame) => toServer?.(f), + onFrame: (cb: (f: ServerFrame) => void) => { + toClient = cb; + }, + }; + return { server, client }; +} + +// A fake engine with a real emitter: the dispatcher's DB-backed handlers run for +// real, and sendTaskUpdated emits so we can assert events reach the client. +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { + db, + pty: { has: () => false }, + mergeQueue: {}, + loopRunner: { describe: () => [] }, + }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: (id: string) => ee.emit("taskUpdated", { id }), + sendLoopsUpdated: () => ee.emit("loopsUpdated", []), + } as unknown as Engine; +} + +function seedTask(db: AteamDb) { + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "t", + slug: "t", + branch: "t", + baseBranch: "main", + worktreePath: "/r/a/w/t", + }); + return { projectId: project!.id, task }; +} + +describe("serveRpc + createRpcClient over an in-memory transport", () => { + it("round-trips a request through the real dispatcher", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const { server, client } = makePair(); + serveRpc(engine, createDispatcher(engine), server); + const rpc = createRpcClient(client); + + const { projectId, task } = seedTask(db); + const listed = (await rpc.call(CH.tasksList, [projectId])) as Array<{ id: string }>; + expect(listed.map((t) => t.id)).toEqual([task.id]); + }); + + it("rejects an unknown method with the server's error", async () => { + const engine = makeEngine(createTestDb()); + const { server, client } = makePair(); + serveRpc(engine, createDispatcher(engine), server); + const rpc = createRpcClient(client); + expect(rpc.call("nope:nope", [])).rejects.toThrow(/Unknown method/); + }); + + it("delivers engine events triggered by a call as notifications", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const { server, client } = makePair(); + serveRpc(engine, createDispatcher(engine), server); + const rpc = createRpcClient(client); + + const { task } = seedTask(db); + const events: Array<{ id: string }> = []; + rpc.on("taskUpdated", (p) => events.push(p as { id: string })); + + const moved = (await rpc.call(CH.tasksSetColumn, [task.id, "review"])) as { column: string }; + expect(moved.column).toBe("review"); + // The setColumn handler's sendTaskUpdated must reach the client as an event. + expect(events.map((e) => e.id)).toContain(task.id); + }); + + it("stops delivering events after dispose", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const { server, client } = makePair(); + const dispose = serveRpc(engine, createDispatcher(engine), server); + const rpc = createRpcClient(client); + + const { task } = seedTask(db); + const events: string[] = []; + rpc.on("taskUpdated", () => events.push("hit")); + + dispose(); // client disconnected — subscriptions freed + engine.sendTaskUpdated(task.id); + expect(events).toEqual([]); + }); +}); From 5f0ddc91e8e8822407716eee16f7962b47bbf2cc Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 5 Jul 2026 22:20:55 +0200 Subject: [PATCH 03/83] feat(server): ateam CLI (daemon + attach relay) over a socket RPC transport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The server-side piece for remote operation: run `ateam daemon` on a box to host the engine over a unix socket, and `ateam attach --stdio` as the stateless relay that `ssh host ateam attach --stdio` execs. - transport/socket.ts: newline-delimited JSON framing over net.Socket (socketServer/ClientTransport) — the same one-object-per-line wire the PTY daemon already uses. - cli.ts: `daemon` runs createEngine + serveRpc per connection (single stateful owner — clients come and go, the engine and its PTY sessions persist); `attach` is a dumb stdin<->socket pipe that auto-starts the daemon if absent. Proven over a REAL unix socket: request roundtrip, an event streamed before its response, and unknown-method error — createRpcClient <-> serveRpc across socketClient/ServerTransport. 103 tests pass. Box-deferred to Phase 4's Hetzner milestone (flagged inline in cli.ts): the daemon runs under Node with node-pty/better-sqlite3 rebuilt (better-sqlite3 can't load under Bun), the PTY daemon bundle shipped beside the bin, and this TS compiled to JS. Adds @types/node to the server package (bun-types mistypes net.Server). shortcut: attach auto-start retries once after 500ms; harden the retry/backoff when standing the first real server. --- bun.lock | 4 + packages/server/package.json | 2 + packages/server/src/cli.ts | 108 ++++++++++++++++++++++++ packages/server/src/transport/socket.ts | 74 ++++++++++++++++ packages/server/test/socket.test.ts | 92 ++++++++++++++++++++ packages/server/tsconfig.json | 5 +- 6 files changed, 284 insertions(+), 1 deletion(-) create mode 100755 packages/server/src/cli.ts create mode 100644 packages/server/src/transport/socket.ts create mode 100644 packages/server/test/socket.test.ts diff --git a/bun.lock b/bun.lock index 72c3d00..8a7919a 100644 --- a/bun.lock +++ b/bun.lock @@ -82,6 +82,9 @@ "packages/server": { "name": "@ateam/server", "version": "0.0.0", + "bin": { + "ateam": "./src/cli.ts", + }, "dependencies": { "@ateam/agents": "workspace:*", "@ateam/db": "workspace:*", @@ -89,6 +92,7 @@ "@ateam/protocol": "workspace:*", }, "devDependencies": { + "@types/node": "^22.10.5", "drizzle-orm": "^0.38.4", }, }, diff --git a/packages/server/package.json b/packages/server/package.json index c455658..6dff990 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -6,6 +6,7 @@ "main": "./src/index.ts", "types": "./src/index.ts", "exports": { ".": "./src/index.ts" }, + "bin": { "ateam": "./src/cli.ts" }, "scripts": { "test": "bun test", "typecheck": "tsc --noEmit" @@ -17,6 +18,7 @@ "@ateam/protocol": "workspace:*" }, "devDependencies": { + "@types/node": "^22.10.5", "drizzle-orm": "^0.38.4" } } diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts new file mode 100755 index 0000000..28f90d4 --- /dev/null +++ b/packages/server/src/cli.ts @@ -0,0 +1,108 @@ +#!/usr/bin/env node +// The `ateam` server CLI — the piece that runs on a remote box (your Hetzner +// server) so a client can drive the engine over SSH. +// +// ateam daemon Persistent engine: SQLite + hooks + the board state +// machine + RPC, listening on a unix socket. Owns all +// durable state; outlives any client. Run under Node with +// node-pty/better-sqlite3 native modules built for it. +// ateam attach --stdio Stateless relay: pipes stdin⇄the daemon socket. This +// is what `ssh host ateam attach --stdio` execs — it holds +// no state, so its death never touches the daemon or its +// PTY sessions. The far-end client frames JSON-RPC; this +// just moves bytes. +// +// shortcut: dist/runtime is box-packaging work — the daemon needs Node (not Bun: +// better-sqlite3 can't load under Bun) with native modules rebuilt, the PTY +// daemon bundle (ATEAM_PTY_DAEMON) shipped beside it, and this TS compiled to +// JS. Wire that up when standing the first server; the logic below is runtime- +// agnostic. +import { spawn } from "node:child_process"; +import { existsSync, mkdirSync, unlinkSync } from "node:fs"; +import { connect, createServer, type Socket } from "node:net"; +import { homedir } from "node:os"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { createDispatcher } from "./dispatcher"; +import { createEngine } from "./engine"; +import { serveRpc } from "./rpc"; +import { socketServerTransport } from "./transport/socket"; + +const SOCK = process.env.ATEAM_RPC_SOCK ?? join(homedir(), ".ateam", "rpc.sock"); + +async function runDaemon(): Promise { + const dataDir = process.env.ATEAM_DATA_DIR ?? join(homedir(), ".ateam"); + // The PTY daemon bundle (node-pty + xterm). Shipped beside the ateam bin on + // the server; overridable for dev. + const ptyDaemon = + process.env.ATEAM_PTY_DAEMON ?? join(dirname(fileURLToPath(import.meta.url)), "daemon.js"); + + const engine = await createEngine({ dataDir, daemonPath: ptyDaemon, execPath: process.execPath }); + // Best-effort: serve RPC (git/tasks/board) even if the PTY daemon isn't up + // yet — agent spawning reconnects lazily, mirroring the desktop. + try { + await engine.connectPty(); + } catch (err) { + console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); + } + engine.startLoops(); + const dispatcher = createDispatcher(engine); + + const dir = dirname(SOCK); + if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); + // Clear a stale socket file; if a daemon were actually live, listen() below + // would EADDRINUSE and we'd exit rather than steal its socket. + try { + if (existsSync(SOCK)) unlinkSync(SOCK); + } catch { + /* best-effort */ + } + + const server = createServer((sock: Socket) => { + // Each client gets its own serveRpc over one connection; the engine (and + // its PTY sessions) is shared and outlives any single client. + serveRpc(engine, dispatcher, socketServerTransport(sock)); + }); + server.on("error", (err) => { + console.error(`[ateam] daemon error: ${err.message}`); + process.exit(1); + }); + server.listen(SOCK, () => console.log(`[ateam] daemon listening at ${SOCK}`)); +} + +function runAttach(): void { + const relay = (spawnedDaemon: boolean): void => { + const sock = connect(SOCK); + sock.once("connect", () => { + process.stdin.pipe(sock); + sock.pipe(process.stdout); + process.stdin.on("end", () => sock.end()); + }); + sock.once("error", (err: NodeJS.ErrnoException) => { + if (err.code === "ECONNREFUSED" && !spawnedDaemon) { + // No daemon yet — start one detached and retry once. + spawn(process.execPath, [fileURLToPath(import.meta.url), "daemon"], { + detached: true, + stdio: "ignore", + }).unref(); + setTimeout(() => relay(true), 500); + return; + } + console.error(`[ateam] attach failed: ${err.message}`); + process.exit(1); + }); + sock.on("close", () => process.exit(0)); + }; + relay(false); +} + +const cmd = process.argv[2]; +if (cmd === "daemon") { + void runDaemon(); +} else if (cmd === "attach") { + // `--stdio` is the only (and default) mode today; accepted for forward-compat. + runAttach(); +} else { + console.error("usage: ateam "); + process.exit(2); +} diff --git a/packages/server/src/transport/socket.ts b/packages/server/src/transport/socket.ts new file mode 100644 index 0000000..d9ec4cc --- /dev/null +++ b/packages/server/src/transport/socket.ts @@ -0,0 +1,74 @@ +// Newline-delimited JSON framing over a net.Socket — the wire the ateam daemon +// speaks to local clients and through the `attach --stdio` relay. Same framing +// the PTY daemon and PtyClient already use: one JSON object per line. +import type { Socket } from "node:net"; +import type { ClientFrame, ClientTransport, ServerFrame } from "@ateam/protocol"; +import type { ServerTransport } from "../rpc"; + +function readLines(socket: Socket, onLine: (line: string) => void): void { + let buf = ""; + socket.on("data", (chunk) => { + buf += chunk.toString("utf8"); + let nl: number; + // biome-ignore lint/suspicious/noAssignInExpressions: stream framing + while ((nl = buf.indexOf("\n")) !== -1) { + const line = buf.slice(0, nl); + buf = buf.slice(nl + 1); + if (line.trim()) onLine(line); + } + }); +} + +/** Fire `handler` exactly once, on the socket's first close or error. */ +function onceClosed(socket: Socket, handler: () => void): void { + let done = false; + const fire = () => { + if (done) return; + done = true; + handler(); + }; + socket.on("close", fire); + socket.on("error", fire); +} + +/** Server side of a socket connection: receives ClientFrames, sends ServerFrames. */ +export function socketServerTransport(socket: Socket): ServerTransport { + return { + send(frame: ServerFrame) { + socket.write(`${JSON.stringify(frame)}\n`); + }, + onFrame(handler) { + readLines(socket, (line) => { + try { + handler(JSON.parse(line) as ClientFrame); + } catch { + /* ignore malformed */ + } + }); + }, + onClose(handler) { + onceClosed(socket, handler); + }, + }; +} + +/** Client side of a socket connection: sends ClientFrames, receives ServerFrames. */ +export function socketClientTransport(socket: Socket): ClientTransport { + return { + send(frame: ClientFrame) { + socket.write(`${JSON.stringify(frame)}\n`); + }, + onFrame(handler) { + readLines(socket, (line) => { + try { + handler(JSON.parse(line) as ServerFrame); + } catch { + /* ignore malformed */ + } + }); + }, + onClose(handler) { + onceClosed(socket, handler); + }, + }; +} diff --git a/packages/server/test/socket.test.ts b/packages/server/test/socket.test.ts new file mode 100644 index 0000000..a4358f7 --- /dev/null +++ b/packages/server/test/socket.test.ts @@ -0,0 +1,92 @@ +import { EventEmitter } from "node:events"; +import { connect, createServer, type Server } from "node:net"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { afterEach, describe, expect, it } from "bun:test"; +import { type AteamDb, repo } from "@ateam/db"; +import { CH, createRpcClient } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; +import { socketClientTransport, socketServerTransport } from "../src/transport/socket"; + +let counter = 0; +const servers: Server[] = []; + +afterEach(() => { + for (const s of servers.splice(0)) s.close(); +}); + +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { db, pty: { has: () => false }, mergeQueue: {}, loopRunner: { describe: () => [] } }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: (id: string) => ee.emit("taskUpdated", { id }), + sendLoopsUpdated: () => ee.emit("loopsUpdated", []), + } as unknown as Engine; +} + +// Stand up a daemon-like RPC server on a temp unix socket, then a connected +// RpcClient — the same socketServer/Client transports the `ateam` daemon uses. +async function connectPair(db: AteamDb) { + const engine = makeEngine(db); + const dispatcher = createDispatcher(engine); + const sockPath = join(tmpdir(), `ateam-t${process.pid}-${counter++}.sock`); + const server = createServer((sock) => serveRpc(engine, dispatcher, socketServerTransport(sock))); + servers.push(server); + await new Promise((res) => server.listen(sockPath, res)); + const sock = connect(sockPath); + await new Promise((res) => sock.once("connect", () => res())); + const rpc = createRpcClient(socketClientTransport(sock)); + return { rpc, sock }; +} + +function seedTask(db: AteamDb) { + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "t", + slug: "t", + branch: "t", + baseBranch: "main", + worktreePath: "/r/a/w/t", + }); + return { projectId: project!.id, task }; +} + +describe("RPC over a real unix socket", () => { + it("round-trips a request through the dispatcher", async () => { + const db = createTestDb(); + const { rpc, sock } = await connectPair(db); + const { projectId, task } = seedTask(db); + + const listed = (await rpc.call(CH.tasksList, [projectId])) as Array<{ id: string }>; + expect(listed.map((t) => t.id)).toEqual([task.id]); + sock.end(); + }); + + it("streams an engine event over the socket, then a response", async () => { + const db = createTestDb(); + const { rpc, sock } = await connectPair(db); + const { task } = seedTask(db); + + const events: string[] = []; + rpc.on("taskUpdated", (p) => events.push((p as { id: string }).id)); + + const moved = (await rpc.call(CH.tasksSetColumn, [task.id, "review"])) as { column: string }; + expect(moved.column).toBe("review"); + expect(events).toContain(task.id); + sock.end(); + }); + + it("surfaces the server error for an unknown method", async () => { + const { rpc, sock } = await connectPair(createTestDb()); + expect(rpc.call("nope:nope", [])).rejects.toThrow(/Unknown method/); + sock.end(); + }); +}); diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 4e0e7f6..ba4fd5f 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -1,5 +1,8 @@ { "extends": "../../tsconfig.base.json", - "compilerOptions": { "rootDir": "." }, + // A node-runtime package (net/child_process/…) with bun:test tests — needs + // both type roots. bun-types alone mistypes net.Server. + "compilerOptions": { "rootDir": ".", "types": ["node", "bun"] }, + // Tests run under bun:test (not tsc), matching the desktop convention. "include": ["src/**/*.ts"] } From 51f6240a87bdd4d00c374e7032fc47209a385e50 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 5 Jul 2026 23:57:53 +0200 Subject: [PATCH 04/83] =?UTF-8?q?feat(server):=20SSH=20client=20transport?= =?UTF-8?q?=20=E2=80=94=20proven=20driving=20the=20engine=20over=20live=20?= =?UTF-8?q?SSH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the client-side transport for remote operation and validates the whole RPC wire over real SSH+tailscale to a Hetzner box. - transport/stream.ts: newline-JSON framing over any read+write stream pair (a duplex socket, or a child's stdout+stdin). socket transports now delegate to it — one framing implementation behind both. - transport/ssh.ts: sshClientTransport(host, remoteArgs) spawns `ssh host …`, speaks RPC over the child's stdio (stderr inherited), returns a ClientTransport + the child. Host/keys/ProxyJump stay OpenSSH's job. Stage-A proof (manual, needs a box): from a Mac, sshClientTransport + createRpcClient drove a stub serveRpc running under node on a Hetzner box over tailscale — the request executed ON the box (ranOn=), multiple calls shared one channel, and server errors propagated. ~600ms first-call RTT. stream.test.ts covers the separate read/write stream case (the SSH shape) via PassThrough pipes. 104 tests pass. shortcut: no keepalive/reconnect on the ssh child yet — add ServerAliveInterval + auto-reconnect with the connection manager (Phase 5). board box footprint fully cleaned; no changes left on the server. --- packages/server/src/index.ts | 4 ++ packages/server/src/transport/socket.ts | 70 ++--------------------- packages/server/src/transport/ssh.ts | 40 +++++++++++++ packages/server/src/transport/stream.ts | 76 +++++++++++++++++++++++++ packages/server/test/stream.test.ts | 56 ++++++++++++++++++ 5 files changed, 182 insertions(+), 64 deletions(-) create mode 100644 packages/server/src/transport/ssh.ts create mode 100644 packages/server/src/transport/stream.ts create mode 100644 packages/server/test/stream.test.ts diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 8862d97..a039695 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -12,3 +12,7 @@ export type { Dispatcher } from "./dispatcher"; export type { Services } from "./services"; export { serveRpc } from "./rpc"; export type { ServerTransport } from "./rpc"; +export { sshClientTransport } from "./transport/ssh"; +export type { SshClient, SshOptions } from "./transport/ssh"; +export { socketClientTransport, socketServerTransport } from "./transport/socket"; +export { streamClientTransport, streamServerTransport } from "./transport/stream"; diff --git a/packages/server/src/transport/socket.ts b/packages/server/src/transport/socket.ts index d9ec4cc..a51efe7 100644 --- a/packages/server/src/transport/socket.ts +++ b/packages/server/src/transport/socket.ts @@ -1,74 +1,16 @@ -// Newline-delimited JSON framing over a net.Socket — the wire the ateam daemon -// speaks to local clients and through the `attach --stdio` relay. Same framing -// the PTY daemon and PtyClient already use: one JSON object per line. +// Socket transports: a net.Socket is a duplex stream (readable === writable), +// so both sides are just the generic stream framing over that one socket. import type { Socket } from "node:net"; -import type { ClientFrame, ClientTransport, ServerFrame } from "@ateam/protocol"; +import type { ClientTransport } from "@ateam/protocol"; import type { ServerTransport } from "../rpc"; - -function readLines(socket: Socket, onLine: (line: string) => void): void { - let buf = ""; - socket.on("data", (chunk) => { - buf += chunk.toString("utf8"); - let nl: number; - // biome-ignore lint/suspicious/noAssignInExpressions: stream framing - while ((nl = buf.indexOf("\n")) !== -1) { - const line = buf.slice(0, nl); - buf = buf.slice(nl + 1); - if (line.trim()) onLine(line); - } - }); -} - -/** Fire `handler` exactly once, on the socket's first close or error. */ -function onceClosed(socket: Socket, handler: () => void): void { - let done = false; - const fire = () => { - if (done) return; - done = true; - handler(); - }; - socket.on("close", fire); - socket.on("error", fire); -} +import { streamClientTransport, streamServerTransport } from "./stream"; /** Server side of a socket connection: receives ClientFrames, sends ServerFrames. */ export function socketServerTransport(socket: Socket): ServerTransport { - return { - send(frame: ServerFrame) { - socket.write(`${JSON.stringify(frame)}\n`); - }, - onFrame(handler) { - readLines(socket, (line) => { - try { - handler(JSON.parse(line) as ClientFrame); - } catch { - /* ignore malformed */ - } - }); - }, - onClose(handler) { - onceClosed(socket, handler); - }, - }; + return streamServerTransport(socket, socket); } /** Client side of a socket connection: sends ClientFrames, receives ServerFrames. */ export function socketClientTransport(socket: Socket): ClientTransport { - return { - send(frame: ClientFrame) { - socket.write(`${JSON.stringify(frame)}\n`); - }, - onFrame(handler) { - readLines(socket, (line) => { - try { - handler(JSON.parse(line) as ServerFrame); - } catch { - /* ignore malformed */ - } - }); - }, - onClose(handler) { - onceClosed(socket, handler); - }, - }; + return streamClientTransport(socket, socket); } diff --git a/packages/server/src/transport/ssh.ts b/packages/server/src/transport/ssh.ts new file mode 100644 index 0000000..e202848 --- /dev/null +++ b/packages/server/src/transport/ssh.ts @@ -0,0 +1,40 @@ +// Client-side SSH transport: spawn `ssh ` and speak the +// RPC protocol over the child's stdio. The remote command is `ateam attach +// --stdio` (which relays to the daemon); its stdout/stdin carry newline-JSON +// frames, stderr is inherited so ssh/auth errors surface. This is the transport +// a desktop/mobile client wraps in createRpcClient to drive a remote engine. +import { type ChildProcess, spawn } from "node:child_process"; +import type { ClientTransport } from "@ateam/protocol"; +import { streamClientTransport } from "./stream"; + +export interface SshClient { + transport: ClientTransport; + child: ChildProcess; + /** Kill the ssh child (ends the relay; the remote daemon and its sessions live on). */ + close(): void; +} + +export interface SshOptions { + /** Extra `ssh` flags placed before the host (e.g. ["-i", keyPath, "-o", "BatchMode=yes"]). */ + sshFlags?: string[]; +} + +/** + * Open an RPC transport to `host` by running `remoteArgs` over SSH. `host` is an + * ssh destination (`user@host`, or an ssh_config alias — ProxyJump/keys/known_hosts + * are OpenSSH's job, not ours). + */ +export function sshClientTransport( + host: string, + remoteArgs: string[], + opts: SshOptions = {}, +): SshClient { + const child = spawn("ssh", [...(opts.sshFlags ?? []), host, ...remoteArgs], { + stdio: ["pipe", "pipe", "inherit"], + }); + if (!child.stdout || !child.stdin) { + throw new Error("ssh child is missing stdio pipes"); + } + const transport = streamClientTransport(child.stdout, child.stdin); + return { transport, child, close: () => child.kill() }; +} diff --git a/packages/server/src/transport/stream.ts b/packages/server/src/transport/stream.ts new file mode 100644 index 0000000..8188c7c --- /dev/null +++ b/packages/server/src/transport/stream.ts @@ -0,0 +1,76 @@ +// Newline-delimited JSON framing over any read+write stream pair — a duplex +// socket (readable === writable) or a child process's stdout+stdin (the SSH +// relay). The one framing implementation behind both socket and ssh transports. +import type { Readable, Writable } from "node:stream"; +import type { ClientFrame, ClientTransport, ServerFrame } from "@ateam/protocol"; +import type { ServerTransport } from "../rpc"; + +function readLines(readable: Readable, onLine: (line: string) => void): void { + let buf = ""; + readable.on("data", (chunk: Buffer | string) => { + buf += typeof chunk === "string" ? chunk : chunk.toString("utf8"); + let nl: number; + // biome-ignore lint/suspicious/noAssignInExpressions: stream framing + while ((nl = buf.indexOf("\n")) !== -1) { + const line = buf.slice(0, nl); + buf = buf.slice(nl + 1); + if (line.trim()) onLine(line); + } + }); +} + +/** Fire `handler` once, on the first close/error of either stream. */ +function onceClosed(readable: Readable, writable: Writable, handler: () => void): void { + let done = false; + const fire = () => { + if (done) return; + done = true; + handler(); + }; + readable.on("close", fire); + readable.on("error", fire); + writable.on("close", fire); + writable.on("error", fire); +} + +/** Server side: reads ClientFrames, writes ServerFrames. */ +export function streamServerTransport(readable: Readable, writable: Writable): ServerTransport { + return { + send(frame: ServerFrame) { + writable.write(`${JSON.stringify(frame)}\n`); + }, + onFrame(handler) { + readLines(readable, (line) => { + try { + handler(JSON.parse(line) as ClientFrame); + } catch { + /* ignore malformed */ + } + }); + }, + onClose(handler) { + onceClosed(readable, writable, handler); + }, + }; +} + +/** Client side: writes ClientFrames, reads ServerFrames. */ +export function streamClientTransport(readable: Readable, writable: Writable): ClientTransport { + return { + send(frame: ClientFrame) { + writable.write(`${JSON.stringify(frame)}\n`); + }, + onFrame(handler) { + readLines(readable, (line) => { + try { + handler(JSON.parse(line) as ServerFrame); + } catch { + /* ignore malformed */ + } + }); + }, + onClose(handler) { + onceClosed(readable, writable, handler); + }, + }; +} diff --git a/packages/server/test/stream.test.ts b/packages/server/test/stream.test.ts new file mode 100644 index 0000000..5beebfc --- /dev/null +++ b/packages/server/test/stream.test.ts @@ -0,0 +1,56 @@ +import { EventEmitter } from "node:events"; +import { PassThrough } from "node:stream"; +import { describe, expect, it } from "bun:test"; +import { type AteamDb, repo } from "@ateam/db"; +import { CH, createRpcClient } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; +import { streamClientTransport, streamServerTransport } from "../src/transport/stream"; + +// The SSH shape: readable !== writable. Two pipes cross-wire a client and server +// exactly like a child process's stdout/stdin, without spawning ssh. +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { db, pty: { has: () => false }, mergeQueue: {}, loopRunner: { describe: () => [] } }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: (id: string) => ee.emit("taskUpdated", { id }), + sendLoopsUpdated: () => ee.emit("loopsUpdated", []), + } as unknown as Engine; +} + +describe("RPC over a separate read/write stream pair (the SSH shape)", () => { + it("round-trips a request and streams an event", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const c2s = new PassThrough(); // client → server + const s2c = new PassThrough(); // server → client + serveRpc(engine, createDispatcher(engine), streamServerTransport(c2s, s2c)); + const rpc = createRpcClient(streamClientTransport(s2c, c2s)); + + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "t", + slug: "t", + branch: "t", + baseBranch: "main", + worktreePath: "/r/a/w/t", + }); + + const events: string[] = []; + rpc.on("taskUpdated", (p) => events.push((p as { id: string }).id)); + + const listed = (await rpc.call(CH.tasksList, [project!.id])) as Array<{ id: string }>; + expect(listed.map((t) => t.id)).toEqual([task.id]); + + const moved = (await rpc.call(CH.tasksSetColumn, [task.id, "review"])) as { column: string }; + expect(moved.column).toBe("review"); + expect(events).toContain(task.id); + }); +}); From ab90d3705b6acdc2c8daeb3ed41c0741d39e3a7c Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 00:18:41 +0200 Subject: [PATCH 05/83] fix(server): create the data dir before opening SQLite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit createEngine opened the db without ensuring its parent dir exists. Electron's userData always does, so the desktop never hit this — but a fresh server's ~/.ateam does not, and better-sqlite3 won't create parent dirs, so `ateam daemon` crashed on first boot. mkdir -p the data dir first. Surfaced running the real daemon live on a Hetzner box (Phase 4 Stage B), where the full loop then worked end to end: register project, create a git worktree, spawn a real claude agent, stream its terminal to the client, drive it with keystrokes, and reattach to the live session after a full disconnect — all over SSH+tailscale. Verified: 104 tests pass, typecheck + build green. --- packages/server/src/engine.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/server/src/engine.ts b/packages/server/src/engine.ts index 55e98d0..e72b83b 100644 --- a/packages/server/src/engine.ts +++ b/packages/server/src/engine.ts @@ -5,7 +5,7 @@ // to webContents) and the SSH server (which frames them as JSON-RPC // notifications) drive the exact same engine. import { EventEmitter } from "node:events"; -import { existsSync, renameSync } from "node:fs"; +import { existsSync, mkdirSync, renameSync } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; import { createDb, repo } from "@ateam/db"; @@ -82,6 +82,10 @@ export async function createEngine(opts: EngineOptions): Promise { const { dataDir, daemonPath, execPath } = opts; const emitter = new EventEmitter(); + // Ensure the data dir exists. Electron's userData always does; a fresh + // server's ~/.ateam may not, and better-sqlite3 won't create parent dirs. + if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true }); + // One-time migration from the pre-rename database filename. const dbPath = join(dataDir, "ateam.sqlite"); if (!existsSync(dbPath) && existsSync(join(dataDir, "grove.sqlite"))) { From 378b057a60b8f99b4ebafd9eb5e82e0641a44381 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 09:52:57 +0200 Subject: [PATCH 06/83] =?UTF-8?q?feat(protocol):=20buildAteamApi=20?= =?UTF-8?q?=E2=80=94=20client-side=20AteamApi=20bound=20over=20the=20RPC?= =?UTF-8?q?=20client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client mirror of the desktop preload's window.ateam, but over any transport (SSH stdio, socket, WebSocket) instead of Electron IPC: every request becomes rpc.call(CH.x); every push event (taskUpdated/loopsUpdated/ ptyData/ptyExit) an rpc.on(...). Returns a total AteamApi by taking a NativeClientApi adapter for the client-local methods no remote engine can serve (native dialogs, clipboard staging, webUtils pathForFile). Lives in @ateam/protocol so any client imports it without node/electron; the package stays dependency-free. Integration-tested through a live serveRpc/dispatcher over the in-memory stream pair. --- packages/protocol/src/client-api.ts | 118 ++++++++++++++++++++++++ packages/protocol/src/index.ts | 3 + packages/server/test/client-api.test.ts | 89 ++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 packages/protocol/src/client-api.ts create mode 100644 packages/server/test/client-api.test.ts diff --git a/packages/protocol/src/client-api.ts b/packages/protocol/src/client-api.ts new file mode 100644 index 0000000..9564e89 --- /dev/null +++ b/packages/protocol/src/client-api.ts @@ -0,0 +1,118 @@ +// Bind the AteamApi surface to an RpcClient — the client-side mirror of the +// desktop preload's `window.ateam`, but over any transport (SSH stdio, a socket, +// a WebSocket) instead of Electron IPC. Every request becomes an rpc.call(CH.x); +// every push event (taskUpdated/loopsUpdated/ptyData/ptyExit) an rpc.on(...). +// +// It returns a *total* AteamApi by taking a `native` adapter for the handful of +// methods that are inherently client-local — a native file dialog, the OS +// clipboard, webUtils' path-for-a-dropped-File — which no remote engine can +// serve. Local-desktop supplies these from Electron; a remote client supplies +// them from its own OS (or, later, from server-fs RPC helpers). +import type { + AgentDTO, + AteamApi, + CleanupCandidate, + CleanupReport, + CreateLoopInput, + DiffResultDTO, + GitStatusSnapshot, + KanbanColumn, + LoopDTO, + LoopTemplateDTO, + MergeEnqueueDTO, + MergeStrategy, + ProjectDTO, + PtyDataEvent, + PtyExitEvent, + PtySnapshot, + SessionDTO, + TaskDTO, + UpdateResultDTO, +} from "./index"; +import { CH } from "./index"; +import type { RpcClient } from "./rpc"; + +/** + * The client-local slice of AteamApi — methods that touch the *client's* OS, not + * the engine: the native folder/file dialogs, the clipboard image staging, and + * webUtils' synchronous path-for-a-File. The host that owns the real device + * (Electron main today) provides these; everything else flows over RPC. + */ +export interface NativeClientApi { + pathForFile(file: File): string; + pick(): Promise; + pickFiles(): Promise; + stageClipboardImage(): Promise; + stageImagePath(path: string): Promise; +} + +/** Build the full AteamApi over an RpcClient, delegating client-local bits to `native`. */ +export function buildAteamApi(rpc: RpcClient, native: NativeClientApi): AteamApi { + // Typed thin wrapper: rpc.call is Promise; each method fixes its type. + const call = (method: string, args: unknown[] = []): Promise => + rpc.call(method, args) as Promise; + + return { + projects: { + pick: native.pick, + register: (repoPath, opts) => call(CH.projectsRegister, [repoPath, opts]), + list: () => call(CH.projectsList), + remove: (id) => call(CH.projectsRemove, [id]), + }, + tasks: { + list: (projectId) => call(CH.tasksList, [projectId]), + create: (input) => call(CH.tasksCreate, [input]), + remove: (input) => call(CH.tasksRemove, [input]), + setColumn: (id, column: KanbanColumn) => call(CH.tasksSetColumn, [id, column]), + cleanupPreview: (projectId) => call(CH.tasksCleanupPreview, [projectId]), + cleanupCandidates: (projectId) => + call(CH.tasksCleanupCandidates, [projectId]), + cleanup: (projectId) => call(CH.tasksCleanup, [projectId]), + }, + git: { + commit: (taskId, message) => call<{ sha: string }>(CH.gitCommit, [taskId, message]), + push: (taskId) => call(CH.gitPush, [taskId]), + update: (taskId) => call(CH.gitUpdate, [taskId]), + merge: (taskId, strategy: MergeStrategy) => + call(CH.gitMerge, [taskId, strategy]), + diff: (taskId) => call(CH.gitDiff, [taskId]), + fileDiff: (taskId, file) => call(CH.gitFileDiff, [taskId, file]), + status: (taskId) => call(CH.gitStatus, [taskId]), + }, + agents: { + list: () => call(CH.agentsList), + }, + loops: { + list: () => call(CH.loopsList), + setEnabled: (id, enabled) => call(CH.loopsSetEnabled, [id, enabled]), + runNow: (id) => call(CH.loopsRunNow, [id]), + templates: () => call(CH.loopsTemplates), + create: (input: CreateLoopInput) => call(CH.loopsCreate, [input]), + remove: (id) => call(CH.loopsDelete, [id]), + onUpdated: (cb) => rpc.on("loopsUpdated", (p) => cb(p as LoopDTO[])), + }, + pty: { + spawnAgent: (input) => call<{ terminalId: string }>(CH.ptySpawnAgent, [input]), + spawnShell: (input) => call<{ terminalId: string }>(CH.ptySpawnShell, [input]), + // Fire-and-forget in the API; over RPC each still gets a (tiny) ack frame. + // shortcut: per-keystroke ptyWrite pays a round-trip ack. Fine over SSH + // (bytes are tiny); add a one-way "notify" frame if it ever shows latency. + write: (terminalId, data) => void call(CH.ptyWrite, [terminalId, data]), + resize: (terminalId, cols, rows) => void call(CH.ptyResize, [terminalId, cols, rows]), + kill: (terminalId) => void call(CH.ptyKill, [terminalId]), + snapshot: (terminalId) => call(CH.ptySnapshot, [terminalId]), + listForTask: (taskId) => call(CH.ptyListForTask, [taskId]), + onData: (cb) => rpc.on("ptyData", (p) => cb(p as PtyDataEvent)), + onExit: (cb) => rpc.on("ptyExit", (p) => cb(p as PtyExitEvent)), + }, + events: { + onTaskUpdated: (cb) => rpc.on("taskUpdated", (p) => cb(p as TaskDTO)), + }, + utils: { + pathForFile: native.pathForFile, + pickFiles: native.pickFiles, + stageClipboardImage: native.stageClipboardImage, + stageImagePath: native.stageImagePath, + }, + }; +} diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 2e43120..2e95dfd 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -340,3 +340,6 @@ export interface AteamApi { // Transport-agnostic RPC framing + client (shared by every transport). export * from "./rpc"; +// Client-side binding of the AteamApi surface over an RpcClient. +export { buildAteamApi } from "./client-api"; +export type { NativeClientApi } from "./client-api"; diff --git a/packages/server/test/client-api.test.ts b/packages/server/test/client-api.test.ts new file mode 100644 index 0000000..464df31 --- /dev/null +++ b/packages/server/test/client-api.test.ts @@ -0,0 +1,89 @@ +import { describe, expect, it } from "bun:test"; +import { EventEmitter } from "node:events"; +import { PassThrough } from "node:stream"; +import { type AteamDb, repo } from "@ateam/db"; +import { buildAteamApi, createRpcClient, type NativeClientApi } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; +import { streamClientTransport, streamServerTransport } from "../src/transport/stream"; + +// Same fake engine as stream.test.ts: enough services for the dispatcher's +// read/update paths, with sendTaskUpdated wired to actually emit the event. +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { db, pty: { has: () => false }, mergeQueue: {}, loopRunner: { describe: () => [] } }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: (id: string) => { + const task = repo.getTask(db, id); + if (task) ee.emit("taskUpdated", { id: task.id, column: task.column }); + }, + sendLoopsUpdated: () => ee.emit("loopsUpdated", []), + } as unknown as Engine; +} + +// The native slice is unreachable over RPC; assert buildAteamApi delegates to it +// verbatim rather than inventing a value. +const native: NativeClientApi = { + pathForFile: () => "/native/path", + pick: async () => "/native/pick", + pickFiles: async () => ["/native/a"], + stageClipboardImage: async () => true, + stageImagePath: async () => false, +}; + +describe("buildAteamApi over a live serveRpc/dispatcher (the client's view)", () => { + it("round-trips typed calls and streams task/loop events", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const c2s = new PassThrough(); + const s2c = new PassThrough(); + serveRpc(engine, createDispatcher(engine), streamServerTransport(c2s, s2c)); + const api = buildAteamApi(createRpcClient(streamClientTransport(s2c, c2s)), native); + + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "t", + slug: "t", + branch: "t", + baseBranch: "main", + worktreePath: "/r/a/w/t", + }); + + // Push event → client subscription. + const updated: string[] = []; + api.events.onTaskUpdated((t) => updated.push(t.id)); + + // A typed request returns the DTO shape, not `unknown`. + const listed = await api.tasks.list(project!.id); + expect(listed.map((t) => t.id)).toEqual([task.id]); + + const moved = await api.tasks.setColumn(task.id, "review"); + expect(moved.column).toBe("review"); + expect(updated).toContain(task.id); + + // Loops path resolves (empty from the fake runner) and doesn't hang. + expect(await api.loops.list()).toEqual([]); + }); + + it("delegates client-native methods to the native adapter, not RPC", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const c2s = new PassThrough(); + const s2c = new PassThrough(); + serveRpc(engine, createDispatcher(engine), streamServerTransport(c2s, s2c)); + const api = buildAteamApi(createRpcClient(streamClientTransport(s2c, c2s)), native); + + expect(api.utils.pathForFile(new File([], "x"))).toBe("/native/path"); + expect(await api.projects.pick()).toBe("/native/pick"); + expect(await api.utils.pickFiles()).toEqual(["/native/a"]); + expect(await api.utils.stageClipboardImage()).toBe(true); + expect(await api.utils.stageImagePath("/x")).toBe(false); + }); +}); From d8bce26537b027912e12f36c4757ed2b350b35f7 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 10:01:59 +0200 Subject: [PATCH 07/83] feat(protocol,server): remote-native fs:listDir + util:writeImageBytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two client-native desktop features re-homed as server-side RPC so a remote client can drive them on the *engine's* machine, not its own: - fs:listDir(path?) — browse the engine's filesystem for the repo picker (subdirectories only, each flagged when it holds a .git; follows symlinked dirs, skips broken links). Over SSH a native folder dialog would browse the wrong box; this browses where the repos actually live. - util:writeImageBytes(base64, ext?) — write an attached/pasted image to a temp file under dataDir/attachments and return its path. A headless server has no GUI clipboard, so the image is handed to the agent as a file path instead of a bitmap. Extension is sanitized (no path/separator injection); the engine prunes attachments older than a week on startup so they never accumulate unboundedly. Surfaced on AteamApi (fs.listDir, utils.writeImageBytes), bound in buildAteamApi over RPC, and implemented in the desktop preload so local mode carries them identically. Dispatcher handlers unit-tested over a real db. --- apps/desktop/src/preload/index.ts | 6 ++- packages/protocol/src/client-api.ts | 5 ++ packages/protocol/src/index.ts | 43 ++++++++++++++-- packages/server/src/dispatcher.ts | 43 +++++++++++++++- packages/server/src/engine.ts | 18 ++++++- packages/server/test/fs-util.test.ts | 76 ++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 packages/server/test/fs-util.test.ts diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index 1350b46..2a6944f 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -1,4 +1,3 @@ -import { contextBridge, ipcRenderer, webUtils } from "electron"; import { type AteamApi, CH, @@ -9,6 +8,7 @@ import { type PtyExitEvent, type TaskDTO, } from "@ateam/protocol"; +import { contextBridge, ipcRenderer, webUtils } from "electron"; const api: AteamApi = { projects: { @@ -38,6 +38,9 @@ const api: AteamApi = { agents: { list: () => ipcRenderer.invoke(CH.agentsList), }, + fs: { + listDir: (path) => ipcRenderer.invoke(CH.fsListDir, path), + }, loops: { list: () => ipcRenderer.invoke(CH.loopsList), setEnabled: (id, enabled) => ipcRenderer.invoke(CH.loopsSetEnabled, id, enabled), @@ -75,6 +78,7 @@ const api: AteamApi = { pickFiles: () => ipcRenderer.invoke(CH.utilPickFiles), stageClipboardImage: () => ipcRenderer.invoke(CH.utilStageImage), stageImagePath: (path) => ipcRenderer.invoke(CH.utilStageImagePath, path), + writeImageBytes: (base64, ext) => ipcRenderer.invoke(CH.utilWriteImageBytes, base64, ext), }, events: { onTaskUpdated: (cb: (task: TaskDTO) => void) => { diff --git a/packages/protocol/src/client-api.ts b/packages/protocol/src/client-api.ts index 9564e89..6c3c7ad 100644 --- a/packages/protocol/src/client-api.ts +++ b/packages/protocol/src/client-api.ts @@ -15,6 +15,7 @@ import type { CleanupReport, CreateLoopInput, DiffResultDTO, + DirListingDTO, GitStatusSnapshot, KanbanColumn, LoopDTO, @@ -82,6 +83,9 @@ export function buildAteamApi(rpc: RpcClient, native: NativeClientApi): AteamApi agents: { list: () => call(CH.agentsList), }, + fs: { + listDir: (path) => call(CH.fsListDir, [path]), + }, loops: { list: () => call(CH.loopsList), setEnabled: (id, enabled) => call(CH.loopsSetEnabled, [id, enabled]), @@ -113,6 +117,7 @@ export function buildAteamApi(rpc: RpcClient, native: NativeClientApi): AteamApi pickFiles: native.pickFiles, stageClipboardImage: native.stageClipboardImage, stageImagePath: native.stageImagePath, + writeImageBytes: (base64, ext) => call(CH.utilWriteImageBytes, [base64, ext]), }, }; } diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 2e95dfd..b730fb7 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -164,6 +164,24 @@ export interface CleanupReport { kept: CleanupSkip[]; } +// A subdirectory in a remote-fs listing (the repo picker over RPC). +export interface DirEntryDTO { + name: string; + /** Absolute path on the engine's machine. */ + path: string; + /** True when the directory holds a `.git` (a git repo root). */ + isRepo: boolean; +} +/** One directory's worth of subdirectories, for navigating the engine's fs. */ +export interface DirListingDTO { + /** The resolved absolute directory that was listed. */ + path: string; + /** Its parent directory, or null at the filesystem root. */ + parent: string | null; + /** Subdirectories, sorted by name. */ + entries: DirEntryDTO[]; +} + // A worktree advised for cleanup, shown in the cleanup dialog with its terminal. export interface CleanupCandidate { id: string; @@ -203,9 +221,11 @@ export const CH = { loopsCreate: "loops:create", loopsDelete: "loops:delete", agentsList: "agents:list", + fsListDir: "fs:listDir", utilPickFiles: "util:pickFiles", utilStageImage: "util:stageImage", utilStageImagePath: "util:stageImagePath", + utilWriteImageBytes: "util:writeImageBytes", ptySpawnAgent: "pty:spawnAgent", ptySpawnShell: "pty:spawnShell", ptyWrite: "pty:write", @@ -279,6 +299,15 @@ export interface AteamApi { agents: { list(): Promise; }; + fs: { + /** + * Browse a directory on the *engine's* machine (the server, when remote) to + * pick a repo — the transport-native replacement for the local folder dialog, + * which would browse the wrong machine over SSH. Defaults to the engine's home + * dir; entries are subdirectories, each flagged when it holds a `.git`. + */ + listDir(path?: string): Promise; + }; loops: { list(): Promise; setEnabled(id: string, enabled: boolean): Promise; @@ -335,11 +364,19 @@ export interface AteamApi { * back to typing the path. */ stageImagePath(path: string): Promise; + /** + * Write raw image bytes (base64) to a temp file on the *engine's* machine and + * return its absolute path. The remote counterpart of clipboard staging: a + * headless server has no GUI clipboard, so an attached/pasted image is handed + * to the agent as a file path (typed into the PTY or appended to its prompt) + * instead of a bitmap on the clipboard. `ext` sets the extension (default "png"). + */ + writeImageBytes(base64: string, ext?: string): Promise; }; } -// Transport-agnostic RPC framing + client (shared by every transport). -export * from "./rpc"; +export type { NativeClientApi } from "./client-api"; // Client-side binding of the AteamApi surface over an RpcClient. export { buildAteamApi } from "./client-api"; -export type { NativeClientApi } from "./client-api"; +// Transport-agnostic RPC framing + client (shared by every transport). +export * from "./rpc"; diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts index ffb2735..41caa7f 100644 --- a/packages/server/src/dispatcher.ts +++ b/packages/server/src/dispatcher.ts @@ -4,8 +4,9 @@ // ipcMain handlers; the desktop now adapts ipcMain → handle(), and the SSH // server will adapt a JSON-RPC channel → handle(). One body, many transports. import { randomUUID } from "node:crypto"; -import { readFileSync } from "node:fs"; -import { basename, join } from "node:path"; +import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { basename, dirname, join, resolve } from "node:path"; import { agentCommand, getAgent, listAgents } from "@ateam/agents"; import { repo } from "@ateam/db"; import { @@ -26,6 +27,7 @@ import { import { CH, type CreateLoopInput, + type DirEntryDTO, type GitStatusSnapshot, type KanbanColumn, type MergeStrategy, @@ -372,6 +374,43 @@ export function createDispatcher(engine: Engine): Dispatcher { })); }, + // ---- fs / util: server-side, remote-native (browse + attach on the + // engine's machine, not the client's — the SSH client is on another box) ---- + [CH.fsListDir]: async (path?: string) => { + // The engine runs as the user (over SSH, in the daemon); browsing its own + // filesystem is the same access the SSH session already has — no new grant. + const dir = path ? resolve(path) : homedir(); + const entries: DirEntryDTO[] = []; + for (const d of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, d.name); + let isDir = d.isDirectory(); + // Follow symlinks-to-dirs (home dirs often symlink project folders); + // skip broken links rather than fail the whole listing. + if (!isDir && d.isSymbolicLink()) { + try { + isDir = statSync(full).isDirectory(); + } catch { + continue; + } + } + if (!isDir) continue; + entries.push({ name: d.name, path: full, isRepo: existsSync(join(full, ".git")) }); + } + entries.sort((a, b) => a.name.localeCompare(b.name)); + const parent = dirname(dir); + return { path: dir, parent: parent === dir ? null : parent, entries }; + }, + [CH.utilWriteImageBytes]: async (base64: string, ext?: string) => { + const safeExt = (ext ?? "png").replace(/[^a-z0-9]/gi, "").toLowerCase() || "png"; + const dir = join(services.userDataDir, "attachments"); + if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); + // Random name: an attachment is handed to the agent immediately; the engine + // prunes this dir on startup so temp images never accumulate unboundedly. + const file = join(dir, `${randomUUID()}.${safeExt}`); + writeFileSync(file, Buffer.from(base64, "base64")); + return file; + }, + // ---- loops (periodic reconcilers) ---- [CH.loopsList]: () => loopRunner.describe(), [CH.loopsSetEnabled]: (id: string, enabled: boolean) => { diff --git a/packages/server/src/engine.ts b/packages/server/src/engine.ts index e72b83b..d53a23f 100644 --- a/packages/server/src/engine.ts +++ b/packages/server/src/engine.ts @@ -5,7 +5,7 @@ // to webContents) and the SSH server (which frames them as JSON-RPC // notifications) drive the exact same engine. import { EventEmitter } from "node:events"; -import { existsSync, mkdirSync, renameSync } from "node:fs"; +import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; import { createDb, repo } from "@ateam/db"; @@ -96,6 +96,22 @@ export async function createEngine(opts: EngineOptions): Promise { } const db = createDb(dbPath); + // Prune stale image attachments (written by util:writeImageBytes when a remote + // client attaches an image) older than a week, so temp files never accumulate + // unboundedly. A path handed to an agent is read within the session it's given. + const attachmentsDir = join(dataDir, "attachments"); + if (existsSync(attachmentsDir)) { + const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000; + for (const name of readdirSync(attachmentsDir)) { + const f = join(attachmentsDir, name); + try { + if (statSync(f).mtimeMs < cutoff) rmSync(f); + } catch { + /* raced/removed — ignore */ + } + } + } + const sendTaskUpdated = (taskId: string): void => { const task = repo.getTask(db, taskId); if (task) emitter.emit("taskUpdated", toTaskDTO(task)); diff --git a/packages/server/test/fs-util.test.ts b/packages/server/test/fs-util.test.ts new file mode 100644 index 0000000..6213b4b --- /dev/null +++ b/packages/server/test/fs-util.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it } from "bun:test"; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { CH } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; + +// The dispatcher only touches services.{db,userDataDir} for these handlers. +function makeEngine(userDataDir: string): Engine { + return { + services: { + db: createTestDb(), + pty: { has: () => false }, + mergeQueue: {}, + loopRunner: { describe: () => [] }, + userDataDir, + }, + sendTaskUpdated: () => {}, + sendLoopsUpdated: () => {}, + } as unknown as Engine; +} + +describe("fs:listDir (remote-native repo picker)", () => { + it("lists subdirectories only, flags git repos, and exposes the parent", async () => { + const root = mkdtempSync(join(tmpdir(), "ateam-fs-")); + mkdirSync(join(root, "plain")); + mkdirSync(join(root, "repo", ".git"), { recursive: true }); + writeFileSync(join(root, "afile.txt"), "x"); // files are excluded from the listing + const d = createDispatcher(makeEngine(root)); + + const listing = (await d.handle(CH.fsListDir, [root])) as { + path: string; + parent: string | null; + entries: { name: string; path: string; isRepo: boolean }[]; + }; + + expect(listing.path).toBe(root); + expect(listing.parent).not.toBeNull(); + // Sorted, directories only (no afile.txt). + expect(listing.entries.map((e) => e.name)).toEqual(["plain", "repo"]); + expect(listing.entries.find((e) => e.name === "repo")?.isRepo).toBe(true); + expect(listing.entries.find((e) => e.name === "plain")?.isRepo).toBe(false); + expect(listing.entries.find((e) => e.name === "repo")?.path).toBe(join(root, "repo")); + }); + + it("rejects (via the dispatcher) a path that does not exist", async () => { + const d = createDispatcher(makeEngine(mkdtempSync(join(tmpdir(), "ateam-fs2-")))); + expect(d.handle(CH.fsListDir, [join(tmpdir(), "definitely-not-here-xyz")])).rejects.toThrow(); + }); +}); + +describe("util:writeImageBytes (remote image attach)", () => { + it("writes the decoded bytes under attachments/ and returns the path", async () => { + const dataDir = mkdtempSync(join(tmpdir(), "ateam-att-")); + const d = createDispatcher(makeEngine(dataDir)); + const png = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a]); + + const file = (await d.handle(CH.utilWriteImageBytes, [png.toString("base64")])) as string; + + expect(file.startsWith(join(dataDir, "attachments"))).toBe(true); + expect(file.endsWith(".png")).toBe(true); + expect(existsSync(file)).toBe(true); + expect(readFileSync(file).equals(png)).toBe(true); + }); + + it("sanitizes the extension so it can't inject a path or separator", async () => { + const dataDir = mkdtempSync(join(tmpdir(), "ateam-att2-")); + const d = createDispatcher(makeEngine(dataDir)); + const file = (await d.handle(CH.utilWriteImageBytes, ["", "../evil.jpg"])) as string; + // Non-alphanumerics stripped: "../evil.jpg" → "eviljpg"; no traversal survives. + expect(file.endsWith(".eviljpg")).toBe(true); + expect(file.startsWith(join(dataDir, "attachments"))).toBe(true); + }); +}); From 72ce5bb82bfc304756fee97750e81e616232c054 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 10:14:10 +0200 Subject: [PATCH 08/83] =?UTF-8?q?feat(db,server):=20connection=20manager?= =?UTF-8?q?=20=E2=80=94=20ssh=5Fconfig=20hosts=20+=20per-host=20records?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client-side registry of remote hosts to drive an engine on: - hosts table (@ateam/db), keyed by ~/.ssh/config alias (its natural PK): server_version, agents_available (json), last_seen. Capability metadata ONLY — no board mirror; the connections list renders from this cache without N live SSH connections, and a host's full board loads live when opened. Client-only; the engine never reads it. repo CRUD: upsertHost/listHosts/getHost/deleteHost, with partial upsert so a bare touch never wipes cached fields. - connections.ts (@ateam/server, beside sshClientTransport): readSshHosts parses Host aliases + HostName from ssh_config (minimal — OpenSSH owns the full semantics at connect time; patterns skipped); listConnections outer-merges config hosts with saved records (flags inSshConfig/known, sorts by recency); recordConnection stamps last_seen on connect. Not on AteamApi — managing connections is a client concern about choosing an engine, not something a remote engine serves. ~/.ssh/config stays the source of connection truth (keys/jumphosts/hostnames = OpenSSH's job); we persist only Ateam's own metadata keyed by alias. --- packages/db/src/bootstrap.ts | 9 ++ packages/db/src/repo.ts | 27 +++++ packages/db/src/schema.ts | 23 ++++ packages/db/test/hosts.test.ts | 43 +++++++ packages/server/src/connections.ts | 136 +++++++++++++++++++++++ packages/server/src/index.ts | 2 + packages/server/test/connections.test.ts | 93 ++++++++++++++++ 7 files changed, 333 insertions(+) create mode 100644 packages/db/test/hosts.test.ts create mode 100644 packages/server/src/connections.ts create mode 100644 packages/server/test/connections.test.ts diff --git a/packages/db/src/bootstrap.ts b/packages/db/src/bootstrap.ts index 04b5fe0..176f32d 100644 --- a/packages/db/src/bootstrap.ts +++ b/packages/db/src/bootstrap.ts @@ -127,6 +127,15 @@ export function bootstrap(db: SqliteExecutor): void { created_at INTEGER ); CREATE INDEX IF NOT EXISTS board_changes_task_idx ON board_changes (task_id); + + CREATE TABLE IF NOT EXISTS hosts ( + host_alias TEXT PRIMARY KEY, + server_version TEXT, + agents_available TEXT, + last_seen INTEGER, + created_at INTEGER + ); + CREATE INDEX IF NOT EXISTS hosts_last_seen_idx ON hosts (last_seen); `); // Migrations for databases created before a column existed. SQLite has no diff --git a/packages/db/src/repo.ts b/packages/db/src/repo.ts index 4cc3261..41fc9c8 100644 --- a/packages/db/src/repo.ts +++ b/packages/db/src/repo.ts @@ -4,6 +4,8 @@ import { agentSessions, type BoardChange, boardChanges, + type Host, + hosts, type Loop, loops, type NewBoardChange, @@ -172,4 +174,29 @@ export const repo = { .all(); return opts.limit ? rows.slice(0, opts.limit) : rows; }, + + // ---- hosts (remote connections; client-only) ---- + /** Insert or update a host record by its ssh_config alias. */ + upsertHost(db: AteamDb, h: Partial & { hostAlias: string }): Host { + const existing = db.select().from(hosts).where(eq(hosts.hostAlias, h.hostAlias)).get(); + if (existing) { + db.update(hosts).set(h).where(eq(hosts.hostAlias, h.hostAlias)).run(); + return db.select().from(hosts).where(eq(hosts.hostAlias, h.hostAlias)).get() as Host; + } + return db.insert(hosts).values(h).returning().get(); + }, + + /** All known hosts, most-recently-reached first (nulls — never connected — last). */ + listHosts(db: AteamDb): Host[] { + return db.select().from(hosts).orderBy(desc(hosts.lastSeen)).all(); + }, + + getHost(db: AteamDb, hostAlias: string): Host | undefined { + return db.select().from(hosts).where(eq(hosts.hostAlias, hostAlias)).get(); + }, + + /** Forget a host — drops only our metadata; ~/.ssh/config is untouched. */ + deleteHost(db: AteamDb, hostAlias: string): void { + db.delete(hosts).where(eq(hosts.hostAlias, hostAlias)).run(); + }, }; diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index 7855223..4882a60 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -226,6 +226,27 @@ export const boardChanges = sqliteTable( (t) => [index("board_changes_task_idx").on(t.taskId)], ); +/** + * Remote hosts the client can drive an engine on, keyed by their `~/.ssh/config` + * alias (unique there, so it's the natural PK). We persist ONLY Ateam's own + * metadata — the last handshake version, which agents the box has, and when it + * was last reached — never connection details (hostname/port/keys/jumphosts stay + * OpenSSH's job). This doubles as the offline cache: the connections list renders + * every known host from here without opening N live SSH connections. Client-only + * state — the engine never reads this table. + */ +export const hosts = sqliteTable( + "hosts", + { + hostAlias: text("host_alias").primaryKey(), + serverVersion: text("server_version"), + agentsAvailable: text("agents_available", { mode: "json" }).$type(), + lastSeen: integer("last_seen"), + createdAt: epochMs("created_at"), + }, + (t) => [index("hosts_last_seen_idx").on(t.lastSeen)], +); + export { sql }; export type Project = typeof projects.$inferSelect; @@ -240,3 +261,5 @@ export type Loop = typeof loops.$inferSelect; export type NewLoop = typeof loops.$inferInsert; export type BoardChange = typeof boardChanges.$inferSelect; export type NewBoardChange = typeof boardChanges.$inferInsert; +export type Host = typeof hosts.$inferSelect; +export type NewHost = typeof hosts.$inferInsert; diff --git a/packages/db/test/hosts.test.ts b/packages/db/test/hosts.test.ts new file mode 100644 index 0000000..5385991 --- /dev/null +++ b/packages/db/test/hosts.test.ts @@ -0,0 +1,43 @@ +import { beforeEach, describe, expect, it } from "bun:test"; +import { type AteamDb, repo } from "../src/index"; +import { createTestDb } from "./helpers/test-db"; + +let db: AteamDb; +beforeEach(() => { + db = createTestDb(); +}); + +describe("hosts repo", () => { + it("upserts, lists most-recently-seen first, gets, and deletes", () => { + repo.upsertHost(db, { + hostAlias: "box-a", + serverVersion: "1.0.0", + agentsAvailable: ["claude"], + lastSeen: 100, + }); + repo.upsertHost(db, { hostAlias: "box-b", lastSeen: 200 }); + + expect(repo.listHosts(db).map((h) => h.hostAlias)).toEqual(["box-b", "box-a"]); + expect(repo.getHost(db, "box-a")?.serverVersion).toBe("1.0.0"); + expect(repo.getHost(db, "box-a")?.agentsAvailable).toEqual(["claude"]); + + repo.deleteHost(db, "box-a"); + expect(repo.getHost(db, "box-a")).toBeUndefined(); + expect(repo.listHosts(db).map((h) => h.hostAlias)).toEqual(["box-b"]); + }); + + it("partial upsert updates only the given fields, preserving the rest", () => { + repo.upsertHost(db, { + hostAlias: "box", + serverVersion: "2.0.0", + agentsAvailable: ["claude", "codex"], + lastSeen: 1, + }); + repo.upsertHost(db, { hostAlias: "box", lastSeen: 999 }); // touch only + + const h = repo.getHost(db, "box"); + expect(h?.lastSeen).toBe(999); + expect(h?.serverVersion).toBe("2.0.0"); + expect(h?.agentsAvailable).toEqual(["claude", "codex"]); + }); +}); diff --git a/packages/server/src/connections.ts b/packages/server/src/connections.ts new file mode 100644 index 0000000..9e7cc91 --- /dev/null +++ b/packages/server/src/connections.ts @@ -0,0 +1,136 @@ +// Client-side connection manager: which remote hosts the user can drive an +// engine on, plus Ateam's own last-known metadata for each. Connection details +// (hostname/port/keys/jumphosts) stay in ~/.ssh/config — OpenSSH's job; we only +// read the alias list from it and persist our metadata keyed by alias. Lives in +// @ateam/server beside sshClientTransport (both are client primitives), and is +// deliberately NOT on AteamApi — managing connections is a client concern *about* +// choosing an engine, not something a remote engine serves. +import { readFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { type AteamDb, type Host, repo } from "@ateam/db"; + +/** A connectable destination parsed from ~/.ssh/config. */ +export interface SshHost { + alias: string; + hostName: string | null; +} + +/** A row in the connections list: ssh_config presence merged with our metadata. */ +export interface ConnectionDTO { + alias: string; + hostName: string | null; + serverVersion: string | null; + agentsAvailable: string[] | null; + lastSeen: number | null; + /** Present in ~/.ssh/config right now (vs a saved record since removed from it). */ + inSshConfig: boolean; + /** We've recorded at least one successful connection (has a saved record). */ + known: boolean; +} + +/** What a successful connection learned about a host, to cache for offline render. */ +export interface ConnectionRecord { + hostAlias: string; + serverVersion?: string | null; + agentsAvailable?: string[] | null; +} + +const DEFAULT_SSH_CONFIG = join(homedir(), ".ssh", "config"); + +/** + * Parse `Host` aliases (and their HostName) from an ssh_config. Minimal by + * design: OpenSSH resolves the full semantics at connect time — we only need the + * connectable alias list for the picker. + * + * shortcut: reads one config file; no `Include` expansion, no `Match` blocks. + * Pattern aliases (containing * ? !) are skipped — they're templates, not + * destinations. Add Include-following if users split their config across files. + */ +export function readSshHosts(configPath: string = DEFAULT_SSH_CONFIG): SshHost[] { + let text: string; + try { + text = readFileSync(configPath, "utf8"); + } catch { + return []; // no ssh config yet — nothing to offer + } + const out: SshHost[] = []; + // Aliases of the stanza currently being parsed; a following HostName applies + // to all of them (`Host a b` shares options between a and b). + let stanza: SshHost[] = []; + for (const raw of text.split("\n")) { + const line = raw.trim(); + if (!line || line.startsWith("#")) continue; + const match = line.match(/^(\S+)\s+(.+)$/); + if (!match?.[1] || match[2] == null) continue; + const key = match[1].toLowerCase(); + const value = match[2].trim(); + if (key === "host") { + stanza = []; + for (const alias of value.split(/\s+/)) { + if (/[*?!]/.test(alias)) continue; // pattern, not a destination + const host: SshHost = { alias, hostName: null }; + out.push(host); + stanza.push(host); + } + } else if (key === "hostname") { + for (const host of stanza) host.hostName = value; + } + } + return out; +} + +/** + * The connections list: every ssh_config host, enriched with our saved metadata, + * plus any saved host whose alias has since left the config (so it can still be + * seen/forgotten). Renders entirely from local state — no live SSH connection. + */ +export function listConnections(db: AteamDb, configPath?: string): ConnectionDTO[] { + const saved = new Map(repo.listHosts(db).map((h) => [h.hostAlias, h])); + const byAlias = new Map(); + + for (const sh of readSshHosts(configPath)) { + const rec = saved.get(sh.alias); + byAlias.set(sh.alias, { + alias: sh.alias, + hostName: sh.hostName, + serverVersion: rec?.serverVersion ?? null, + agentsAvailable: rec?.agentsAvailable ?? null, + lastSeen: rec?.lastSeen ?? null, + inSshConfig: true, + known: rec != null, + }); + } + for (const rec of saved.values()) { + if (byAlias.has(rec.hostAlias)) continue; + byAlias.set(rec.hostAlias, { + alias: rec.hostAlias, + hostName: null, + serverVersion: rec.serverVersion, + agentsAvailable: rec.agentsAvailable, + lastSeen: rec.lastSeen, + inSshConfig: false, + known: true, + }); + } + // Recently-reached first; never-connected (null lastSeen) after, ties by alias. + return [...byAlias.values()].sort((a, b) => { + if ((a.lastSeen ?? 0) !== (b.lastSeen ?? 0)) return (b.lastSeen ?? 0) - (a.lastSeen ?? 0); + return a.alias.localeCompare(b.alias); + }); +} + +/** + * Record a successful connection: stamp lastSeen and cache whatever the box + * reported. Only provided fields are written, so a bare touch never wipes a + * previously-cached version/agent list. + */ +export function recordConnection(db: AteamDb, rec: ConnectionRecord): Host { + const patch: Partial & { hostAlias: string } = { + hostAlias: rec.hostAlias, + lastSeen: Date.now(), + }; + if (rec.serverVersion !== undefined) patch.serverVersion = rec.serverVersion; + if (rec.agentsAvailable !== undefined) patch.agentsAvailable = rec.agentsAvailable; + return repo.upsertHost(db, patch); +} diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index a039695..2cbef49 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -14,5 +14,7 @@ export { serveRpc } from "./rpc"; export type { ServerTransport } from "./rpc"; export { sshClientTransport } from "./transport/ssh"; export type { SshClient, SshOptions } from "./transport/ssh"; +export { listConnections, readSshHosts, recordConnection } from "./connections"; +export type { ConnectionDTO, ConnectionRecord, SshHost } from "./connections"; export { socketClientTransport, socketServerTransport } from "./transport/socket"; export { streamClientTransport, streamServerTransport } from "./transport/stream"; diff --git a/packages/server/test/connections.test.ts b/packages/server/test/connections.test.ts new file mode 100644 index 0000000..40aa8af --- /dev/null +++ b/packages/server/test/connections.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from "bun:test"; +import { mkdtempSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { repo } from "@ateam/db"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { listConnections, readSshHosts, recordConnection } from "../src/connections"; + +function writeConfig(content: string): string { + const p = join(mkdtempSync(join(tmpdir(), "ateam-ssh-")), "config"); + writeFileSync(p, content); + return p; +} + +describe("readSshHosts", () => { + it("parses aliases + HostName, sharing options across a multi-alias stanza", () => { + const cfg = writeConfig( + [ + "# a comment", + "Host hetzner-devbox", + " HostName 100.72.63.61", + " User pallaoro", + "", + "Host prod staging", + " HostName example.com", + "", + "Host *", + " ForwardAgent yes", + ].join("\n"), + ); + const hosts = readSshHosts(cfg); + // Wildcard `*` stanza excluded; multi-alias stanza yields both, sharing HostName. + expect(hosts.map((h) => h.alias)).toEqual(["hetzner-devbox", "prod", "staging"]); + expect(hosts.find((h) => h.alias === "hetzner-devbox")?.hostName).toBe("100.72.63.61"); + expect(hosts.find((h) => h.alias === "prod")?.hostName).toBe("example.com"); + expect(hosts.find((h) => h.alias === "staging")?.hostName).toBe("example.com"); + }); + + it("returns [] when the config file is missing", () => { + expect(readSshHosts(join(tmpdir(), "definitely-no-ssh-config-xyz"))).toEqual([]); + }); +}); + +describe("listConnections", () => { + it("merges ssh_config hosts with saved records and sorts by recency", () => { + const db = createTestDb(); + const cfg = writeConfig("Host box-a\n HostName 10.0.0.1\nHost box-b\n HostName 10.0.0.2\n"); + // box-a connected just now; box-b in config but never connected; box-gone + // saved but no longer in the config. + recordConnection(db, { + hostAlias: "box-a", + serverVersion: "1.2.3", + agentsAvailable: ["claude"], + }); + repo.upsertHost(db, { hostAlias: "box-gone", lastSeen: 5, serverVersion: "0.9" }); + + const conns = listConnections(db, cfg); + const byAlias = Object.fromEntries(conns.map((c) => [c.alias, c])); + + expect(byAlias["box-a"]?.known).toBe(true); + expect(byAlias["box-a"]?.inSshConfig).toBe(true); + expect(byAlias["box-a"]?.serverVersion).toBe("1.2.3"); + expect(byAlias["box-a"]?.hostName).toBe("10.0.0.1"); + + expect(byAlias["box-b"]?.known).toBe(false); + expect(byAlias["box-b"]?.inSshConfig).toBe(true); + expect(byAlias["box-b"]?.lastSeen).toBeNull(); + + expect(byAlias["box-gone"]?.known).toBe(true); + expect(byAlias["box-gone"]?.inSshConfig).toBe(false); + + // box-a (fresh lastSeen) first; box-b (never connected) last. + expect(conns[0]?.alias).toBe("box-a"); + expect(conns.at(-1)?.alias).toBe("box-b"); + }); +}); + +describe("recordConnection", () => { + it("stamps lastSeen and preserves cached fields on a bare touch", () => { + const db = createTestDb(); + recordConnection(db, { + hostAlias: "box", + serverVersion: "1.0.0", + agentsAvailable: ["claude", "codex"], + }); + recordConnection(db, { hostAlias: "box" }); // touch only + + const h = repo.getHost(db, "box"); + expect(h?.serverVersion).toBe("1.0.0"); + expect(h?.agentsAvailable).toEqual(["claude", "codex"]); + expect(typeof h?.lastSeen).toBe("number"); + }); +}); From f6cf6671d1611e3a3e749a8d53e05024b6e2e003 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 10:22:14 +0200 Subject: [PATCH 09/83] feat(protocol,server): system:hello connect handshake with PROTOCOL_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compatibility gate for remote connections. A client opens a transport and calls serverHandshake(rpc) FIRST, checking the engine's protocolVersion before trusting the rest of the surface — so a version-skewed remote fails cleanly at the handshake instead of cryptically mid-call (a newer client hitting an older daemon's missing method throws 'Unknown method'; a changed DTO shape corrupts silently). - PROTOCOL_VERSION (monotonic int in @ateam/protocol, the wire-contract pkg; bump on any breaking CH/args/DTO change). Deliberately not the npm version — workspaces are 0.0.0 and the daemon is esbuild-bundled, so package.json is neither meaningful nor readable at runtime. - CH.systemHello dispatcher handler returns { protocolVersion, agents }, reusing listAgents() for the box's installed agents. - serverHandshake(rpc) client helper; a low-level connect primitive, deliberately NOT on AteamApi. Feeds recordConnection's cached version/agents. Mirrors the initialize/protocolVersion handshake this repo already speaks in board-mcp.ts (and the MCP/LSP norm). Tested end-to-end over the stream transport. --- packages/protocol/src/client-api.ts | 11 ++++++++ packages/protocol/src/index.ts | 23 ++++++++++++++++- packages/server/src/dispatcher.ts | 12 +++++++++ packages/server/test/system.test.ts | 40 +++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/server/test/system.test.ts diff --git a/packages/protocol/src/client-api.ts b/packages/protocol/src/client-api.ts index 6c3c7ad..dd406df 100644 --- a/packages/protocol/src/client-api.ts +++ b/packages/protocol/src/client-api.ts @@ -27,12 +27,23 @@ import type { PtyExitEvent, PtySnapshot, SessionDTO, + SystemInfo, TaskDTO, UpdateResultDTO, } from "./index"; import { CH } from "./index"; import type { RpcClient } from "./rpc"; +/** + * The connect-time handshake: ask the engine its protocol version + agents. Call + * this on the raw RpcClient BEFORE building the full api, and compare + * `info.protocolVersion` against `PROTOCOL_VERSION` to gate a version-skewed + * remote. It's a low-level connect primitive, deliberately not on AteamApi. + */ +export function serverHandshake(rpc: RpcClient): Promise { + return rpc.call(CH.systemHello) as Promise; +} + /** * The client-local slice of AteamApi — methods that touch the *client's* OS, not * the engine: the native folder/file dialogs, the clipboard image staging, and diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index b730fb7..6b5f6f1 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -3,6 +3,16 @@ // renderer, the Electron main process, and the (future) headless @ateam/server // over SSH — shares one definition without pulling in node/electron/db internals. +/** + * Wire-contract version. A client checks it on connect (via `system:hello`) and + * refuses/warns on mismatch, so a version-skewed remote fails cleanly at the + * handshake instead of cryptically mid-call ("Unknown method"/corrupt shape). + * BUMP THIS on any breaking change to CH methods, their args, or DTO shapes. + * Monotonic integer — deliberately not the npm version (workspaces are 0.0.0 and + * the daemon is bundled, so package.json is neither meaningful nor readable here). + */ +export const PROTOCOL_VERSION = 1; + export type KanbanColumn = "todo" | "running" | "needs_attention" | "review" | "merged"; export type AgentStatus = "idle" | "running" | "awaiting_input" | "stopped"; @@ -164,6 +174,16 @@ export interface CleanupReport { kept: CleanupSkip[]; } +/** + * The connect-time handshake reply (`system:hello`): the engine's protocol + * version for the compatibility check, and which agents its box actually has. + */ +export interface SystemInfo { + protocolVersion: number; + /** Ids of agents installed + available on the engine's machine. */ + agents: string[]; +} + // A subdirectory in a remote-fs listing (the repo picker over RPC). export interface DirEntryDTO { name: string; @@ -221,6 +241,7 @@ export const CH = { loopsCreate: "loops:create", loopsDelete: "loops:delete", agentsList: "agents:list", + systemHello: "system:hello", fsListDir: "fs:listDir", utilPickFiles: "util:pickFiles", utilStageImage: "util:stageImage", @@ -377,6 +398,6 @@ export interface AteamApi { export type { NativeClientApi } from "./client-api"; // Client-side binding of the AteamApi surface over an RpcClient. -export { buildAteamApi } from "./client-api"; +export { buildAteamApi, serverHandshake } from "./client-api"; // Transport-agnostic RPC framing + client (shared by every transport). export * from "./rpc"; diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts index 41caa7f..44517cb 100644 --- a/packages/server/src/dispatcher.ts +++ b/packages/server/src/dispatcher.ts @@ -31,6 +31,7 @@ import { type GitStatusSnapshot, type KanbanColumn, type MergeStrategy, + PROTOCOL_VERSION, } from "@ateam/protocol"; import { buildAgentEnv, ensureClaudeHooks, ensureCodexHooks } from "./agent-setup"; import type { Engine } from "./engine"; @@ -374,6 +375,17 @@ export function createDispatcher(engine: Engine): Dispatcher { })); }, + // ---- system: connect-time handshake ---- + // The client calls this first over a fresh transport and checks + // protocolVersion before trusting the rest of the surface (see serverHandshake). + [CH.systemHello]: async () => { + const agents = await listAgents(); + return { + protocolVersion: PROTOCOL_VERSION, + agents: agents.filter((a) => a.available).map((a) => a.id), + }; + }, + // ---- fs / util: server-side, remote-native (browse + attach on the // engine's machine, not the client's — the SSH client is on another box) ---- [CH.fsListDir]: async (path?: string) => { diff --git a/packages/server/test/system.test.ts b/packages/server/test/system.test.ts new file mode 100644 index 0000000..f6f15ea --- /dev/null +++ b/packages/server/test/system.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from "bun:test"; +import { EventEmitter } from "node:events"; +import { PassThrough } from "node:stream"; +import type { AteamDb } from "@ateam/db"; +import { createRpcClient, PROTOCOL_VERSION, serverHandshake } from "@ateam/protocol"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; +import { streamClientTransport, streamServerTransport } from "../src/transport/stream"; + +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { db, pty: { has: () => false }, mergeQueue: {}, loopRunner: { describe: () => [] } }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: () => {}, + sendLoopsUpdated: () => {}, + } as unknown as Engine; +} + +describe("system:hello handshake", () => { + it("serverHandshake reports the protocol version + available agents over RPC", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const c2s = new PassThrough(); + const s2c = new PassThrough(); + serveRpc(engine, createDispatcher(engine), streamServerTransport(c2s, s2c)); + const rpc = createRpcClient(streamClientTransport(s2c, c2s)); + + const info = await serverHandshake(rpc); + // The compatibility field a version-skewed client gates on. + expect(info.protocolVersion).toBe(PROTOCOL_VERSION); + // The box's installed agents (ids); shape asserted, membership is env-dependent. + expect(Array.isArray(info.agents)).toBe(true); + }); +}); From 9103841ad1ff735f5765b4285068ab498a81e4ad Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 10:47:33 +0200 Subject: [PATCH 10/83] refactor(server,desktop): relocate the PTY daemon into @ateam/server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The daemon is Electron-free (node + node-pty + a headless xterm), and the server owns the rest of the PTY subsystem (pty-client.ts) — so for the server to ship a standalone `ateam` dist it must own the daemon source too, not reach into the desktop app. Moves apps/desktop/src/daemon/index.ts → packages/server/src/pty/daemon.ts (single source of truth; no TS import sites, only a build-input path + a runtime path in cli.ts). node-pty/@xterm/headless/@xterm/addon-serialize are added to @ateam/server AND kept as desktop deps: the desktop's bundled daemon.js still requires them at runtime and electron-rebuild must still see node-pty, so its native-module resolution is unchanged. The desktop's electron.vite input repoints to the new path. Verified: server typecheck + 80 tests, desktop typecheck + build (daemon.js 253kB, node-pty externalized). Residual: electron-rebuild ABI + live Electron runtime need a real desktop run (unchanged by design; only the source moved). --- apps/desktop/electron.vite.config.ts | 7 ++++-- bun.lock | 3 +++ packages/server/package.json | 5 +++- .../server/src/pty/daemon.ts | 23 ++++++++----------- 4 files changed, 22 insertions(+), 16 deletions(-) rename apps/desktop/src/daemon/index.ts => packages/server/src/pty/daemon.ts (90%) diff --git a/apps/desktop/electron.vite.config.ts b/apps/desktop/electron.vite.config.ts index f926109..b01726f 100644 --- a/apps/desktop/electron.vite.config.ts +++ b/apps/desktop/electron.vite.config.ts @@ -23,8 +23,11 @@ export default defineConfig({ rollupOptions: { input: { index: resolve(__dirname, "src/main/index.ts"), - // The detached PTY daemon, built alongside main → out/main/daemon.js - daemon: resolve(__dirname, "src/daemon/index.ts"), + // The detached PTY daemon, built alongside main → out/main/daemon.js. + // Source lives in @ateam/server (its PTY subsystem); the desktop and + // the server dist bundle the one file. node-pty/@xterm stay desktop + // deps too, so electron-rebuild + runtime resolution are unchanged. + daemon: resolve(__dirname, "../../packages/server/src/pty/daemon.ts"), }, }, }, diff --git a/bun.lock b/bun.lock index 8a7919a..cb9c438 100644 --- a/bun.lock +++ b/bun.lock @@ -90,6 +90,9 @@ "@ateam/db": "workspace:*", "@ateam/git-core": "workspace:*", "@ateam/protocol": "workspace:*", + "@xterm/addon-serialize": "^0.13.0", + "@xterm/headless": "^5.5.0", + "node-pty": "^1.0.0", }, "devDependencies": { "@types/node": "^22.10.5", diff --git a/packages/server/package.json b/packages/server/package.json index 6dff990..de25f97 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -15,7 +15,10 @@ "@ateam/agents": "workspace:*", "@ateam/db": "workspace:*", "@ateam/git-core": "workspace:*", - "@ateam/protocol": "workspace:*" + "@ateam/protocol": "workspace:*", + "@xterm/addon-serialize": "^0.13.0", + "@xterm/headless": "^5.5.0", + "node-pty": "^1.0.0" }, "devDependencies": { "@types/node": "^22.10.5", diff --git a/apps/desktop/src/daemon/index.ts b/packages/server/src/pty/daemon.ts similarity index 90% rename from apps/desktop/src/daemon/index.ts rename to packages/server/src/pty/daemon.ts index 325d9a7..ec28d9e 100644 --- a/apps/desktop/src/daemon/index.ts +++ b/packages/server/src/pty/daemon.ts @@ -1,6 +1,9 @@ -// Standalone PTY daemon. Runs as a DETACHED process (the Electron binary -// launched with ELECTRON_RUN_AS_NODE=1 so node-pty's native module matches the -// arm64 ABI) and outlives the app, so terminals/agents survive an app restart. +// Standalone PTY daemon — part of @ateam/server's PTY subsystem (alongside +// pty-client.ts). Runs as a DETACHED process that outlives its parent, so +// terminals/agents survive a restart. The desktop bundles it and runs it via the +// Electron binary as node (ELECTRON_RUN_AS_NODE=1, matching node-pty's ABI); the +// server dist runs the same file under plain Node on the box. Host-agnostic: it +// speaks only node + node-pty + a headless xterm, never Electron. // // Protocol: newline-delimited JSON over a unix socket. Terminal bytes are // base64-encoded in the `data` field. Clients connect, (re)attach by listing @@ -17,16 +20,14 @@ // retained window every new view attaches with paste broken (newlines arrive as // Enters instead of one bracketed block). import { existsSync, mkdirSync, unlinkSync } from "node:fs"; -import net from "node:net"; -import { connect as netConnect } from "node:net"; +import net, { connect as netConnect } from "node:net"; import { homedir } from "node:os"; import { dirname, join } from "node:path"; import { SerializeAddon } from "@xterm/addon-serialize"; import { Terminal } from "@xterm/headless"; import * as pty from "node-pty"; -const SOCK = - process.env.ATEAM_PTY_SOCK || join(homedir(), ".ateam", "pty-daemon.sock"); +const SOCK = process.env.ATEAM_PTY_SOCK || join(homedir(), ".ateam", "pty-daemon.sock"); const SCROLLBACK = 5000; // lines of scrollback the emulator (and snapshot) keeps const IDLE_EXIT_MS = 10 * 60 * 1000; // exit if no sessions for 10 min @@ -129,9 +130,7 @@ function spawnSession(m: { function handleMessage(sock: net.Socket, m: Record): void { switch (m.t) { case "spawn": - spawnSession( - m as unknown as Parameters[0], - ); + spawnSession(m as unknown as Parameters[0]); break; case "write": sessions.get(m.terminalId as string)?.proc.write(unb64(m.data as string)); @@ -167,9 +166,7 @@ function handleMessage(sock: net.Socket, m: Record): void { case "snapshot": { const s = sessions.get(m.terminalId as string); const reply = (data: string, seq: number) => - sock.write( - `${JSON.stringify({ t: "snapshot", id: m.id, data: b64(data), seq })}\n`, - ); + sock.write(`${JSON.stringify({ t: "snapshot", id: m.id, data: b64(data), seq })}\n`); if (!s) { reply("", 0); break; From e3d493b968bc146788ea86131bc086963ea3f71b Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 10:58:39 +0200 Subject: [PATCH 11/83] build(server): bun-bundle a standalone `ateam` server dist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retires the dist/runtime shortcut in cli.ts and replaces Phase-4 hand-bundling with a repeatable target: `bun run build` → dist/{cli.js, daemon.js, package.json}. Reuses bun's bundler (no new dep); CJS output (simple-git's @kwsites/file-exists does a bare require that breaks under bundled ESM). better-sqlite3 + node-pty are externalized — the only two native modules; the box installs them for its own arch via the emitted dist/package.json (node-pty aliased to the @homebridge prebuilt fork, better-sqlite3 via node prebuilds, so no compiler is needed there). Everything else is bundled in. Two single-entry passes so cli.js + daemon.js land flat (cli.ts resolves daemon.js beside it). Verified: both externalize their native module, both node --check valid. --- packages/server/package.json | 1 + packages/server/scripts/build.ts | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 packages/server/scripts/build.ts diff --git a/packages/server/package.json b/packages/server/package.json index de25f97..412c527 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -8,6 +8,7 @@ "exports": { ".": "./src/index.ts" }, "bin": { "ateam": "./src/cli.ts" }, "scripts": { + "build": "bun run scripts/build.ts", "test": "bun test", "typecheck": "tsc --noEmit" }, diff --git a/packages/server/scripts/build.ts b/packages/server/scripts/build.ts new file mode 100644 index 0000000..5e20d61 --- /dev/null +++ b/packages/server/scripts/build.ts @@ -0,0 +1,62 @@ +// Build the standalone `ateam` server dist for a remote box: the CLI + the PTY +// daemon, bundled to CJS with the two NATIVE modules externalized. Everything +// else (drizzle, simple-git, @xterm, the @ateam/* workspace packages) is bundled +// in. The box installs only better-sqlite3 + node-pty for its own arch — and +// since the box has no compiler, node-pty is aliased to the prebuilt fork and +// better-sqlite3 uses its node prebuilds (see the emitted dist/package.json). +// +// CJS (not ESM) is deliberate: simple-git pulls @kwsites/file-exists, which does +// a bare `require`, and that breaks under a bundled-ESM output. +// +// Two single-entry bundles, not one multi-entry: bun preserves each entry's +// src-relative path, which would put the daemon at dist/pty/daemon.js — but +// cli.ts resolves the daemon as `daemon.js` BESIDE itself. Building each alone +// flattens both to the dist root. +// +// Output: dist/{cli.js, daemon.js, package.json}. Run: `bun run build`. +import { mkdirSync, rmSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const serverRoot = dirname(dirname(fileURLToPath(import.meta.url))); +const dist = join(serverRoot, "dist"); +const EXTERNAL = ["better-sqlite3", "node-pty"]; // native — installed on the box + +rmSync(dist, { recursive: true, force: true }); +mkdirSync(dist, { recursive: true }); + +for (const entry of ["src/cli.ts", "src/pty/daemon.ts"]) { + const res = await Bun.build({ + entrypoints: [join(serverRoot, entry)], + outdir: dist, + target: "node", + format: "cjs", + external: EXTERNAL, + }); + if (!res.success) { + for (const log of res.logs) console.error(log); + process.exit(1); + } +} + +// The box runs `npm install` here to fetch ONLY the two native modules for its +// own platform; the aliased fork ships prebuilt binaries so no compiler is needed. +writeFileSync( + join(dist, "package.json"), + `${JSON.stringify( + { + name: "ateam-server-dist", + version: "0.0.0", + private: true, + bin: { ateam: "./cli.js" }, + dependencies: { + "better-sqlite3": "^11.8.1", + "node-pty": "npm:@homebridge/node-pty-prebuilt-multiarch@^0.13.1", + }, + }, + null, + 2, + )}\n`, +); + +console.log(`built ateam dist → ${dist}`); From 736eba91daa991b46a2d5cf9279a9782be934177 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 11:21:22 +0200 Subject: [PATCH 12/83] fix(server): make the ateam CLI work on a fresh remote box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four bugs the first real over-SSH install surfaced (all in the attach relay / daemon boot), each caught by driving the box end-to-end: - import.meta.url is INLINED by the bundler to the BUILD-TIME source path, so the daemon paths (PTY daemon location, and the daemon the relay spawns) pointed at the build host's filesystem — nonexistent on the box. Derive them from the running script's own path (process.argv[1], realpath-resolved) instead. This was why the PTY daemon 'did not become reachable'. - attach only auto-started the daemon on ECONNREFUSED, but a fresh box has no socket file at all → ENOENT. Handle both, and poll with backoff (daemon cold-start time varies) instead of a single fixed wait. - the socket 'close' handler (exit 0) was registered before connecting, so it fired on every FAILED connect — right after the ENOENT that schedules a retry — killing attach before the retry ran (it had already spawned an orphan daemon). Register close-ends-relay only AFTER a successful connect. - runDaemon awaited connectPty() before listening, so the RPC socket was blocked behind the PTY connect timeout; serve RPC immediately and connect PTY in the background (agent spawning reconnects lazily). Also route the auto-started (detached) daemon's output to ~/.ateam/daemon.log — a detached daemon with no logs is undebuggable on a remote box. Proven on a fresh box: one SSH attach cold-starts both daemons, handshake + a real RPC call succeed, and both daemons persist across disconnect. --- packages/server/src/cli.ts | 73 ++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 28f90d4..27c60fd 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -18,11 +18,10 @@ // JS. Wire that up when standing the first server; the logic below is runtime- // agnostic. import { spawn } from "node:child_process"; -import { existsSync, mkdirSync, unlinkSync } from "node:fs"; +import { existsSync, mkdirSync, openSync, realpathSync, unlinkSync } from "node:fs"; import { connect, createServer, type Socket } from "node:net"; import { homedir } from "node:os"; import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; import { createDispatcher } from "./dispatcher"; import { createEngine } from "./engine"; import { serveRpc } from "./rpc"; @@ -30,21 +29,20 @@ import { socketServerTransport } from "./transport/socket"; const SOCK = process.env.ATEAM_RPC_SOCK ?? join(homedir(), ".ateam", "rpc.sock"); +// Absolute path to THIS running cli.js. Do NOT use import.meta.url: the bundler +// inlines it to the BUILD-TIME source path (the build host's filesystem), so the +// daemon paths derived from it would point at a machine that isn't this one. The +// executing script's own path (realpath-resolved, so a `bin` symlink still lands +// in the dist dir beside daemon.js) is what's portable across boxes. +const SELF = process.argv[1] ? realpathSync(process.argv[1]) : ""; + async function runDaemon(): Promise { const dataDir = process.env.ATEAM_DATA_DIR ?? join(homedir(), ".ateam"); // The PTY daemon bundle (node-pty + xterm). Shipped beside the ateam bin on // the server; overridable for dev. - const ptyDaemon = - process.env.ATEAM_PTY_DAEMON ?? join(dirname(fileURLToPath(import.meta.url)), "daemon.js"); + const ptyDaemon = process.env.ATEAM_PTY_DAEMON ?? join(dirname(SELF), "daemon.js"); const engine = await createEngine({ dataDir, daemonPath: ptyDaemon, execPath: process.execPath }); - // Best-effort: serve RPC (git/tasks/board) even if the PTY daemon isn't up - // yet — agent spawning reconnects lazily, mirroring the desktop. - try { - await engine.connectPty(); - } catch (err) { - console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); - } engine.startLoops(); const dispatcher = createDispatcher(engine); @@ -68,32 +66,63 @@ async function runDaemon(): Promise { process.exit(1); }); server.listen(SOCK, () => console.log(`[ateam] daemon listening at ${SOCK}`)); + + // Connect to the PTY daemon in the BACKGROUND — don't block RPC on it. The + // git/tasks/board surface serves immediately (a client's handshake shouldn't + // wait out the PTY connect), and agent spawning reconnects lazily (PtyClient + // respawns/reconnects on demand). Awaiting here is what previously stalled a + // fresh box's first attach past its retry window. + void engine.connectPty().catch((err) => { + console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); + }); } function runAttach(): void { - const relay = (spawnedDaemon: boolean): void => { + let spawnedDaemon = false; + let retries = 0; + const relay = (): void => { const sock = connect(SOCK); sock.once("connect", () => { process.stdin.pipe(sock); sock.pipe(process.stdout); process.stdin.on("end", () => sock.end()); + // Only a close AFTER we've actually connected ends the relay. Registering + // this at the socket level would fire on every FAILED connect too (each + // connect error emits 'error' THEN 'close'), exiting before the retry runs. + sock.on("close", () => process.exit(0)); }); sock.once("error", (err: NodeJS.ErrnoException) => { - if (err.code === "ECONNREFUSED" && !spawnedDaemon) { - // No daemon yet — start one detached and retry once. - spawn(process.execPath, [fileURLToPath(import.meta.url), "daemon"], { - detached: true, - stdio: "ignore", - }).unref(); - setTimeout(() => relay(true), 500); - return; + // Both mean "no live daemon here": ECONNREFUSED = stale socket, nothing + // listening; ENOENT = socket file absent (a fresh box's first attach). + const noDaemon = err.code === "ECONNREFUSED" || err.code === "ENOENT"; + if (noDaemon) { + if (!spawnedDaemon) { + spawnedDaemon = true; + // Start one detached, then poll until it's listening — first-run + // startup (native module load + engine setup) takes a variable + // moment, so retry with backoff rather than a single fixed wait. + // Route its output to a log file: a detached daemon with no logs is + // undebuggable on a remote box (and this is where its startup errors + // surface). + const dataDir = dirname(SOCK); + if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true }); + const log = openSync(join(dataDir, "daemon.log"), "a"); + spawn(process.execPath, [SELF, "daemon"], { + detached: true, + stdio: ["ignore", log, log], + }).unref(); + } + if (retries < 40) { + retries++; + setTimeout(relay, 250); // up to ~10s for the daemon to come up + return; + } } console.error(`[ateam] attach failed: ${err.message}`); process.exit(1); }); - sock.on("close", () => process.exit(0)); }; - relay(false); + relay(); } const cmd = process.argv[2]; From b35b8546672c9c24f602b698bf9293056cca7a10 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 11:32:57 +0200 Subject: [PATCH 13/83] feat(server): one-shot install-remote.sh + half-open RPC support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install-remote.sh codifies the proven remote setup: build the dist, find node 22 on the box, copy dist, npm-install the two native modules (prebuilds, no compiler), drop an `ateam` launcher on the login PATH (pins node 22 for the native ABI), and verify the handshake. One command stands up a working remote engine — proven end-to-end on the Hetzner box (agents:["claude"] reported). The launcher is invoked as `bash -lc 'exec ateam attach --stdio'`: a login shell so the daemon's PATH resolves agent CLIs (else the handshake reports no agents), and node 22 so better-sqlite3/node-pty load. Files are only created or overwritten, never removed. allowHalfOpen on the RPC server: a one-shot client that sends a request then closes its write side (EOF) must still get the reply — without it the socket's read-end 'end' auto-closes the write-end and drops the response. Persistent clients (the desktop) are unaffected. --- packages/server/scripts/install-remote.sh | 70 +++++++++++++++++++++++ packages/server/src/cli.ts | 5 +- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100755 packages/server/scripts/install-remote.sh diff --git a/packages/server/scripts/install-remote.sh b/packages/server/scripts/install-remote.sh new file mode 100755 index 0000000..a09f499 --- /dev/null +++ b/packages/server/scripts/install-remote.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# One-shot installer: build the `ateam` server dist locally and install it on a +# remote box over SSH, then verify the handshake. Proven against a Hetzner box +# (Ubuntu, node via nvm). +# +# scripts/install-remote.sh +# SSH_FLAGS="-i ~/.ssh/mykey" scripts/install-remote.sh user@host +# +# The box needs a node 22.x (via nvm): better-sqlite3 ships node-22 prebuilds and +# node-pty is the prebuilt fork, so NO compiler is required. Agent CLIs (claude, +# codex, …) are discovered at connect time from a login shell, so they can live +# anywhere on the login PATH — the installer doesn't need to know where. +# +# Files/dirs are only ever created or overwritten, never removed. +set -euo pipefail + +HOST="${1:?usage: install-remote.sh (user@host or an ssh_config alias)}" +SSH_FLAGS="${SSH_FLAGS:-}" +APP_DIR="ateam-app" # under the remote home +HERE="$(cd "$(dirname "$0")/.." && pwd)" # packages/server +run() { ssh ${SSH_FLAGS} "$HOST" "$@"; } + +echo "==> [1/6] build dist (bun bundle)" +(cd "$HERE" && bun run build >/dev/null) + +echo "==> [2/6] locate node 22 on $HOST" +N22="$(run 'ls -d "$HOME"/.nvm/versions/node/v22* 2>/dev/null | tail -1')/bin/node" +run "test -x '$N22'" || { + echo "!! node 22 not found on $HOST — run 'nvm install 22' there first" + exit 1 +} +echo " node: $N22" + +echo "==> [3/6] copy dist to ~/$APP_DIR" +run "mkdir -p ~/$APP_DIR ~/.local/bin" +scp ${SSH_FLAGS} -q "$HERE/dist/cli.js" "$HERE/dist/daemon.js" "$HERE/dist/package.json" "$HOST:$APP_DIR/" + +echo "==> [4/6] install native modules (node 22 prebuilds; no compiler)" +run "PATH=\"$(dirname "$N22")\":\$PATH; cd ~/$APP_DIR && npm install --omit=dev --no-audit --no-fund >/dev/null 2>&1" + +echo "==> [5/6] install the 'ateam' launcher on the login PATH (~/.local/bin/ateam)" +# Generated locally (with node 22 pinned) and copied, to sidestep ssh quoting. +# It runs cli.js under node 22 (matching the native ABI); a login shell around it +# supplies the PATH that resolves agent CLIs. +WRAP="$(mktemp)" +printf '#!/bin/sh\nexec %s "$HOME/%s/cli.js" "$@"\n' "$N22" "$APP_DIR" >"$WRAP" +scp ${SSH_FLAGS} -q "$WRAP" "$HOST:.local/bin/ateam" +rm -f "$WRAP" +run "chmod +x ~/.local/bin/ateam" + +echo "==> [6/6] verify handshake over a login shell (~10s)" +REQ="$(mktemp)" +printf '{"t":"req","id":1,"method":"system:hello","args":[]}\n' >"$REQ" +# `attach` is a persistent relay — it won't self-exit after the reply, so cap it +# with `timeout` and tolerate that non-zero exit (|| true); we only need the one +# reply line. A persistent client (the desktop) keeps the connection open and is +# unaffected by this one-shot pattern. +OUT="$(ssh ${SSH_FLAGS} "$HOST" "bash -lc 'timeout 12 ateam attach --stdio'" <"$REQ" 2>/dev/null | head -1 || true)" +rm -f "$REQ" +case "$OUT" in +*protocolVersion*) echo " OK $OUT" ;; +*) + echo "!! handshake failed: ${OUT:-}" + exit 1 + ;; +esac + +echo +echo "Installed. A client connects to this host with:" +echo " bash -lc 'exec ateam attach --stdio'" diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 27c60fd..efd8346 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -56,7 +56,10 @@ async function runDaemon(): Promise { /* best-effort */ } - const server = createServer((sock: Socket) => { + // allowHalfOpen: a one-shot client that sends a request then closes its write + // side (EOF) must still receive the reply — without this the socket's read-end + // 'end' auto-closes the write-end, dropping the response mid-flight. + const server = createServer({ allowHalfOpen: true }, (sock: Socket) => { // Each client gets its own serveRpc over one connection; the engine (and // its PTY sessions) is shared and outlives any single client. serveRpc(engine, dispatcher, socketServerTransport(sock)); From 691a278df5cc557d5ba5bc54b42315a47275c926 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 12:05:33 +0200 Subject: [PATCH 14/83] =?UTF-8?q?feat(desktop):=20swappable=20local?= =?UTF-8?q?=E2=87=84remote=20engine=20backend=20in=20the=20main=20process?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Electron main process can now drive either the in-process local engine or a remote engine reached over SSH, chosen at runtime — the renderer and the core preload surface are untouched. - backend.ts: `Backend` = one swappable engine ({kind,methods,handle,on,dispose}); localBackend = dispatcher + engine.on, remoteBackend = rpc.call/rpc.on. A stable `Router` is what registerIpc binds against once, routing to the active backend so a connection swap never re-registers ipcMain channels. - host.ts: createHost owns the active backend, rebinds the 4 forwarded events on swap, and connect(alias) opens sshClientTransport → handshake (20s timeout) → PROTOCOL_VERSION gate → recordConnection → swap; connect(null) returns to local. registerHostIpc wires host:list/connect/current + pushes evt:host:changed. - shared/host.ts: HOST_CH + HostStatus + AteamHost (protocol-only deps), added to both desktop tsconfigs; preload exposes window.ateamHost; global.d.ts declares it. - ConnectionDTO graduated @ateam/server → @ateam/protocol: a pure boundary DTO the renderer must read without pulling server/node types into its web tsconfig. SshHost/ConnectionRecord stay server-internal; additive, no PROTOCOL_VERSION bump. Renderer screens (connections UI, remote dir-browser, image-attach branch) land next — they need a live display to smoke. --- apps/desktop/src/main/backend.ts | 64 +++++++++ apps/desktop/src/main/host.ts | 161 ++++++++++++++++++++++ apps/desktop/src/main/index.ts | 16 +-- apps/desktop/src/main/ipc.ts | 18 +-- apps/desktop/src/preload/index.ts | 16 +++ apps/desktop/src/renderer/src/global.d.ts | 2 + apps/desktop/src/shared/host.ts | 36 +++++ apps/desktop/tsconfig.node.json | 1 + apps/desktop/tsconfig.web.json | 2 +- packages/protocol/src/index.ts | 20 +++ packages/server/src/connections.ts | 18 +-- 11 files changed, 324 insertions(+), 30 deletions(-) create mode 100644 apps/desktop/src/main/backend.ts create mode 100644 apps/desktop/src/main/host.ts create mode 100644 apps/desktop/src/shared/host.ts diff --git a/apps/desktop/src/main/backend.ts b/apps/desktop/src/main/backend.ts new file mode 100644 index 0000000..de2b003 --- /dev/null +++ b/apps/desktop/src/main/backend.ts @@ -0,0 +1,64 @@ +// The local⇄remote seam. A Backend is one engine the desktop can drive: the +// in-process local engine (dispatcher + engine events) or a remote engine reached +// over SSH (an RpcClient — every call/event goes down the same JSON-RPC wire). +// Both satisfy one shape, so the IPC bridge (ipc.ts) and event forwarding (host.ts) +// don't care which is active — they route to whatever Backend is current. +import type { RpcClient } from "@ateam/protocol"; +import { createDispatcher, type Engine } from "@ateam/server"; + +/** The four engine push-events forwarded to the renderer. */ +export type BackendEvent = "taskUpdated" | "loopsUpdated" | "ptyData" | "ptyExit"; + +export interface Backend { + readonly kind: "local" | "remote"; + /** The RPC method channels this backend serves (same set for local + remote). */ + readonly methods: readonly string[]; + /** Route one request; the IPC bridge awaits (or ignores, for send channels) this. */ + handle(method: string, args: unknown[]): unknown | Promise; + /** Subscribe to a push-event; returns an unsubscribe. */ + on(event: BackendEvent, cb: (payload: unknown) => void): () => void; + /** Release transport resources. No-op for local (the engine outlives swaps). */ + dispose(): void; +} + +/** + * A stable indirection the IPC bridge registers against ONCE at startup: its + * `handle` always routes to whatever Backend is currently active, so connecting + * to a remote host never re-registers ipcMain channels (which would throw). + */ +export interface Router { + readonly methods: readonly string[]; + handle(method: string, args: unknown[]): unknown | Promise; +} + +/** The in-process engine: a dispatcher over it, its own events. Never disposed. */ +export function localBackend(engine: Engine): Backend { + const dispatcher = createDispatcher(engine); + return { + kind: "local", + methods: dispatcher.methods, + handle: (method, args) => dispatcher.handle(method, args), + // engine.on is typed per-event; the Backend surface is event-agnostic. + on: (event, cb) => engine.on(event, cb as never), + dispose: () => {}, + }; +} + +/** + * A remote engine over SSH. `methods` is borrowed from the local dispatcher (the + * contract is identical on both sides). `dispose` tears down the SSH transport — + * the remote daemon and its PTY sessions live on, per attach's design. + */ +export function remoteBackend( + rpc: RpcClient, + methods: readonly string[], + dispose: () => void, +): Backend { + return { + kind: "remote", + methods, + handle: (method, args) => rpc.call(method, args), + on: (event, cb) => rpc.on(event, cb), + dispose, + }; +} diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts new file mode 100644 index 0000000..626403b --- /dev/null +++ b/apps/desktop/src/main/host.ts @@ -0,0 +1,161 @@ +// The connection controller: which engine drives the app, and swapping between +// them. Owns the always-alive local engine, the currently-active Backend, and the +// forwarding of that backend's push-events to the renderer. Connecting to a remote +// host opens an SSH transport, handshakes (gating the protocol version), caches the +// result, and re-points the active backend + event stream at it. +import type { BrowserWindow } from "electron"; +import { ipcMain } from "electron"; +import { + CH, + createRpcClient, + PROTOCOL_VERSION, + type RpcClient, + type SystemInfo, +} from "@ateam/protocol"; +import { + type ConnectionDTO, + type Engine, + listConnections, + recordConnection, + sshClientTransport, +} from "@ateam/server"; +import { type Backend, type BackendEvent, localBackend, remoteBackend, type Router } from "./backend"; +import { HOST_CH, type HostStatus } from "../shared/host"; + +// The one pre-quoted remote command (ssh space-joins remote args, so `bash -lc` +// must arrive as a single element): a login shell (agent-CLI PATH) execing the +// attach relay. Proven live against the Hetzner box. +const REMOTE_ATTACH = "bash -lc 'exec ateam attach --stdio'"; +// Cap a connect: ssh can hang on an auth prompt or an unreachable host with no +// error, and the UI must not wait forever. A live daemon replies in well under this. +const CONNECT_TIMEOUT_MS = 20_000; + +/** The four push-events forwarded from the active backend to the renderer. */ +const FORWARDED: { event: BackendEvent; channel: string }[] = [ + { event: "taskUpdated", channel: CH.evtTaskUpdated }, + { event: "loopsUpdated", channel: CH.evtLoopsUpdated }, + { event: "ptyData", channel: CH.evtPtyData }, + { event: "ptyExit", channel: CH.evtPtyExit }, +]; + +/** The main-process connection controller (the renderer-facing shape is AteamHost). */ +export interface Host { + /** The stable indirection the IPC bridge registers against once. */ + readonly router: Router; + list(): Promise; + connect(alias: string | null): Promise; + current(): Promise; +} + +export interface HostDeps { + /** The in-process engine — the default backend and the connections-registry db owner. */ + localEngine: Engine; + /** The window to forward events to (may be null before it's created). */ + getWin: () => BrowserWindow | null; +} + +export function createHost({ localEngine, getWin }: HostDeps): Host { + const db = localEngine.services.db; + const local = localBackend(localEngine); + + let active: Backend = local; + let activeAlias: string | null = null; + // Bind the local engine's events immediately so it forwards from startup; swaps + // re-bind. Guarded by getWin() at emit time, so a not-yet-created window is fine. + let unbindEvents: () => void = bindEvents(local); + + function bindEvents(backend: Backend): () => void { + const offs = FORWARDED.map(({ event, channel }) => + backend.on(event, (payload) => getWin()?.webContents.send(channel, payload)), + ); + return () => { + for (const off of offs) off(); + }; + } + + async function statusOf(backend: Backend, alias: string | null): Promise { + const info = (await backend.handle(CH.systemHello, [])) as SystemInfo; + return { mode: backend.kind, alias, info }; + } + + function swap(next: Backend, alias: string | null): void { + // Never dispose the local engine — it stays alive as the default backend and + // owns the connections-registry db. + if (active !== local && active !== next) active.dispose(); + unbindEvents(); + active = next; + activeAlias = alias; + unbindEvents = bindEvents(next); + void statusOf(next, alias).then((status) => + getWin()?.webContents.send(HOST_CH.evtChanged, status), + ); + } + + async function connect(alias: string | null): Promise { + if (alias === null) { + swap(local, null); + return statusOf(local, null); + } + + const client = sshClientTransport(alias, [REMOTE_ATTACH]); + const rpc: RpcClient = createRpcClient(client.transport); + let info: SystemInfo; + try { + info = await withTimeout(rpc.call(CH.systemHello) as Promise, CONNECT_TIMEOUT_MS); + } catch (err) { + client.close(); + throw err; + } + if (info.protocolVersion !== PROTOCOL_VERSION) { + client.close(); + throw new Error( + `Protocol mismatch: "${alias}" speaks v${info.protocolVersion}, this app speaks v${PROTOCOL_VERSION}. Update the older side.`, + ); + } + + recordConnection(db, { + hostAlias: alias, + serverVersion: String(info.protocolVersion), + agentsAvailable: info.agents, + }); + // The remote's method set matches the local dispatcher's (same contract). + swap(remoteBackend(rpc, local.methods, client.close), alias); + return { mode: "remote", alias, info }; + } + + const router: Router = { + methods: local.methods, + handle: (method, args) => active.handle(method, args), + }; + + return { + router, + list: async (): Promise => listConnections(db), + connect, + current: (): Promise => statusOf(active, activeAlias), + }; +} + +/** Register the connection-control IPC channels against a host. Call once. */ +export function registerHostIpc(host: Host): void { + ipcMain.handle(HOST_CH.list, () => host.list()); + ipcMain.handle(HOST_CH.connect, (_e, alias: string | null) => host.connect(alias)); + ipcMain.handle(HOST_CH.current, () => host.current()); +} + +/** Reject (and clean up) if a promise doesn't settle in time. */ +function withTimeout(p: Promise, ms: number): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(`connection timed out after ${ms}ms`)), ms); + p.then( + (v) => { + clearTimeout(timer); + resolve(v); + }, + (e) => { + clearTimeout(timer); + reject(e); + }, + ); + }); +} diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 00519fc..cac2e87 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -3,9 +3,9 @@ import { readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { app, BrowserWindow, dialog, Menu } from "electron"; import { autoUpdater } from "electron-updater"; -import { CH } from "@ateam/protocol"; -import { createDispatcher, createEngine, type Engine } from "@ateam/server"; +import { createEngine, type Engine } from "@ateam/server"; import { APP_NAME } from "./app-name"; +import { createHost, registerHostIpc } from "./host"; import { registerIpc } from "./ipc"; let win: BrowserWindow | null = null; @@ -308,12 +308,12 @@ app.whenReady().then(async () => { daemonPath: join(__dirname, "daemon.js"), execPath: process.execPath, }); - // Forward the engine's transport-agnostic events to the renderer. - engine.on("taskUpdated", (task) => win?.webContents.send(CH.evtTaskUpdated, task)); - engine.on("loopsUpdated", (loops) => win?.webContents.send(CH.evtLoopsUpdated, loops)); - engine.on("ptyData", (e) => win?.webContents.send(CH.evtPtyData, e)); - engine.on("ptyExit", (e) => win?.webContents.send(CH.evtPtyExit, e)); - registerIpc(createDispatcher(engine)); + // The local engine is the default backend; the host swaps in a remote one (over + // SSH) on connect and re-points the IPC bridge + event forwarding at it. Binding + // the engine's events to the renderer is the host's job now (see createHost). + const host = createHost({ localEngine: engine, getWin: () => win }); + registerIpc(host.router); + registerHostIpc(host); if (SMOKE) { // Headless boot check: prove the engine inits (db, hook server, notify diff --git a/apps/desktop/src/main/ipc.ts b/apps/desktop/src/main/ipc.ts index ce6948f..95e3389 100644 --- a/apps/desktop/src/main/ipc.ts +++ b/apps/desktop/src/main/ipc.ts @@ -1,6 +1,6 @@ import { clipboard, dialog, ipcMain, nativeImage } from "electron"; import { CH } from "@ateam/protocol"; -import type { Dispatcher } from "@ateam/server"; +import type { Router } from "./backend"; /** * Load an image file and put it on the clipboard as a real bitmap, so a @@ -21,16 +21,18 @@ function stageImageOnClipboard(path: string | null): boolean { const SEND_CHANNELS = new Set([CH.ptyWrite, CH.ptyResize]); /** - * Bridge Electron IPC to the transport-agnostic engine dispatcher. Every engine - * method flows through `dispatcher.handle`; only the handful of handlers that - * need Electron's native dialog/clipboard live here directly. + * Bridge Electron IPC to the active engine backend. Every engine method flows + * through `router.handle` — which routes to whichever backend (local in-process, + * or a remote host over SSH) is currently active, so channels are registered once + * and never re-bound on a connection swap. Only the handful of handlers that need + * Electron's native dialog/clipboard live here directly. */ -export function registerIpc(dispatcher: Dispatcher): void { - for (const method of dispatcher.methods) { +export function registerIpc(router: Router): void { + for (const method of router.methods) { if (SEND_CHANNELS.has(method)) { - ipcMain.on(method, (_e, ...args: unknown[]) => void dispatcher.handle(method, args)); + ipcMain.on(method, (_e, ...args: unknown[]) => void router.handle(method, args)); } else { - ipcMain.handle(method, (_e, ...args: unknown[]) => dispatcher.handle(method, args)); + ipcMain.handle(method, (_e, ...args: unknown[]) => router.handle(method, args)); } } diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index 2a6944f..db9d4c3 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -9,6 +9,7 @@ import { type TaskDTO, } from "@ateam/protocol"; import { contextBridge, ipcRenderer, webUtils } from "electron"; +import { type AteamHost, HOST_CH, type HostStatus } from "../shared/host"; const api: AteamApi = { projects: { @@ -90,3 +91,18 @@ const api: AteamApi = { }; contextBridge.exposeInMainWorld("ateam", api); + +// The connection-control surface (which engine drives the app) — separate from +// window.ateam (the engine itself). See apps/desktop/src/shared/host.ts. +const host: AteamHost = { + list: () => ipcRenderer.invoke(HOST_CH.list), + connect: (alias) => ipcRenderer.invoke(HOST_CH.connect, alias), + current: () => ipcRenderer.invoke(HOST_CH.current), + onChanged: (cb: (status: HostStatus) => void) => { + const handler = (_: unknown, status: HostStatus) => cb(status); + ipcRenderer.on(HOST_CH.evtChanged, handler); + return () => ipcRenderer.off(HOST_CH.evtChanged, handler); + }, +}; + +contextBridge.exposeInMainWorld("ateamHost", host); diff --git a/apps/desktop/src/renderer/src/global.d.ts b/apps/desktop/src/renderer/src/global.d.ts index 32ba60d..2463bcc 100644 --- a/apps/desktop/src/renderer/src/global.d.ts +++ b/apps/desktop/src/renderer/src/global.d.ts @@ -1,8 +1,10 @@ import type { AteamApi } from "@ateam/protocol"; +import type { AteamHost } from "../../shared/host"; declare global { interface Window { ateam: AteamApi; + ateamHost: AteamHost; } } diff --git a/apps/desktop/src/shared/host.ts b/apps/desktop/src/shared/host.ts new file mode 100644 index 0000000..7f6dabc --- /dev/null +++ b/apps/desktop/src/shared/host.ts @@ -0,0 +1,36 @@ +// The desktop's connection-control contract: which engine drives the app. This +// is renderer↔main IPC *about choosing an engine* — deliberately separate from +// window.ateam (the engine surface itself), mirroring how @ateam/server keeps +// connection management off AteamApi. Imports only @ateam/protocol (dependency- +// free), so both the node (main/preload) and web (renderer) tsconfigs resolve it. +import type { ConnectionDTO, SystemInfo } from "@ateam/protocol"; + +/** Renderer↔main channels for listing/choosing/observing the active engine. */ +export const HOST_CH = { + list: "host:list", + connect: "host:connect", + current: "host:current", + evtChanged: "evt:host:changed", +} as const; + +/** Which engine is driving the app right now. */ +export interface HostStatus { + mode: "local" | "remote"; + /** ssh_config alias when remote; null for the in-process local engine. */ + alias: string | null; + /** The engine's handshake: protocol version + the agents its machine has. */ + info: SystemInfo; +} + +/** + * window.ateamHost — the connection-control surface. `connect(null)` switches back + * to the local in-process engine; `connect(alias)` drives the engine on that + * ssh_config host over SSH. Distinct from window.ateam, which is whichever engine + * is currently active. + */ +export interface AteamHost { + list(): Promise; + connect(alias: string | null): Promise; + current(): Promise; + onChanged(cb: (status: HostStatus) => void): () => void; +} diff --git a/apps/desktop/tsconfig.node.json b/apps/desktop/tsconfig.node.json index 7029dd1..aa919ad 100644 --- a/apps/desktop/tsconfig.node.json +++ b/apps/desktop/tsconfig.node.json @@ -10,6 +10,7 @@ "src/main/**/*.ts", "src/daemon/**/*.ts", "src/preload/**/*.ts", + "src/shared/**/*.ts", "electron.vite.config.ts" ] } diff --git a/apps/desktop/tsconfig.web.json b/apps/desktop/tsconfig.web.json index 0e1775d..524caa9 100644 --- a/apps/desktop/tsconfig.web.json +++ b/apps/desktop/tsconfig.web.json @@ -6,5 +6,5 @@ "jsx": "react-jsx", "noEmit": true }, - "include": ["src/renderer/**/*.ts", "src/renderer/**/*.tsx"] + "include": ["src/renderer/**/*.ts", "src/renderer/**/*.tsx", "src/shared/**/*.ts"] } diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 6b5f6f1..17236c4 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -202,6 +202,26 @@ export interface DirListingDTO { entries: DirEntryDTO[]; } +/** + * A row in the connections list: an ssh_config alias enriched with Ateam's own + * last-known metadata for that host. Rendered by the client's connection picker; + * produced by `@ateam/server`'s `listConnections`. A boundary DTO (server writes, + * renderer reads), so it lives here rather than in the server package — the + * ssh_config parse-shape (`SshHost`) and write-shape (`ConnectionRecord`) stay + * server-internal. + */ +export interface ConnectionDTO { + alias: string; + hostName: string | null; + serverVersion: string | null; + agentsAvailable: string[] | null; + lastSeen: number | null; + /** Present in ~/.ssh/config right now (vs a saved record since removed from it). */ + inSshConfig: boolean; + /** We've recorded at least one successful connection (has a saved record). */ + known: boolean; +} + // A worktree advised for cleanup, shown in the cleanup dialog with its terminal. export interface CleanupCandidate { id: string; diff --git a/packages/server/src/connections.ts b/packages/server/src/connections.ts index 9e7cc91..fdcfa89 100644 --- a/packages/server/src/connections.ts +++ b/packages/server/src/connections.ts @@ -8,27 +8,19 @@ import { readFileSync } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; +import type { ConnectionDTO } from "@ateam/protocol"; import { type AteamDb, type Host, repo } from "@ateam/db"; +// ConnectionDTO is a client↔renderer boundary DTO — its home is @ateam/protocol; +// re-exported here so `listConnections`' callers keep importing it from the server. +export type { ConnectionDTO } from "@ateam/protocol"; + /** A connectable destination parsed from ~/.ssh/config. */ export interface SshHost { alias: string; hostName: string | null; } -/** A row in the connections list: ssh_config presence merged with our metadata. */ -export interface ConnectionDTO { - alias: string; - hostName: string | null; - serverVersion: string | null; - agentsAvailable: string[] | null; - lastSeen: number | null; - /** Present in ~/.ssh/config right now (vs a saved record since removed from it). */ - inSshConfig: boolean; - /** We've recorded at least one successful connection (has a saved record). */ - known: boolean; -} - /** What a successful connection learned about a host, to cache for offline render. */ export interface ConnectionRecord { hostAlias: string; From 79dbb0389ff3dd37f381ec3698656974794712ef Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 17:35:13 +0200 Subject: [PATCH 15/83] =?UTF-8?q?feat(server,desktop):=20per-connection=20?= =?UTF-8?q?transport=20choice=20=E2=80=94=20SSH=20or=20Tailscale/TCP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A connection now records how the user wants to reach its box, and the client opens the matching transport. Both feed the identical createRpcClient/ buildAteamApi — it's one pluggable ClientTransport seam, not two codepaths. - cli.ts: opt-in daemon TCP listener (ATEAM_TCP_HOST/ATEAM_TCP_PORT), reusing the same onConnection/socketServerTransport. Refuses a wildcard/0.0.0.0 bind — this socket trusts the network (a Tailscale ACL), not a per-connection secret, so exposing it publicly would hand out an unauthenticated engine. - db + protocol: hosts table, ConnectionDTO and ConnectionRecord gain `transport` ("ssh" | "tcp") and `endpoint` (host:port for tcp; null for ssh). Bootstrap CREATE + idempotent ALTER migration. For a tcp host we DO store the endpoint — there's no ssh_config to own it. - connections.ts: listConnections maps them (ssh_config hosts → ssh; saved-only records → their stored transport); recordConnection persists them. - host.ts: connect() looks up the connection and openTransport() branches — ssh via sshClientTransport(attach relay), tcp via socketClientTransport(net.connect). Rationale (two /scalable passes): a WebSocket transport forces bespoke auth (breaks "no login, no cloud") for no scaling gain; and no React Native SSH library exposes a raw streaming exec channel (only buffered execute() or a PTY shell), so SSH-on-mobile needs a native module. Raw TCP over Tailscale reuses off-the-shelf primitives on both ends with Tailscale (WireGuard) as the auth boundary. Tests: buildAteamApi over a real TCP socket; a tcp-host connection-manager case. --- apps/desktop/src/main/host.ts | 51 +++++++++++++-- packages/db/src/bootstrap.ts | 6 +- packages/db/src/schema.ts | 20 ++++-- packages/protocol/src/index.ts | 4 ++ packages/server/src/cli.ts | 43 ++++++++++-- packages/server/src/connections.ts | 13 ++++ packages/server/test/connections.test.ts | 25 +++++++ packages/server/test/tcp-transport.test.ts | 76 ++++++++++++++++++++++ 8 files changed, 218 insertions(+), 20 deletions(-) create mode 100644 packages/server/test/tcp-transport.test.ts diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts index 6b2cfba..19d31b3 100644 --- a/apps/desktop/src/main/host.ts +++ b/apps/desktop/src/main/host.ts @@ -1,11 +1,15 @@ // The connection controller: which engine drives the app, and swapping between // them. Owns the always-alive local engine, the currently-active Backend, and the // forwarding of that backend's push-events to the renderer. Connecting to a remote -// host opens an SSH transport, handshakes (gating the protocol version), caches the -// result, and re-points the active backend + event stream at it. +// host opens the connection's chosen transport — SSH (the `attach` relay over +// OpenSSH) or a direct TCP socket (a Tailscale client to the daemon's TCP port) — +// handshakes (gating the protocol version), caches the result, and re-points the +// active backend + event stream at it. +import { connect as netConnect } from "node:net"; import { ipcMain } from "electron"; import { CH, + type ClientTransport, createRpcClient, PROTOCOL_VERSION, type RpcClient, @@ -16,6 +20,7 @@ import { type Engine, listConnections, recordConnection, + socketClientTransport, sshClientTransport, } from "@ateam/server"; import { type Backend, type BackendEvent, localBackend, remoteBackend, type Router } from "./backend"; @@ -29,6 +34,34 @@ const REMOTE_ATTACH = "bash -lc 'exec ateam attach --stdio'"; // error, and the UI must not wait forever. A live daemon replies in well under this. const CONNECT_TIMEOUT_MS = 20_000; +/** Split "host:port" (or bracketed IPv6 "[fd7a::1]:7420") into its parts. */ +function parseEndpoint(endpoint: string): { host: string; port: number } { + const m = /^\[(.+)\]:(\d+)$/.exec(endpoint) ?? /^(.+):(\d+)$/.exec(endpoint); + const host = m?.[1]; + const port = m?.[2]; + if (!host || !port) throw new Error(`invalid endpoint "${endpoint}" — expected host:port`); + return { host, port: Number(port) }; +} + +/** + * Open the client transport for a connection's chosen method. Both feed the + * identical createRpcClient/buildAteamApi — only the byte pipe differs: + * - "ssh": the proven `attach` relay over OpenSSH (keys/known_hosts are its job). + * - "tcp": a direct socket to the daemon's TCP listener, typically over Tailscale + * (WireGuard is the network trust boundary; no ssh subprocess needed). + * `dispose` tears down the pipe; the remote daemon + its PTY sessions live on. + */ +function openTransport(conn: ConnectionDTO): { transport: ClientTransport; dispose: () => void } { + if (conn.transport === "tcp") { + if (!conn.endpoint) throw new Error(`connection "${conn.alias}" has no TCP endpoint`); + const { host, port } = parseEndpoint(conn.endpoint); + const sock = netConnect(port, host); + return { transport: socketClientTransport(sock), dispose: () => sock.destroy() }; + } + const client = sshClientTransport(conn.alias, [REMOTE_ATTACH]); + return { transport: client.transport, dispose: client.close }; +} + /** The push-events forwarded from the active backend to every window. */ const FORWARDED: { event: BackendEvent; channel: string }[] = [ { event: "taskUpdated", channel: CH.evtTaskUpdated }, @@ -95,17 +128,21 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { return statusOf(local, null); } - const client = sshClientTransport(alias, [REMOTE_ATTACH]); - const rpc: RpcClient = createRpcClient(client.transport); + // The user's chosen transport for this host lives on its connection record. + const conn = listConnections(db).find((c) => c.alias === alias); + if (!conn) throw new Error(`unknown connection "${alias}"`); + + const { transport, dispose } = openTransport(conn); + const rpc: RpcClient = createRpcClient(transport); let info: SystemInfo; try { info = await withTimeout(rpc.call(CH.systemHello) as Promise, CONNECT_TIMEOUT_MS); } catch (err) { - client.close(); + dispose(); throw err; } if (info.protocolVersion !== PROTOCOL_VERSION) { - client.close(); + dispose(); throw new Error( `Protocol mismatch: "${alias}" speaks v${info.protocolVersion}, this app speaks v${PROTOCOL_VERSION}. Update the older side.`, ); @@ -117,7 +154,7 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { agentsAvailable: info.agents, }); // The remote's method set matches the local dispatcher's (same contract). - swap(remoteBackend(rpc, local.methods, client.close), alias); + swap(remoteBackend(rpc, local.methods, dispose), alias); return { mode: "remote", alias, info }; } diff --git a/packages/db/src/bootstrap.ts b/packages/db/src/bootstrap.ts index 176f32d..8535c36 100644 --- a/packages/db/src/bootstrap.ts +++ b/packages/db/src/bootstrap.ts @@ -133,7 +133,9 @@ export function bootstrap(db: SqliteExecutor): void { server_version TEXT, agents_available TEXT, last_seen INTEGER, - created_at INTEGER + created_at INTEGER, + transport TEXT DEFAULT 'ssh', + endpoint TEXT ); CREATE INDEX IF NOT EXISTS hosts_last_seen_idx ON hosts (last_seen); `); @@ -151,6 +153,8 @@ export function bootstrap(db: SqliteExecutor): void { "ALTER TABLE loops ADD COLUMN config TEXT", "ALTER TABLE loops ADD COLUMN cadence_mode TEXT", "ALTER TABLE loops ADD COLUMN interval_ms INTEGER", + "ALTER TABLE hosts ADD COLUMN transport TEXT DEFAULT 'ssh'", + "ALTER TABLE hosts ADD COLUMN endpoint TEXT", ]) { try { db.exec(sql); diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index 4882a60..9ca2023 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -227,13 +227,15 @@ export const boardChanges = sqliteTable( ); /** - * Remote hosts the client can drive an engine on, keyed by their `~/.ssh/config` - * alias (unique there, so it's the natural PK). We persist ONLY Ateam's own - * metadata — the last handshake version, which agents the box has, and when it - * was last reached — never connection details (hostname/port/keys/jumphosts stay - * OpenSSH's job). This doubles as the offline cache: the connections list renders - * every known host from here without opening N live SSH connections. Client-only - * state — the engine never reads this table. + * Remote hosts the client can drive an engine on, keyed by an alias (the natural + * PK). We persist Ateam's own metadata — the last handshake version, which agents + * the box has, and when it was last reached. `transport` records how the user + * chose to connect: "ssh" (OpenSSH owns hostname/port/keys — resolved from + * ~/.ssh/config at connect time, so `endpoint` stays null) or "tcp" (a direct + * socket to the daemon's TCP listener, typically over Tailscale — there's no + * ssh_config to own it, so we store the `endpoint` host:port here). Doubles as the + * offline cache: the connections list renders every known host from here without + * opening N live connections. Client-only state — the engine never reads this table. */ export const hosts = sqliteTable( "hosts", @@ -243,6 +245,10 @@ export const hosts = sqliteTable( agentsAvailable: text("agents_available", { mode: "json" }).$type(), lastSeen: integer("last_seen"), createdAt: epochMs("created_at"), + /** How to connect: "ssh" (default) or "tcp". Null in old rows → treat as ssh. */ + transport: text("transport").$type<"ssh" | "tcp">(), + /** "host:port" for a tcp connection (e.g. the Tailscale IP); null for ssh. */ + endpoint: text("endpoint"), }, (t) => [index("hosts_last_seen_idx").on(t.lastSeen)], ); diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 1d7e737..414f264 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -220,6 +220,10 @@ export interface ConnectionDTO { inSshConfig: boolean; /** We've recorded at least one successful connection (has a saved record). */ known: boolean; + /** How the user connects: "ssh" (OpenSSH) or "tcp" (a direct socket, e.g. Tailscale). */ + transport: "ssh" | "tcp"; + /** "host:port" for a "tcp" connection; null for "ssh" (OpenSSH resolves it). */ + endpoint: string | null; } // A worktree advised for cleanup, shown in the cleanup dialog with its terminal. diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index efd8346..66035e4 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -56,20 +56,53 @@ async function runDaemon(): Promise { /* best-effort */ } + // Each client gets its own serveRpc over one connection; the engine (and its + // PTY sessions) is shared and outlives any single client. The same handler + // serves every listener — a net.Socket is a net.Socket whether it arrived over + // the unix socket (a local `attach` relay / SSH) or a TCP port (a Tailscale + // client), so socketServerTransport is transport-agnostic here. + const onConnection = (sock: Socket): void => { + serveRpc(engine, dispatcher, socketServerTransport(sock)); + }; + // allowHalfOpen: a one-shot client that sends a request then closes its write // side (EOF) must still receive the reply — without this the socket's read-end // 'end' auto-closes the write-end, dropping the response mid-flight. - const server = createServer({ allowHalfOpen: true }, (sock: Socket) => { - // Each client gets its own serveRpc over one connection; the engine (and - // its PTY sessions) is shared and outlives any single client. - serveRpc(engine, dispatcher, socketServerTransport(sock)); - }); + const server = createServer({ allowHalfOpen: true }, onConnection); server.on("error", (err) => { console.error(`[ateam] daemon error: ${err.message}`); process.exit(1); }); server.listen(SOCK, () => console.log(`[ateam] daemon listening at ${SOCK}`)); + // Optional TCP listener, for network clients that can't run `ateam attach` + // (the phone over Tailscale). Opt-in via env; the SAME onConnection serves it. + // This socket carries NO auth of its own — auth is the network's job (a + // Tailscale ACL, a private interface), exactly like the unix socket trusts + // filesystem perms. So we REFUSE a wildcard bind: exposing an unauthenticated + // engine on 0.0.0.0 would hand it to the whole network. Bind to an explicit + // private address (the Tailscale IP) only. + const tcpPort = process.env.ATEAM_TCP_PORT; + const tcpHost = process.env.ATEAM_TCP_HOST; + if (tcpPort) { + const port = Number(tcpPort); + if (!tcpHost || tcpHost === "0.0.0.0" || tcpHost === "::" || !Number.isInteger(port) || port <= 0) { + console.error( + "[ateam] refusing TCP listen: set ATEAM_TCP_HOST to an explicit private address " + + "(e.g. the Tailscale IP) and ATEAM_TCP_PORT to a port — never a wildcard bind", + ); + process.exit(1); + } + const tcpServer = createServer({ allowHalfOpen: true }, onConnection); + tcpServer.on("error", (err) => { + console.error(`[ateam] TCP listener error: ${err.message}`); + process.exit(1); + }); + tcpServer.listen(port, tcpHost, () => + console.log(`[ateam] daemon also listening on tcp://${tcpHost}:${port}`), + ); + } + // Connect to the PTY daemon in the BACKGROUND — don't block RPC on it. The // git/tasks/board surface serves immediately (a client's handshake shouldn't // wait out the PTY connect), and agent spawning reconnects lazily (PtyClient diff --git a/packages/server/src/connections.ts b/packages/server/src/connections.ts index fdcfa89..f281bdb 100644 --- a/packages/server/src/connections.ts +++ b/packages/server/src/connections.ts @@ -26,6 +26,10 @@ export interface ConnectionRecord { hostAlias: string; serverVersion?: string | null; agentsAvailable?: string[] | null; + /** The chosen transport (set when creating a "tcp" host; ssh hosts stay default). */ + transport?: "ssh" | "tcp"; + /** "host:port" for a tcp host (the Tailscale endpoint); null/omitted for ssh. */ + endpoint?: string | null; } const DEFAULT_SSH_CONFIG = join(homedir(), ".ssh", "config"); @@ -91,6 +95,9 @@ export function listConnections(db: AteamDb, configPath?: string): ConnectionDTO lastSeen: rec?.lastSeen ?? null, inSshConfig: true, known: rec != null, + // A host from ssh_config is inherently an SSH connection. + transport: "ssh", + endpoint: null, }); } for (const rec of saved.values()) { @@ -103,6 +110,10 @@ export function listConnections(db: AteamDb, configPath?: string): ConnectionDTO lastSeen: rec.lastSeen, inSshConfig: false, known: true, + // A saved-only host is usually a tcp/Tailscale connection the user added; + // default to ssh for legacy rows written before the column existed. + transport: rec.transport ?? "ssh", + endpoint: rec.endpoint ?? null, }); } // Recently-reached first; never-connected (null lastSeen) after, ties by alias. @@ -124,5 +135,7 @@ export function recordConnection(db: AteamDb, rec: ConnectionRecord): Host { }; if (rec.serverVersion !== undefined) patch.serverVersion = rec.serverVersion; if (rec.agentsAvailable !== undefined) patch.agentsAvailable = rec.agentsAvailable; + if (rec.transport !== undefined) patch.transport = rec.transport; + if (rec.endpoint !== undefined) patch.endpoint = rec.endpoint; return repo.upsertHost(db, patch); } diff --git a/packages/server/test/connections.test.ts b/packages/server/test/connections.test.ts index 40aa8af..bccd076 100644 --- a/packages/server/test/connections.test.ts +++ b/packages/server/test/connections.test.ts @@ -91,3 +91,28 @@ describe("recordConnection", () => { expect(typeof h?.lastSeen).toBe("number"); }); }); + +describe("transport choice", () => { + it("surfaces a saved tcp host with its endpoint; ssh_config hosts stay ssh", () => { + const db = createTestDb(); + const cfg = writeConfig("Host ssh-box\n HostName 10.0.0.9\n"); + // A Tailscale/tcp host the user added — not in ssh_config, carries an endpoint. + recordConnection(db, { + hostAlias: "tailnet-box", + transport: "tcp", + endpoint: "100.72.63.61:7420", + serverVersion: "1", + agentsAvailable: ["claude"], + }); + + const byAlias = Object.fromEntries(listConnections(db, cfg).map((c) => [c.alias, c])); + + expect(byAlias["tailnet-box"]?.transport).toBe("tcp"); + expect(byAlias["tailnet-box"]?.endpoint).toBe("100.72.63.61:7420"); + expect(byAlias["tailnet-box"]?.inSshConfig).toBe(false); + + // A host from ssh_config is inherently ssh, with no stored endpoint. + expect(byAlias["ssh-box"]?.transport).toBe("ssh"); + expect(byAlias["ssh-box"]?.endpoint).toBeNull(); + }); +}); diff --git a/packages/server/test/tcp-transport.test.ts b/packages/server/test/tcp-transport.test.ts new file mode 100644 index 0000000..d148518 --- /dev/null +++ b/packages/server/test/tcp-transport.test.ts @@ -0,0 +1,76 @@ +// The Tailscale-mode transport: buildAteamApi driving the engine over a raw TCP +// socket. This is the exact client seam the phone uses (react-native-tcp-socket → +// socketClientTransport → createRpcClient → buildAteamApi) and the shape the +// daemon's opt-in TCP listener serves. Stubs the engine/dispatcher so the test +// isolates the TRANSPORT + binding, not the native-module-laden engine. +import { type AddressInfo, connect, createServer } from "node:net"; +import { expect, test } from "bun:test"; +import { + buildAteamApi, + CH, + createRpcClient, + type NativeClientApi, + serverHandshake, +} from "@ateam/protocol"; +import { serveRpc } from "../src/rpc"; +import { socketClientTransport, socketServerTransport } from "../src/transport/socket"; + +// serveRpc only reads engine.on (to forward events) and dispatcher.handle. +const stubEngine = { on: () => () => {} } as unknown as Parameters[0]; + +const nativeStub: NativeClientApi = { + pathForFile: () => "", + pick: async () => null, + pickFiles: async () => [], + stageClipboardImage: async () => false, + stageImagePath: async () => false, + openProject: async () => {}, + boundProjectId: () => null, +}; + +test("buildAteamApi drives the engine over a real TCP socket", async () => { + const project = { + id: "p1", + name: "demo", + repoPath: "/x", + defaultBranch: "main", + githubOwner: null, + githubName: null, + color: null, + }; + const dispatcher = { + methods: [CH.systemHello, CH.projectsList], + handle: async (method: string) => { + if (method === CH.systemHello) return { protocolVersion: 1, agents: ["claude"] }; + if (method === CH.projectsList) return [project]; + throw new Error(`unexpected method ${method}`); + }, + } as unknown as Parameters[1]; + + const server = createServer({ allowHalfOpen: true }, (sock) => + serveRpc(stubEngine, dispatcher, socketServerTransport(sock)), + ); + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); + const { port } = server.address() as AddressInfo; + + const sock = connect(port, "127.0.0.1"); + await new Promise((resolve, reject) => { + sock.once("connect", resolve); + sock.once("error", reject); + }); + + // Exactly the phone's connect flow: handshake first (gate the version), then + // the full AteamApi over the same RPC client. + const rpc = createRpcClient(socketClientTransport(sock)); + const info = await serverHandshake(rpc); + expect(info.protocolVersion).toBe(1); + expect(info.agents).toEqual(["claude"]); + + const api = buildAteamApi(rpc, nativeStub); + const list = await api.projects.list(); + expect(list).toHaveLength(1); + expect(list[0]?.name).toBe("demo"); + + sock.destroy(); + await new Promise((resolve) => server.close(() => resolve())); +}); From bec035692d908484a767d66b21c8031ed2195950 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 20:08:03 +0200 Subject: [PATCH 16/83] =?UTF-8?q?revert(server,db,desktop):=20drop=20the?= =?UTF-8?q?=20per-connection=20transport=20choice=20=E2=80=94=20always=20S?= =?UTF-8?q?SH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A connection is a single SSH target (user@host + key) whose host can be a Tailscale IP; Tailscale is reachability, not a separate transport. Undoes the prior commit's transport=ssh|tcp field + endpoint, the daemon's opt-in TCP listener, and host.ts's TCP branch — a remote client connects only via the `attach` relay over OpenSSH, and the tailnet IP lives in the SSH host itself (ssh_config HostName), so nothing changes from SSH's perspective. --- apps/desktop/src/main/host.ts | 52 +++------------ packages/db/src/bootstrap.ts | 6 +- packages/db/src/schema.ts | 20 ++---- packages/protocol/src/index.ts | 4 -- packages/server/src/cli.ts | 43 ++---------- packages/server/src/connections.ts | 13 ---- packages/server/test/connections.test.ts | 25 ------- packages/server/test/tcp-transport.test.ts | 76 ---------------------- 8 files changed, 21 insertions(+), 218 deletions(-) delete mode 100644 packages/server/test/tcp-transport.test.ts diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts index 19d31b3..51554f2 100644 --- a/apps/desktop/src/main/host.ts +++ b/apps/desktop/src/main/host.ts @@ -1,15 +1,12 @@ // The connection controller: which engine drives the app, and swapping between // them. Owns the always-alive local engine, the currently-active Backend, and the // forwarding of that backend's push-events to the renderer. Connecting to a remote -// host opens the connection's chosen transport — SSH (the `attach` relay over -// OpenSSH) or a direct TCP socket (a Tailscale client to the daemon's TCP port) — -// handshakes (gating the protocol version), caches the result, and re-points the -// active backend + event stream at it. -import { connect as netConnect } from "node:net"; +// host opens an SSH transport (the `attach` relay over OpenSSH), handshakes (gating +// the protocol version), caches the result, and re-points the active backend + +// event stream at it. import { ipcMain } from "electron"; import { CH, - type ClientTransport, createRpcClient, PROTOCOL_VERSION, type RpcClient, @@ -20,7 +17,6 @@ import { type Engine, listConnections, recordConnection, - socketClientTransport, sshClientTransport, } from "@ateam/server"; import { type Backend, type BackendEvent, localBackend, remoteBackend, type Router } from "./backend"; @@ -34,34 +30,6 @@ const REMOTE_ATTACH = "bash -lc 'exec ateam attach --stdio'"; // error, and the UI must not wait forever. A live daemon replies in well under this. const CONNECT_TIMEOUT_MS = 20_000; -/** Split "host:port" (or bracketed IPv6 "[fd7a::1]:7420") into its parts. */ -function parseEndpoint(endpoint: string): { host: string; port: number } { - const m = /^\[(.+)\]:(\d+)$/.exec(endpoint) ?? /^(.+):(\d+)$/.exec(endpoint); - const host = m?.[1]; - const port = m?.[2]; - if (!host || !port) throw new Error(`invalid endpoint "${endpoint}" — expected host:port`); - return { host, port: Number(port) }; -} - -/** - * Open the client transport for a connection's chosen method. Both feed the - * identical createRpcClient/buildAteamApi — only the byte pipe differs: - * - "ssh": the proven `attach` relay over OpenSSH (keys/known_hosts are its job). - * - "tcp": a direct socket to the daemon's TCP listener, typically over Tailscale - * (WireGuard is the network trust boundary; no ssh subprocess needed). - * `dispose` tears down the pipe; the remote daemon + its PTY sessions live on. - */ -function openTransport(conn: ConnectionDTO): { transport: ClientTransport; dispose: () => void } { - if (conn.transport === "tcp") { - if (!conn.endpoint) throw new Error(`connection "${conn.alias}" has no TCP endpoint`); - const { host, port } = parseEndpoint(conn.endpoint); - const sock = netConnect(port, host); - return { transport: socketClientTransport(sock), dispose: () => sock.destroy() }; - } - const client = sshClientTransport(conn.alias, [REMOTE_ATTACH]); - return { transport: client.transport, dispose: client.close }; -} - /** The push-events forwarded from the active backend to every window. */ const FORWARDED: { event: BackendEvent; channel: string }[] = [ { event: "taskUpdated", channel: CH.evtTaskUpdated }, @@ -128,21 +96,17 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { return statusOf(local, null); } - // The user's chosen transport for this host lives on its connection record. - const conn = listConnections(db).find((c) => c.alias === alias); - if (!conn) throw new Error(`unknown connection "${alias}"`); - - const { transport, dispose } = openTransport(conn); - const rpc: RpcClient = createRpcClient(transport); + const client = sshClientTransport(alias, [REMOTE_ATTACH]); + const rpc: RpcClient = createRpcClient(client.transport); let info: SystemInfo; try { info = await withTimeout(rpc.call(CH.systemHello) as Promise, CONNECT_TIMEOUT_MS); } catch (err) { - dispose(); + client.close(); throw err; } if (info.protocolVersion !== PROTOCOL_VERSION) { - dispose(); + client.close(); throw new Error( `Protocol mismatch: "${alias}" speaks v${info.protocolVersion}, this app speaks v${PROTOCOL_VERSION}. Update the older side.`, ); @@ -154,7 +118,7 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { agentsAvailable: info.agents, }); // The remote's method set matches the local dispatcher's (same contract). - swap(remoteBackend(rpc, local.methods, dispose), alias); + swap(remoteBackend(rpc, local.methods, client.close), alias); return { mode: "remote", alias, info }; } diff --git a/packages/db/src/bootstrap.ts b/packages/db/src/bootstrap.ts index 8535c36..176f32d 100644 --- a/packages/db/src/bootstrap.ts +++ b/packages/db/src/bootstrap.ts @@ -133,9 +133,7 @@ export function bootstrap(db: SqliteExecutor): void { server_version TEXT, agents_available TEXT, last_seen INTEGER, - created_at INTEGER, - transport TEXT DEFAULT 'ssh', - endpoint TEXT + created_at INTEGER ); CREATE INDEX IF NOT EXISTS hosts_last_seen_idx ON hosts (last_seen); `); @@ -153,8 +151,6 @@ export function bootstrap(db: SqliteExecutor): void { "ALTER TABLE loops ADD COLUMN config TEXT", "ALTER TABLE loops ADD COLUMN cadence_mode TEXT", "ALTER TABLE loops ADD COLUMN interval_ms INTEGER", - "ALTER TABLE hosts ADD COLUMN transport TEXT DEFAULT 'ssh'", - "ALTER TABLE hosts ADD COLUMN endpoint TEXT", ]) { try { db.exec(sql); diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index 9ca2023..4882a60 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -227,15 +227,13 @@ export const boardChanges = sqliteTable( ); /** - * Remote hosts the client can drive an engine on, keyed by an alias (the natural - * PK). We persist Ateam's own metadata — the last handshake version, which agents - * the box has, and when it was last reached. `transport` records how the user - * chose to connect: "ssh" (OpenSSH owns hostname/port/keys — resolved from - * ~/.ssh/config at connect time, so `endpoint` stays null) or "tcp" (a direct - * socket to the daemon's TCP listener, typically over Tailscale — there's no - * ssh_config to own it, so we store the `endpoint` host:port here). Doubles as the - * offline cache: the connections list renders every known host from here without - * opening N live connections. Client-only state — the engine never reads this table. + * Remote hosts the client can drive an engine on, keyed by their `~/.ssh/config` + * alias (unique there, so it's the natural PK). We persist ONLY Ateam's own + * metadata — the last handshake version, which agents the box has, and when it + * was last reached — never connection details (hostname/port/keys/jumphosts stay + * OpenSSH's job). This doubles as the offline cache: the connections list renders + * every known host from here without opening N live SSH connections. Client-only + * state — the engine never reads this table. */ export const hosts = sqliteTable( "hosts", @@ -245,10 +243,6 @@ export const hosts = sqliteTable( agentsAvailable: text("agents_available", { mode: "json" }).$type(), lastSeen: integer("last_seen"), createdAt: epochMs("created_at"), - /** How to connect: "ssh" (default) or "tcp". Null in old rows → treat as ssh. */ - transport: text("transport").$type<"ssh" | "tcp">(), - /** "host:port" for a tcp connection (e.g. the Tailscale IP); null for ssh. */ - endpoint: text("endpoint"), }, (t) => [index("hosts_last_seen_idx").on(t.lastSeen)], ); diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 414f264..1d7e737 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -220,10 +220,6 @@ export interface ConnectionDTO { inSshConfig: boolean; /** We've recorded at least one successful connection (has a saved record). */ known: boolean; - /** How the user connects: "ssh" (OpenSSH) or "tcp" (a direct socket, e.g. Tailscale). */ - transport: "ssh" | "tcp"; - /** "host:port" for a "tcp" connection; null for "ssh" (OpenSSH resolves it). */ - endpoint: string | null; } // A worktree advised for cleanup, shown in the cleanup dialog with its terminal. diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 66035e4..efd8346 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -56,53 +56,20 @@ async function runDaemon(): Promise { /* best-effort */ } - // Each client gets its own serveRpc over one connection; the engine (and its - // PTY sessions) is shared and outlives any single client. The same handler - // serves every listener — a net.Socket is a net.Socket whether it arrived over - // the unix socket (a local `attach` relay / SSH) or a TCP port (a Tailscale - // client), so socketServerTransport is transport-agnostic here. - const onConnection = (sock: Socket): void => { - serveRpc(engine, dispatcher, socketServerTransport(sock)); - }; - // allowHalfOpen: a one-shot client that sends a request then closes its write // side (EOF) must still receive the reply — without this the socket's read-end // 'end' auto-closes the write-end, dropping the response mid-flight. - const server = createServer({ allowHalfOpen: true }, onConnection); + const server = createServer({ allowHalfOpen: true }, (sock: Socket) => { + // Each client gets its own serveRpc over one connection; the engine (and + // its PTY sessions) is shared and outlives any single client. + serveRpc(engine, dispatcher, socketServerTransport(sock)); + }); server.on("error", (err) => { console.error(`[ateam] daemon error: ${err.message}`); process.exit(1); }); server.listen(SOCK, () => console.log(`[ateam] daemon listening at ${SOCK}`)); - // Optional TCP listener, for network clients that can't run `ateam attach` - // (the phone over Tailscale). Opt-in via env; the SAME onConnection serves it. - // This socket carries NO auth of its own — auth is the network's job (a - // Tailscale ACL, a private interface), exactly like the unix socket trusts - // filesystem perms. So we REFUSE a wildcard bind: exposing an unauthenticated - // engine on 0.0.0.0 would hand it to the whole network. Bind to an explicit - // private address (the Tailscale IP) only. - const tcpPort = process.env.ATEAM_TCP_PORT; - const tcpHost = process.env.ATEAM_TCP_HOST; - if (tcpPort) { - const port = Number(tcpPort); - if (!tcpHost || tcpHost === "0.0.0.0" || tcpHost === "::" || !Number.isInteger(port) || port <= 0) { - console.error( - "[ateam] refusing TCP listen: set ATEAM_TCP_HOST to an explicit private address " + - "(e.g. the Tailscale IP) and ATEAM_TCP_PORT to a port — never a wildcard bind", - ); - process.exit(1); - } - const tcpServer = createServer({ allowHalfOpen: true }, onConnection); - tcpServer.on("error", (err) => { - console.error(`[ateam] TCP listener error: ${err.message}`); - process.exit(1); - }); - tcpServer.listen(port, tcpHost, () => - console.log(`[ateam] daemon also listening on tcp://${tcpHost}:${port}`), - ); - } - // Connect to the PTY daemon in the BACKGROUND — don't block RPC on it. The // git/tasks/board surface serves immediately (a client's handshake shouldn't // wait out the PTY connect), and agent spawning reconnects lazily (PtyClient diff --git a/packages/server/src/connections.ts b/packages/server/src/connections.ts index f281bdb..fdcfa89 100644 --- a/packages/server/src/connections.ts +++ b/packages/server/src/connections.ts @@ -26,10 +26,6 @@ export interface ConnectionRecord { hostAlias: string; serverVersion?: string | null; agentsAvailable?: string[] | null; - /** The chosen transport (set when creating a "tcp" host; ssh hosts stay default). */ - transport?: "ssh" | "tcp"; - /** "host:port" for a tcp host (the Tailscale endpoint); null/omitted for ssh. */ - endpoint?: string | null; } const DEFAULT_SSH_CONFIG = join(homedir(), ".ssh", "config"); @@ -95,9 +91,6 @@ export function listConnections(db: AteamDb, configPath?: string): ConnectionDTO lastSeen: rec?.lastSeen ?? null, inSshConfig: true, known: rec != null, - // A host from ssh_config is inherently an SSH connection. - transport: "ssh", - endpoint: null, }); } for (const rec of saved.values()) { @@ -110,10 +103,6 @@ export function listConnections(db: AteamDb, configPath?: string): ConnectionDTO lastSeen: rec.lastSeen, inSshConfig: false, known: true, - // A saved-only host is usually a tcp/Tailscale connection the user added; - // default to ssh for legacy rows written before the column existed. - transport: rec.transport ?? "ssh", - endpoint: rec.endpoint ?? null, }); } // Recently-reached first; never-connected (null lastSeen) after, ties by alias. @@ -135,7 +124,5 @@ export function recordConnection(db: AteamDb, rec: ConnectionRecord): Host { }; if (rec.serverVersion !== undefined) patch.serverVersion = rec.serverVersion; if (rec.agentsAvailable !== undefined) patch.agentsAvailable = rec.agentsAvailable; - if (rec.transport !== undefined) patch.transport = rec.transport; - if (rec.endpoint !== undefined) patch.endpoint = rec.endpoint; return repo.upsertHost(db, patch); } diff --git a/packages/server/test/connections.test.ts b/packages/server/test/connections.test.ts index bccd076..40aa8af 100644 --- a/packages/server/test/connections.test.ts +++ b/packages/server/test/connections.test.ts @@ -91,28 +91,3 @@ describe("recordConnection", () => { expect(typeof h?.lastSeen).toBe("number"); }); }); - -describe("transport choice", () => { - it("surfaces a saved tcp host with its endpoint; ssh_config hosts stay ssh", () => { - const db = createTestDb(); - const cfg = writeConfig("Host ssh-box\n HostName 10.0.0.9\n"); - // A Tailscale/tcp host the user added — not in ssh_config, carries an endpoint. - recordConnection(db, { - hostAlias: "tailnet-box", - transport: "tcp", - endpoint: "100.72.63.61:7420", - serverVersion: "1", - agentsAvailable: ["claude"], - }); - - const byAlias = Object.fromEntries(listConnections(db, cfg).map((c) => [c.alias, c])); - - expect(byAlias["tailnet-box"]?.transport).toBe("tcp"); - expect(byAlias["tailnet-box"]?.endpoint).toBe("100.72.63.61:7420"); - expect(byAlias["tailnet-box"]?.inSshConfig).toBe(false); - - // A host from ssh_config is inherently ssh, with no stored endpoint. - expect(byAlias["ssh-box"]?.transport).toBe("ssh"); - expect(byAlias["ssh-box"]?.endpoint).toBeNull(); - }); -}); diff --git a/packages/server/test/tcp-transport.test.ts b/packages/server/test/tcp-transport.test.ts deleted file mode 100644 index d148518..0000000 --- a/packages/server/test/tcp-transport.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -// The Tailscale-mode transport: buildAteamApi driving the engine over a raw TCP -// socket. This is the exact client seam the phone uses (react-native-tcp-socket → -// socketClientTransport → createRpcClient → buildAteamApi) and the shape the -// daemon's opt-in TCP listener serves. Stubs the engine/dispatcher so the test -// isolates the TRANSPORT + binding, not the native-module-laden engine. -import { type AddressInfo, connect, createServer } from "node:net"; -import { expect, test } from "bun:test"; -import { - buildAteamApi, - CH, - createRpcClient, - type NativeClientApi, - serverHandshake, -} from "@ateam/protocol"; -import { serveRpc } from "../src/rpc"; -import { socketClientTransport, socketServerTransport } from "../src/transport/socket"; - -// serveRpc only reads engine.on (to forward events) and dispatcher.handle. -const stubEngine = { on: () => () => {} } as unknown as Parameters[0]; - -const nativeStub: NativeClientApi = { - pathForFile: () => "", - pick: async () => null, - pickFiles: async () => [], - stageClipboardImage: async () => false, - stageImagePath: async () => false, - openProject: async () => {}, - boundProjectId: () => null, -}; - -test("buildAteamApi drives the engine over a real TCP socket", async () => { - const project = { - id: "p1", - name: "demo", - repoPath: "/x", - defaultBranch: "main", - githubOwner: null, - githubName: null, - color: null, - }; - const dispatcher = { - methods: [CH.systemHello, CH.projectsList], - handle: async (method: string) => { - if (method === CH.systemHello) return { protocolVersion: 1, agents: ["claude"] }; - if (method === CH.projectsList) return [project]; - throw new Error(`unexpected method ${method}`); - }, - } as unknown as Parameters[1]; - - const server = createServer({ allowHalfOpen: true }, (sock) => - serveRpc(stubEngine, dispatcher, socketServerTransport(sock)), - ); - await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); - const { port } = server.address() as AddressInfo; - - const sock = connect(port, "127.0.0.1"); - await new Promise((resolve, reject) => { - sock.once("connect", resolve); - sock.once("error", reject); - }); - - // Exactly the phone's connect flow: handshake first (gate the version), then - // the full AteamApi over the same RPC client. - const rpc = createRpcClient(socketClientTransport(sock)); - const info = await serverHandshake(rpc); - expect(info.protocolVersion).toBe(1); - expect(info.agents).toEqual(["claude"]); - - const api = buildAteamApi(rpc, nativeStub); - const list = await api.projects.list(); - expect(list).toHaveLength(1); - expect(list[0]?.name).toBe("demo"); - - sock.destroy(); - await new Promise((resolve) => server.close(() => resolve())); -}); From c76174e3ff9f7af9d836cb1d4680bec8d3c638b2 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 20:08:17 +0200 Subject: [PATCH 17/83] =?UTF-8?q?feat(mobile):=20apps/mobile=20=E2=80=94?= =?UTF-8?q?=20Expo/React=20Native=20board=20preview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A React Native client scaffold (Expo SDK 52 / RN 0.76, pinned for Xcode 16.2 — SDK 57 needs Swift 6.2) with a board + connection screen, running in the iOS simulator. Dark Ateam identity applying the clawnify DESIGN-apps structural signature (eyebrow-labeled zones, chips for facts vs tinted badges for signals, monochrome chrome, borders not shadows, no emoji) — not its brand theme. The connection header is a single SSH target (pallaoro@) — the host is just an editable IP you point at the box's Tailscale address. Mock data; live SSH wiring (buildAteamApi over a native-SSH ClientTransport) is next. Excluded from the bun workspace (own npm/Metro toolchain): root package.json globs !apps/mobile, and apps/mobile/metro.config.js pins module resolution. --- apps/mobile/.claude/settings.json | 5 + apps/mobile/.gitignore | 41 + apps/mobile/AGENTS.md | 3 + apps/mobile/App.tsx | 235 + apps/mobile/CLAUDE.md | 1 + apps/mobile/LICENSE | 21 + apps/mobile/app.json | 26 + .../mobile/assets/android-icon-background.png | Bin 0 -> 17549 bytes .../mobile/assets/android-icon-foreground.png | Bin 0 -> 78796 bytes .../mobile/assets/android-icon-monochrome.png | Bin 0 -> 4140 bytes apps/mobile/assets/favicon.png | Bin 0 -> 1129 bytes apps/mobile/assets/icon.png | Bin 0 -> 393493 bytes apps/mobile/assets/splash-icon.png | Bin 0 -> 17547 bytes apps/mobile/index.ts | 8 + apps/mobile/metro.config.js | 14 + apps/mobile/package-lock.json | 9366 +++++++++++++++++ apps/mobile/package.json | 22 + apps/mobile/tsconfig.json | 6 + package.json | 3 +- 19 files changed, 9750 insertions(+), 1 deletion(-) create mode 100644 apps/mobile/.claude/settings.json create mode 100644 apps/mobile/.gitignore create mode 100644 apps/mobile/AGENTS.md create mode 100644 apps/mobile/App.tsx create mode 100644 apps/mobile/CLAUDE.md create mode 100644 apps/mobile/LICENSE create mode 100644 apps/mobile/app.json create mode 100644 apps/mobile/assets/android-icon-background.png create mode 100644 apps/mobile/assets/android-icon-foreground.png create mode 100644 apps/mobile/assets/android-icon-monochrome.png create mode 100644 apps/mobile/assets/favicon.png create mode 100644 apps/mobile/assets/icon.png create mode 100644 apps/mobile/assets/splash-icon.png create mode 100644 apps/mobile/index.ts create mode 100644 apps/mobile/metro.config.js create mode 100644 apps/mobile/package-lock.json create mode 100644 apps/mobile/package.json create mode 100644 apps/mobile/tsconfig.json diff --git a/apps/mobile/.claude/settings.json b/apps/mobile/.claude/settings.json new file mode 100644 index 0000000..176e6a5 --- /dev/null +++ b/apps/mobile/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "enabledPlugins": { + "expo@claude-plugins-official": true + } +} diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore new file mode 100644 index 0000000..d914c32 --- /dev/null +++ b/apps/mobile/.gitignore @@ -0,0 +1,41 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ +expo-env.d.ts + +# Native +.kotlin/ +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + +# generated native folders +/ios +/android diff --git a/apps/mobile/AGENTS.md b/apps/mobile/AGENTS.md new file mode 100644 index 0000000..0e6bc80 --- /dev/null +++ b/apps/mobile/AGENTS.md @@ -0,0 +1,3 @@ +# Expo HAS CHANGED + +Read the exact versioned docs at https://docs.expo.dev/versions/v57.0.0/ before writing any code. diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx new file mode 100644 index 0000000..f21a9b4 --- /dev/null +++ b/apps/mobile/App.tsx @@ -0,0 +1,235 @@ +// Ateam mobile — board + connection preview. +// Design: Ateam's own dark/teal identity, applying the clawnify DESIGN-apps +// structural signature (labeled eyebrow zones · chips for facts vs tinted badges +// for signals · monochrome chrome, color reserved for status · engineered numbers +// · borders not shadows · no emoji) — NOT its brand theme (coral / light canvas). +// Preview scope: mock data. Transport is always SSH; the host shown is the box's +// Tailscale IP. Live wiring (buildAteamApi over an SSH ClientTransport) is next. +import { ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View } from "react-native"; + +const C = { + bg: "#0b0d10", + surface: "#14171c", + sunken: "#1a1e25", + line: "#242b35", + ink: "#e7ebf1", + muted: "#8b96a6", + faint: "#5a6472", + teal: "#35d1c0", + amber: "#e6a94b", + blue: "#6ea8fe", + green: "#67cd8b", +}; + +// Status tints (color over a low-opacity wash of itself — the dark-mode badge rule). +const TINT: Record = { + [C.amber]: "rgba(230,169,75,0.14)", + [C.teal]: "rgba(53,209,192,0.14)", + [C.blue]: "rgba(110,168,254,0.14)", + [C.green]: "rgba(103,205,139,0.14)", + [C.muted]: "rgba(139,150,166,0.12)", +}; + +type Column = "needs_attention" | "running" | "review" | "todo" | "merged"; +const COLUMNS: { key: Column; label: string; tint: string }[] = [ + { key: "needs_attention", label: "Needs You", tint: C.amber }, + { key: "running", label: "In Progress", tint: C.teal }, + { key: "review", label: "Review", tint: C.blue }, + { key: "todo", label: "Backlog", tint: C.muted }, + { key: "merged", label: "Done", tint: C.green }, +]; + +type Task = { name: string; column: Column; agent: string; branch: string; note: string }; +const TASKS: Task[] = [ + { name: "Fix SSH reconnect on wake", column: "needs_attention", agent: "claude", branch: "fix/ssh-reconnect", note: "awaiting your input" }, + { name: "Tailscale reachability for the daemon", column: "running", agent: "claude", branch: "feat/tailnet-host", note: "editing host.ts" }, + { name: "Board reconciler perf", column: "running", agent: "codex", branch: "perf/reconciler", note: "running tests" }, + { name: "Connections screen", column: "review", agent: "claude", branch: "feat/connections-ui", note: "3 files changed" }, + { name: "Rename daemon → engine", column: "todo", agent: "claude", branch: "chore/rename", note: "queued" }, + { name: "Remote fs picker", column: "merged", agent: "claude", branch: "feat/fs-listdir", note: "merged · PR #45" }, +]; + +// Fact → chip: neutral, bordered, sunken fill. Never colored. +function Chip({ children }: { children: string }) { + return ( + + + {children} + + + ); +} + +// Signal → badge: tinted wash + colored text, pill radius. +function Badge({ children, tint }: { children: string; tint: string }) { + return ( + + + {children} + + + ); +} + +function AgentTag({ agent }: { agent: string }) { + // Identity, not status — monochrome, so color stays reserved for signals. + return ( + + {agent[0]?.toUpperCase()} + + ); +} + +function TaskCard({ task, tint }: { task: Task; tint: string }) { + return ( + + + + + {task.name} + + + + {task.branch} + {task.note} + + + ); +} + +export default function App() { + useColorScheme(); // reserved: theme-aware later + + return ( + + + + {/* Toolbar */} + + + + A + + Ateam + + + + hetzner-devbox + + + + SSH ·{" "} + pallaoro@100.72.63.61 · claude + + + + {/* Board — one eyebrow-labeled zone per column */} + + {COLUMNS.map((col) => { + const tasks = TASKS.filter((t) => t.column === col.key); + if (tasks.length === 0) return null; + return ( + + + + {col.label} + {tasks.length} + + {tasks.map((t) => ( + + ))} + + ); + })} + preview · mock board · live SSH wiring next + + + ); +} + +const styles = StyleSheet.create({ + root: { flex: 1, backgroundColor: C.bg, paddingTop: 60 }, + + header: { paddingHorizontal: 18, paddingBottom: 14, borderBottomWidth: 1, borderBottomColor: C.line }, + brandRow: { flexDirection: "row", alignItems: "center", gap: 10 }, + monogram: { + width: 30, + height: 30, + borderRadius: 8, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + monogramText: { color: C.teal, fontSize: 16, fontWeight: "800" }, + brand: { color: C.ink, fontSize: 20, fontWeight: "700", letterSpacing: -0.3 }, + spacer: { flex: 1 }, + connPill: { + flexDirection: "row", + alignItems: "center", + gap: 6, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + paddingHorizontal: 10, + paddingVertical: 5, + borderRadius: 999, + }, + connDot: { width: 7, height: 7, borderRadius: 4, backgroundColor: C.green }, + connText: { color: C.muted, fontSize: 12, fontWeight: "600" }, + connMeta: { color: C.muted, fontSize: 12, marginTop: 12 }, + connHost: { color: C.ink, fontVariant: ["tabular-nums"] }, + + board: { flex: 1 }, + boardContent: { padding: 16, paddingBottom: 40 }, + zone: { marginBottom: 22 }, + eyebrowRow: { flexDirection: "row", alignItems: "center", gap: 8, marginBottom: 10, paddingLeft: 2 }, + tick: { width: 3, height: 12, borderRadius: 2 }, + eyebrow: { + color: C.muted, + fontSize: 11, + fontWeight: "600", + textTransform: "uppercase", + letterSpacing: 1.1, + }, + eyebrowCount: { color: C.faint, fontSize: 11, fontWeight: "600", fontVariant: ["tabular-nums"] }, + + card: { + backgroundColor: C.surface, + borderWidth: 1, + borderColor: C.line, + borderLeftWidth: 3, + borderRadius: 8, + padding: 12, + marginBottom: 8, + }, + cardTop: { flexDirection: "row", alignItems: "flex-start", gap: 9 }, + agentTag: { + width: 22, + height: 22, + borderRadius: 6, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + agentInitial: { color: C.muted, fontSize: 11, fontWeight: "700" }, + cardName: { color: C.ink, fontSize: 15, fontWeight: "600", flex: 1, lineHeight: 20 }, + cardMeta: { flexDirection: "row", alignItems: "center", gap: 6, marginTop: 10, flexWrap: "wrap" }, + + chip: { + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + borderRadius: 6, + paddingHorizontal: 7, + paddingVertical: 3, + }, + chipText: { color: C.muted, fontSize: 11, fontVariant: ["tabular-nums"] }, + badge: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 3 }, + badgeText: { fontSize: 11, fontWeight: "600" }, + + footnote: { color: C.faint, fontSize: 11, textAlign: "center", marginTop: 8 }, +}); diff --git a/apps/mobile/CLAUDE.md b/apps/mobile/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/apps/mobile/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/apps/mobile/LICENSE b/apps/mobile/LICENSE new file mode 100644 index 0000000..30b20e3 --- /dev/null +++ b/apps/mobile/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present 650 Industries, Inc. (aka Expo) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/apps/mobile/app.json b/apps/mobile/app.json new file mode 100644 index 0000000..f4f5398 --- /dev/null +++ b/apps/mobile/app.json @@ -0,0 +1,26 @@ +{ + "expo": { + "name": "mobile", + "slug": "mobile", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "light", + "ios": { + "supportsTablet": true, + "bundleIdentifier": "com.ricalla.mobile" + }, + "android": { + "adaptiveIcon": { + "backgroundColor": "#E6F4FE", + "foregroundImage": "./assets/android-icon-foreground.png", + "backgroundImage": "./assets/android-icon-background.png", + "monochromeImage": "./assets/android-icon-monochrome.png" + }, + "predictiveBackGestureEnabled": false + }, + "web": { + "favicon": "./assets/favicon.png" + } + } +} diff --git a/apps/mobile/assets/android-icon-background.png b/apps/mobile/assets/android-icon-background.png new file mode 100644 index 0000000000000000000000000000000000000000..5ffefc5bb57a3d7b39ec6ff4e96979226522cc49 GIT binary patch literal 17549 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

f!0B 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 literal 0 HcmV?d00001 diff --git a/apps/mobile/assets/android-icon-monochrome.png b/apps/mobile/assets/android-icon-monochrome.png new file mode 100644 index 0000000000000000000000000000000000000000..77484ebdbca253297baea4a7d416233aa47a45c0 GIT binary patch literal 4140 zcmds4`#;nD``_G?M(cKNH;M{5n{L+KorqWtQBFDAMuoN!a)@COO1e8JiX5_%Lu_&w zVuqV?OF3_C4wZ9SzO~SheO~K+e7`?^|ANmRkN0Em_w~LG&*$~JuIu%FT|Mc13?Z!| z4S_%q_I5U|5D1hmzP4@wl9$dXJ@5xVZ|5BaffzW7FX-dLIpshIjdDF^4XJ*uwg4Vr z!B$RI5J=4pnGL)o1oCUUy^WQ79F#wPI98Qiu;qVbTx=VBN_q0@@RCT??3)$*Q6o3_ zChT_aGStaF=bZO=%-LrCs4ipw-~VU{;MUPb{MQGiQX=>Lw$T49AYBvHC`w3fiz4g1 zxV0P@vdjE;!8TV35ca?4$GK-OVKLvHDzz@`t;#jVPBceMb*qmqMz5}}hejpk9oJ6o z5lz(Q9|$j;QC~8Ls%x>{?QHJ<=aSi*$qm{D+u-{ANTp}+!T!xU24l4VmAa~cJ8!ka zuL(ZhyF1d7)Nsas#D4p;jFfFjjub27jK2*S)!~8zPs&kEw+_dBn;+i6bFt}TXtAE6A;jap7sj;sp5ja4aL zlTH1ENx?+3pG%~B2InPzo}7c^Ylqx}Q0=dEefT3;Xxe4Q5C7xRS-w`takgJTYy7f* zW_WyD+;_pk!osg`l}DEb9(?}hTk#@7^hh@3F9=ol*s)^*_jj)sRhpmc6lsUtgiy_1 zlv_j{xX`}`iuqlShz*}sJ{5%Ol!BvtTm@E40=^c8ki(fioLyPYQ^pWr$f}U{?<|Ho zLasun@rHFYb{)!R4=cpVQ7YOn>+Duk#i-@}b9pKyX#>(wOnozH`1Jn!PgX+krdAY} zs*!Wi2h2v90l@qcgzA7`h|MeZvC3R0kCc|v-V56I)?yzOq{jd=DF`b=J@xZ;q9-H3RSSwSTYK|&-o6R6KaIVr;EtiVAozdX$KGnC7Ac#l$rw9(LMRlIEfS z#e`hz3e0JHC4V#&?|zgb$34AYh>p+&o@8;Cqc2=AJ#pQVzM2VuYp|}oD#-A>%?BMt#7bLRE)X22(>NL6gkiBYrLR6$ol)^SV9JObVi4M;311p>qpD-70*?F{61`ytpXx zG^|5q?q%s%BiPKy)D7JOcQX4@FiH6g>Vlz!7gF~Ek zVaVsoYdDTs1-XxKUT3CwT|3#klrxJ>63$e?4r#ME_Z_(G+G=nA*+bK;^*xfg$%rj; zpB_Mha!VLA!Lb{=4%_7p`|I~UkuQ48IV)tFIMR=TaAgk@qhoiL>Nj5$%%;vWMxQHp zSHn>;THo4fgp;|4qvKpQnU+=T#W!w5ALJn|7IHkWX1;@vm+~>sE$rmvBSQSf_b>aC zg+`L4X*G@#SuWA4C2A0XqF1c`Ml_dgJC4}d&H&AIXfF#na<0BPKM=dFQYTcYNGII` zp|+wh3ayF$F#5x?ojBumW}j|Z zl3>}JdwV8QIMv?Xz9hIIP}eP8c>n(Wwa@Kca7@W1lg#<0ep)REks=NOD%_WC*-9=< zY5qJ*D3fl$4jg5@Xk6^g9D`| zqRHfP%Zk~`|7ptOi0&fIbZ_a99Y9awryhn<6Y8>LKGyS7i_T1QQXt-g1O=_Fm^rn7 ziU*kAkvPm7zIas_GGB37!(;fms=9ofD(F~_DYP2{3&YwHndu)H_}wS8&f$r9kRUhf zT@M_%WW>n0?r#@VN9*a{DPRWs`3|pmaQ_#J6To8KnCjXljK7&8-GaymsJ`xOC zm_TXycg7|@JbX!TMabyyasM+1w>Agw!Xyk@GlbIX7kz1lpjozW-@cjCCM?p; zStvLZTR2xFx|l-fXEi<(&uU2m)&-3{YCA4YT?%B%p?T$QC$2E1N9uK;`i^K1D+azg zErKMGr4Q#aUl*BQbRFxAr|Ex0AD5YGh9PrD88j)~dsoCc4Ffr?wxvXb%1s_THcmz; zMXToIZw$daHCc^!HZR5q6z#r&LXczNg>8LRNtw`GZSbO)ufG8p7xPf;jz;-Is4a`J z*nPS=dH|H;YyypJ1b5T4;XIKV#U#ziG8kWgY*5-zs+++>IfyV{}4{UnmEXY)1hnl(1 zBv3oA8q-#Eo^=S0O4{qQ{!FN1#1-fEC=9tIKU<6!L>~mSz#g(Hhud&?v~oreZ8p$= zZ%RvRx_>1Cj+#&|Pkc-EccGIw2BO$Pt+;EDsp~j4lgO;z%|*YeM@@hgak-LuxsQDo zCPu#jSgJGEK2|2^+JSJ~2X^B6Veqx`*yA(x0W{IR=g5T`p}5nPBOk-02SF^f@t_#=9_VNz7$B)^b4i?_erJ0F zsGTqA5Q5)o|FB{)z)A9aB<@;*#8do_dYY`dFJ4fec&Pzj+ZFgFwB#ZXUz+IQlCNtF zq79_@LpB1K7jN}e~_om2L!D*1CqWBm@<~!dZdByG^B^^Dr0V(3k;;vtfCo>7MLxdE0;5&nv%k zFHs&vLPyg-@N)Y+g?osdYszRR@B!sf9gZDxN9EIyDa6i|#4(3MFs~n(o1H{~lH*Mh z$4`ck3aRwE3Ccj}_+>GUEznbpL6IzvEU9?<=Nu_HC-KzvF~c~Y#sO|4WuE7j7%-;he19q{tgq-Ysm;L@d5h` z(0L37a#HQL44Zlwl3F9IaJ%ycLA8*0YJE^Mb8MbN9;qA#3Vp41?v9j^1@pTvW-9|9 zhjo5k=&J=LUTJGNwa3%w!gEKj^5|r=HO1pN#Y3-6HK|Yyl4~jfNWP(hlPvD;;w0R7 zsFBFzyhXn{P2DN+6p`$_w?_D(WGAuH*)Nuq0U;dOekZ%ed4@y&(qIDS)r&Q^lHU@p zeiV;W3*mHja?ftGqwnx!^TrFG2;Oo$D_4~gBJ z^xupa$0%kcle0v=&%M4K>d*M3d%kl#O%^xub^~kn+U|xX#P5D#*$~3ZhOlymFtCh7 z>ipUkdmntx6J9A#lyk`@oSX)HSV1_b!dKe9z=>x~4=Cp~E`jbZ@zm-^=mWt8Ct<<2 z9TUPxrTjndHU`jIx2S5fREB?CY6It?U^cvFBT@a&=$9VLw00hN`fN78*Nuy|H`Q0S zDHZPgwAy6vl#x{QnKEQ%{Ju-uZ`q79e%rW37WarsrCzkqQA?iJ7*sbcj81irReKg1 zkm{EP1`YXSR literal 0 HcmV?d00001 diff --git a/apps/mobile/assets/favicon.png b/apps/mobile/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..408bd746615785760b09e6f23fa8378d3e614331 GIT binary patch literal 1129 zcmV-v1eW`WP)_aY0~Jks(?}v7_xUud z^7&IRydH}ITNsLl({49i1>{P6S;TY(+6r8WMRB%aw0 z;rtJIzFmzc5HNL=9nP`82+ya4@oUf#@Yz^2v_e<5fcycE^D5sGmvQI}3cr41BGHS5 zqZDE=37um+VRnU?J;~S+$dyt83jNjd>z;2;pUk?vq zeO3i60?7N6KB`a@Xqwf576E=dI{Wq;=pe8Fuime*W0heiTZW(n7BKrp?#Y*rF2M3c zzx4i+hFS*>P=l^%%#EN?@GW4Y z$)Z)i=b??9ER}*r!M6aJ=O|?;b?O;SL}2Vnx2Jch;7fqa`;;bgN%_uX<$k~Gwwj{g zXC@mNPJ0%YD-DO?$pM#BSL4dY&-pd{e^mwi|7(`GFw^DZY9WITPR3M8QA1nicpRJhj$ zyC5jC6?({2N=y4_(Q5S+eTj23=C^QVEZpro<|KMQeWwB$gK@sC^5hGVE;SL4Meh13 zTp7;YD+y6uQ-tlGF#nS$Ioc=FEuq}}alo`1@8om-5H5>%D<4B5PGEMAn`h5(I@~?& zUYJ*`Sky=ubjHp(Uxf}s*t|~v+OayU7}V|1cUW`sSVq`L(}gX7q98OaK!-qW*IMuR zU$s!riFH6Kk&VutaYLImSFDQeI8H)4!uWcuCzNsyHOyD^Ks!c)Y^pb&aGh|6&WC11 zPnH_W7MwQpBM{M6C7axCH~p~(wO?6mb412^vTU?i$?PJ!pX7u1RnS?(TymxO;GS`H-A*@45HC zw_dNsVo!Hf@2cwRs_LrVVM+>8C`kB70000*Mp|4M0DyUVgaIHxJ^efKY5MW>59pvQ zB?>4VA^i391JPDm-2nhV#(Mq(0#ed&pTOPC->NyP$;VlS_qJ<$t#hH+1MMCax#ON!Q_HS zq@<+$_C_YW%HooLp+Ef+AUAV#wB==CadB~Bc423>u{UL5<>BFB0kg5Nu`xYCFgdtc zJL8M~VQFKEvrf6#vO_2+f`&y(@0D;qo5SUNqECCJ6b|N9O9(fM!s z{viAt{++eCqu}2t|JD89SZefrMf8qRp1OJUF@kFPpvHfrIz-(-Pzw4jf|BWJMV`Xb&{UitnF&k?Wb5ke# zKN9&j+|yeAR#O#YyML_hUn~5qXO`yAT>bU*A9#PGK0!RK;{O4`{(nL|$>D#R<4^B@ zlJ_qu|6knk|6UDAOMM5krv?6(@L0ir3;n-`{>|VY)Zc2M{=cimKZgE7{X_3RcIzKg z@SC?MTOf$U&+;$3B8b!pd$a+7z2lG(7kTSCyLWFMN7?_G5`j$!;~n3;0RKTBRoazosXkB*|<2pI>@!9j(I;Hl4OpAT*K_}iDK z29xy!oU_Uk3_y8AQ+R}}V=#3=>^koM+NrnV_`OuB_<0!9_v3ThdPzvk_)`c0MHkn6 zlN<#cr+%0NTR~j?JoXwu|J*V(Lw|I^z3mbve|rH{NgB`zBdehP2Urh%5g&%kGX(@pZ^-26{gF5Xi*V4=z#mWam-k%~L}Z{v(K}4j}Up zluYb0Dvv0bcJQ{RI12Fgxj`vCgB|mWO+1=wB2(7mNy7wO?uHV6UM4Dn`|=NVULr7B zwhbve^MKTJwDIyw=|km?=iIrKe$_o z`k9;XG^(e4cW@O|0EQM%J^oYfx=JIIn`DoPGw_){n`vSQGh$O>rNXB}d#X0TXOaA& z?=AllApl?$C@)HiBp<1PP4$)VR!(Sao&@SKRPSQ;6 zKySSI`U!LBA}E8fKN*8x#z8ygZsV)BPZkAP?pA0@%Z^^TYn`P}4HedPv~hDZCzf!1 z`K8NS$3q%8(akU59Q7z2HP8toYG5yGEhA^(z4JYLC+%4&|7hivG)Uk?o=PiaPBpgr zsJO?Tu1r2vhz@F9?dwOr2p}%<@rN?W%BSbIiR~;tEhNc~^o+CyU)QDx z((;iUbjPwgWk3YUcZ_Fcdh>?4l_YK59s8LuW}I+$6Q>qB4L{|xXvNGPoBHdiIbE#s z64rSpGzF`dcZxrI`CxB?zkqzIzRt+ds&XD**ex84sW>0gSUzar!{Y}pF(f2G3#^Hy zde2-T#&Z?ChI=N)w*mUu9<%<8;FI5sJ|MOzYD=S^i7ea1p+c{jz3eOy9y`HKen^_+ zv&Pr5)IM~a@6`?(>u%knko$Hyep`EN%>D5T9F&&w7%30sr@-VZko##P{razk{aNJ5 zGI$jlAKAuMHXA!E>5l;=_rcZbQ{##qA8dGtbV5%M9$m$2_t;_N`@4MOFPL?|Qk*05OJ6_l zG_#*6z(o+pDkjT8CqiM|t4t>vzN>Nu4(wtT_ywnjs3^D$$iLKqsPsDQ-lGYm~d6dC=)P%P{?n)aRJeLtTrBYt#X99`k`6c7M5{=Db5 z<5QhYs#7T9& zI}0>zSzZ|Ovr5bqX|1}Ca(?WeE?sJJ8_49n!VPiHbjHM7usV$~_Xsg|ImjA;e)bZU z-=%jz&t45yQn5c$&8yM*hooGNc1L-B3f|73KC0{01+2gzwSQvjNX-?f7a!3vSh>gk zHq)}XGW<}_H3iYu!LI-S9H6YSd~rnL<9Nv33p%KJy!7!hT**bjI4%~5*}oM0xjKi} z39)QdEaS1ebVY47In5~Oti^L(N3kZwRK984C zCm$v~#%~w;+o2eI6Yp0_d4$qak^dEIl((;%2^ivZ+Ih>7`sU=s%Ow-(eHGZuO!E9e z7)H|SH5u6)?`OT2Ix9!DhW&z`Z*<<{paY;<<{&gpSL=LwYVeMD)YU-0qX<9Q>9*JN zT#L7u2-CDJ{V4^&nw^JZh`z2K1+FOZV^!0JOb3TLl)TNm*#6uXx#SI$2zlzX{NKPa z$K0CPG$x(M8Qw!UQn-Q?QxX$7&%Wian6hR^jAU-O+pz`a!QN~=F~xr8rf@GWS-#;y z*^z!wHb^67B;Ps6EL7}WGgW|{A6(|^yW?;+&Qw^JGekOy+p|I%$js;bJ!Z1T!u0{_ z!ojLWMLxK*q0+-CGCn+B3mD`R>A{(*!H9M_dl^c~OvvmnUvv;zjEOjwUVJhva=V!% zGC0TFfYd)b3;`$~hzEr+060@H!KHN#wv(0S_!i24Tju~}$9NeOrX~N=Yo@TR?VZ|% z)xevPjFP(S*VT3bdXyZ01x~+X(~5dx`@Y6mPg#2V`|!oHx$*e%B$Bj;!AziF(yy4ll`SI~MUyPSkgJ{|K4a&PO>e_GGJk21k0~jZxq2ytPD{(0@G@{NROC z`Ei3AbI> z!~@7kF|ydhm6KtVjtAuAL3>TR+WYeL1$xiEKHF2#_@A9ia^B=VR?)y{a0kxtd7*F;3PjD^`m!j!o+QG`N2Dg~fpCj{vZlCPor^VkUA<#QO*2xljf*idfi}kdU=52r z1Vc5L1IU$jp))O@=G;cGxGfMEWLCo(o-z$r&x^l7J!ogdMTyz^1WXD}@Fo+hF-GFx zy|lek)S)d6xeGW(vCavRl7U=RkAHTFwhhSB`XY%nBOYF`VKB+bX_IFy&S?9%i5YZRX95kHe{D+@EswnreOL;JsG90EAA}tz<9z)n{xUk|G^z)n0;b~kI zGmpc_fuQQO7-mx9M_2nkY;luFPF_RR$)xGs096UGBwW&f2^DZ4dJ1l?I+hs7qz9KV z2@fw~j4|m`s9%NL3n_4$FQ7}go(td$!{K^~AauV!rvCbqcl|L-v-9cA&+Kjm67knO zD9VH{2|JhD#Xa~L8XG+ZGPGwt%~vsO%x|SBkIXonP?CvpEX`TeUO zc4XaOjoPglc6u}H>;?$$InIYDzYZ%d-0^5MIdFM?RHRb25~n{4Pvn>H`K+?*PBC%$ z<^YNuS-ay`z3T4S`g*mZhLici)*i0xbWCx7rSdlgo6izQx=%sx$Lo`xcQ9bM*wFSA zTz`F=iqLk0YHAIvF-Z=LcCZa6R<#POwj7U@CxM?BEx7gvXXj&hHueE^%%T{R_c=hw z?eYyt#14-4#Y>BfXP>6mAnRQ7m^6OkCXd3S>_r>B5`;=vor!;&u zU-6?0tIsR{Ey$*}FiU3toUoeDh~4r>Dl)V5)CuKe#?E_Tioqx2dL=TwT5araf#-8SMy|;I_=h>`r zN!KX>j`!hpJS+UF^+Ho_cDk?7o;J6F2c8~3wT(KkChSywPW<4zCHY)|xn@tOU6Qi_ z>dWNO5tlPiY_*Esc)EaJjOIrkO217J;liJmg1YJL1b2mpLf)}SqI$NF-ZJe)pWE}! zpcq8_q*F#1SEUez&DJin`NFyOYcF~} zkZm%08XR1RzM2XgZBg#m;t+Fte{=yZKU=gP28$zGRU4iyTEX2Q4`gv@c7JprmLpk0l41hP82g6#JD)2*=B)lwZ%{0vDK){% znRqie48bOD3~=GQ-!9`h>CwFfPo5S8@Fi_Vs1MeX>0fV8-!Ss z1ea zP`GVqf%l_)ipo&73)Et$a33PfeskkhzYR&5RR#!Apk&GPA$*ss#T6OPwH>K`3T zbkYtJVH(8qaTOmBbh;mLxK}PdJ{=RgnDxp01q|`L|v{1nc+%H>h<3ggRvTJe3 zC=Z8?7G`8mH|KO4E6uWrQP>6GlZ07Hr8~DS%rOD{FZ{Gbu{_TR$U{EIae#0{REUI}wJ7$>HVHKP>-+)H3t`iv1CaNRl# ziQ?T!Qgjj9X;m8c)B#ngUu0+ub*bq0&nerm^{2q%83A;;~I~od3uZjsA>d*a3lLje^spJ%fJr|5Gn}EwCEtZ(j zS>_w6<#~)!X{Y+r?hMA%l$%$ZD6?#G#)EBwEm=wvlKqN-rL%zZ6T*g`Woo%uD)ou2 zkDyIOn&Bd8u)fYD*i0Hsz3>648A(j}Gc_ki-Kb|UzO|j%bgG#>dAMVjeKG&))aCJ- z?$Ytaa`EM;IFty|BA15O`FX0%qIe$|;wRWQ29JUKs-E2I8y`S%EQ3wITq0yBI1EWF zqX$zmhg(h?nUZbPG|h=y({N#Joj<+o_Fd*A-Fd&cUmhRSTzqBUXcr}9zyyFT2UmE5 zU=y&8zJ!icwj0BVp($cbZ>T(j zMgZbisrR<`MJad84l9WKJ*?8-X~N91qJC8=2if)}I+vag1rhL|$m<0&Re=CiY<(^n zjZAE4rZ%E+a83&0q(Qpfkj&-s5xI-5HWjm0DIMEuKR4iu(92>%6wr_1-=}+Lxyt7@Q-Ltdn~7i!-y( zML_lL=>&a2hM#GPi`BwG#A=6&%sfFtA3*C5n+HOqTRS7%+WO`BomVq|?QDjUm9Pc{uD?}%UFA{FSdG(_QF_-wNF%#q zQ~uS|*%oCI13nKy0M1+L^rFvi{v|ywBrr~{#CR_9nI3zICRO9>&&2_|B zgkXZpR}Nzen6$LD?K}@hPv^zkU%VymMv`hOd3SyFSNn1k@RE3+8=VNOSZyv6PMbG8 zE0*p3+yZ(q>hSuRP&_Esll>#f^f^OS;iMk3XV=uG#mQ1oTtrumo{d#lIMWO3#p6;6EA9nMv)o2!S8u!Pysvk`=`ZYBR`M z@BDxVuT^l_h|%pgD*Yk2xeOV`0^gQotzZyG7=*r8*#(u3n zt@u$h&P!BeCPU>jVdo_IGFDLvXbFxI5 zwY|qkxo7dAui~RygQ17~0HmzkC{c6KlR|EXD`A_3W|lR5i?0rJ8(J=xAI9DYYINOQ zywqu~h&c6Kr<3wWXt~boNa)-sv|X#8z9m5fgw#i!ByN=8(k)ewBgTK#igdF|)q}mp zU6CW$;^zLf3C%u66X=T`!;Wxa_N(!f9E3~WABQS?nez8p zRYi>dY@xQDtkRt!7} zw7Kn;{lmqyr(&VZ8)?HGqslIc48cl!0gPELp|)ZyY0lh&on!qw zmJ34sycmNy8?8~9z0Ks` zf)A|fSn3o^a@JgpnyR;;h>OLADPV4Z3q`~z z5AcpiT3zgWBsWV`ALnYzszo``lZ-i{NHK6vT>DwwElAvDJd|mA# z4S`7VkxaVc){tY>UH=Gfoq4-#C!O&me_mOt7|^OkIFBG1Qx&SMMF?lZGGP&$*#&iUb^c4JE~4y96sy~Y_-1+dz%HIej{kshhl&};_Gv_IEJW+mh$Ut z$>;V)3pxN%`KaB&L|TTRiQAYqmEQR3x+*^g!tXt&tC(gLI}#1s?A+hA**SiN7RFC+ z~*_Q-M>#u~Let8k> zkK21c6=KK7FHDlSltd{zxa%7c?dj{4yOuA7>NKO=-q0iMlJN`Y*&qPwG|vq~Q#zdY zT`O=sB*V%UT3f-}cXT8^U|=2>b~k_5oIgMgr`utLq~-FeYm?_nuGi=CqQv+>Dh>|- z66~T!rj=>isH$e$zMH`W2;QIixYRcutId9&UWy6aAI1g9Wkt{N*37&~YMH&Gd+`FY ze)6_wQufY4JkhqHV~mcND3d6&^oFvw&Uv6X?|q#o;q3^Jhn8v1c0FvqgL;e<|Vk}DkdB6Cs{z%gWjO@FM8|?ZSFLYc3{waZVg9O`WRPZ zilxJUFI2l~3mbKRl0F+hq3HcB@TbDt4pUnm63e*20t9auqrohdtRdWyK%c9JdzGOV z+^2D^KDU!>E@MD&oDN*#t0p>@Udxn^aDr>N8V0FMRwUQM6$>{IIuCq&-K~RGd}nXY z5E`=-lC}ineNMO2v4(-c*?a_llXkgS)BHUg!|SOHw|uaRh^TX#ldEU7`_=kgzk2OR z0v=upra35gorgx*syylDUftnZ@9-plbDS6lgSxB(c7I*}!@COfpQym;6+mFk zs%;5}tBc3On%38v!Pyf0vns1)oMx4RH%7|CQ@J(-J=jvpim*dLRU|n4= zx5CsrS`pjgpb>6(YvLdVj$uwrqm)1_1V zK*>9rr?MW;+K_me+6+tH`_>PHU=j)(_>;){ZLHix?Tj&ofLxTzSA;Ia=TA{YMrj;7 zHw9x|3>ENGc@vU!q&`n{h{x%(+t@Q)gmQ~F0~otchnjUmFNU`u_%;ri0qJB39QtK` z2ytIVyA$hgLEh{Q%L}<0R+g5$tvZQdV!h_1YO6we?JZt-S5>+oXG@Mpn@WYgEr#O| z!y`)K`uc9-@}Pu+rlSM$cv)M<#10p(7@*>Y?-FB4^Uc`;Yn{D`;+G*IWPia=d&*Oe zeQ~xx=cP$it$F?OMJl2HApZu0gla zjknPX3h%WO=s0F(wSs?AG3-!KomO*&zh_~x)>7A6>}&#kFWSqm_?H@kj~3~G+mtw$BRer7Zigf znBG_{uUg;h33~OG9x7ou!MX$6yFbuSTjXH4DA~I{?cCF{UZ+mD9*{q7C zDSsmvS%E*-^maB9V|nDmio|9EUSdMcNT%t@^L?G)mwp7%V1yM&hDUjR3U}5mQ;V84 z9P%Z-3S7iDnpn^-)#DIzcHxnRqxdxL-Y5HdQH^oH2#H+8!4S$lfIxwdpZ8pMsbz}C zL2?A{Rrf-da6_uH_y?v#metPz-9HCU@2OVJimQxEc}8Xqs%J7w*RDOnx3s$lV1+UZ zEeO0F!yYW5%C+5mBw--+>`jb&;&$>_u(|bL=WlTh4yHNCs9{pj2kVb-;mygZ8ueR5Z$960u1>vPq zUsO``z#S+dQM*ow^G#b=>*(t6RU1Q}nT2f&i-L~!I69I(5hY8GRv{zwC@D{5<**lHv9}YB`q}N1I=<*_V{fCHbcdwM%3G{94!=n416`ogHm zKy(FxyH2!&32&l0zYx8F77=-9<|jxv)|$l)o-8rJ1^R5P{cVR7&xe3MrvzBIfWUZ|%FtT~CNbf!kIUc$hEMU2Jr&<5nZbk9e6sDdP0y_!8Z>&;>yK9U={Qo56$79jT~b zdpMRH;(0y3Sdt$Uk%tXM(fRf0@!=r-v`#Vn)bsAJ)ypf{p${m|#xr<;9`y_!234vv z)7l`cQWHkW^-|AJXI3@NM>!)xP*iM84YBQz+o!}8ULTZ<9uufjcWUd^v_q0!tT0s{ zSO3Zy1NGGML@%%q(CS(4dOh3z*=z4R!p0g&?TJ?3Ou!3|oa|TN73h<@6-O(rb$YgJ>H4CS-<_WOW3Rs50_%oMzHoSd2qF{`EuJK3W|R+x zw9RkC?y*m(>2Z6^JQ1A;BSIpb#23IxDNu{?Y+ZFMO80VENfjG>6sqEB74CJO2qy<@ zj7}%GZQuY$lV*!zXLmu(6a?O9Rk^ply&q0=EFKRC%3k5Ik{4PMH~2oDdbo^qvQ4Bs zYzy7(4~C}=Lj$;2PRhj}2GN#;cp~gUeA3u1RDzoIh@B4rDYEzX zo8v=z~%)A7K3FUIeClwIqjlmek2{-Rs@>fdEFwU_@-tfRLnKlv>#>{C>N81cWa`=T& z_&cC~jOx~V{~EV%HurXT^0w}julp{nnQt&Tv2{<4C;LiHrYoXdA0X~ zGT74flG*zv^_JMMV>nuFB6sV)dL<5&8Pod&P{x5f z#>r=0R(n}cRO^}KN=CMl`}*wBb0q$>LsvJPcvh@<2n$4((8Wb zfN6)oOu4dxcp${n>f>lXX;BhW@(K1O0<7y%OTMlK$9tB2Z2?QvM6)1nq}Fcb_X)1~ zOfHFUNc{ElzT=>i$N(gz6r#lS@Szf9^eF+x9{Gjo(2pl;G>WR?ps2Meo4v=4!CQ7R zI9JRnOOw{R-NSjem^?1s=Ifpp98^5&U?XAC?Y_r{A{rNk@#MLt$oGa1b7i_2d^w)Q zAgM=M<;Lz+6K*x!UcQ~JTRsIntCtfh=~gBO^peE~Ib$F%Nu;L(aI@6)!&+|DdQmYk zFq_WQIxt6h?Y?s5yX@^0Gn2J8Y%^`Ouy1he2Y&Cs^`2eC*>!p?+MAFIp-d)}Z~vi3 zIfkf`Tb`ElKGcP;MXBN6G7@Pb3WJee~pb%-LT;H~G zAy1)Q>NIe+R>K?ju_Eh*0LHc%>B+ID#PujNxxk~#0ruM8eXq0$v&8N2I4)*GhyckP z`OCb?{ohx((2lB>_=l2=by>C+YFkdmOYjUNm805Y<}vKW(axf9M|nHc!cy4$L;;I@ z?a@nKXJ*5koboO=?`;-5*LX$!Q8MXkw3UM*@Ao8JvR(tcX}r*I#~DtxzcCU3P!NYltFVIGa{_`(sCp4t+lY zLwmZqLaT2gjcuO2m?G!n~K~T3rtm@+W zbkpd!)2}51%v1#li*|;VB!-eJ)?1lk@|$)GgE8k-47o74x!|(aUJ7ucixof-KC`s_=x>Zl(bWz6(O!k_ zkTK4*i|5$KYfAyu;~+`>VSpiVv95j8aE!DNL<%>^gKV7eA~)SK8J<|sCwo@>p;U2- zlY-AUR5bOg7l!2@o;~lPdYBH1>D|yxR8{-i1TOc1KD4Sy9SyB6C|=UJ2nfb=}88* zOZN>{gE@v+5~9k4O@FY{-!d7tD{la%UDYR{R@X2A5mC32>w>T3H47y8vS=P|AqR`P z5L}ZQ_mfG6#MZL`OGz8Qv;`&{DD?OMEu(^Kvm0{R_|ymqM}_AL$eBLn?vE>OA)LaA zDF^#yx&jEHs1)`Ctmv4Lbfy|@&WzJ0@L8C?OAZePTw(6FX?Q$s;8HQNzQQJ6t58lh zm>xN!EUb*Qm5YFbkxm+<;ctq}UDFz&eRw<)o3f|2y94c!gLY%2_Geq4@eN1tlo3oM zT@vRDma9)v2=lUW9{#$!eW#h;I*<^3wXj zl6;|tHQ2sHQ(r$KQwe^u8dUvGX%|5^xOV-@5?Rk-Q4jyi3>64w#TOb(DaGPx+v;K8 z;BMc*d$`W&ApW@?`jDdemC(F}ZhgJaKDs;rQ?!HMUtA%E9~a}~JqTQS0NkX-iU@95DVE+^{CQ!Lb@u5qZ z$Xd?%ZDr<0eVA2djPNUN2hT%Y52rTS?XOZG7ylHB?`BcCvW; ziDU#NzkEo9-1<X4sX*I4rOe*3ZWeHjx4)F=$CYzCA_N+M|y-Ayf~Z?puU zS{5KZR->Fy*r8)Me{yhlPF>*=&J^!3F4D(Hz}wr;L(Ko{P>`30ci)2}f{C$?FCKcK zDOF;=$@%)b=J018PZZ;)%PgeuR22CfM$j=}_lg&*Rie^Q#_Er?DuyiOAhY`WThxh# zOZ#J4<5J`t9kF`ft_099P;=5n8^en$R%PK_=UarZ=w^~I!Y>I^_>&bHVdDmqD}qUJ zV?tD05NL>KktpNlmQ`BaKE2docg8e&lMmCHd&9!yG)E4=N9EKWvJT~UxVy;kzHV~AlU=@<%H3J^)kXobnqjQi^g;#QSNtBnTv;(&MiBe zXJt*Eze?Vl*j8gKGK_w5h-fFurDOWO0w6Ib)n&Ew4d3cf?Z9U_$Y90l22OH{%>jl) zSSIeX!A>ESZN=M!y^qaZAJZ3n?A^zWgX-Ch#v)Ybo0}RdmKGb_ZSRp%xnVvAeVP`@ zuLmE9V+)|~V*C6RU_MfB+0xw*#SVdj87WDzh;0|wIz6sC8_`A@7iTwSG|J)L8ip2x zI)bC0q7B{VF>x{kY8Ww)Et%;nl=&+0(O^UfV_$%N$_e&RZLE0jSQnEIgy}P6U8(B> z*#j$L+ZQxEL}55_Ha5TT09U65qlpD{^qEiMQz8WcUy7+_C zMSP))P^Ai84=(~HoOaTZ$-*m1@%e{;k}%I{PBH7Y`l}05LIEI3oG~1+n9JbUptteu zx<>8#RCCAyuwR0+$R}U}I*@~k%h%u=hJp0JEA3q=$B&!(w9VTF%#*@V)EI?`j~nnL zrB;iqY-KISv+apGDYXJ7;@5;5#L)TcZ%LByUfoE+k@krwMrgv2B1@N|6F{ZgO5R;q zKm7DS^Bv97<-EGkZQ|e>LZHTr^`lZZIKsyNFtz$t9l0x71W-PhRNJ~dk~S1mTM-6I zmHtj3%jkeNMMnf|H|`es=vW7LfB;@+`-WBiy6zTGdnm-CalXY-h=Jtm_907hF{S0C zJMr?R8V48{r3da4z^jd0sylC~slDVDgmafcXFH$;1`P*7*J>g-rI!Es#BHn8H!c;q zd%knXstzURhaUc*7lW50JR3U#^s?B9#R_WkR)N+0f{L|R7GEWMu!GSnD@=CV4BJ~` z!6pyK8fQ}k)&{nCLnVcx>*9JRojv1Hxuwpc;YNcBq?A~2jSIe7t2m>{&(W9~3fRrA+zQ zBlg_?-ZQC&OWrhu2O6_qPP*iOoBM(!9Ma(0-gAJMC}4PUl%bC07I)H;RzDS{j~VE__-N!!;Ip$O8^O5%$_ z+hQw1qlUBx(|^0N=_52-ts-e^bU$nl+b+{udfc=aoV*>6%CAGT&8?KhVPk|& zuJfwBom%p)`*4xQUw&6oHs4esEUkB7YNfTc&QU1ulrIz5WDVeF373Bj(r$ZJLy~zf z*UF2CNem)TdraK5`^;+3%F}UUV`Y(&=chr zyQhWJkIL6|S+B*qSt zx+mk1wtZoyL9N#Sw2U+%9-d!SMnDcghKeD=>-T6lWlIg7_W+c(2w@loW&O`NORs}1 zr~sLoQ05BiL;BOe^7RA&sf3#6R_WvFy@wRtaAH;d^_*_2n_lRE(lH9Yi9KBdKMZ@P zUB}}kJPF}eUmMT+M~F?U;3>cA<2t%H1M;4VL4>yY`(R4Xt=`(hk~FfwgEN*z_xiFW~dFO`3 z)F_}`3DfTv9lGD-2>(l)KZ@XRFV$;VF7BR{&Vs z4$x)OI`)o|#B(o*V2F>hq5RNWqMJs)4q$9UABASnNAWxY-`_0of#B(|V(_v-REE|8 zIxTh^-!-2$rv@5gi?kO)f(Xgot(uXLSad1QhfFCb01d4qO^_wCiFz<@ll;hS;nfPu z;-LKA%}=f+_xp{aY$q5uypqL>6|zs-93^ItSLtYt<&N|hPvzO#GRQ*sygxxuqOSoZ zM38~QE*%}e$)ommBLrDAH0OnQivwn;)528fD*c>oQ+#rbqR(!vaS=&AG`-&ksH0vI?~h~GA46J6DvH2NNJ>kMJ7h zaYgqaUH_nfYUJ@ivvyN`j@JS8fq4e1nK25z0R|rPc=7(hb3t39E3tG)gIu&=XqAgS z!ruWOmZWIlc0&U(2zTxxjQn3#EJ=)qYm-~07XoSZk!5im(&VD*isk2s&JX8bPYW5^ZN?c>}V za2=#`Nrr$Ntd9WC@>v{dc6iJf6e)%#9~Y;sF`2?7Y!AF_b@ZR9g$(e6Q@XQ_mC*nW zaa^p%`2~l9Pevm%jP?;nY2O}s;f}7U0Hl7)fMr#}x8iM;^#ogLrj$?}{=)vBzhVLj zZ;B=0ev8t!|9Scq?pe>^+Du|&M-9B^vMJGB%3=Ax#0TaLaO6To;x|E`7zZg4YMB4Bm zsqsFcwp6FV&B@!`Pq>Sf0E!u<9oD4VX=vTCum{_SfHRuIS!^gBPxwgbIeq?|`h<`G zr_D&WCFY{_aofOAFxV^Sqf8X=UV_m6R4aL%<{c29+pD@k8H{Whuizg^5@#iuUMm{} zTsGC+`F!a1qyfSp+eBG;LsI2nelDDkbBoT0t(d+LI$+zVFc(T3*_sbMcWk4_ zB<<#^VHjgd%az?f6V7CrEYKDYtz@N>$X)o&IKaa zbP1kma`A5$9rE%oY<6?l(7OoIJe6o;%K^p^owT7x3CmFU;#<0l0GNvPsLY$C!?>?nDl=Cv_I!8#x3+hZ9>Pl?P7$_Ls_YabjN?U~1M zh7ulWTqy@{f(vZvx|i>d^hwC!Xx+Z{6)Xw?T*~OPAPk;+zf`J~=Tr4E#0_F9s1_xo7tHAib)WW?}3X zZ`G&o>QLB81ZP~#Oghcpw&wtLX!ZdEkl5=pY9^x-iRqM=bQHAsQ;N+TPj?lblDx-h z={l(Al-$_YKrp(3QJ5sMuPhxb7{6+7z8@#7?h>Z;`e=JaW{QHGqu*gdO$o`(3*5;t z#j@1IKWBkK=sbq%DeGQg#m+GsSk>@>pDSjoC9ECxB}NWkd^6EUHW!CNLJoBdS#Ef~ zub2%mysu~-#6R*wKm2Np9x2DRDqVZJk+9P-@nwO_il^fL(exHvadb`F=-?jQgABnT zxVw9R06~KV5ALpmy9Rf6cXuBwKyY_=hcox{e&-MLS~Fd{chzMT*{+g)2QytCf-!{n zJJc_NLkSt!2h~FXXo)Yt;?TJAs%T>UX>|;-TjsI4Fcn2|^Td8;S@p@;@NxTKTp}_& zYbY8mwf&O!EPwO(JUPzIY$OF662HvDMH0+o_)ys(0YXEW(H&SYhn$4}I|}Gf7z>oB znBi&wU@sg2K`i^KpcFf~nQ;z!i)-YA4cUe;pLo5KW!o+#wBz*iSe^UX{#KMYhaWEy z^q@{?de;R(7f0i5dEB~VyH^g|Ah1U^m?u^)Bnno22bVQ#Y<%_VUAvt&Vi z+-8QDX^vT))A&AcYaFaA@uRAeaN+qbQ^n>PNF}%blmajjOqxr%N!=SdqBzAnBW$)( z0Qf;Gs@spZgO4+cQyfGuu<#WmWI{dd52Pf{S(TF;k2U~QCs-D=$=0vCj zzA9fSRsugW_K7Xhh}8G^Io%oDFHeHfLqeh1mI2VZi#l}3!|TF@XKhh)XYH>V*6+e* zumC6--YwfRQWi^%-5Ih zR;~x1iZdSbx(F$2*RSY-u<^Tg{-{N4J!1RolNGPT#A!p&%74G$PGLe36vwk@KcLFn zr{K_dbI(hNg^oo3AhHtoee0dssqd23bY2om;ha&Go(dUXvTSD36&|RA!Xg5)^m`Jk zNx=s@K-Jsxkmtku|G#4Yyspg7COb>1GAKd}`z*w5P5bWAx%G~@-tBpN*q}pa3jayU zU01x@zUARK3RM1r7!4l^3*poQ@Vts8R8xCCpM(2wE;&{gip|sn$YA}bji=joRyKLAmGt*{_*>q>j2>!~?SRaa5_tL-Nm@gSLshm}G1~oX#oHdxmsRfuA2+8i zIlJJWSr^`x?$vwc+z@PI5>LWTLadaV{gd~{WPoF`^+E7|BBcMFYzzQ3J_tAeHW&8- znt=E=8hmw$)7|O#dRTEnz*qcbK%}TX_#{0fV$tSjR~;%l$ON_rz}rCpd8z$5q;kJc zH9y&$|DzaW%?=A#rH68>LIlu~V-h;>1Ob9)-AS;EBETX4c);f}ehoiraiK5QUd%L6 zv2vPiCj^t9NsWO~(?cmH^zaDpntTnEJpzv*Sn$k!Ts?^S@Sn*2e?Z>~RPqobnb
    H|zz{j8vX-lqku;-NW2E3;BMf3f>Jhxt3 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
    %-(a@!i`89VK;?-qg=ZiR0A&pVk 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

    wrV@M0ad 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 literal 0 HcmV?d00001 diff --git a/apps/mobile/assets/splash-icon.png b/apps/mobile/assets/splash-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..03d6f6b6c6727954aec1d8206222769afd178d8d GIT binary patch literal 17547 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 App); +// It also ensures that whether you load the app in Expo Go or in a native build, +// the environment is set up appropriately +registerRootComponent(App); diff --git a/apps/mobile/metro.config.js b/apps/mobile/metro.config.js new file mode 100644 index 0000000..7bb37a4 --- /dev/null +++ b/apps/mobile/metro.config.js @@ -0,0 +1,14 @@ +// Metro, isolated to this app's own node_modules. apps/mobile sits inside a bun +// workspace whose root node_modules would otherwise shadow react/react-native and +// version-clash. Pinning resolution here keeps the RN bundle self-contained (the +// preview imports only react + react-native — no workspace packages yet). +const { getDefaultConfig } = require("expo/metro-config"); +const path = require("node:path"); + +const projectRoot = __dirname; +const config = getDefaultConfig(projectRoot); + +config.resolver.nodeModulesPaths = [path.resolve(projectRoot, "node_modules")]; +config.resolver.disableHierarchicalLookup = true; + +module.exports = config; diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json new file mode 100644 index 0000000..db7137b --- /dev/null +++ b/apps/mobile/package-lock.json @@ -0,0 +1,9366 @@ +{ + "name": "mobile", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mobile", + "version": "1.0.0", + "dependencies": { + "expo": "^52.0.49", + "expo-status-bar": "~2.0.1", + "react": "18.3.1", + "react-native": "0.76.9" + }, + "devDependencies": { + "@types/react": "~19.2.2", + "typescript": "~6.0.3" + } + }, + "node_modules/@0no-co/graphql.web": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.3.2.tgz", + "integrity": "sha512-Q1+pRlLhE31GOY/2c9BAEnFTNxO7Awtc6fhhEDlxyCBQ2N0IhD32cPVvPChrK9mwBNSgRdW/sF1kd2e0ojHj1Q==", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz", + "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-decorators": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-default-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.29.7.tgz", + "integrity": "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", + "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-default-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.29.7.tgz", + "integrity": "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.29.7.tgz", + "integrity": "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz", + "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz", + "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", + "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.29.7.tgz", + "integrity": "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-flow": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz", + "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz", + "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz", + "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz", + "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", + "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", + "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz", + "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz", + "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz", + "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-syntax-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz", + "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-flow": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.29.7.tgz", + "integrity": "sha512-KYIRV0BuaN68CDdsqFkAD7MU7yipUqQNuNElwATdxaIdpTjhvtY82QvkBJs7zV3Evxj2jFAAZ1iO8nyy0nhjqA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-transform-flow-strip-types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.29.7.tgz", + "integrity": "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-transform-react-display-name": "^7.29.7", + "@babel/plugin-transform-react-jsx": "^7.29.7", + "@babel/plugin-transform-react-jsx-development": "^7.29.7", + "@babel/plugin-transform-react-pure-annotations": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/register": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.29.7.tgz", + "integrity": "sha512-AMGJoWuES861riy6pcB0fphE1YXybtQnBYQMuIyPv6mKLiosfa79BKTnAOyx215c/3RJPJpdQwoHZ3earVH7AA==", + "dependencies": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.6", + "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse--for-generate-function-map": { + "name": "@babel/traverse", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse--for-generate-function-map/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/bunyan": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.1.tgz", + "integrity": "sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==", + "dependencies": { + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@expo/cli": { + "version": "0.22.28", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.28.tgz", + "integrity": "sha512-lvt72KNitGuixYD2l3SZmRKVu2G4zJpmg5V7WfUBNpmUU5oODBw/6qmiJ6kSLAlfDozscUk+BBGknBBzxUrwrA==", + "dependencies": { + "@0no-co/graphql.web": "^1.0.8", + "@babel/runtime": "^7.20.0", + "@expo/code-signing-certificates": "^0.0.6", + "@expo/config": "~10.0.11", + "@expo/config-plugins": "~9.0.17", + "@expo/devcert": "^1.1.2", + "@expo/env": "~0.4.2", + "@expo/image-utils": "^0.6.5", + "@expo/json-file": "^9.0.2", + "@expo/metro-config": "~0.19.12", + "@expo/osascript": "^2.1.6", + "@expo/package-manager": "^1.7.2", + "@expo/plist": "^0.2.2", + "@expo/prebuild-config": "~8.2.0", + "@expo/rudder-sdk-node": "^1.1.1", + "@expo/spawn-async": "^1.7.2", + "@expo/ws-tunnel": "^1.0.1", + "@expo/xcpretty": "^4.3.0", + "@react-native/dev-middleware": "0.76.9", + "@urql/core": "^5.0.6", + "@urql/exchange-retry": "^1.3.0", + "accepts": "^1.3.8", + "arg": "^5.0.2", + "better-opn": "~3.0.2", + "bplist-creator": "0.0.7", + "bplist-parser": "^0.3.1", + "cacache": "^18.0.2", + "chalk": "^4.0.0", + "ci-info": "^3.3.0", + "compression": "^1.7.4", + "connect": "^3.7.0", + "debug": "^4.3.4", + "env-editor": "^0.4.1", + "fast-glob": "^3.3.2", + "form-data": "^3.0.1", + "freeport-async": "^2.0.0", + "fs-extra": "~8.1.0", + "getenv": "^1.0.0", + "glob": "^10.4.2", + "internal-ip": "^4.3.0", + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1", + "lodash.debounce": "^4.0.8", + "minimatch": "^3.0.4", + "node-forge": "^1.3.3", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "picomatch": "^3.0.1", + "pretty-bytes": "^5.6.0", + "pretty-format": "^29.7.0", + "progress": "^2.0.3", + "prompts": "^2.3.2", + "qrcode-terminal": "0.11.0", + "require-from-string": "^2.0.2", + "requireg": "^0.2.2", + "resolve": "^1.22.2", + "resolve-from": "^5.0.0", + "resolve.exports": "^2.0.3", + "semver": "^7.6.0", + "send": "^0.19.0", + "slugify": "^1.3.4", + "source-map-support": "~0.5.21", + "stacktrace-parser": "^0.1.10", + "structured-headers": "^0.4.1", + "tar": "^6.2.1", + "temp-dir": "^2.0.0", + "tempy": "^0.7.1", + "terminal-link": "^2.1.1", + "undici": "^6.18.2", + "unique-string": "~2.0.0", + "wrap-ansi": "^7.0.0", + "ws": "^8.12.1" + }, + "bin": { + "expo-internal": "build/bin/cli" + } + }, + "node_modules/@expo/code-signing-certificates": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", + "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", + "dependencies": { + "node-forge": "^1.3.3" + } + }, + "node_modules/@expo/config": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.11.tgz", + "integrity": "sha512-nociJ4zr/NmbVfMNe9j/+zRlt7wz/siISu7PjdWE4WE+elEGxWWxsGzltdJG0llzrM+khx8qUiFK5aiVcdMBww==", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "@expo/config-plugins": "~9.0.17", + "@expo/config-types": "^52.0.5", + "@expo/json-file": "^9.0.2", + "deepmerge": "^4.3.1", + "getenv": "^1.0.0", + "glob": "^10.4.2", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0", + "resolve-workspace-root": "^2.0.0", + "semver": "^7.6.0", + "slugify": "^1.3.4", + "sucrase": "3.35.0" + } + }, + "node_modules/@expo/config-plugins": { + "version": "9.0.17", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.17.tgz", + "integrity": "sha512-m24F1COquwOm7PBl5wRbkT9P9DviCXe0D7S7nQsolfbhdCWuvMkfXeoWmgjtdhy7sDlOyIgBrAdnB6MfsWKqIg==", + "dependencies": { + "@expo/config-types": "^52.0.5", + "@expo/json-file": "~9.0.2", + "@expo/plist": "^0.2.2", + "@expo/sdk-runtime-versions": "^1.0.0", + "chalk": "^4.1.2", + "debug": "^4.3.5", + "getenv": "^1.0.0", + "glob": "^10.4.2", + "resolve-from": "^5.0.0", + "semver": "^7.5.4", + "slash": "^3.0.0", + "slugify": "^1.6.6", + "xcode": "^3.0.1", + "xml2js": "0.6.0" + } + }, + "node_modules/@expo/config-plugins/node_modules/@expo/json-file": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.2.tgz", + "integrity": "sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3", + "write-file-atomic": "^2.3.0" + } + }, + "node_modules/@expo/config-types": { + "version": "52.0.5", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-52.0.5.tgz", + "integrity": "sha512-AMDeuDLHXXqd8W+0zSjIt7f37vUd/BP8p43k68NHpyAvQO+z8mbQZm3cNQVAMySeayK2XoPigAFB1JF2NFajaA==" + }, + "node_modules/@expo/devcert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz", + "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==", + "dependencies": { + "@expo/sudo-prompt": "^9.3.1", + "debug": "^3.1.0" + } + }, + "node_modules/@expo/devcert/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@expo/env": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-0.4.2.tgz", + "integrity": "sha512-TgbCgvSk0Kq0e2fLoqHwEBL4M0ztFjnBEz0YCDm5boc1nvkV1VMuIMteVdeBwnTh8Z0oPJTwHCD49vhMEt1I6A==", + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^1.0.0" + } + }, + "node_modules/@expo/fingerprint": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.11.tgz", + "integrity": "sha512-gNyn1KnAOpEa8gSNsYqXMTcq0fSwqU/vit6fP5863vLSKxHm/dNt/gm/uZJxrRZxKq71KUJWF6I7d3z8qIfq5g==", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "arg": "^5.0.2", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "find-up": "^5.0.0", + "getenv": "^1.0.0", + "minimatch": "^3.0.4", + "p-limit": "^3.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + }, + "bin": { + "fingerprint": "bin/cli.js" + } + }, + "node_modules/@expo/image-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.6.5.tgz", + "integrity": "sha512-RsS/1CwJYzccvlprYktD42KjyfWZECH6PPIEowvoSmXfGLfdViwcUEI4RvBfKX5Jli6P67H+6YmHvPTbGOboew==", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "fs-extra": "9.0.0", + "getenv": "^1.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "temp-dir": "~2.0.0", + "unique-string": "~2.0.0" + } + }, + "node_modules/@expo/image-utils/node_modules/fs-extra": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", + "integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@expo/image-utils/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@expo/image-utils/node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@expo/image-utils/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@expo/json-file": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.1.5.tgz", + "integrity": "sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3" + } + }, + "node_modules/@expo/metro-config": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.12.tgz", + "integrity": "sha512-fhT3x1ikQWHpZgw7VrEghBdscFPz1laRYa8WcVRB18nTTqorF6S8qPYslkJu1faEziHZS7c2uyDzTYnrg/CKbg==", + "dependencies": { + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", + "@babel/parser": "^7.20.0", + "@babel/types": "^7.20.0", + "@expo/config": "~10.0.11", + "@expo/env": "~0.4.2", + "@expo/json-file": "~9.0.2", + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "fs-extra": "^9.1.0", + "getenv": "^1.0.0", + "glob": "^10.4.2", + "jsc-safe-url": "^0.2.4", + "lightningcss": "~1.27.0", + "minimatch": "^3.0.4", + "postcss": "~8.4.32", + "resolve-from": "^5.0.0" + } + }, + "node_modules/@expo/metro-config/node_modules/@expo/json-file": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.2.tgz", + "integrity": "sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3", + "write-file-atomic": "^2.3.0" + } + }, + "node_modules/@expo/metro-config/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@expo/metro-config/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@expo/metro-config/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@expo/osascript": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.7.0.tgz", + "integrity": "sha512-wKIXL8UtbuX4KwavPasIW3CUcgTbYfjzLcgUhjyKUAYDEqMaf6gmU1bqz3ffBPTokmX+G8/vFG1ZuI9etQWukA==", + "dependencies": { + "@expo/spawn-async": "^1.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/package-manager": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.13.0.tgz", + "integrity": "sha512-s3W3eZafJDEyVL7W/jxj2Nz3eONKxSCU604S5xj8ijrVaRz83x0DnZznLf/UXQEI1w+FyibH68nHeQyk767b1A==", + "dependencies": { + "@expo/json-file": "^11.0.0", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.0.0", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "resolve-workspace-root": "^2.0.0" + } + }, + "node_modules/@expo/package-manager/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/package-manager/node_modules/@expo/json-file": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-11.0.0.tgz", + "integrity": "sha512-pHJCETqFL5x5BzNV6cEPwjwuECgGmnl0bNmfHIJ6LM1tlh2eVXi5HEdit3zby/JO/B8Otk5cgcqtJXgvvUat3A==", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, + "node_modules/@expo/plist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.2.2.tgz", + "integrity": "sha512-ZZGvTO6vEWq02UAPs3LIdja+HRO18+LRI5QuDl6Hs3Ps7KX7xU6Y6kjahWKY37Rx2YjNpX07dGpBFzzC+vKa2g==", + "dependencies": { + "@xmldom/xmldom": "~0.7.7", + "base64-js": "^1.2.3", + "xmlbuilder": "^14.0.0" + } + }, + "node_modules/@expo/prebuild-config": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.2.0.tgz", + "integrity": "sha512-CxiPpd980s0jyxi7eyN3i/7YKu3XL+8qPjBZUCYtc0+axpGweqIkq2CslyLSKHyqVyH/zlPkbVgWdyiYavFS5Q==", + "dependencies": { + "@expo/config": "~10.0.11", + "@expo/config-plugins": "~9.0.17", + "@expo/config-types": "^52.0.5", + "@expo/image-utils": "^0.6.5", + "@expo/json-file": "^9.0.2", + "@react-native/normalize-colors": "0.76.9", + "debug": "^4.3.1", + "fs-extra": "^9.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" + } + }, + "node_modules/@expo/prebuild-config/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@expo/prebuild-config/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@expo/prebuild-config/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@expo/rudder-sdk-node": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@expo/rudder-sdk-node/-/rudder-sdk-node-1.1.1.tgz", + "integrity": "sha512-uy/hS/awclDJ1S88w9UGpc6Nm9XnNUjzOAAib1A3PVAnGQIwebg8DpFqOthFBTlZxeuV/BKbZ5jmTbtNZkp1WQ==", + "dependencies": { + "@expo/bunyan": "^4.0.0", + "@segment/loosely-validate-event": "^2.0.0", + "fetch-retry": "^4.1.1", + "md5": "^2.2.1", + "node-fetch": "^2.6.1", + "remove-trailing-slash": "^0.1.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/sdk-runtime-versions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", + "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==" + }, + "node_modules/@expo/spawn-async": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz", + "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==", + "dependencies": { + "cross-spawn": "^7.0.6" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/sudo-prompt": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz", + "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==" + }, + "node_modules/@expo/vector-icons": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.4.tgz", + "integrity": "sha512-+yKshcbpDfbV4zoXOgHxCwh7lkE9VVTT5T03OUlBsqfze1PLy6Hi4jp1vSb1GVbY6eskvMIivGVc9SKzIv0oEQ==", + "dependencies": { + "prop-types": "^15.8.1" + } + }, + "node_modules/@expo/ws-tunnel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz", + "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==" + }, + "node_modules/@expo/xcpretty": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz", + "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "chalk": "^4.1.0", + "js-yaml": "^4.1.0" + }, + "bin": { + "excpretty": "build/cli.js" + } + }, + "node_modules/@expo/xcpretty/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "dependencies": { + "@jest/types": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@react-native/assets-registry": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.9.tgz", + "integrity": "sha512-pN0Ws5xsjWOZ8P37efh0jqHHQmq+oNGKT4AyAoKRpxBDDDmlAmpaYjer9Qz7PpDKF+IUyRjF/+rBsM50a8JcUg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/babel-plugin-codegen": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.9.tgz", + "integrity": "sha512-vxL/vtDEIYHfWKm5oTaEmwcnNGsua/i9OjIxBDBFiJDu5i5RU3bpmDiXQm/bJxrJNPRp5lW0I0kpGihVhnMAIQ==", + "dependencies": { + "@react-native/codegen": "0.76.9" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/babel-preset": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.9.tgz", + "integrity": "sha512-TbSeCplCM6WhL3hR2MjC/E1a9cRnMLz7i767T7mP90oWkklEjyPxWl+0GGoVGnJ8FC/jLUupg/HvREKjjif6lw==", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.25.2", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/template": "^7.25.0", + "@react-native/babel-plugin-codegen": "0.76.9", + "babel-plugin-syntax-hermes-parser": "^0.25.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/codegen": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.9.tgz", + "integrity": "sha512-AzlCHMTKrAVC2709V4ZGtBXmGVtWTpWm3Ruv5vXcd3/anH4mGucfJ4rjbWKdaYQJMpXa3ytGomQrsIsT/s8kgA==", + "dependencies": { + "@babel/parser": "^7.25.3", + "glob": "^7.1.1", + "hermes-parser": "0.23.1", + "invariant": "^2.2.4", + "jscodeshift": "^0.14.0", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1", + "yargs": "^17.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/@react-native/codegen/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@react-native/community-cli-plugin": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.9.tgz", + "integrity": "sha512-08jx8ixCjjd4jNQwNpP8yqrjrDctN2qvPPlf6ebz1OJQk8e1sbUl3wVn1zhhMvWrYcaraDnatPb5uCPq+dn3NQ==", + "dependencies": { + "@react-native/dev-middleware": "0.76.9", + "@react-native/metro-babel-transformer": "0.76.9", + "chalk": "^4.0.0", + "execa": "^5.1.1", + "invariant": "^2.2.4", + "metro": "^0.81.0", + "metro-config": "^0.81.0", + "metro-core": "^0.81.0", + "node-fetch": "^2.2.0", + "readline": "^1.3.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@react-native-community/cli": "*" + }, + "peerDependenciesMeta": { + "@react-native-community/cli": { + "optional": true + } + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/@react-native/debugger-frontend": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.9.tgz", + "integrity": "sha512-0Ru72Bm066xmxFuOXhhvrryxvb57uI79yDSFf+hxRpktkC98NMuRenlJhslMrbJ6WjCu1vOe/9UjWNYyxXTRTA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/dev-middleware": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.9.tgz", + "integrity": "sha512-xkd3C3dRcmZLjFTEAOvC14q3apMLouIvJViCZY/p1EfCMrNND31dgE1dYrLTiI045WAWMt5bD15i6f7dE2/QWA==", + "dependencies": { + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.76.9", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^0.2.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "open": "^7.0.3", + "selfsigned": "^2.4.1", + "serve-static": "^1.13.1", + "ws": "^6.2.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/@react-native/dev-middleware/node_modules/ws": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.4.tgz", + "integrity": "sha512-PNIUUyLI5YpkJZj60YBzX1o0ByQ4ovvfmq9N/Kig/PAYbVlGyz4R6G0SEWrD0O9acc0sT2+IdMBVLFv8FSi0Nw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@react-native/gradle-plugin": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.9.tgz", + "integrity": "sha512-uGzp3dL4GfNDz+jOb8Nik1Vrfq1LHm0zESizrGhHACFiFlUSflVAnWuUAjlZlz5XfLhzGVvunG4Vdrpw8CD2ng==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/js-polyfills": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.9.tgz", + "integrity": "sha512-s6z6m8cK4SMjIX1hm8LT187aQ6//ujLrjzDBogqDCYXRbfjbAYovw5as/v2a2rhUIyJbS3UjokZm3W0H+Oh/RQ==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/metro-babel-transformer": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.9.tgz", + "integrity": "sha512-HGq11347UHNiO/NvVbAO35hQCmH8YZRs7in7nVq7SL99pnpZK4WXwLdAXmSuwz5uYqOuwnKYDlpadz8fkE94Mg==", + "dependencies": { + "@babel/core": "^7.25.2", + "@react-native/babel-preset": "0.76.9", + "hermes-parser": "0.23.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/normalize-colors": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.9.tgz", + "integrity": "sha512-TUdMG2JGk72M9d8DYbubdOlrzTYjw+YMe/xOnLU4viDgWRHsCbtRS9x0IAxRjs3amj/7zmK3Atm8jUPvdAc8qw==" + }, + "node_modules/@react-native/virtualized-lists": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.9.tgz", + "integrity": "sha512-2neUfZKuqMK2LzfS8NyOWOyWUJOWgDym5fUph6fN9qF+LNPjAvnc4Zr9+o+59qjNu/yXwQgVMWNU4+8WJuPVWw==", + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/react": "^18.2.6", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@segment/loosely-validate-event": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", + "integrity": "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==", + "dependencies": { + "component-type": "^1.2.1", + "join-component": "^1.1.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz", + "integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@urql/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz", + "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==", + "dependencies": { + "@0no-co/graphql.web": "^1.0.13", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/exchange-retry": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz", + "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==", + "dependencies": { + "@urql/core": "^5.1.2", + "wonka": "^6.3.2" + }, + "peerDependencies": { + "@urql/core": "^5.0.0" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", + "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", + "deprecated": "this version has critical issues, please update to the latest version", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/ast-types": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", + "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-react-native-web": { + "version": "0.19.13", + "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.13.tgz", + "integrity": "sha512-4hHoto6xaN23LCyZgL9LJZc3olmAxd7b6jDzlZnKXAh4rRAbZRKNBJoOOdp46OBqgy+K0t0guTj5/mhA8inymQ==" + }, + "node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz", + "integrity": "sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==", + "dependencies": { + "hermes-parser": "0.25.1" + } + }, + "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + }, + "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "dependencies": { + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-expo": { + "version": "12.0.12", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.12.tgz", + "integrity": "sha512-qAuaGGZIN//DyQVackP7Czr1SMq5dYb5tpu/uQqL/f1bRARb74r+kBWQRLJGxQ3QujsEw13SyAodCZIOUoD6KQ==", + "dependencies": { + "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/preset-react": "^7.22.15", + "@babel/preset-typescript": "^7.23.0", + "@react-native/babel-preset": "0.76.9", + "babel-plugin-react-native-web": "~0.19.13", + "react-refresh": "^0.14.2" + }, + "peerDependencies": { + "babel-plugin-react-compiler": "^19.0.0-beta-9ee70a1-20241017", + "react-compiler-runtime": "^19.0.0-beta-8a03594-20241020" + }, + "peerDependenciesMeta": { + "babel-plugin-react-compiler": { + "optional": true + }, + "react-compiler-runtime": { + "optional": true + } + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/better-opn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", + "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "dependencies": { + "open": "^8.0.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/better-opn/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bplist-creator": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", + "integrity": "sha512-xp/tcaV3T5PCiaY04mXga7o/TE+t95gqeLmADeBI1CvZtdWTbgBt3uLpvh4UWtenKeBhCV6oVxGk38yZr2uYEA==", + "dependencies": { + "stream-buffers": "~2.2.0" + } + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001802", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001802.tgz", + "integrity": "sha512-vmv8ub2xwTNmljSKf82mtCk5JH7hC+YgzLj3P5zotvA0tPQ9016tdNNOG8WRca1IxOnhSsivB+J0z5FeE5LOUw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chromium-edge-launcher": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz", + "integrity": "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "node_modules/chromium-edge-launcher/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/component-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.2.tgz", + "integrity": "sha512-99VUHREHiN5cLeHm3YLq312p6v+HUEcwtLCAtelvUDI6+SH5g5Cr85oNR2S1o6ywzL0ykMbuwLzM2ANocjEOIA==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.387", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.387.tgz", + "integrity": "sha512-TaxwufTFDufvPEoXdhwVrA3UdFWBeWGkYoJ1K8ldF1xe6gKfth6iRNS5lTQ5JPNOHdGQm8PT1QYKUqFLCiUefQ==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-editor": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz", + "integrity": "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/expo": { + "version": "52.0.49", + "resolved": "https://registry.npmjs.org/expo/-/expo-52.0.49.tgz", + "integrity": "sha512-ge3gUnuyGEePWWKzPY7TQ7FsvtFTdmsdYDHeBVUjMr9KIoQig/gf8A03oH26p3UtTL6sUJcyOIg9vwIHGNPSUw==", + "dependencies": { + "@babel/runtime": "^7.20.0", + "@expo/cli": "0.22.28", + "@expo/config": "~10.0.11", + "@expo/config-plugins": "~9.0.17", + "@expo/fingerprint": "0.11.11", + "@expo/metro-config": "0.19.12", + "@expo/vector-icons": "~14.0.4", + "babel-preset-expo": "~12.0.12", + "expo-asset": "~11.0.5", + "expo-constants": "~17.0.8", + "expo-file-system": "~18.0.12", + "expo-font": "~13.0.4", + "expo-keep-awake": "~14.0.3", + "expo-modules-autolinking": "2.0.8", + "expo-modules-core": "2.2.3", + "fbemitter": "^3.0.0", + "web-streams-polyfill": "^3.3.2", + "whatwg-url-without-unicode": "8.0.0-3" + }, + "bin": { + "expo": "bin/cli", + "expo-modules-autolinking": "bin/autolinking", + "fingerprint": "bin/fingerprint" + }, + "peerDependencies": { + "@expo/dom-webview": "*", + "@expo/metro-runtime": "*", + "react": "*", + "react-native": "*", + "react-native-webview": "*" + }, + "peerDependenciesMeta": { + "@expo/dom-webview": { + "optional": true + }, + "@expo/metro-runtime": { + "optional": true + }, + "react-native-webview": { + "optional": true + } + } + }, + "node_modules/expo-asset": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.0.5.tgz", + "integrity": "sha512-TL60LmMBGVzs3NQcO8ylWqBumMh4sx0lmeJsn7+9C88fylGDhyyVnKZ1PyTXo9CVDBkndutZx2JUEQWM9BaiXw==", + "dependencies": { + "@expo/image-utils": "^0.6.5", + "expo-constants": "~17.0.8", + "invariant": "^2.2.4", + "md5-file": "^3.2.3" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-constants": { + "version": "17.0.8", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.8.tgz", + "integrity": "sha512-XfWRyQAf1yUNgWZ1TnE8pFBMqGmFP5Gb+SFSgszxDdOoheB/NI5D4p7q86kI2fvGyfTrxAe+D+74nZkfsGvUlg==", + "dependencies": { + "@expo/config": "~10.0.11", + "@expo/env": "~0.4.2" + }, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo-file-system": { + "version": "18.0.12", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.12.tgz", + "integrity": "sha512-HAkrd/mb8r+G3lJ9MzmGeuW2B+BxQR1joKfeCyY4deLl1zoZ48FrAWjgZjHK9aHUVhJ0ehzInu/NQtikKytaeg==", + "dependencies": { + "web-streams-polyfill": "^3.3.2" + }, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo-font": { + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-13.0.4.tgz", + "integrity": "sha512-eAP5hyBgC8gafFtprsz0HMaB795qZfgJWqTmU0NfbSin1wUuVySFMEPMOrTkTgmazU73v4Cb4x7p86jY1XXYUw==", + "dependencies": { + "fontfaceobserver": "^2.1.0" + }, + "peerDependencies": { + "expo": "*", + "react": "*" + } + }, + "node_modules/expo-keep-awake": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-14.0.3.tgz", + "integrity": "sha512-6Jh94G6NvTZfuLnm2vwIpKe3GdOiVBuISl7FI8GqN0/9UOg9E0WXXp5cDcfAG8bn80RfgLJS8P7EPUGTZyOvhg==", + "peerDependencies": { + "expo": "*", + "react": "*" + } + }, + "node_modules/expo-modules-autolinking": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.8.tgz", + "integrity": "sha512-DezgnEYFQYic8hKGhkbztBA3QUmSftjaNDIKNAtS2iGJmzCcNIkatjN2slFDSWjSTNo8gOvPQyMKfyHWFvLpOQ==", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "fast-glob": "^3.2.5", + "find-up": "^5.0.0", + "fs-extra": "^9.1.0", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "expo-modules-autolinking": "bin/expo-modules-autolinking.js" + } + }, + "node_modules/expo-modules-autolinking/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/expo-modules-autolinking/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/expo-modules-autolinking/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/expo-modules-core": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.2.3.tgz", + "integrity": "sha512-01QqZzpP/wWlxnNly4G06MsOBUTbMDj02DQigZoXfDh80vd/rk3/uVXqnZgOdLSggTs6DnvOgAUy0H2q30XdUg==", + "dependencies": { + "invariant": "^2.2.4" + } + }, + "node_modules/expo-status-bar": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.1.tgz", + "integrity": "sha512-AkIPX7jWHRPp83UBZ1iXtVvyr0g+DgBVvIXTtlmPtmUsm8Vq9Bb5IGj86PW8osuFlgoTVAg7HI/+Ok7yEYwiRg==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fbemitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", + "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", + "dependencies": { + "fbjs": "^3.0.0" + } + }, + "node_modules/fbjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", + "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", + "dependencies": { + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^1.0.35" + } + }, + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, + "node_modules/fetch-retry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-4.1.1.tgz", + "integrity": "sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==" + }, + "node_modules/flow-estree": { + "version": "0.321.0", + "resolved": "https://registry.npmjs.org/flow-estree/-/flow-estree-0.321.0.tgz", + "integrity": "sha512-rQY7YKoo+PKpAHQjEP2cxyIefk04OCEKUlbtV4y6LAUG3Ly7guQX9YH8th6drSmYcNkMgpqWMaHRhhYaAF69CA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/flow-parser": { + "version": "0.321.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.321.0.tgz", + "integrity": "sha512-9LNK2rp/NWWbwdEK6mxC54XfQRyD2lVV0iPVBYf+5o5vvqJl7ietkR1hX3/dZ39j0GAbL4PIFoeekDViOW0x/Q==", + "dependencies": { + "flow-estree": "0.321.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fontfaceobserver": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", + "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.5.tgz", + "integrity": "sha512-j23EibVLnp4zNXGW7LjryXYa2X6U/M96yoOX+ybZxwkYajdxRNEqYY3zhh7y0i6kfISKS2jr+EJq1YTUDEv5+w==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/freeport-async": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz", + "integrity": "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/getenv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/getenv/-/getenv-1.0.0.tgz", + "integrity": "sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "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", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz", + "integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==" + }, + "node_modules/hermes-parser": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz", + "integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==", + "dependencies": { + "hermes-estree": "0.23.1" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz", + "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jimp-compact": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", + "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==" + }, + "node_modules/join-component": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz", + "integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsc-android": { + "version": "250231.0.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", + "integrity": "sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==" + }, + "node_modules/jsc-safe-url": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", + "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==" + }, + "node_modules/jscodeshift": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.14.0.tgz", + "integrity": "sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==", + "dependencies": { + "@babel/core": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/preset-flow": "^7.13.13", + "@babel/preset-typescript": "^7.13.0", + "@babel/register": "^7.13.16", + "babel-core": "^7.0.0-bridge.0", + "chalk": "^4.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.21.0", + "temp": "^0.8.4", + "write-file-atomic": "^2.3.0" + }, + "bin": { + "jscodeshift": "bin/jscodeshift.js" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/lightningcss": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", + "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.27.0", + "lightningcss-darwin-x64": "1.27.0", + "lightningcss-freebsd-x64": "1.27.0", + "lightningcss-linux-arm-gnueabihf": "1.27.0", + "lightningcss-linux-arm64-gnu": "1.27.0", + "lightningcss-linux-arm64-musl": "1.27.0", + "lightningcss-linux-x64-gnu": "1.27.0", + "lightningcss-linux-x64-musl": "1.27.0", + "lightningcss-win32-arm64-msvc": "1.27.0", + "lightningcss-win32-x64-msvc": "1.27.0" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", + "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", + "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", + "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", + "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", + "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", + "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", + "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", + "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", + "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", + "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marky": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5-file": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz", + "integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==", + "dependencies": { + "buffer-alloc": "^1.1.0" + }, + "bin": { + "md5-file": "cli.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/metro": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.81.5.tgz", + "integrity": "sha512-YpFF0DDDpDVygeca2mAn7K0+us+XKmiGk4rIYMz/CRdjFoCGqAei/IQSpV0UrGfQbToSugpMQeQJveaWSH88Hg==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "@babel/types": "^7.25.2", + "accepts": "^1.3.7", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "error-stack-parser": "^2.0.6", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.25.1", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.81.5", + "metro-cache": "0.81.5", + "metro-cache-key": "0.81.5", + "metro-config": "0.81.5", + "metro-core": "0.81.5", + "metro-file-map": "0.81.5", + "metro-resolver": "0.81.5", + "metro-runtime": "0.81.5", + "metro-source-map": "0.81.5", + "metro-symbolicate": "0.81.5", + "metro-transform-plugins": "0.81.5", + "metro-transform-worker": "0.81.5", + "mime-types": "^2.1.27", + "nullthrows": "^1.1.1", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "throat": "^5.0.0", + "ws": "^7.5.10", + "yargs": "^17.6.2" + }, + "bin": { + "metro": "src/cli.js" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-babel-transformer": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.5.tgz", + "integrity": "sha512-oKCQuajU5srm+ZdDcFg86pG/U8hkSjBlkyFjz380SZ4TTIiI5F+OQB830i53D8hmqmcosa4wR/pnKv8y4Q3dLw==", + "dependencies": { + "@babel/core": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "hermes-parser": "0.25.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-babel-transformer/node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + }, + "node_modules/metro-babel-transformer/node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/metro-cache": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.5.tgz", + "integrity": "sha512-wOsXuEgmZMZ5DMPoz1pEDerjJ11AuMy9JifH4yNW7NmWS0ghCRqvDxk13LsElzLshey8C+my/tmXauXZ3OqZgg==", + "dependencies": { + "exponential-backoff": "^3.1.1", + "flow-enums-runtime": "^0.0.6", + "metro-core": "0.81.5" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-cache-key": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.5.tgz", + "integrity": "sha512-lGWnGVm1UwO8faRZ+LXQUesZSmP1LOg14OVR+KNPBip8kbMECbQJ8c10nGesw28uQT7AE0lwQThZPXlxDyCLKQ==", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-config": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.5.tgz", + "integrity": "sha512-oDRAzUvj6RNRxratFdcVAqtAsg+T3qcKrGdqGZFUdwzlFJdHGR9Z413sW583uD2ynsuOjA2QB6US8FdwiBdNKg==", + "dependencies": { + "connect": "^3.6.5", + "cosmiconfig": "^5.0.5", + "flow-enums-runtime": "^0.0.6", + "jest-validate": "^29.7.0", + "metro": "0.81.5", + "metro-cache": "0.81.5", + "metro-core": "0.81.5", + "metro-runtime": "0.81.5" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-core": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.5.tgz", + "integrity": "sha512-+2R0c8ByfV2N7CH5wpdIajCWa8escUFd8TukfoXyBq/vb6yTCsznoA25FhNXJ+MC/cz1L447Zj3vdUfCXIZBwg==", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.81.5" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-file-map": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.5.tgz", + "integrity": "sha512-mW1PKyiO3qZvjeeVjj1brhkmIotObA3/9jdbY1fQQYvEWM6Ml7bN/oJCRDGn2+bJRlG+J8pwyJ+DgdrM4BsKyg==", + "dependencies": { + "debug": "^2.2.0", + "fb-watchman": "^2.0.0", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-file-map/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro-file-map/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/metro-minify-terser": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.5.tgz", + "integrity": "sha512-/mn4AxjANnsSS3/Bb+zA1G5yIS5xygbbz/OuPaJYs0CPcZCaWt66D+65j4Ft/nJkffUxcwE9mk4ubpkl3rjgtw==", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "terser": "^5.15.0" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-resolver": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.5.tgz", + "integrity": "sha512-6BX8Nq3g3go3FxcyXkVbWe7IgctjDTk6D9flq+P201DfHHQ28J+DWFpVelFcrNTn4tIfbP/Bw7u/0g2BGmeXfQ==", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-runtime": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.5.tgz", + "integrity": "sha512-M/Gf71ictUKP9+77dV/y8XlAWg7xl76uhU7ggYFUwEdOHHWPG6gLBr1iiK0BmTjPFH8yRo/xyqMli4s3oGorPQ==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-source-map": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.5.tgz", + "integrity": "sha512-Jz+CjvCKLNbJZYJTBeN3Kq9kIJf6b61MoLBdaOQZJ5Ajhw6Pf95Nn21XwA8BwfUYgajsi6IXsp/dTZsYJbN00Q==", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-symbolicate": "0.81.5", + "nullthrows": "^1.1.1", + "ob1": "0.81.5", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-symbolicate": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.5.tgz", + "integrity": "sha512-X3HV3n3D6FuTE11UWFICqHbFMdTavfO48nXsSpnNGFkUZBexffu0Xd+fYKp+DJLNaQr3S+lAs8q9CgtDTlRRuA==", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-source-map": "0.81.5", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-transform-plugins": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.5.tgz", + "integrity": "sha512-MmHhVx/1dJC94FN7m3oHgv5uOjKH8EX8pBeu1pnPMxbJrx6ZuIejO0k84zTSaQTZ8RxX1wqwzWBpXAWPjEX8mA==", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "flow-enums-runtime": "^0.0.6", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro-transform-worker": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.5.tgz", + "integrity": "sha512-lUFyWVHa7lZFRSLJEv+m4jH8WrR5gU7VIjUlg4XmxQfV8ngY4V10ARKynLhMYPeQGl7Qvf+Ayg0eCZ272YZ4Mg==", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "metro": "0.81.5", + "metro-babel-transformer": "0.81.5", + "metro-cache": "0.81.5", + "metro-cache-key": "0.81.5", + "metro-minify-terser": "0.81.5", + "metro-source-map": "0.81.5", + "metro-transform-plugins": "0.81.5", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/metro/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/metro/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/metro/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro/node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + }, + "node_modules/metro/node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/metro/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/metro/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/nested-error-stacks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz", + "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", + "dependencies": { + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.10.5" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "node_modules/ob1": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.5.tgz", + "integrity": "sha512-iNpbeXPLmaiT9I5g16gFFFjsF3sGxLpYG2EGP3dfFB4z+l9X60mp/yRzStHhMtuNt8qmf7Ww80nOPQHngHhnIQ==", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-png": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", + "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==", + "dependencies": { + "pngjs": "^3.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.2.tgz", + "integrity": "sha512-cfDHL6LStTEKlNilboNtobT/kEa30PtAf2Q1OgszfrG/rpVl1xaFWT9ktfkS306GmHgmnad1Sw4wabhlvFtsTw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", + "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", + "dependencies": { + "@xmldom/xmldom": "^0.9.10", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/plist/node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "engines": { + "node": ">=14.6" + } + }, + "node_modules/plist/node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qrcode-terminal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", + "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-devtools-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-5.3.2.tgz", + "integrity": "sha512-crr9HkVrDiJ0A4zot89oS0Cgv0Oa4OG1Em4jit3P3ZxZSKPMYyMjfwMqgcJna9o625g8oN87rBm8SWWrSTBZxg==", + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-devtools-core/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/react-native": { + "version": "0.76.9", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.9.tgz", + "integrity": "sha512-+LRwecWmTDco7OweGsrECIqJu0iyrREd6CTCgC/uLLYipiHvk+MH9nd6drFtCw/6Blz6eoKTcH9YTTJusNtrWg==", + "dependencies": { + "@jest/create-cache-key-function": "^29.6.3", + "@react-native/assets-registry": "0.76.9", + "@react-native/codegen": "0.76.9", + "@react-native/community-cli-plugin": "0.76.9", + "@react-native/gradle-plugin": "0.76.9", + "@react-native/js-polyfills": "0.76.9", + "@react-native/normalize-colors": "0.76.9", + "@react-native/virtualized-lists": "0.76.9", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "ansi-regex": "^5.0.0", + "babel-jest": "^29.7.0", + "babel-plugin-syntax-hermes-parser": "^0.23.1", + "base64-js": "^1.5.1", + "chalk": "^4.0.0", + "commander": "^12.0.0", + "event-target-shim": "^5.0.1", + "flow-enums-runtime": "^0.0.6", + "glob": "^7.1.1", + "invariant": "^2.2.4", + "jest-environment-node": "^29.6.3", + "jsc-android": "^250231.0.0", + "memoize-one": "^5.0.0", + "metro-runtime": "^0.81.0", + "metro-source-map": "^0.81.0", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1", + "pretty-format": "^29.7.0", + "promise": "^8.3.0", + "react-devtools-core": "^5.3.1", + "react-refresh": "^0.14.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "0.24.0-canary-efb381bbf-20230505", + "semver": "^7.1.3", + "stacktrace-parser": "^0.1.10", + "whatwg-fetch": "^3.0.0", + "ws": "^6.2.3", + "yargs": "^17.6.2" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/react": "^18.2.6", + "react": "^18.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz", + "integrity": "sha512-uNLD0tk2tLUjGFdmCk+u/3FEw2o+BAwW4g+z2QVlxJrzZYOOPADroEcNtTPt5lNiScctaUmnsTkVEnOwZUOLhA==", + "dependencies": { + "hermes-parser": "0.23.1" + } + }, + "node_modules/react-native/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/react-native/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/react-native/node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/react-native/node_modules/ws": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.4.tgz", + "integrity": "sha512-PNIUUyLI5YpkJZj60YBzX1o0ByQ4ovvfmq9N/Kig/PAYbVlGyz4R6G0SEWrD0O9acc0sT2+IdMBVLFv8FSi0Nw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" + }, + "node_modules/recast": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.21.5.tgz", + "integrity": "sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==", + "dependencies": { + "ast-types": "0.15.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" + }, + "node_modules/regjsparser": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", + "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/remove-trailing-slash": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz", + "integrity": "sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireg": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz", + "integrity": "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==", + "dependencies": { + "nested-error-stacks": "~2.0.1", + "rc": "~1.2.7", + "resolve": "~1.7.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/requireg/node_modules/resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dependencies": { + "path-parse": "^1.0.5" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-workspace-root": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz", + "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==" + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.24.0-canary-efb381bbf-20230505", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz", + "integrity": "sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-plist": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", + "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "dependencies": { + "bplist-creator": "0.1.0", + "bplist-parser": "0.3.1", + "plist": "^3.0.5" + } + }, + "node_modules/simple-plist/node_modules/bplist-creator": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "dependencies": { + "stream-buffers": "2.2.x" + } + }, + "node_modules/simple-plist/node_modules/bplist-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/structured-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz", + "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar 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", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/temp": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", + "dependencies": { + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/temp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tempy": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.7.1.tgz", + "integrity": "sha512-vXPxwOyaNVi9nyczO16mxmHGpl6ASC5/TVhRRHpqeYHvKQm58EaWNvZXxAhR0lYYnBOQFjXjhzeLsaXdjxLjRg==", + "dependencies": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", + "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==" + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "dependencies": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url-without-unicode/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wonka": { + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.6.tgz", + "integrity": "sha512-MXH+6mDHAZ2GuMpgKS055FR6v0xVP3XwquxIMYXgiW+FejHQlMGlvVRZT4qMCxR+bEo/FCtIdKxwej9WV3YQag==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xcode": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", + "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "dependencies": { + "simple-plist": "^1.1.0", + "uuid": "^7.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xcode/node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/xml2js": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", + "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-14.0.0.tgz", + "integrity": "sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/apps/mobile/package.json b/apps/mobile/package.json new file mode 100644 index 0000000..a7a1f35 --- /dev/null +++ b/apps/mobile/package.json @@ -0,0 +1,22 @@ +{ + "name": "mobile", + "version": "1.0.0", + "main": "index.ts", + "dependencies": { + "expo": "^52.0.49", + "expo-status-bar": "~2.0.1", + "react": "18.3.1", + "react-native": "0.76.9" + }, + "devDependencies": { + "@types/react": "~19.2.2", + "typescript": "~6.0.3" + }, + "scripts": { + "start": "expo start", + "android": "expo run:android", + "ios": "expo run:ios", + "web": "expo start --web" + }, + "private": true +} diff --git a/apps/mobile/tsconfig.json b/apps/mobile/tsconfig.json new file mode 100644 index 0000000..b9567f6 --- /dev/null +++ b/apps/mobile/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "expo/tsconfig.base", + "compilerOptions": { + "strict": true + } +} diff --git a/package.json b/package.json index cbdd2cd..5d1c4cd 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "packageManager": "bun@1.3.11", "workspaces": [ "apps/*", - "packages/*" + "packages/*", + "!apps/mobile" ], "scripts": { "test": "bun test", From ff2fb3e285d1dcf0c6af33f5f94486b0cce4870e Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 20:24:50 +0200 Subject: [PATCH 18/83] =?UTF-8?q?feat(mobile):=20connection=20screen=20?= =?UTF-8?q?=E2=80=94=20SSH=20host=20form=20(Termius-modeled)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an "add connection" screen and board↔connection nav. The connection is one SSH target modeled on Termius's host form — Label · IP/Hostname · Port · Username · SSH Key — where the host is just the box's Tailscale IP (no transport toggle; always SSH). Same Ateam dark identity + clawnify structural signature as the board (eyebrow zones, grouped rows with hairline dividers, key as a chip, one teal primary action). First run opens on the form; Connect → board. Still mock data. --- apps/mobile/App.tsx | 173 +++++++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 43 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index f21a9b4..4227c51 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -3,9 +3,12 @@ // structural signature (labeled eyebrow zones · chips for facts vs tinted badges // for signals · monochrome chrome, color reserved for status · engineered numbers // · borders not shadows · no emoji) — NOT its brand theme (coral / light canvas). -// Preview scope: mock data. Transport is always SSH; the host shown is the box's -// Tailscale IP. Live wiring (buildAteamApi over an SSH ClientTransport) is next. -import { ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View } from "react-native"; +// Connection model = ALWAYS SSH: a host is Label · IP/Hostname · Port · Username · +// Key (Termius's model); the IP is just what you point at the box's Tailscale +// address. Preview scope: mock data; live SSH wiring (buildAteamApi over a +// native-SSH ClientTransport) is next. +import { useState } from "react"; +import { Pressable, ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View } from "react-native"; const C = { bg: "#0b0d10", @@ -21,7 +24,6 @@ const C = { green: "#67cd8b", }; -// Status tints (color over a low-opacity wash of itself — the dark-mode badge rule). const TINT: Record = { [C.amber]: "rgba(230,169,75,0.14)", [C.teal]: "rgba(53,209,192,0.14)", @@ -49,7 +51,6 @@ const TASKS: Task[] = [ { name: "Remote fs picker", column: "merged", agent: "claude", branch: "feat/fs-listdir", note: "merged · PR #45" }, ]; -// Fact → chip: neutral, bordered, sunken fill. Never colored. function Chip({ children }: { children: string }) { return ( @@ -60,7 +61,6 @@ function Chip({ children }: { children: string }) { ); } -// Signal → badge: tinted wash + colored text, pill radius. function Badge({ children, tint }: { children: string; tint: string }) { return ( @@ -72,7 +72,6 @@ function Badge({ children, tint }: { children: string; tint: string }) { } function AgentTag({ agent }: { agent: string }) { - // Identity, not status — monochrome, so color stays reserved for signals. return ( {agent[0]?.toUpperCase()} @@ -97,14 +96,83 @@ function TaskCard({ task, tint }: { task: Task; tint: string }) { ); } -export default function App() { - useColorScheme(); // reserved: theme-aware later +// ── Connection screen — one SSH target, Termius-modeled (no transport toggle) ── + +function FieldRow({ + label, + value, + keyChip, + last, +}: { + label: string; + value: string; + keyChip?: boolean; + last?: boolean; +}) { + return ( + + {label} + {keyChip ? ( + + {value} + + ) : ( + {value} + )} + + ); +} +function ConnectionScreen({ onConnect }: { onConnect: () => void }) { return ( + + + A + + New connection + + + Connect + + + + + + + Host + + + + + + + + + + Credentials + + + + + + + + Always SSH. The IP is the box's Tailscale address — same user, same key. Tailscale just + changes the address you connect to. + + + + ); +} + +// ── Board screen ── - {/* Toolbar */} +function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { + return ( + + @@ -112,18 +180,16 @@ export default function App() { Ateam - + hetzner-devbox - + - SSH ·{" "} - pallaoro@100.72.63.61 · claude + SSH · pallaoro@100.72.63.61 · claude - {/* Board — one eyebrow-labeled zone per column */} {COLUMNS.map((col) => { const tasks = TASKS.filter((t) => t.column === col.key); @@ -147,10 +213,32 @@ export default function App() { ); } +export default function App() { + useColorScheme(); // reserved: theme-aware later + // First run opens on the connection form (no saved host yet); Connect → board. + const [view, setView] = useState<"connect" | "board">("connect"); + return view === "connect" ? ( + setView("board")} /> + ) : ( + setView("connect")} /> + ); +} + const styles = StyleSheet.create({ root: { flex: 1, backgroundColor: C.bg, paddingTop: 60 }, + // header / nav header: { paddingHorizontal: 18, paddingBottom: 14, borderBottomWidth: 1, borderBottomColor: C.line }, + navBar: { + flexDirection: "row", + alignItems: "center", + gap: 10, + paddingHorizontal: 18, + paddingBottom: 14, + borderBottomWidth: 1, + borderBottomColor: C.line, + }, + navTitle: { color: C.ink, fontSize: 17, fontWeight: "700", letterSpacing: -0.2 }, brandRow: { flexDirection: "row", alignItems: "center", gap: 10 }, monogram: { width: 30, @@ -165,6 +253,8 @@ const styles = StyleSheet.create({ monogramText: { color: C.teal, fontSize: 16, fontWeight: "800" }, brand: { color: C.ink, fontSize: 20, fontWeight: "700", letterSpacing: -0.3 }, spacer: { flex: 1 }, + connectBtn: { backgroundColor: C.teal, paddingHorizontal: 16, paddingVertical: 8, borderRadius: 8 }, + connectBtnText: { color: "#04211d", fontSize: 13, fontWeight: "800" }, connPill: { flexDirection: "row", alignItems: "center", @@ -181,29 +271,35 @@ const styles = StyleSheet.create({ connMeta: { color: C.muted, fontSize: 12, marginTop: 12 }, connHost: { color: C.ink, fontVariant: ["tabular-nums"] }, - board: { flex: 1 }, - boardContent: { padding: 16, paddingBottom: 40 }, - zone: { marginBottom: 22 }, + // eyebrow eyebrowRow: { flexDirection: "row", alignItems: "center", gap: 8, marginBottom: 10, paddingLeft: 2 }, tick: { width: 3, height: 12, borderRadius: 2 }, - eyebrow: { - color: C.muted, - fontSize: 11, - fontWeight: "600", - textTransform: "uppercase", - letterSpacing: 1.1, - }, + eyebrow: { color: C.muted, fontSize: 11, fontWeight: "600", textTransform: "uppercase", letterSpacing: 1.1 }, eyebrowCount: { color: C.faint, fontSize: 11, fontWeight: "600", fontVariant: ["tabular-nums"] }, - card: { - backgroundColor: C.surface, - borderWidth: 1, - borderColor: C.line, - borderLeftWidth: 3, - borderRadius: 8, - padding: 12, - marginBottom: 8, + // connection form + formContent: { padding: 16, paddingTop: 20, paddingBottom: 40 }, + formCard: { backgroundColor: C.surface, borderWidth: 1, borderColor: C.line, borderRadius: 10 }, + fieldRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 14, + paddingVertical: 14, + gap: 12, }, + fieldDivider: { borderBottomWidth: 1, borderBottomColor: C.line }, + fieldLabel: { color: C.muted, fontSize: 14 }, + fieldValue: { color: C.ink, fontSize: 14, fontVariant: ["tabular-nums"], flexShrink: 1, textAlign: "right" }, + keyChip: { backgroundColor: C.sunken, borderWidth: 1, borderColor: C.line, borderRadius: 6, paddingHorizontal: 8, paddingVertical: 3 }, + keyChipText: { color: C.teal, fontSize: 12, fontWeight: "600", letterSpacing: 0.3 }, + formNote: { color: C.faint, fontSize: 12, lineHeight: 18, marginTop: 18, paddingHorizontal: 2 }, + + // board + board: { flex: 1 }, + boardContent: { padding: 16, paddingBottom: 40 }, + zone: { marginBottom: 22 }, + card: { backgroundColor: C.surface, borderWidth: 1, borderColor: C.line, borderLeftWidth: 3, borderRadius: 8, padding: 12, marginBottom: 8 }, cardTop: { flexDirection: "row", alignItems: "flex-start", gap: 9 }, agentTag: { width: 22, @@ -218,18 +314,9 @@ const styles = StyleSheet.create({ agentInitial: { color: C.muted, fontSize: 11, fontWeight: "700" }, cardName: { color: C.ink, fontSize: 15, fontWeight: "600", flex: 1, lineHeight: 20 }, cardMeta: { flexDirection: "row", alignItems: "center", gap: 6, marginTop: 10, flexWrap: "wrap" }, - - chip: { - backgroundColor: C.sunken, - borderWidth: 1, - borderColor: C.line, - borderRadius: 6, - paddingHorizontal: 7, - paddingVertical: 3, - }, + chip: { backgroundColor: C.sunken, borderWidth: 1, borderColor: C.line, borderRadius: 6, paddingHorizontal: 7, paddingVertical: 3 }, chipText: { color: C.muted, fontSize: 11, fontVariant: ["tabular-nums"] }, badge: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 3 }, badgeText: { fontSize: 11, fontWeight: "600" }, - footnote: { color: C.faint, fontSize: 11, textAlign: "center", marginTop: 8 }, }); From ed87faf75c4888fbc2ddfae2cae9b0d2dbf56aeb Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 20:44:48 +0200 Subject: [PATCH 19/83] fix(mobile): drop the colored left-rail on task cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rounded-card-plus-colored-left-border combo is an AI-slop tell (accent rail on a rounded card) and the rail was redundant — the column color already lives in the section eyebrow tick and the status badge. Cards are now uniform rounded cards with a hairline border; color reads as signal, not ornament. Also default the app to the board view (home), with the connection form reachable from the connection pill. --- apps/mobile/App.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 4227c51..c4b6f34 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -81,7 +81,7 @@ function AgentTag({ agent }: { agent: string }) { function TaskCard({ task, tint }: { task: Task; tint: string }) { return ( - + @@ -215,8 +215,8 @@ function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { export default function App() { useColorScheme(); // reserved: theme-aware later - // First run opens on the connection form (no saved host yet); Connect → board. - const [view, setView] = useState<"connect" | "board">("connect"); + // Board is home; tapping the connection pill opens the SSH host form. + const [view, setView] = useState<"connect" | "board">("board"); return view === "connect" ? ( setView("board")} /> ) : ( @@ -299,7 +299,7 @@ const styles = StyleSheet.create({ board: { flex: 1 }, boardContent: { padding: 16, paddingBottom: 40 }, zone: { marginBottom: 22 }, - card: { backgroundColor: C.surface, borderWidth: 1, borderColor: C.line, borderLeftWidth: 3, borderRadius: 8, padding: 12, marginBottom: 8 }, + card: { backgroundColor: C.surface, borderWidth: 1, borderColor: C.line, borderRadius: 8, padding: 12, marginBottom: 8 }, cardTop: { flexDirection: "row", alignItems: "flex-start", gap: 9 }, agentTag: { width: 22, From 2a6afb9e8895509c1107d150aefa103ca36a0e3c Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 20:49:26 +0200 Subject: [PATCH 20/83] feat(mobile): use the real Ateam logo + theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the placeholder "A" monogram + improvised teal with Ateam's actual brand, pulled from the desktop app: - Logo: the "mission-control tiling" mark from apps/desktop/build/icon.svg (a wide top pane + two dimming squares), redrawn with Views — scales + themes, no native SVG dependency. - Theme tokens from apps/desktop/src/renderer/src/index.css: #0c0c0e canvas, #7c5cff purple accent, ink/#e6e6ea text, amber/blue/green status. The primary action is ink/white (a hue is never the CTA), matching the desktop. - Accent (purple) rationed to In Progress + the SSH-key chip; status colors carry needs-you/review/done. No teal anywhere. --- apps/mobile/App.tsx | 114 +++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index c4b6f34..880f089 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -1,41 +1,42 @@ // Ateam mobile — board + connection preview. -// Design: Ateam's own dark/teal identity, applying the clawnify DESIGN-apps -// structural signature (labeled eyebrow zones · chips for facts vs tinted badges -// for signals · monochrome chrome, color reserved for status · engineered numbers -// · borders not shadows · no emoji) — NOT its brand theme (coral / light canvas). -// Connection model = ALWAYS SSH: a host is Label · IP/Hostname · Port · Username · -// Key (Termius's model); the IP is just what you point at the box's Tailscale -// address. Preview scope: mock data; live SSH wiring (buildAteamApi over a -// native-SSH ClientTransport) is next. +// Theme = Ateam's real tokens (apps/desktop/src/renderer/src/index.css): near-black +// #0c0c0e canvas, purple accent #7c5cff, ink/white primary action (a hue is never +// the CTA), amber/blue/green status. Logo = the "mission-control tiling" mark from +// apps/desktop/build/icon.svg, redrawn with Views. Structure follows the clawnify +// DESIGN-apps signature (eyebrow zones · chips for facts vs tinted badges for +// signals · monochrome chrome · no emoji). Connection = ALWAYS SSH (a host is +// Label · IP/Hostname · Port · Username · Key; the IP is the box's Tailscale +// address). Preview: mock data; live SSH wiring next. import { useState } from "react"; import { Pressable, ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View } from "react-native"; const C = { - bg: "#0b0d10", - surface: "#14171c", - sunken: "#1a1e25", - line: "#242b35", - ink: "#e7ebf1", - muted: "#8b96a6", - faint: "#5a6472", - teal: "#35d1c0", - amber: "#e6a94b", - blue: "#6ea8fe", - green: "#67cd8b", + bg: "#0c0c0e", + surface: "#141418", // --bg-elev + sunken: "#1c1c22", // --bg-elev-2 + line: "#2a2a33", // --border + ink: "#e6e6ea", // --text + muted: "#9a9aa6", // --text-dim + faint: "#6a6a75", + accent: "#7c5cff", // --accent (Ateam purple) + green: "#4ade80", + amber: "#fbbf24", + red: "#f87171", + blue: "#60a5fa", }; const TINT: Record = { - [C.amber]: "rgba(230,169,75,0.14)", - [C.teal]: "rgba(53,209,192,0.14)", - [C.blue]: "rgba(110,168,254,0.14)", - [C.green]: "rgba(103,205,139,0.14)", - [C.muted]: "rgba(139,150,166,0.12)", + [C.amber]: "rgba(251,191,36,0.13)", + [C.accent]: "rgba(124,92,255,0.16)", + [C.blue]: "rgba(96,165,250,0.14)", + [C.green]: "rgba(74,222,128,0.13)", + [C.muted]: "rgba(154,154,166,0.12)", }; type Column = "needs_attention" | "running" | "review" | "todo" | "merged"; const COLUMNS: { key: Column; label: string; tint: string }[] = [ { key: "needs_attention", label: "Needs You", tint: C.amber }, - { key: "running", label: "In Progress", tint: C.teal }, + { key: "running", label: "In Progress", tint: C.accent }, { key: "review", label: "Review", tint: C.blue }, { key: "todo", label: "Backlog", tint: C.muted }, { key: "merged", label: "Done", tint: C.green }, @@ -51,6 +52,20 @@ const TASKS: Task[] = [ { name: "Remote fs picker", column: "merged", agent: "claude", branch: "feat/fs-listdir", note: "merged · PR #45" }, ]; +// The Ateam logo mark: a wide top pane + two dimming squares (icon.svg), on a dark +// tile. Redrawn with Views so it scales + themes with no native SVG dependency. +function LogoMark() { + return ( + + + + + + + + ); +} + function Chip({ children }: { children: string }) { return ( @@ -128,9 +143,7 @@ function ConnectionScreen({ onConnect }: { onConnect: () => void }) { - - A - + New connection @@ -140,7 +153,7 @@ function ConnectionScreen({ onConnect }: { onConnect: () => void }) { - + Host @@ -150,7 +163,7 @@ function ConnectionScreen({ onConnect }: { onConnect: () => void }) { - + Credentials @@ -175,9 +188,7 @@ function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { - - A - + Ateam @@ -227,6 +238,23 @@ export default function App() { const styles = StyleSheet.create({ root: { flex: 1, backgroundColor: C.bg, paddingTop: 60 }, + // logo mark (icon.svg redrawn) + logo: { + width: 32, + height: 32, + borderRadius: 9, + backgroundColor: "#26262e", + borderWidth: 1, + borderColor: C.line, + paddingHorizontal: 6, + paddingVertical: 6, + justifyContent: "center", + gap: 2.5, + }, + logoTop: { height: 9, borderRadius: 1.5, backgroundColor: C.ink }, + logoBottom: { flexDirection: "row", gap: 2.5 }, + logoSq: { flex: 1, height: 8, borderRadius: 1.5, backgroundColor: "#ffffff" }, + // header / nav header: { paddingHorizontal: 18, paddingBottom: 14, borderBottomWidth: 1, borderBottomColor: C.line }, navBar: { @@ -240,21 +268,11 @@ const styles = StyleSheet.create({ }, navTitle: { color: C.ink, fontSize: 17, fontWeight: "700", letterSpacing: -0.2 }, brandRow: { flexDirection: "row", alignItems: "center", gap: 10 }, - monogram: { - width: 30, - height: 30, - borderRadius: 8, - backgroundColor: C.sunken, - borderWidth: 1, - borderColor: C.line, - alignItems: "center", - justifyContent: "center", - }, - monogramText: { color: C.teal, fontSize: 16, fontWeight: "800" }, brand: { color: C.ink, fontSize: 20, fontWeight: "700", letterSpacing: -0.3 }, spacer: { flex: 1 }, - connectBtn: { backgroundColor: C.teal, paddingHorizontal: 16, paddingVertical: 8, borderRadius: 8 }, - connectBtnText: { color: "#04211d", fontSize: 13, fontWeight: "800" }, + // Primary action = ink/white (a hue is never the CTA — Ateam + clawnify). + connectBtn: { backgroundColor: C.ink, paddingHorizontal: 16, paddingVertical: 8, borderRadius: 8 }, + connectBtnText: { color: "#15151a", fontSize: 13, fontWeight: "800" }, connPill: { flexDirection: "row", alignItems: "center", @@ -291,8 +309,8 @@ const styles = StyleSheet.create({ fieldDivider: { borderBottomWidth: 1, borderBottomColor: C.line }, fieldLabel: { color: C.muted, fontSize: 14 }, fieldValue: { color: C.ink, fontSize: 14, fontVariant: ["tabular-nums"], flexShrink: 1, textAlign: "right" }, - keyChip: { backgroundColor: C.sunken, borderWidth: 1, borderColor: C.line, borderRadius: 6, paddingHorizontal: 8, paddingVertical: 3 }, - keyChipText: { color: C.teal, fontSize: 12, fontWeight: "600", letterSpacing: 0.3 }, + keyChip: { backgroundColor: TINT[C.accent], borderWidth: 1, borderColor: "rgba(124,92,255,0.4)", borderRadius: 6, paddingHorizontal: 8, paddingVertical: 3 }, + keyChipText: { color: C.accent, fontSize: 12, fontWeight: "600", letterSpacing: 0.3 }, formNote: { color: C.faint, fontSize: 12, lineHeight: 18, marginTop: 18, paddingHorizontal: 2 }, // board From 49dc00557d3278e83da32ea117b0f6cf5c8141fc Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 23:08:39 +0200 Subject: [PATCH 21/83] feat(server): interactive remote-terminal client over SSH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit connect-cli.ts: a headless terminal-only client — the CLI counterpart to the desktop app. Opens the same transport the desktop uses (ssh attach --stdio → JSON-RPC), handshakes with a version gate, dumps the live board, spawns a raw login shell in a task's worktree on the box, and bridges the local TTY: raw stdin → pty.write, pty.onData → stdout, snapshot replay with seq-dedupe, resize sync, Ctrl-] detach. Imports the transport by module path, not the @ateam/server barrel, so it stays free of the engine's native modules and runs under bun. --- packages/server/src/connect-cli.ts | 257 +++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 packages/server/src/connect-cli.ts diff --git a/packages/server/src/connect-cli.ts b/packages/server/src/connect-cli.ts new file mode 100644 index 0000000..50bc4d5 --- /dev/null +++ b/packages/server/src/connect-cli.ts @@ -0,0 +1,257 @@ +#!/usr/bin/env bun +// A headless, interactive CLIENT for a remote Ateam engine — the terminal-only +// counterpart to the desktop app. It opens the SAME transport the desktop uses +// (`ssh ateam attach --stdio` → newline-JSON-RPC over stdio), handshakes, +// prints the box's live board (proving it's the engine's real state, not mock), +// then bridges your local TTY to a RAW PTY *on the server*. +// +// The spawned terminal is a login shell in a task's worktree ON THE BOX — a real +// server terminal. Type `claude` in it to launch the Claude Code TUI over the +// wire, exactly as if sitting at the box. Detach with Ctrl-] and the remote shell +// (and anything running in it, e.g. a claude session) lives on — reattach later +// with `--terminal `, which replays the current screen via the PTY snapshot. +// +// Connection details (User, IdentityFile, ProxyJump, known_hosts) are OpenSSH's +// job via ~/.ssh/config — you pass an ssh alias, same as the desktop's connection +// picker. The transport is imported by its module path (not the @ateam/server +// barrel) so this client stays free of the engine's native modules (better-sqlite3 +// / node-pty) and runs under plain bun/node. +// +// bun packages/server/src/connect-cli.ts [alias] [--task ] [--terminal ] [--key ] +// default alias: hetzner-devbox +import { homedir } from "node:os"; +import { + type AteamApi, + buildAteamApi, + createRpcClient, + type NativeClientApi, + PROTOCOL_VERSION, + type PtyDataEvent, + type RpcClient, + type SystemInfo, + serverHandshake, +} from "@ateam/protocol"; +import { type SshClient, sshClientTransport } from "./transport/ssh"; + +// ssh space-joins the remote args, so `bash -lc '…'` must arrive as ONE argv +// element (a login shell so nvm/agent-CLI PATH is set) execing the attach relay. +const REMOTE_ATTACH = "bash -lc 'exec ateam attach --stdio'"; +const DETACH_BYTE = 0x1d; // Ctrl-] — frees the escape from the remote shell. +const HANDSHAKE_TIMEOUT_MS = 20_000; // ssh can hang on auth/unreachable with no error. + +// The client-local slice of AteamApi (native dialogs / clipboard / windows) that +// no remote engine can serve. A headless terminal never invokes these, so a +// throwing stub is the honest total — buildAteamApi needs the shape, not the impl. +const headlessNative: NativeClientApi = { + pathForFile: () => { + throw new Error("no native filesystem in the terminal client"); + }, + pick: async () => null, + pickFiles: async () => [], + stageClipboardImage: async () => false, + stageImagePath: async () => false, + openProject: async () => {}, + boundProjectId: () => null, +}; + +interface Args { + alias: string; + taskId?: string; + terminalId?: string; + key?: string; +} + +function parseArgs(argv: string[]): Args { + const args: Args = { alias: "hetzner-devbox" }; + const rest = argv.slice(2); + for (let i = 0; i < rest.length; i++) { + const tok = rest[i]; + if (tok === "--task") args.taskId = rest[++i]; + else if (tok === "--terminal") args.terminalId = rest[++i]; + else if (tok === "--key") args.key = rest[++i]; + else if (tok && !tok.startsWith("-")) args.alias = tok; + } + return args; +} + +/** Everything to stderr so stdout carries ONLY the raw PTY stream (pipe-friendly). */ +function log(msg: string): void { + process.stderr.write(`${msg}\n`); +} + +function withTimeout(p: Promise, ms: number, what: string): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(`${what} timed out after ${ms}ms`)), ms); + p.then( + (v) => { + clearTimeout(timer); + resolve(v); + }, + (e) => { + clearTimeout(timer); + reject(e); + }, + ); + }); +} + +async function main(): Promise { + const args = parseArgs(process.argv); + const sshFlags = [ + "-o", + "BatchMode=yes", + "-o", + "ConnectTimeout=10", + "-o", + "StrictHostKeyChecking=accept-new", + ]; + if (args.key) sshFlags.push("-i", args.key.replace(/^~/, homedir())); + + log(`· connecting to ${args.alias} …`); + const client = sshClientTransport(args.alias, [REMOTE_ATTACH], { sshFlags }); + const rpc: RpcClient = createRpcClient(client.transport); + + let info: SystemInfo; + try { + info = await withTimeout(serverHandshake(rpc), HANDSHAKE_TIMEOUT_MS, "handshake"); + } catch (err) { + client.close(); + throw err; + } + if (info.protocolVersion !== PROTOCOL_VERSION) { + client.close(); + throw new Error( + `protocol mismatch: ${args.alias} speaks v${info.protocolVersion}, this client speaks v${PROTOCOL_VERSION} — update the older side`, + ); + } + const api = buildAteamApi(rpc, headlessNative); + log( + `· connected — engine protocol v${info.protocolVersion}; agents: ${info.agents.join(", ") || "none"}`, + ); + + // Resolve which server PTY to drive. + let terminalId = args.terminalId; + if (!terminalId) { + // Dump the live board (proves real engine state) and pick a task to shell into. + const projects = await api.projects.list(); + let taskId = args.taskId; + for (const project of projects) { + const tasks = await api.tasks.list(project.id); + log(`\n▸ ${project.name} · ${project.repoPath}`); + for (const task of tasks) { + const live = await api.pty.listForTask(task.id); + const liveTag = live.length + ? ` (${live.length} live session${live.length === 1 ? "" : "s"})` + : ""; + log(` • ${task.name} [${task.column}]${liveTag} ${task.id}`); + if (!taskId) taskId = task.id; + } + } + if (!taskId) { + client.close(); + throw new Error("no tasks on the box to open a shell in — create one from the app first"); + } + log(`\n· spawning a raw login shell on the server, in task ${taskId} …`); + const spawned = await api.pty.spawnShell({ taskId }); + terminalId = spawned.terminalId; + log(`· server shell ready: ${terminalId} (reattach later with --terminal ${terminalId})`); + } + + await driveTerminal(api, client, terminalId); +} + +/** Bridge the local TTY to the remote PTY: snapshot replay, live stream, raw input. */ +async function driveTerminal(api: AteamApi, client: SshClient, terminalId: string): Promise { + const isTTY = Boolean(process.stdin.isTTY && process.stdout.isTTY); + + // Buffer live chunks until the snapshot is painted, then apply only newer ones + // (seq-dedupe) so bytes the snapshot already reflects are never doubled. + const buffered: PtyDataEvent[] = []; + let applied = false; + let lastSeq = -1; + const offData = api.pty.onData((e) => { + if (e.terminalId !== terminalId) return; + if (!applied) { + buffered.push(e); + return; + } + if (e.seq > lastSeq) { + lastSeq = e.seq; + process.stdout.write(e.data); + } + }); + + let done = false; + const finish = (msg: string, code = 0): void => { + if (done) return; + done = true; + offData(); + offExit(); + // Restore the terminal BEFORE anything else — never leave the user's shell + // wedged in raw mode. + if (isTTY && process.stdin.isRaw) process.stdin.setRawMode(false); + process.stdin.pause(); + log(msg); + client.close(); // ends the ssh relay; the remote shell + its sessions live on + process.exit(code); + }; + const offExit = api.pty.onExit((e) => { + if (e.terminalId === terminalId) + finish(`\n· remote shell exited (code ${e.exitCode})`, e.exitCode); + }); + client.child.on("exit", () => finish("\n· ssh connection closed")); + + // Size the remote PTY to our window (TUIs like claude need correct cols/rows). + const pushResize = (): void => + api.pty.resize(terminalId, process.stdout.columns ?? 80, process.stdout.rows ?? 24); + if (isTTY) pushResize(); + + // Snapshot replay: paint the server's current screen, then flush newer live chunks. + try { + const snap = await api.pty.snapshot(terminalId); + if (snap.data) process.stdout.write(snap.data); + lastSeq = snap.seq; + for (const e of buffered) { + if (e.seq > lastSeq) { + lastSeq = e.seq; + process.stdout.write(e.data); + } + } + } finally { + applied = true; + } + + if (isTTY) { + process.stdout.on("resize", pushResize); + process.stdin.setRawMode(true); + log(`\n· attached to server shell — type \`claude\` for the TUI. Ctrl-] to detach.\r\n`); + } + process.stdin.resume(); + process.stdin.on("data", (buf: Buffer) => { + // Ctrl-] detaches locally (leaving the remote shell alive); every other byte + // — arrows, Ctrl-C, Enter, paste — is forwarded raw to the server PTY. + if (isTTY && buf.includes(DETACH_BYTE)) { + finish( + `\n· detached — remote shell ${terminalId} still running (reattach: --terminal ${terminalId})`, + ); + return; + } + api.pty.write(terminalId, buf.toString("utf8")); + }); + // Piped (non-TTY) input, for scripted use: after stdin ends, drain briefly then + // detach. shortcut: fixed 1.5s drain — fine for scripts; interactive use is TTY. + if (!isTTY) + process.stdin.on("end", () => setTimeout(() => finish("\n· (piped input done)"), 1500)); +} + +if (import.meta.main) { + main().catch((err) => { + try { + if (process.stdin.isTTY && process.stdin.isRaw) process.stdin.setRawMode(false); + } catch { + /* best-effort restore */ + } + process.stderr.write(`\n✗ ${err instanceof Error ? err.message : String(err)}\n`); + process.exit(1); + }); +} From 6ba64dd43375a83a0465db5cdda7ca66b8df437e Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 6 Jul 2026 23:18:56 +0200 Subject: [PATCH 22/83] fix(server): make `ateam daemon` single-instance safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A second `ateam daemon` blindly unlink()'d the live socket then listen()'d — on the false premise that a live daemon would trip EADDRINUSE — silently supplanting the first and orphaning its engine, live PTY sessions, and SQLite writer. Probe by connecting first: bow out if a daemon already serves the socket; only unlink a genuinely stale file. Handle a startup race via EADDRINUSE re-probe, and connect the PTY daemon only after we own the socket so a bowed-out daemon leaves no stray PTY daemon. --- packages/server/src/cli.ts | 66 +++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index efd8346..28d4aeb 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -37,6 +37,17 @@ const SOCK = process.env.ATEAM_RPC_SOCK ?? join(homedir(), ".ateam", "rpc.sock") const SELF = process.argv[1] ? realpathSync(process.argv[1]) : ""; async function runDaemon(): Promise { + // Single-instance guard: if a daemon already serves SOCK, bow out — do NOT + // steal it. The old code blindly unlink()'d the socket then listen()'d, on the + // false premise that a live daemon would trip EADDRINUSE; but unlinking the file + // is exactly what defeats that guard, so a second `ateam daemon` silently + // supplanted the first — orphaning its engine, live PTY sessions, and SQLite + // writer. Probe by connecting first: only a live listener should stop us. + if (await isDaemonLive(SOCK)) { + console.log(`[ateam] a daemon is already listening at ${SOCK}; nothing to do`); + return; + } + const dataDir = process.env.ATEAM_DATA_DIR ?? join(homedir(), ".ateam"); // The PTY daemon bundle (node-pty + xterm). Shipped beside the ateam bin on // the server; overridable for dev. @@ -48,8 +59,8 @@ async function runDaemon(): Promise { const dir = dirname(SOCK); if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); - // Clear a stale socket file; if a daemon were actually live, listen() below - // would EADDRINUSE and we'd exit rather than steal its socket. + // The probe found no live daemon, so any socket file here is stale (a crashed + // daemon leaves the file behind) — remove it so listen() can bind. try { if (existsSync(SOCK)) unlinkSync(SOCK); } catch { @@ -64,19 +75,52 @@ async function runDaemon(): Promise { // its PTY sessions) is shared and outlives any single client. serveRpc(engine, dispatcher, socketServerTransport(sock)); }); - server.on("error", (err) => { + server.on("error", (err: NodeJS.ErrnoException) => { + // Lost a startup race: another daemon bound SOCK between our probe and + // listen(). If it's live, bow out cleanly instead of dying with an error. + if (err.code === "EADDRINUSE") { + void isDaemonLive(SOCK).then((live) => { + if (live) { + console.log(`[ateam] another daemon won the socket; exiting`); + process.exit(0); + } + console.error(`[ateam] ${SOCK} is busy but no daemon answers`); + process.exit(1); + }); + return; + } console.error(`[ateam] daemon error: ${err.message}`); process.exit(1); }); - server.listen(SOCK, () => console.log(`[ateam] daemon listening at ${SOCK}`)); + server.listen(SOCK, () => { + console.log(`[ateam] daemon listening at ${SOCK}`); + // Connect the PTY daemon in the BACKGROUND, and only once we own the socket: + // don't block RPC on it (git/tasks/board serves immediately; agent spawning + // reconnects lazily), and a daemon that bowed out never spawns a stray PTY + // daemon. Awaiting here previously stalled a fresh box's first attach. + void engine.connectPty().catch((err) => { + console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); + }); + }); +} - // Connect to the PTY daemon in the BACKGROUND — don't block RPC on it. The - // git/tasks/board surface serves immediately (a client's handshake shouldn't - // wait out the PTY connect), and agent spawning reconnects lazily (PtyClient - // respawns/reconnects on demand). Awaiting here is what previously stalled a - // fresh box's first attach past its retry window. - void engine.connectPty().catch((err) => { - console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); +/** + * Is a daemon already listening on `sock`? Connect-probe: a successful connect + * means a live listener owns it; ECONNREFUSED means a stale socket file (crashed + * daemon, no listener); ENOENT means no file at all. Only a live listener should + * stop a new daemon from starting. + */ +function isDaemonLive(sock: string): Promise { + return new Promise((resolve) => { + const probe = connect(sock); + probe.once("connect", () => { + probe.destroy(); + resolve(true); + }); + probe.once("error", () => { + probe.destroy(); + resolve(false); + }); }); } From 581145977f268ad314b426ab96798df9d077067d Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 14:30:10 +0200 Subject: [PATCH 23/83] feat(mobile,server): wire the phone to a live engine over a WebSocket/Tailscale transport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit React Native can't spawn `ssh` (the desktop's transport) and no RN SSH library exposes a clean streaming channel, so the phone reaches a box the way Coder/Gitpod/ Codespaces do it: a WebSocket over Tailscale, with WireGuard as the auth boundary. buildAteamApi + the wire contract are pure TS, so they run in RN unchanged — only the transport is new. - protocol/ws.ts: wsClientTransport over the platform-global WebSocket (RN/browser/ Bun), dependency-free and DOM-lib-free. Queues frames until OPEN so the connect- time system:hello handshake is never dropped. - server/transport/ws.ts + cli.ts: wsServerTransport (one JSON frame per message, reusing serveRpc/dispatcher) behind an OPT-IN listener (ATEAM_WS_ADDR). Off by default — the box stays listener-free and the desktop SSH path is unchanged; binds an explicit tailnet IP and REFUSES a 0.0.0.0/:: wildcard (same guard the reverted TCP listener used). ws bundles into the standalone dist. - apps/mobile: real client. src/connection.ts does wsClientTransport → createRpcClient → serverHandshake (PROTOCOL_VERSION gate + timeout) → buildAteamApi. App.tsx board is live (every project's tasks, taskUpdated pushes merged in place) with real host/port inputs. Metro + tsconfig resolve just @ateam/protocol without reopening the RN-shadowing the config guards against. - Scrub personal host/IP (hetzner-devbox / 100.72.63.61 / pallaoro) from App.tsx, connect-cli.ts, and the connections test fixture. Tests: buildAteamApi over a real WebSocket (server ↔ Bun global WebSocket client), proving the phone path incl. queue-until-open. Typechecks: protocol, server, desktop, mobile all green. Not verified here: the Metro bundle / live simulator run. --- apps/mobile/App.tsx | 400 ++++++++++++++++++----- apps/mobile/metro.config.js | 8 + apps/mobile/package.json | 3 +- apps/mobile/src/connection.ts | 75 +++++ apps/mobile/tsconfig.json | 6 +- bun.lock | 12 +- packages/protocol/src/index.ts | 3 + packages/protocol/src/ws.ts | 83 +++++ packages/server/package.json | 12 +- packages/server/scripts/build.ts | 4 +- packages/server/src/cli.ts | 44 +++ packages/server/src/connect-cli.ts | 4 +- packages/server/src/index.ts | 20 +- packages/server/src/transport/ws.ts | 32 ++ packages/server/test/connections.test.ts | 10 +- packages/server/test/ws.test.ts | 87 +++++ 16 files changed, 694 insertions(+), 109 deletions(-) create mode 100644 apps/mobile/src/connection.ts create mode 100644 packages/protocol/src/ws.ts create mode 100644 packages/server/src/transport/ws.ts create mode 100644 packages/server/test/ws.test.ts diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 880f089..2612001 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -1,14 +1,29 @@ -// Ateam mobile — board + connection preview. +// Ateam mobile — a thin remote for a box running the Ateam engine. The phone +// opens a WebSocket to the box's opt-in `ateam` WS listener (over Tailscale), +// handshakes, and drives the SAME engine the desktop does via the shared +// @ateam/protocol contract (see src/connection.ts). The board below is LIVE: +// projects/tasks come from the engine and taskUpdated pushes keep it fresh. +// // Theme = Ateam's real tokens (apps/desktop/src/renderer/src/index.css): near-black // #0c0c0e canvas, purple accent #7c5cff, ink/white primary action (a hue is never // the CTA), amber/blue/green status. Logo = the "mission-control tiling" mark from -// apps/desktop/build/icon.svg, redrawn with Views. Structure follows the clawnify -// DESIGN-apps signature (eyebrow zones · chips for facts vs tinted badges for -// signals · monochrome chrome · no emoji). Connection = ALWAYS SSH (a host is -// Label · IP/Hostname · Port · Username · Key; the IP is the box's Tailscale -// address). Preview: mock data; live SSH wiring next. -import { useState } from "react"; -import { Pressable, ScrollView, StatusBar, StyleSheet, Text, useColorScheme, View } from "react-native"; +// apps/desktop/build/icon.svg, redrawn with Views. Connection = ALWAYS a WebSocket +// to a Tailscale address (RN can't spawn ssh; WireGuard is the auth boundary). + +import type { ProjectDTO, TaskDTO } from "@ateam/protocol"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { + ActivityIndicator, + Pressable, + ScrollView, + StatusBar, + StyleSheet, + Text, + TextInput, + useColorScheme, + View, +} from "react-native"; +import { type Connection, connect } from "./src/connection"; const C = { bg: "#0c0c0e", @@ -31,10 +46,12 @@ const TINT: Record = { [C.blue]: "rgba(96,165,250,0.14)", [C.green]: "rgba(74,222,128,0.13)", [C.muted]: "rgba(154,154,166,0.12)", + [C.red]: "rgba(248,113,113,0.14)", }; -type Column = "needs_attention" | "running" | "review" | "todo" | "merged"; -const COLUMNS: { key: Column; label: string; tint: string }[] = [ +// Column keys match @ateam/protocol's KanbanColumn exactly, so a live TaskDTO's +// `column` drops straight into the right zone. +const COLUMNS: { key: TaskDTO["column"]; label: string; tint: string }[] = [ { key: "needs_attention", label: "Needs You", tint: C.amber }, { key: "running", label: "In Progress", tint: C.accent }, { key: "review", label: "Review", tint: C.blue }, @@ -42,15 +59,17 @@ const COLUMNS: { key: Column; label: string; tint: string }[] = [ { key: "merged", label: "Done", tint: C.green }, ]; -type Task = { name: string; column: Column; agent: string; branch: string; note: string }; -const TASKS: Task[] = [ - { name: "Fix SSH reconnect on wake", column: "needs_attention", agent: "claude", branch: "fix/ssh-reconnect", note: "awaiting your input" }, - { name: "Tailscale reachability for the daemon", column: "running", agent: "claude", branch: "feat/tailnet-host", note: "editing host.ts" }, - { name: "Board reconciler perf", column: "running", agent: "codex", branch: "perf/reconciler", note: "running tests" }, - { name: "Connections screen", column: "review", agent: "claude", branch: "feat/connections-ui", note: "3 files changed" }, - { name: "Rename daemon → engine", column: "todo", agent: "claude", branch: "chore/rename", note: "queued" }, - { name: "Remote fs picker", column: "merged", agent: "claude", branch: "feat/fs-listdir", note: "merged · PR #45" }, -]; +// A short status line for a card, derived from the live task (mirrors the desktop's +// signal priority: a pending question first, then agent state, then git/PR facts). +function taskNote(t: TaskDTO): string { + if (t.column === "needs_attention") return "awaiting your input"; + if (t.agentStatus === "running") return "running"; + if (t.mergeStatus) return t.mergeStatus; + if (t.prNumber != null) return `PR #${t.prNumber}`; + const dirty = t.gitStatus?.dirty ?? 0; + if (dirty > 0) return `${dirty} changed`; + return t.agentStatus ?? "idle"; +} // The Ateam logo mark: a wide top pane + two dimming squares (icon.svg), on a dark // tile. Redrawn with Views so it scales + themes with no native SVG dependency. @@ -89,56 +108,79 @@ function Badge({ children, tint }: { children: string; tint: string }) { function AgentTag({ agent }: { agent: string }) { return ( - {agent[0]?.toUpperCase()} + {agent[0]?.toUpperCase() ?? "·"} ); } -function TaskCard({ task, tint }: { task: Task; tint: string }) { +function TaskCard({ task, tint }: { task: TaskDTO; tint: string }) { return ( - + {task.name} {task.branch} - {task.note} + {taskNote(task)} ); } -// ── Connection screen — one SSH target, Termius-modeled (no transport toggle) ── +// ── Connection screen — one WebSocket target (host = the box's Tailscale IP) ── -function FieldRow({ +function Field({ label, value, - keyChip, + onChangeText, + placeholder, + keyboardType, last, }: { label: string; value: string; - keyChip?: boolean; + onChangeText: (t: string) => void; + placeholder: string; + keyboardType?: "default" | "numeric"; last?: boolean; }) { return ( {label} - {keyChip ? ( - - {value} - - ) : ( - {value} - )} + ); } -function ConnectionScreen({ onConnect }: { onConnect: () => void }) { +function ConnectionScreen({ + host, + port, + setHost, + setPort, + onConnect, + connecting, + error, +}: { + host: string; + port: string; + setHost: (t: string) => void; + setPort: (t: string) => void; + onConnect: () => void; + connecting: boolean; + error: string | null; +}) { return ( @@ -146,43 +188,76 @@ function ConnectionScreen({ onConnect }: { onConnect: () => void }) { New connection - - Connect + + {connecting ? ( + + ) : ( + Connect + )} - Host + Box - - - + + - - - Credentials - - - - - + {error ? ( + + {error} + + ) : null} - Always SSH. The IP is the box's Tailscale address — same user, same key. Tailscale just - changes the address you connect to. + The phone opens a WebSocket to your box's `ateam` listener over Tailscale — WireGuard is + the encryption and the auth boundary. Enable it on the box with{" "} + ATEAM_WS_ADDR=<tailscale-ip>:<port> (never a + wildcard bind). ); } -// ── Board screen ── +// ── Board screen — LIVE tasks from the connected engine ── -function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { +function BoardScreen({ + host, + agents, + tasks, + loading, + onOpenConnection, + onRefresh, +}: { + host: string; + agents: string[]; + tasks: TaskDTO[]; + loading: boolean; + onOpenConnection: () => void; + onRefresh: () => void; +}) { return ( @@ -193,32 +268,52 @@ function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { - hetzner-devbox + + {host} + - SSH · pallaoro@100.72.63.61 · claude + WS · {host} ·{" "} + {agents.length ? agents.join(", ") : "no agents"} - - {COLUMNS.map((col) => { - const tasks = TASKS.filter((t) => t.column === col.key); - if (tasks.length === 0) return null; - return ( - - - - {col.label} - {tasks.length} + + {loading && tasks.length === 0 ? ( + + + loading board… + + ) : tasks.length === 0 ? ( + + no tasks on this box yet + + ) : ( + COLUMNS.map((col) => { + const inCol = tasks.filter((t) => t.column === col.key); + if (inCol.length === 0) return null; + return ( + + + + {col.label} + {inCol.length} + + {inCol.map((t) => ( + + ))} - {tasks.map((t) => ( - - ))} - - ); - })} - preview · mock board · live SSH wiring next + ); + }) + )} + + tap to refresh + ); @@ -226,12 +321,89 @@ function BoardScreen({ onOpenConnection }: { onOpenConnection: () => void }) { export default function App() { useColorScheme(); // reserved: theme-aware later - // Board is home; tapping the connection pill opens the SSH host form. - const [view, setView] = useState<"connect" | "board">("board"); + const [view, setView] = useState<"connect" | "board">("connect"); + const [host, setHost] = useState(""); + const [port, setPort] = useState("8787"); + const [connecting, setConnecting] = useState(false); + const [error, setError] = useState(null); + const [tasks, setTasks] = useState([]); + const [agents, setAgents] = useState([]); + const [loading, setLoading] = useState(false); + const conn = useRef(null); + + // Pull the whole board: every project's tasks, flattened. Sorted newest-active + // first so the freshest work leads each column. + const refresh = useCallback(async () => { + const api = conn.current?.api; + if (!api) return; + setLoading(true); + try { + const projects: ProjectDTO[] = await api.projects.list(); + const perProject = await Promise.all(projects.map((p) => api.tasks.list(p.id))); + const all = perProject.flat().sort((a, b) => (b.lastEventAt ?? 0) - (a.lastEventAt ?? 0)); + setTasks(all); + } finally { + setLoading(false); + } + }, []); + + // Live updates: merge each pushed task in place (replace by id, or prepend if new). + useEffect(() => { + const api = conn.current?.api; + if (!api || view !== "board") return; + const off = api.events.onTaskUpdated((t) => { + setTasks((prev) => { + const i = prev.findIndex((x) => x.id === t.id); + if (i === -1) return [t, ...prev]; + const next = prev.slice(); + next[i] = t; + return next; + }); + }); + return off; + }, [view]); + + const onConnect = useCallback(async () => { + if (!host.trim()) { + setError("Enter the box's Tailscale IP or hostname."); + return; + } + setConnecting(true); + setError(null); + try { + conn.current?.close(); + const c = await connect(`ws://${host.trim()}:${port.trim() || "8787"}`); + conn.current = c; + setAgents(c.info.agents); + setView("board"); + await refresh(); + } catch (err) { + conn.current = null; + setError(err instanceof Error ? err.message : String(err)); + } finally { + setConnecting(false); + } + }, [host, port, refresh]); + return view === "connect" ? ( - setView("board")} /> + ) : ( - setView("connect")} /> + setView("connect")} + onRefresh={refresh} + /> ); } @@ -256,7 +428,12 @@ const styles = StyleSheet.create({ logoSq: { flex: 1, height: 8, borderRadius: 1.5, backgroundColor: "#ffffff" }, // header / nav - header: { paddingHorizontal: 18, paddingBottom: 14, borderBottomWidth: 1, borderBottomColor: C.line }, + header: { + paddingHorizontal: 18, + paddingBottom: 14, + borderBottomWidth: 1, + borderBottomColor: C.line, + }, navBar: { flexDirection: "row", alignItems: "center", @@ -271,7 +448,15 @@ const styles = StyleSheet.create({ brand: { color: C.ink, fontSize: 20, fontWeight: "700", letterSpacing: -0.3 }, spacer: { flex: 1 }, // Primary action = ink/white (a hue is never the CTA — Ateam + clawnify). - connectBtn: { backgroundColor: C.ink, paddingHorizontal: 16, paddingVertical: 8, borderRadius: 8 }, + connectBtn: { + backgroundColor: C.ink, + paddingHorizontal: 16, + paddingVertical: 8, + borderRadius: 8, + minWidth: 74, + alignItems: "center", + }, + connectBtnBusy: { opacity: 0.7 }, connectBtnText: { color: "#15151a", fontSize: 13, fontWeight: "800" }, connPill: { flexDirection: "row", @@ -283,6 +468,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 10, paddingVertical: 5, borderRadius: 999, + maxWidth: 180, }, connDot: { width: 7, height: 7, borderRadius: 4, backgroundColor: C.green }, connText: { color: C.muted, fontSize: 12, fontWeight: "600" }, @@ -290,9 +476,21 @@ const styles = StyleSheet.create({ connHost: { color: C.ink, fontVariant: ["tabular-nums"] }, // eyebrow - eyebrowRow: { flexDirection: "row", alignItems: "center", gap: 8, marginBottom: 10, paddingLeft: 2 }, + eyebrowRow: { + flexDirection: "row", + alignItems: "center", + gap: 8, + marginBottom: 10, + paddingLeft: 2, + }, tick: { width: 3, height: 12, borderRadius: 2 }, - eyebrow: { color: C.muted, fontSize: 11, fontWeight: "600", textTransform: "uppercase", letterSpacing: 1.1 }, + eyebrow: { + color: C.muted, + fontSize: 11, + fontWeight: "600", + textTransform: "uppercase", + letterSpacing: 1.1, + }, eyebrowCount: { color: C.faint, fontSize: 11, fontWeight: "600", fontVariant: ["tabular-nums"] }, // connection form @@ -303,21 +501,44 @@ const styles = StyleSheet.create({ alignItems: "center", justifyContent: "space-between", paddingHorizontal: 14, - paddingVertical: 14, + paddingVertical: 6, gap: 12, }, fieldDivider: { borderBottomWidth: 1, borderBottomColor: C.line }, fieldLabel: { color: C.muted, fontSize: 14 }, - fieldValue: { color: C.ink, fontSize: 14, fontVariant: ["tabular-nums"], flexShrink: 1, textAlign: "right" }, - keyChip: { backgroundColor: TINT[C.accent], borderWidth: 1, borderColor: "rgba(124,92,255,0.4)", borderRadius: 6, paddingHorizontal: 8, paddingVertical: 3 }, - keyChipText: { color: C.accent, fontSize: 12, fontWeight: "600", letterSpacing: 0.3 }, + fieldInput: { + color: C.ink, + fontSize: 14, + fontVariant: ["tabular-nums"], + flex: 1, + textAlign: "right", + paddingVertical: 8, + }, + errorBox: { + backgroundColor: TINT[C.red], + borderWidth: 1, + borderColor: "rgba(248,113,113,0.4)", + borderRadius: 8, + padding: 12, + marginTop: 16, + }, + errorText: { color: C.red, fontSize: 13, lineHeight: 18 }, formNote: { color: C.faint, fontSize: 12, lineHeight: 18, marginTop: 18, paddingHorizontal: 2 }, + mono: { color: C.muted, fontVariant: ["tabular-nums"] }, // board board: { flex: 1 }, boardContent: { padding: 16, paddingBottom: 40 }, + centerPad: { alignItems: "center", paddingVertical: 48, gap: 12 }, zone: { marginBottom: 22 }, - card: { backgroundColor: C.surface, borderWidth: 1, borderColor: C.line, borderRadius: 8, padding: 12, marginBottom: 8 }, + card: { + backgroundColor: C.surface, + borderWidth: 1, + borderColor: C.line, + borderRadius: 8, + padding: 12, + marginBottom: 8, + }, cardTop: { flexDirection: "row", alignItems: "flex-start", gap: 9 }, agentTag: { width: 22, @@ -332,7 +553,14 @@ const styles = StyleSheet.create({ agentInitial: { color: C.muted, fontSize: 11, fontWeight: "700" }, cardName: { color: C.ink, fontSize: 15, fontWeight: "600", flex: 1, lineHeight: 20 }, cardMeta: { flexDirection: "row", alignItems: "center", gap: 6, marginTop: 10, flexWrap: "wrap" }, - chip: { backgroundColor: C.sunken, borderWidth: 1, borderColor: C.line, borderRadius: 6, paddingHorizontal: 7, paddingVertical: 3 }, + chip: { + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + borderRadius: 6, + paddingHorizontal: 7, + paddingVertical: 3, + }, chipText: { color: C.muted, fontSize: 11, fontVariant: ["tabular-nums"] }, badge: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 3 }, badgeText: { fontSize: 11, fontWeight: "600" }, diff --git a/apps/mobile/metro.config.js b/apps/mobile/metro.config.js index 7bb37a4..a5ec37a 100644 --- a/apps/mobile/metro.config.js +++ b/apps/mobile/metro.config.js @@ -11,4 +11,12 @@ const config = getDefaultConfig(projectRoot); config.resolver.nodeModulesPaths = [path.resolve(projectRoot, "node_modules")]; config.resolver.disableHierarchicalLookup = true; +// Surgically link the one workspace package the app consumes — @ateam/protocol, +// the pure-TS wire contract (no deps of its own). We watch its folder so Metro +// transpiles its source, and map just its name, WITHOUT reopening hierarchical +// lookup — so the bun-root node_modules still can't shadow react/react-native. +const protocolDir = path.resolve(projectRoot, "../../packages/protocol"); +config.watchFolders = [protocolDir]; +config.resolver.extraNodeModules = { "@ateam/protocol": protocolDir }; + module.exports = config; diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a7a1f35..7af71fd 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -16,7 +16,8 @@ "start": "expo start", "android": "expo run:android", "ios": "expo run:ios", - "web": "expo start --web" + "web": "expo start --web", + "typecheck": "tsc --noEmit" }, "private": true } diff --git a/apps/mobile/src/connection.ts b/apps/mobile/src/connection.ts new file mode 100644 index 0000000..8b015dc --- /dev/null +++ b/apps/mobile/src/connection.ts @@ -0,0 +1,75 @@ +// The phone's link to a box: open a WebSocket to the box's opt-in `ateam` WS +// listener (reachable over Tailscale), handshake the protocol version, then bind +// the full AteamApi over it. React Native can't spawn `ssh` like the desktop, but +// it ships a WebSocket — and @ateam/protocol is pure TS, so buildAteamApi runs +// here unchanged. This is the whole client: everything else is the shared contract. +import { + type AteamApi, + buildAteamApi, + createRpcClient, + type NativeClientApi, + PROTOCOL_VERSION, + type SystemInfo, + serverHandshake, + wsClientTransport, +} from "@ateam/protocol"; + +// A remote client owns no local dialogs or clipboard: folder-pick and image +// attach flow over RPC (fs.listDir / util.writeImageBytes) instead, so this +// client-native slice is inert here. Single-window, so the window surface stubs too. +const mobileNative: NativeClientApi = { + pathForFile: () => "", + pick: async () => null, + pickFiles: async () => [], + stageClipboardImage: async () => false, + stageImagePath: async () => false, + openProject: async () => {}, + boundProjectId: () => null, +}; + +export interface Connection { + api: AteamApi; + info: SystemInfo; + /** Close the socket; the daemon and its live sessions live on. */ + close(): void; +} + +const CONNECT_TIMEOUT_MS = 15_000; + +/** Connect to `ws://host:port` (the box's Tailscale address + WS port). */ +export async function connect(url: string): Promise { + const client = wsClientTransport(url); + const rpc = createRpcClient(client.transport); + let info: SystemInfo; + try { + // A bad host / firewalled port leaves the socket hanging with no error, so + // cap the handshake — the UI must not wait forever on connect. + info = await withTimeout(serverHandshake(rpc), CONNECT_TIMEOUT_MS); + } catch (err) { + client.close(); + throw err; + } + if (info.protocolVersion !== PROTOCOL_VERSION) { + client.close(); + throw new Error( + `Protocol mismatch: box speaks v${info.protocolVersion}, app speaks v${PROTOCOL_VERSION}. Update the older side.`, + ); + } + return { api: buildAteamApi(rpc, mobileNative), info, close: client.close }; +} + +function withTimeout(p: Promise, ms: number): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(`connection timed out after ${ms}ms`)), ms); + p.then( + (v) => { + clearTimeout(timer); + resolve(v); + }, + (e) => { + clearTimeout(timer); + reject(e); + }, + ); + }); +} diff --git a/apps/mobile/tsconfig.json b/apps/mobile/tsconfig.json index b9567f6..2242c20 100644 --- a/apps/mobile/tsconfig.json +++ b/apps/mobile/tsconfig.json @@ -1,6 +1,10 @@ { "extends": "expo/tsconfig.base", "compilerOptions": { - "strict": true + "strict": true, + "moduleResolution": "bundler", + "paths": { + "@ateam/protocol": ["../../packages/protocol/src/index.ts"] + } } } diff --git a/bun.lock b/bun.lock index cb9c438..a02510f 100644 --- a/bun.lock +++ b/bun.lock @@ -12,7 +12,7 @@ }, "apps/desktop": { "name": "@ateam/desktop", - "version": "0.1.25", + "version": "0.1.27", "dependencies": { "better-sqlite3": "^11.8.1", "electron-updater": "^6.8.3", @@ -93,9 +93,11 @@ "@xterm/addon-serialize": "^0.13.0", "@xterm/headless": "^5.5.0", "node-pty": "^1.0.0", + "ws": "^8.21.0", }, "devDependencies": { "@types/node": "^22.10.5", + "@types/ws": "^8.18.1", "drizzle-orm": "^0.38.4", }, }, @@ -381,6 +383,8 @@ "@types/verror": ["@types/verror@1.10.11", "", {}, "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], @@ -1103,6 +1107,8 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -1167,6 +1173,8 @@ "@types/responselike/@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], + "@types/ws/@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], + "@types/yauzl/@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], "app-builder-lib/@electron/notarize": ["@electron/notarize@2.5.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], @@ -1327,6 +1335,8 @@ "@types/responselike/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + "@types/ws/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + "@types/yauzl/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], "app-builder-lib/@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 1d7e737..05c4c33 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -439,3 +439,6 @@ export type { NativeClientApi } from "./client-api"; export { buildAteamApi, serverHandshake } from "./client-api"; // Transport-agnostic RPC framing + client (shared by every transport). export * from "./rpc"; +export type { WsClient } from "./ws"; +// WebSocket ClientTransport over the platform-global WebSocket (browser / RN / Bun). +export { wsClientTransport } from "./ws"; diff --git a/packages/protocol/src/ws.ts b/packages/protocol/src/ws.ts new file mode 100644 index 0000000..ea2e40e --- /dev/null +++ b/packages/protocol/src/ws.ts @@ -0,0 +1,83 @@ +// A ClientTransport over the platform-global WebSocket — the one built into the +// browser, React Native, and Bun alike. Dependency-free and DOM-lib-free: it +// depends only on the tiny structural subset below and reads the constructor off +// globalThis, so it runs in the desktop renderer, a PWA, and the Expo mobile app +// with no `ws` package and no node `net`. This is the transport the phone uses to +// reach a box's opt-in WS listener over Tailscale (see @ateam/server's cli.ts). +// +// WebSocket is already message-framed, so — unlike the stdio/socket transports — +// there is no newline framing: one JSON frame per message. +import type { ClientFrame, ClientTransport, ServerFrame } from "./rpc"; + +/** The minimal WebSocket surface we use; every platform's global satisfies it. */ +interface MinimalWebSocket { + send(data: string): void; + close(): void; + onopen: (() => void) | null; + onclose: (() => void) | null; + onerror: (() => void) | null; + onmessage: ((event: { data: unknown }) => void) | null; +} +type WebSocketCtor = new (url: string) => MinimalWebSocket; + +export interface WsClient { + transport: ClientTransport; + /** Close the socket; fires the transport's onClose so in-flight calls reject. */ + close(): void; +} + +/** + * Open an RPC transport to `url` (e.g. `ws://100.x.y.z:PORT` — the box's Tailscale + * address). Frames sent before the socket is OPEN are queued and flushed on open, + * so the connect-time `system:hello` handshake is never dropped. + */ +export function wsClientTransport(url: string): WsClient { + const Ctor = (globalThis as { WebSocket?: WebSocketCtor }).WebSocket; + if (!Ctor) throw new Error("no global WebSocket on this platform"); + const ws = new Ctor(url); + + let open = false; + let closed = false; + const queue: string[] = []; + const closeHandlers: (() => void)[] = []; + let frameHandler: ((frame: ServerFrame) => void) | null = null; + + ws.onopen = () => { + open = true; + for (const msg of queue) ws.send(msg); + queue.length = 0; + }; + ws.onmessage = (event) => { + if (!frameHandler) return; + try { + frameHandler(JSON.parse(String(event.data)) as ServerFrame); + } catch { + /* ignore malformed */ + } + }; + // close and error both mean "channel gone"; fire the handlers exactly once. + const fireClosed = () => { + if (closed) return; + closed = true; + for (const h of closeHandlers) h(); + }; + ws.onclose = fireClosed; + ws.onerror = fireClosed; + + return { + transport: { + send(frame: ClientFrame) { + const msg = JSON.stringify(frame); + if (open) ws.send(msg); + else queue.push(msg); + }, + onFrame(handler) { + frameHandler = handler; + }, + onClose(handler) { + closeHandlers.push(handler); + }, + }, + close: () => ws.close(), + }; +} diff --git a/packages/server/package.json b/packages/server/package.json index 412c527..752aed3 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -5,8 +5,12 @@ "type": "module", "main": "./src/index.ts", "types": "./src/index.ts", - "exports": { ".": "./src/index.ts" }, - "bin": { "ateam": "./src/cli.ts" }, + "exports": { + ".": "./src/index.ts" + }, + "bin": { + "ateam": "./src/cli.ts" + }, "scripts": { "build": "bun run scripts/build.ts", "test": "bun test", @@ -19,10 +23,12 @@ "@ateam/protocol": "workspace:*", "@xterm/addon-serialize": "^0.13.0", "@xterm/headless": "^5.5.0", - "node-pty": "^1.0.0" + "node-pty": "^1.0.0", + "ws": "^8.21.0" }, "devDependencies": { "@types/node": "^22.10.5", + "@types/ws": "^8.18.1", "drizzle-orm": "^0.38.4" } } diff --git a/packages/server/scripts/build.ts b/packages/server/scripts/build.ts index 5e20d61..9f21152 100644 --- a/packages/server/scripts/build.ts +++ b/packages/server/scripts/build.ts @@ -20,7 +20,9 @@ import { fileURLToPath } from "node:url"; const serverRoot = dirname(dirname(fileURLToPath(import.meta.url))); const dist = join(serverRoot, "dist"); -const EXTERNAL = ["better-sqlite3", "node-pty"]; // native — installed on the box +// native — installed on the box; the last two are `ws`'s OPTIONAL native speedups +// (it try/catch-requires them and falls back to pure JS), so leave them unbundled. +const EXTERNAL = ["better-sqlite3", "node-pty", "bufferutil", "utf-8-validate"]; rmSync(dist, { recursive: true, force: true }); mkdirSync(dist, { recursive: true }); diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 28d4aeb..55023e6 100755 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -22,10 +22,14 @@ import { existsSync, mkdirSync, openSync, realpathSync, unlinkSync } from "node: import { connect, createServer, type Socket } from "node:net"; import { homedir } from "node:os"; import { dirname, join } from "node:path"; +import { WebSocketServer } from "ws"; +import type { Dispatcher } from "./dispatcher"; import { createDispatcher } from "./dispatcher"; +import type { Engine } from "./engine"; import { createEngine } from "./engine"; import { serveRpc } from "./rpc"; import { socketServerTransport } from "./transport/socket"; +import { wsServerTransport } from "./transport/ws"; const SOCK = process.env.ATEAM_RPC_SOCK ?? join(homedir(), ".ateam", "rpc.sock"); @@ -102,6 +106,46 @@ async function runDaemon(): Promise { console.error(`[ateam] PTY daemon connect failed: ${(err as Error).message}`); }); }); + + maybeStartWsListener(engine, dispatcher); +} + +/** + * Opt-in WebSocket listener, for network clients that can't run `ateam attach` + * over SSH — the phone over Tailscale (React Native has no child `ssh`, but ships + * a WebSocket). OFF by default: the box stays listener-free and the desktop's + * SSH-only path is unchanged unless ATEAM_WS_ADDR is set. + * + * This socket carries NO auth of its own — auth is the network's job (a Tailscale + * ACL / a private interface), exactly as the unix socket trusts filesystem perms. + * So we REFUSE a wildcard bind: exposing an unauthenticated engine on 0.0.0.0 + * would hand it to the whole network. Bind to an explicit private address (the + * Tailscale IP) only. Same guard the reverted TCP listener used. + */ +function maybeStartWsListener(engine: Engine, dispatcher: Dispatcher): void { + const addr = process.env.ATEAM_WS_ADDR; + if (!addr) return; + const lastColon = addr.lastIndexOf(":"); + const host = lastColon > 0 ? addr.slice(0, lastColon) : ""; + const port = Number(addr.slice(lastColon + 1)); + if (!host || host === "0.0.0.0" || host === "::" || !Number.isInteger(port) || port <= 0) { + console.error( + "[ateam] refusing WS listen: set ATEAM_WS_ADDR to : where host is an " + + "explicit private address (e.g. the Tailscale IP) — never a wildcard (0.0.0.0/::)", + ); + process.exit(1); + } + const wss = new WebSocketServer({ host, port }); + wss.on("connection", (sock) => { + // Each client gets its own serveRpc; the engine (and its PTY sessions) is + // shared and outlives any single client — same contract as the socket path. + serveRpc(engine, dispatcher, wsServerTransport(sock)); + }); + wss.on("error", (err: Error) => { + console.error(`[ateam] WS listener error: ${err.message}`); + process.exit(1); + }); + wss.on("listening", () => console.log(`[ateam] daemon also listening on ws://${host}:${port}`)); } /** diff --git a/packages/server/src/connect-cli.ts b/packages/server/src/connect-cli.ts index 50bc4d5..43bcf33 100644 --- a/packages/server/src/connect-cli.ts +++ b/packages/server/src/connect-cli.ts @@ -18,7 +18,7 @@ // / node-pty) and runs under plain bun/node. // // bun packages/server/src/connect-cli.ts [alias] [--task ] [--terminal ] [--key ] -// default alias: hetzner-devbox +// default alias: devbox import { homedir } from "node:os"; import { type AteamApi, @@ -62,7 +62,7 @@ interface Args { } function parseArgs(argv: string[]): Args { - const args: Args = { alias: "hetzner-devbox" }; + const args: Args = { alias: "devbox" }; const rest = argv.slice(2); for (let i = 0; i < rest.length; i++) { const tok = rest[i]; diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 2cbef49..8861560 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -5,16 +5,18 @@ // Public API: build the engine, then a dispatcher over it. Each transport // (Electron ipcMain today, JSON-RPC over SSH next) forwards the engine's events // and adapts its own request channel to dispatcher.handle(). -export { createEngine } from "./engine"; -export type { Engine, EngineOptions } from "./engine"; -export { createDispatcher } from "./dispatcher"; + +export type { ConnectionDTO, ConnectionRecord, SshHost } from "./connections"; +export { listConnections, readSshHosts, recordConnection } from "./connections"; export type { Dispatcher } from "./dispatcher"; -export type { Services } from "./services"; -export { serveRpc } from "./rpc"; +export { createDispatcher } from "./dispatcher"; +export type { Engine, EngineOptions } from "./engine"; +export { createEngine } from "./engine"; export type { ServerTransport } from "./rpc"; -export { sshClientTransport } from "./transport/ssh"; -export type { SshClient, SshOptions } from "./transport/ssh"; -export { listConnections, readSshHosts, recordConnection } from "./connections"; -export type { ConnectionDTO, ConnectionRecord, SshHost } from "./connections"; +export { serveRpc } from "./rpc"; +export type { Services } from "./services"; export { socketClientTransport, socketServerTransport } from "./transport/socket"; +export type { SshClient, SshOptions } from "./transport/ssh"; +export { sshClientTransport } from "./transport/ssh"; export { streamClientTransport, streamServerTransport } from "./transport/stream"; +export { wsServerTransport } from "./transport/ws"; diff --git a/packages/server/src/transport/ws.ts b/packages/server/src/transport/ws.ts new file mode 100644 index 0000000..4c55288 --- /dev/null +++ b/packages/server/src/transport/ws.ts @@ -0,0 +1,32 @@ +// Server side of a WebSocket connection: one JSON frame per message. WebSocket is +// already message-framed, so — unlike socket.ts, which layers newline framing over +// a raw byte stream — there's nothing to delimit; each `message` IS one frame. +// This backs the daemon's opt-in WS listener (the phone's transport over Tailscale); +// the client half is @ateam/protocol's wsClientTransport, over the RN/browser global. + +import type { ClientFrame, ServerFrame } from "@ateam/protocol"; +import type { WebSocket } from "ws"; +import type { ServerTransport } from "../rpc"; + +/** Adapt one `ws` connection to a ServerTransport for serveRpc. */ +export function wsServerTransport(socket: WebSocket): ServerTransport { + return { + send(frame: ServerFrame) { + socket.send(JSON.stringify(frame)); + }, + onFrame(handler) { + socket.on("message", (data: unknown) => { + try { + handler(JSON.parse(String(data)) as ClientFrame); + } catch { + /* ignore malformed */ + } + }); + }, + onClose(handler) { + // close and error both mean the client is gone; ws fires 'close' after + // 'error' anyway, so listening on 'close' alone frees the subscriptions once. + socket.on("close", handler); + }, + }; +} diff --git a/packages/server/test/connections.test.ts b/packages/server/test/connections.test.ts index 40aa8af..ae58d97 100644 --- a/packages/server/test/connections.test.ts +++ b/packages/server/test/connections.test.ts @@ -17,9 +17,9 @@ describe("readSshHosts", () => { const cfg = writeConfig( [ "# a comment", - "Host hetzner-devbox", - " HostName 100.72.63.61", - " User pallaoro", + "Host devbox", + " HostName 100.64.0.1", + " User dev", "", "Host prod staging", " HostName example.com", @@ -30,8 +30,8 @@ describe("readSshHosts", () => { ); const hosts = readSshHosts(cfg); // Wildcard `*` stanza excluded; multi-alias stanza yields both, sharing HostName. - expect(hosts.map((h) => h.alias)).toEqual(["hetzner-devbox", "prod", "staging"]); - expect(hosts.find((h) => h.alias === "hetzner-devbox")?.hostName).toBe("100.72.63.61"); + expect(hosts.map((h) => h.alias)).toEqual(["devbox", "prod", "staging"]); + expect(hosts.find((h) => h.alias === "devbox")?.hostName).toBe("100.64.0.1"); expect(hosts.find((h) => h.alias === "prod")?.hostName).toBe("example.com"); expect(hosts.find((h) => h.alias === "staging")?.hostName).toBe("example.com"); }); diff --git a/packages/server/test/ws.test.ts b/packages/server/test/ws.test.ts new file mode 100644 index 0000000..178aa28 --- /dev/null +++ b/packages/server/test/ws.test.ts @@ -0,0 +1,87 @@ +import { describe, expect, it } from "bun:test"; +import { EventEmitter } from "node:events"; +import type { AddressInfo } from "node:net"; +import { type AteamDb, repo } from "@ateam/db"; +import { + buildAteamApi, + createRpcClient, + type NativeClientApi, + wsClientTransport, +} from "@ateam/protocol"; +import { WebSocketServer } from "ws"; +import { createTestDb } from "../../db/test/helpers/test-db"; +import { createDispatcher } from "../src/dispatcher"; +import type { Engine } from "../src/engine"; +import { serveRpc } from "../src/rpc"; +import { wsServerTransport } from "../src/transport/ws"; + +// The mobile shape: the phone speaks the platform-global WebSocket to the box's +// opt-in WS listener. This exercises the WHOLE path — wsServerTransport ↔ real ws +// server ↔ Bun's global WebSocket client ↔ wsClientTransport ↔ buildAteamApi — so +// it proves the transport the phone actually uses, not a stand-in. +function makeEngine(db: AteamDb): Engine { + const ee = new EventEmitter(); + return { + services: { db, pty: { has: () => false }, mergeQueue: {}, loopRunner: { describe: () => [] } }, + on: (event: string, cb: (p: unknown) => void) => { + ee.on(event, cb); + return () => ee.off(event, cb); + }, + sendTaskUpdated: (id: string) => { + const task = repo.getTask(db, id); + if (task) ee.emit("taskUpdated", { id: task.id, column: task.column }); + }, + sendLoopsUpdated: () => ee.emit("loopsUpdated", []), + } as unknown as Engine; +} + +const native: NativeClientApi = { + pathForFile: () => "", + pick: async () => null, + pickFiles: async () => [], + stageClipboardImage: async () => false, + stageImagePath: async () => false, +}; + +describe("buildAteamApi over a real WebSocket (the phone's transport)", () => { + it("round-trips typed calls and streams a task event over ws", async () => { + const db = createTestDb(); + const engine = makeEngine(db); + const wss = new WebSocketServer({ host: "127.0.0.1", port: 0 }); + wss.on("connection", (sock) => + serveRpc(engine, createDispatcher(engine), wsServerTransport(sock)), + ); + await new Promise((resolve) => wss.once("listening", resolve)); + const { port } = wss.address() as AddressInfo; + + const client = wsClientTransport(`ws://127.0.0.1:${port}`); + const api = buildAteamApi(createRpcClient(client.transport), native); + + const project = repo.upsertProject(db, { repoPath: "/r/a", name: "A" }); + const task = repo.createTask(db, { + projectId: project!.id, + name: "t", + slug: "t", + branch: "t", + baseBranch: "main", + worktreePath: "/r/a/w/t", + }); + + const updated: string[] = []; + api.events.onTaskUpdated((t) => updated.push(t.id)); + + // A call issued before the socket is OPEN must still land (frames queue and + // flush on open) — this is the connect-time handshake behavior. + const listed = await api.tasks.list(project!.id); + expect(listed.map((t) => t.id)).toEqual([task.id]); + + const moved = await api.tasks.setColumn(task.id, "review"); + expect(moved.column).toBe("review"); + // Give the event a tick to cross the socket back. + await new Promise((r) => setTimeout(r, 20)); + expect(updated).toContain(task.id); + + client.close(); + wss.close(); + }); +}); From afe06f33e03c6ad74870ef6cfd08bccfeecc85e2 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 16:43:57 +0200 Subject: [PATCH 24/83] =?UTF-8?q?feat(mobile):=20live=20terminal=20?= =?UTF-8?q?=E2=80=94=20attach=20to=20a=20task's=20agent=20session=20from?= =?UTF-8?q?=20the=20phone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tapping a task opens a real terminal on the box: if the task has a live agent session (its Claude Code TUI running) we ATTACH and replay its screen; otherwise we spawn a login shell. Detaching never kills the session, so the agent keeps working and you reattach later — the "task = live agent session" model, driven from the phone. Proven end-to-end on a physical iPhone: the full Claude Code TUI rendered in the app, running in a worktree on the Hetzner box, over Tailscale. - xterm.js renders inside a react-native-webview (a raw PTY stream is ANSI escapes — it needs a real terminal emulator). xterm + fit addon are inlined (scripts/gen-xterm-assets.mjs → src/xterm-assets.ts) because the webview is offline/CSP-restricted; terminal-html.ts assembles them + the bridge. - TerminalScreen.tsx wires the webview ↔ PTY with the same contract as the desktop Terminal.tsx and connect-cli: spawnShell/listForTask, snapshot + seq dedupe (buffer-until-ready), onData→write, fit→resize, onExit. TUI key toolbar (esc / ⇧tab / / / arrows / ^C) modeled on Termius, for keys the soft keyboard can't send. - App.tsx: task cards are pressable → open TerminalScreen for that task. - Deps: react-native-webview (native module → pod install on build), @xterm/xterm + @xterm/addon-fit (dist inlined). Metro bundle 561 modules / 2.57MB, mobile typecheck clean. --- apps/mobile/App.tsx | 21 +- apps/mobile/package-lock.json | 31 ++- apps/mobile/package.json | 5 +- apps/mobile/scripts/gen-xterm-assets.mjs | 33 +++ apps/mobile/src/TerminalScreen.tsx | 298 +++++++++++++++++++++++ apps/mobile/src/terminal-html.ts | 76 ++++++ apps/mobile/src/xterm-assets.ts | 6 + 7 files changed, 464 insertions(+), 6 deletions(-) create mode 100644 apps/mobile/scripts/gen-xterm-assets.mjs create mode 100644 apps/mobile/src/TerminalScreen.tsx create mode 100644 apps/mobile/src/terminal-html.ts create mode 100644 apps/mobile/src/xterm-assets.ts diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 2612001..3c7704a 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -24,6 +24,7 @@ import { View, } from "react-native"; import { type Connection, connect } from "./src/connection"; +import { TerminalScreen } from "./src/TerminalScreen"; const C = { bg: "#0c0c0e", @@ -113,9 +114,9 @@ function AgentTag({ agent }: { agent: string }) { ); } -function TaskCard({ task, tint }: { task: TaskDTO; tint: string }) { +function TaskCard({ task, tint, onOpen }: { task: TaskDTO; tint: string; onOpen: () => void }) { return ( - + @@ -126,7 +127,7 @@ function TaskCard({ task, tint }: { task: TaskDTO; tint: string }) { {task.branch} {taskNote(task)} - + ); } @@ -250,6 +251,7 @@ function BoardScreen({ loading, onOpenConnection, onRefresh, + onOpenTask, }: { host: string; agents: string[]; @@ -257,6 +259,7 @@ function BoardScreen({ loading: boolean; onOpenConnection: () => void; onRefresh: () => void; + onOpenTask: (task: TaskDTO) => void; }) { return ( @@ -305,7 +308,7 @@ function BoardScreen({ {inCol.length} {inCol.map((t) => ( - + onOpenTask(t)} /> ))} ); @@ -329,6 +332,7 @@ export default function App() { const [tasks, setTasks] = useState([]); const [agents, setAgents] = useState([]); const [loading, setLoading] = useState(false); + const [openTask, setOpenTask] = useState(null); const conn = useRef(null); // Pull the whole board: every project's tasks, flattened. Sorted newest-active @@ -385,6 +389,14 @@ export default function App() { } }, [host, port, refresh]); + // A tapped task opens its live terminal; the engine api comes from the live + // connection. Overlays the board (which stays mounted behind it). + if (openTask && conn.current) { + return ( + setOpenTask(null)} /> + ); + } + return view === "connect" ? ( setView("connect")} onRefresh={refresh} + onOpenTask={setOpenTask} /> ); } diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index db7137b..3387d9c 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -8,10 +8,13 @@ "name": "mobile", "version": "1.0.0", "dependencies": { + "@xterm/addon-fit": "^0.11.0", + "@xterm/xterm": "^6.0.0", "expo": "^52.0.49", "expo-status-bar": "~2.0.1", "react": "18.3.1", - "react-native": "0.76.9" + "react-native": "0.76.9", + "react-native-webview": "13.12.5" }, "devDependencies": { "@types/react": "~19.2.2", @@ -2935,6 +2938,19 @@ "node": ">=10.0.0" } }, + "node_modules/@xterm/addon-fit": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.11.0.tgz", + "integrity": "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g==" + }, + "node_modules/@xterm/xterm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-6.0.0.tgz", + "integrity": "sha512-TQwDdQGtwwDt+2cgKDLn0IRaSxYu1tSUjgKarSDkUM0ZNiSRXFpjxEsvc/Zgc5kq5omJ+V0a8/kIM2WD3sMOYg==", + "workspaces": [ + "addons/*" + ] + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -7671,6 +7687,19 @@ } } }, + "node_modules/react-native-webview": { + "version": "13.12.5", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.12.5.tgz", + "integrity": "sha512-INOKPom4dFyzkbxbkuQNfeRG9/iYnyRDzrDkJeyvSWgJAW2IDdJkWFJBS2v0RxIL4gqLgHkiIZDOfiLaNnw83Q==", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz", diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 7af71fd..32d57a7 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -3,10 +3,13 @@ "version": "1.0.0", "main": "index.ts", "dependencies": { + "@xterm/addon-fit": "^0.11.0", + "@xterm/xterm": "^6.0.0", "expo": "^52.0.49", "expo-status-bar": "~2.0.1", "react": "18.3.1", - "react-native": "0.76.9" + "react-native": "0.76.9", + "react-native-webview": "13.12.5" }, "devDependencies": { "@types/react": "~19.2.2", diff --git a/apps/mobile/scripts/gen-xterm-assets.mjs b/apps/mobile/scripts/gen-xterm-assets.mjs new file mode 100644 index 0000000..b24faa7 --- /dev/null +++ b/apps/mobile/scripts/gen-xterm-assets.mjs @@ -0,0 +1,33 @@ +// Generate src/xterm-assets.ts by inlining xterm.js + its CSS + the fit addon as +// string constants. The terminal renders inside a react-native-webview, which is +// offline and CSP-restricted — it can't pull xterm from a CDN or read node_modules +// at runtime — so the library source must be embedded in the JS bundle. +// +// JSON.stringify (not a template literal) makes each blob a safe JS string literal +// regardless of backticks/${} inside the minified source. +// +// Regenerate after bumping @xterm/*: node scripts/gen-xterm-assets.mjs +import { readFileSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = dirname(fileURLToPath(import.meta.url)); +const mobile = dirname(here); +const read = (p) => readFileSync(join(mobile, "node_modules", p), "utf8"); + +const xtermJs = read("@xterm/xterm/lib/xterm.js"); +const xtermCss = read("@xterm/xterm/css/xterm.css"); +const fitJs = read("@xterm/addon-fit/lib/addon-fit.js"); + +const out = `// GENERATED by scripts/gen-xterm-assets.mjs — do not edit by hand. +// xterm.js + CSS + the fit addon, inlined for the offline webview terminal. +/* biome-ignore-all lint: generated third-party bundle */ +export const XTERM_JS = ${JSON.stringify(xtermJs)}; +export const XTERM_CSS = ${JSON.stringify(xtermCss)}; +export const FIT_ADDON_JS = ${JSON.stringify(fitJs)}; +`; + +writeFileSync(join(mobile, "src", "xterm-assets.ts"), out); +console.log( + `wrote src/xterm-assets.ts (xterm ${(xtermJs.length / 1024) | 0}KB, css ${(xtermCss.length / 1024) | 0}KB, fit ${(fitJs.length / 1024) | 0}KB)`, +); diff --git a/apps/mobile/src/TerminalScreen.tsx b/apps/mobile/src/TerminalScreen.tsx new file mode 100644 index 0000000..294ce57 --- /dev/null +++ b/apps/mobile/src/TerminalScreen.tsx @@ -0,0 +1,298 @@ +// A live terminal on the box, for one task. Resolves the PTY the way the task +// model implies: if the task already has a live agent session (its Claude Code +// TUI running), ATTACH to it and replay its screen — you land in the running +// agent, not a fresh shell. Only if nothing is live do we spawn a login shell +// (type `claude` to start one). Detaching (Close/unmount) never kills the session, +// so the agent keeps working and you can reattach later — exactly like the desktop +// and connect-cli. +// +// xterm.js renders inside a WebView (a raw PTY stream is ANSI escapes — it needs a +// real terminal emulator). The bridge + snapshot/seq-dedupe mirror Terminal.tsx. + +import type { AteamApi, PtyDataEvent, TaskDTO } from "@ateam/protocol"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { + ActivityIndicator, + KeyboardAvoidingView, + Platform, + Pressable, + ScrollView, + StyleSheet, + Text, + View, +} from "react-native"; +import { WebView, type WebViewMessageEvent } from "react-native-webview"; +import { buildTerminalHtml } from "./terminal-html"; + +const C = { + bg: "#0c0c0e", + surface: "#141418", + sunken: "#1c1c22", + line: "#2a2a33", + ink: "#e6e6ea", + muted: "#9a9aa6", + faint: "#6a6a75", + accent: "#7c5cff", + red: "#f87171", +}; + +// TUI control bytes — the keys a soft keyboard can't send, modeled on the row +// Termius surfaces for the Claude TUI (esc / shift-tab / arrows / slash). +const KEYS: { label: string; bytes: string; wide?: boolean }[] = [ + { label: "esc", bytes: "\x1b" }, + { label: "⇧tab", bytes: "\x1b[Z" }, + { label: "/", bytes: "/" }, + { label: "←", bytes: "\x1b[D" }, + { label: "↑", bytes: "\x1b[A" }, + { label: "↓", bytes: "\x1b[B" }, + { label: "→", bytes: "\x1b[C" }, + { label: "^C", bytes: "\x03" }, +]; + +const HTML = buildTerminalHtml(); + +export function TerminalScreen({ + api, + task, + onClose, +}: { + api: AteamApi; + task: TaskDTO; + onClose: () => void; +}) { + const webRef = useRef(null); + const [terminalId, setTerminalId] = useState(null); + const [status, setStatus] = useState<"connecting" | "live" | "exited" | "error">("connecting"); + const [detail, setDetail] = useState("resolving session…"); + + // Snapshot/seq state (refs — must not trigger re-render on every PTY chunk). + const buffered = useRef([]); + const applied = useRef(false); + const lastSeq = useRef(-1); + + const inject = useCallback((data: string) => { + // injectJavaScript evals a JS string; JSON.stringify makes `data` a safe + // literal (control chars, quotes, newlines all escaped). `true;` suppresses + // the "no return value" warning. + webRef.current?.injectJavaScript(`window.__termWrite(${JSON.stringify(data)});true;`); + }, []); + + // Resolve the PTY (attach-if-live, else spawn) and subscribe to its stream. + useEffect(() => { + let cancelled = false; + let offData = () => {}; + let offExit = () => {}; + + (async () => { + try { + const live = await api.pty.listForTask(task.id); + let id = live[0]?.terminalId ?? null; + if (!id) { + setDetail("starting a shell on the box…"); + id = (await api.pty.spawnShell({ taskId: task.id })).terminalId; + } else { + setDetail("attaching to the live agent…"); + } + if (cancelled) return; + + // Subscribe BEFORE the snapshot so chunks arriving during it are buffered + // and replayed in order (seq-dedupe) — never doubled, never dropped. + offData = api.pty.onData((e) => { + if (e.terminalId !== id) return; + if (!applied.current) { + buffered.current.push(e); + return; + } + if (e.seq > lastSeq.current) { + lastSeq.current = e.seq; + inject(e.data); + } + }); + offExit = api.pty.onExit((e) => { + if (e.terminalId === id) { + setStatus("exited"); + setDetail(`session exited (code ${e.exitCode})`); + } + }); + + setTerminalId(id); + setStatus("live"); + } catch (err) { + if (cancelled) return; + setStatus("error"); + setDetail(err instanceof Error ? err.message : String(err)); + } + })(); + + return () => { + cancelled = true; + offData(); + offExit(); + // Detach only — the session (and the running agent) lives on. + }; + }, [api, task.id, inject]); + + // Bridge messages from the webview (xterm) back to the PTY. + const onMessage = useCallback( + async (e: WebViewMessageEvent) => { + const id = terminalId; + if (!id) return; + let msg: { type: string; data?: string; cols?: number; rows?: number }; + try { + msg = JSON.parse(e.nativeEvent.data); + } catch { + return; + } + if (msg.type === "input" && typeof msg.data === "string") { + api.pty.write(id, msg.data); + } else if (msg.type === "resize" && msg.cols && msg.rows) { + api.pty.resize(id, msg.cols, msg.rows); + } else if (msg.type === "ready") { + // xterm is mounted: size the PTY, paint its current screen, then flush + // any chunks that streamed in while we were setting up. + if (msg.cols && msg.rows) api.pty.resize(id, msg.cols, msg.rows); + try { + const snap = await api.pty.snapshot(id); + if (snap.data) inject(snap.data); + lastSeq.current = snap.seq; + for (const c of buffered.current) { + if (c.seq > lastSeq.current) { + lastSeq.current = c.seq; + inject(c.data); + } + } + } finally { + buffered.current = []; + applied.current = true; + } + } + }, + [api, terminalId, inject], + ); + + const send = useCallback( + (bytes: string) => { + if (terminalId) { + api.pty.write(terminalId, bytes); + webRef.current?.injectJavaScript("window.__termFocus();true;"); + } + }, + [api, terminalId], + ); + + return ( + + + + ‹ Board + + + {task.name} + + + + + + {terminalId ? ( + + + {/* TUI key toolbar (soft keyboard can't send these). */} + + {KEYS.map((k) => ( + send(k.bytes)} hitSlop={4}> + {k.label} + + ))} + + + ); +} + +function statusColor(s: "connecting" | "live" | "exited" | "error"): string { + if (s === "live") return "#4ade80"; + if (s === "error") return C.red; + if (s === "exited") return C.faint; + return "#fbbf24"; +} + +const styles = StyleSheet.create({ + root: { flex: 1, backgroundColor: C.bg, paddingTop: 60 }, + header: { + flexDirection: "row", + alignItems: "center", + gap: 10, + paddingHorizontal: 14, + paddingBottom: 12, + borderBottomWidth: 1, + borderBottomColor: C.line, + }, + closeBtn: { paddingVertical: 4, paddingRight: 4 }, + closeText: { color: C.accent, fontSize: 15, fontWeight: "600" }, + title: { color: C.ink, fontSize: 15, fontWeight: "700", flex: 1 }, + dot: { width: 8, height: 8, borderRadius: 4 }, + termWrap: { flex: 1, backgroundColor: "#000" }, + web: { flex: 1, backgroundColor: "#000" }, + center: { flex: 1, alignItems: "center", justifyContent: "center", gap: 12 }, + hint: { color: C.muted, fontSize: 13 }, + errText: { + color: C.red, + fontSize: 13, + textAlign: "center", + paddingHorizontal: 24, + lineHeight: 18, + }, + keyBar: { + maxHeight: 48, + backgroundColor: C.surface, + borderTopWidth: 1, + borderTopColor: C.line, + }, + keyBarContent: { alignItems: "center", gap: 8, paddingHorizontal: 10, paddingVertical: 7 }, + key: { + minWidth: 44, + height: 34, + paddingHorizontal: 12, + borderRadius: 8, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + keyText: { color: C.ink, fontSize: 14, fontWeight: "600" }, +}); diff --git a/apps/mobile/src/terminal-html.ts b/apps/mobile/src/terminal-html.ts new file mode 100644 index 0000000..2d51bf8 --- /dev/null +++ b/apps/mobile/src/terminal-html.ts @@ -0,0 +1,76 @@ +// The HTML document that runs inside the terminal WebView: xterm.js + the fit +// addon (both inlined, offline) plus a small bridge to the React Native host. +// +// Bridge protocol (mirrors the desktop Terminal.tsx + connect-cli exactly): +// RN → webview window.__termWrite(str) write PTY bytes into xterm +// window.__termFit() refit to the viewport, report new size +// window.__termFocus() focus (pop the keyboard) +// webview → RN postMessage {type:"ready", cols, rows} xterm mounted +// postMessage {type:"input", data} user keystrokes → pty.write +// postMessage {type:"resize", cols, rows} fit changed → pty.resize +import { FIT_ADDON_JS, XTERM_CSS, XTERM_JS } from "./xterm-assets"; + +// Terminal look matches the desktop renderer (black bg, #e6e6ea fg, mono). +export function buildTerminalHtml(): string { + return ` + + + + + + + +

    + + + + +`; +} diff --git a/apps/mobile/src/xterm-assets.ts b/apps/mobile/src/xterm-assets.ts new file mode 100644 index 0000000..a98363a --- /dev/null +++ b/apps/mobile/src/xterm-assets.ts @@ -0,0 +1,6 @@ +// GENERATED by scripts/gen-xterm-assets.mjs — do not edit by hand. +// xterm.js + CSS + the fit addon, inlined for the offline webview terminal. +/* biome-ignore-all lint: generated third-party bundle */ +export const XTERM_JS = "!function(e,t){if(\"object\"==typeof exports&&\"object\"==typeof module)module.exports=t();else if(\"function\"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)(\"object\"==typeof exports?exports:e)[s]=i[s]}}(globalThis,(()=>(()=>{\"use strict\";var e={2840:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.AccessibilityManager=void 0;const n=i(7721),o=i(4292),a=i(7150),l=i(7098),h=i(6501),c=i(7093);let d=class extends a.Disposable{constructor(e,t,i,s){super(),this._terminal=e,this._coreBrowserService=i,this._renderService=s,this._rowColumns=new WeakMap,this._liveRegionLineCount=0,this._charsToConsume=[],this._charsToAnnounce=\"\";const r=this._coreBrowserService.mainDocument;this._accessibilityContainer=r.createElement(\"div\"),this._accessibilityContainer.classList.add(\"xterm-accessibility\"),this._rowContainer=r.createElement(\"div\"),this._rowContainer.setAttribute(\"role\",\"list\"),this._rowContainer.classList.add(\"xterm-accessibility-tree\"),this._rowElements=[];for(let e=0;ethis._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener(\"focus\",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener(\"focus\",this._bottomBoundaryFocusListener),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=r.createElement(\"div\"),this._liveRegion.classList.add(\"live-region\"),this._liveRegion.setAttribute(\"aria-live\",\"assertive\"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this._register(new o.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error(\"Cannot enable accessibility before Terminal.open\");this._terminal.element.insertAdjacentElement(\"afterbegin\",this._accessibilityContainer),this._register(this._terminal.onResize((e=>this._handleResize(e.rows)))),this._register(this._terminal.onRender((e=>this._refreshRows(e.start,e.end)))),this._register(this._terminal.onScroll((()=>this._refreshRows()))),this._register(this._terminal.onA11yChar((e=>this._handleChar(e)))),this._register(this._terminal.onLineFeed((()=>this._handleChar(\"\\n\")))),this._register(this._terminal.onA11yTab((e=>this._handleTab(e)))),this._register(this._terminal.onKey((e=>this._handleKey(e.key)))),this._register(this._terminal.onBlur((()=>this._clearLiveRegion()))),this._register(this._renderService.onDimensionsChange((()=>this._refreshRowsDimensions()))),this._register((0,c.addDisposableListener)(r,\"selectionchange\",(()=>this._handleSelectionChange()))),this._register(this._coreBrowserService.onDprChange((()=>this._refreshRowsDimensions()))),this._refreshRowsDimensions(),this._refreshRows(),this._register((0,a.toDisposable)((()=>{this._accessibilityContainer.remove(),this._rowElements.length=0})))}_handleTab(e){for(let t=0;t0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,\"\\n\"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent+=n.tooMuchOutput.get())))}_clearLiveRegion(){this._liveRegion.textContent=\"\",this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.lines.get(i.ydisp+r),t=[],n=e?.translateToString(!0,void 0,void 0,t)||\"\",o=(i.ydisp+r+1).toString(),a=this._rowElements[r];a&&(0===n.length?(a.textContent=\" \",this._rowColumns.set(a,[0,1])):(a.textContent=n,this._rowColumns.set(a,t)),a.setAttribute(\"aria-posinset\",o),a.setAttribute(\"aria-setsize\",s),this._alignRowWidth(a))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce=\"\")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute(\"aria-posinset\")===(0===t?\"1\":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,n;if(0===t?(r=i,n=this._rowElements.pop(),this._rowContainer.removeChild(n)):(r=this._rowElements.shift(),n=i,this._rowContainer.removeChild(r)),r.removeEventListener(\"focus\",this._topBoundaryFocusListener),n.removeEventListener(\"focus\",this._bottomBoundaryFocusListener),0===t){const e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement(\"afterbegin\",e)}else{const e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener(\"focus\",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener(\"focus\",this._bottomBoundaryFocusListener),this._terminal.scrollLines(0===t?-1:1),this._rowElements[0===t?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleSelectionChange(){if(0===this._rowElements.length)return;const e=this._coreBrowserService.mainDocument.getSelection();if(!e)return;if(e.isCollapsed)return void(this._rowContainer.contains(e.anchorNode)&&this._terminal.clearSelection());if(!e.anchorNode||!e.focusNode)return void console.error(\"anchorNode and/or focusNode are null\");let t={node:e.anchorNode,offset:e.anchorOffset},i={node:e.focusNode,offset:e.focusOffset};if((t.node.compareDocumentPosition(i.node)&Node.DOCUMENT_POSITION_PRECEDING||t.node===i.node&&t.offset>i.offset)&&([t,i]=[i,t]),t.node.compareDocumentPosition(this._rowElements[0])&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_FOLLOWING)&&(t={node:this._rowElements[0].childNodes[0],offset:0}),!this._rowContainer.contains(t.node))return;const s=this._rowElements.slice(-1)[0];if(i.node.compareDocumentPosition(s)&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_PRECEDING)&&(i={node:s,offset:s.textContent?.length??0}),!this._rowContainer.contains(i.node))return;const r=({node:e,offset:t})=>{const i=e instanceof Text?e.parentNode:e;let s=parseInt(i?.getAttribute(\"aria-posinset\"),10)-1;if(isNaN(s))return console.warn(\"row is invalid. Race condition?\"),null;const r=this._rowColumns.get(i);if(!r)return console.warn(\"columns is null. Race condition?\"),null;let n=t=this._terminal.cols&&(++s,n=0),{row:s,column:n}},n=r(t),o=r(i);if(n&&o){if(n.row>o.row||n.row===o.row&&n.column>=o.column)throw new Error(\"invalid range\");this._terminal.select(n.column,n.row,(o.row-n.row)*this._terminal.cols-n.column+o.column)}}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener(\"focus\",this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;ee;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener(\"focus\",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const e=this._coreBrowserService.mainDocument.createElement(\"div\");return e.setAttribute(\"role\",\"listitem\"),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){Object.assign(this._accessibilityContainer.style,{width:`${this._renderService.dimensions.css.canvas.width}px`,fontSize:`${this._terminal.options.fontSize}px`}),this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;e{function i(e){return e.replace(/\\r?\\n/g,\"\\r\")}function s(e,t){return t?\"\u001b[200~\"+e+\"\u001b[201~\":e}function r(e,t,r,n){e=s(e=i(e),r.decPrivateModes.bracketedPasteMode&&!0!==n.rawOptions.ignoreBracketedPasteMode),r.triggerDataEvent(e,!0),t.value=\"\"}function n(e,t,i){const s=i.getBoundingClientRect(),r=e.clientX-s.left-10,n=e.clientY-s.top-10;t.style.width=\"20px\",t.style.height=\"20px\",t.style.left=`${r}px`,t.style.top=`${n}px`,t.style.zIndex=\"1000\",t.focus()}Object.defineProperty(t,\"__esModule\",{value:!0}),t.prepareTextForTerminal=i,t.bracketTextForPaste=s,t.copyHandler=function(e,t){e.clipboardData&&e.clipboardData.setData(\"text/plain\",t.selectionText),e.preventDefault()},t.handlePasteEvent=function(e,t,i,s){e.stopPropagation(),e.clipboardData&&r(e.clipboardData.getData(\"text/plain\"),t,i,s)},t.paste=r,t.moveTextAreaUnderMouseCursor=n,t.rightClickHandler=function(e,t,i,s,r){n(e,t,i),r&&s.rightClickSelect(e),t.value=s.selectionText,t.select()}},7174:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ColorContrastCache=void 0;const s=i(7710);t.ColorContrastCache=class{constructor(){this._color=new s.TwoKeyMap,this._css=new s.TwoKeyMap}setCss(e,t,i){this._css.set(e,t,i)}getCss(e,t){return this._css.get(e,t)}setColor(e,t,i){this._color.set(e,t,i)}getColor(e,t){return this._color.get(e,t)}clear(){this._color.clear(),this._css.clear()}}},1718:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CoreBrowserTerminal=void 0;const s=i(7861),r=i(7721),n=i(3285),o=i(4017),a=i(4196),l=i(9925),h=i(3618),c=i(3955),d=i(4792),u=i(945),_=i(9574),f=i(9820),p=i(9784),g=i(5783),m=i(2079),v=i(7098),S=i(9078),b=i(4103),C=i(5777),y=i(701),w=i(6107),E=i(3534),D=i(706),L=i(8693),R=i(4720),A=i(6501),T=i(2486),k=i(2840),M=i(8906),O=i(802),I=i(7093),P=i(7150);class x extends C.CoreTerminal{get linkifier(){return this._linkifier.value}get onFocus(){return this._onFocus.event}get onBlur(){return this._onBlur.event}get onA11yChar(){return this._onA11yCharEmitter.event}get onA11yTab(){return this._onA11yTabEmitter.event}get onWillOpen(){return this._onWillOpen.event}constructor(e={}){super(e),this._linkifier=this._register(new P.MutableDisposable),this.browser=y,this._keyDownHandled=!1,this._keyDownSeen=!1,this._keyPressHandled=!1,this._unprocessedDeadKey=!1,this._accessibilityManager=this._register(new P.MutableDisposable),this._onCursorMove=this._register(new O.Emitter),this.onCursorMove=this._onCursorMove.event,this._onKey=this._register(new O.Emitter),this.onKey=this._onKey.event,this._onRender=this._register(new O.Emitter),this.onRender=this._onRender.event,this._onSelectionChange=this._register(new O.Emitter),this.onSelectionChange=this._onSelectionChange.event,this._onTitleChange=this._register(new O.Emitter),this.onTitleChange=this._onTitleChange.event,this._onBell=this._register(new O.Emitter),this.onBell=this._onBell.event,this._onFocus=this._register(new O.Emitter),this._onBlur=this._register(new O.Emitter),this._onA11yCharEmitter=this._register(new O.Emitter),this._onA11yTabEmitter=this._register(new O.Emitter),this._onWillOpen=this._register(new O.Emitter),this._setup(),this._decorationService=this._instantiationService.createInstance(R.DecorationService),this._instantiationService.setService(A.IDecorationService,this._decorationService),this._linkProviderService=this._instantiationService.createInstance(f.LinkProviderService),this._instantiationService.setService(v.ILinkProviderService,this._linkProviderService),this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(n.OscLinkProvider)),this._register(this._inputHandler.onRequestBell((()=>this._onBell.fire()))),this._register(this._inputHandler.onRequestRefreshRows((e=>this.refresh(e?.start??0,e?.end??this.rows-1)))),this._register(this._inputHandler.onRequestSendFocus((()=>this._reportFocus()))),this._register(this._inputHandler.onRequestReset((()=>this.reset()))),this._register(this._inputHandler.onRequestWindowsOptionsReport((e=>this._reportWindowsOptions(e)))),this._register(this._inputHandler.onColor((e=>this._handleColorEvent(e)))),this._register(O.Event.forward(this._inputHandler.onCursorMove,this._onCursorMove)),this._register(O.Event.forward(this._inputHandler.onTitleChange,this._onTitleChange)),this._register(O.Event.forward(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this._register(O.Event.forward(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this._register(this._bufferService.onResize((e=>this._afterResize(e.cols,e.rows)))),this._register((0,P.toDisposable)((()=>{this._customKeyEventHandler=void 0,this.element?.parentNode?.removeChild(this.element)})))}_handleColorEvent(e){if(this._themeService)for(const t of e){let e,i=\"\";switch(t.index){case 256:e=\"foreground\",i=\"10\";break;case 257:e=\"background\",i=\"11\";break;case 258:e=\"cursor\",i=\"12\";break;default:e=\"ansi\",i=\"4;\"+t.index}switch(t.type){case 0:const s=b.color.toColorRGB(\"ansi\"===e?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`${E.C0.ESC}]${i};${(0,L.toRgbString)(s)}${E.C1_ESCAPED.ST}`);break;case 1:if(\"ansi\"===e)this._themeService.modifyColors((e=>e.ansi[t.index]=b.channels.toColor(...t.color)));else{const i=e;this._themeService.modifyColors((e=>e[i]=b.channels.toColor(...t.color)))}break;case 2:this._themeService.restoreColor(t.index)}}}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(k.AccessibilityManager,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(E.C0.ESC+\"[I\"),this.element.classList.add(\"focus\"),this._showCursor(),this._onFocus.fire()}blur(){return this.textarea?.blur()}_handleTextAreaBlur(){this.textarea.value=\"\",this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent(E.C0.ESC+\"[O\"),this.element.classList.remove(\"focus\"),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;const e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;const i=Math.min(this.buffer.x,this.cols-1),s=this._renderService.dimensions.css.cell.height,r=t.getWidth(i),n=this._renderService.dimensions.css.cell.width*r,o=this.buffer.y*this._renderService.dimensions.css.cell.height,a=i*this._renderService.dimensions.css.cell.width;this.textarea.style.left=a+\"px\",this.textarea.style.top=o+\"px\",this.textarea.style.width=n+\"px\",this.textarea.style.height=s+\"px\",this.textarea.style.lineHeight=s+\"px\",this.textarea.style.zIndex=\"-5\"}_initGlobal(){this._bindKeys(),this._register((0,I.addDisposableListener)(this.element,\"copy\",(e=>{this.hasSelection()&&(0,s.copyHandler)(e,this._selectionService)})));const e=e=>(0,s.handlePasteEvent)(e,this.textarea,this.coreService,this.optionsService);this._register((0,I.addDisposableListener)(this.textarea,\"paste\",e)),this._register((0,I.addDisposableListener)(this.element,\"paste\",e)),y.isFirefox?this._register((0,I.addDisposableListener)(this.element,\"mousedown\",(e=>{2===e.button&&(0,s.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)}))):this._register((0,I.addDisposableListener)(this.element,\"contextmenu\",(e=>{(0,s.rightClickHandler)(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)}))),y.isLinux&&this._register((0,I.addDisposableListener)(this.element,\"auxclick\",(e=>{1===e.button&&(0,s.moveTextAreaUnderMouseCursor)(e,this.textarea,this.screenElement)})))}_bindKeys(){this._register((0,I.addDisposableListener)(this.textarea,\"keyup\",(e=>this._keyUp(e)),!0)),this._register((0,I.addDisposableListener)(this.textarea,\"keydown\",(e=>this._keyDown(e)),!0)),this._register((0,I.addDisposableListener)(this.textarea,\"keypress\",(e=>this._keyPress(e)),!0)),this._register((0,I.addDisposableListener)(this.textarea,\"compositionstart\",(()=>this._compositionHelper.compositionstart()))),this._register((0,I.addDisposableListener)(this.textarea,\"compositionupdate\",(e=>this._compositionHelper.compositionupdate(e)))),this._register((0,I.addDisposableListener)(this.textarea,\"compositionend\",(()=>this._compositionHelper.compositionend()))),this._register((0,I.addDisposableListener)(this.textarea,\"input\",(e=>this._inputEvent(e)),!0)),this._register(this.onRender((()=>this._compositionHelper.updateCompositionElements())))}open(e){if(!e)throw new Error(\"Terminal requires a parent element.\");if(e.isConnected||this._logService.debug(\"Terminal.open was called on an element that was not attached to the DOM\"),this.element?.ownerDocument.defaultView&&this._coreBrowserService)return void(this.element.ownerDocument.defaultView!==this._coreBrowserService.window&&(this._coreBrowserService.window=this.element.ownerDocument.defaultView));this._document=e.ownerDocument,this.options.documentOverride&&this.options.documentOverride instanceof Document&&(this._document=this.optionsService.rawOptions.documentOverride),this.element=this._document.createElement(\"div\"),this.element.dir=\"ltr\",this.element.classList.add(\"terminal\"),this.element.classList.add(\"xterm\"),e.appendChild(this.element);const t=this._document.createDocumentFragment();this._viewportElement=this._document.createElement(\"div\"),this._viewportElement.classList.add(\"xterm-viewport\"),t.appendChild(this._viewportElement),this.screenElement=this._document.createElement(\"div\"),this.screenElement.classList.add(\"xterm-screen\"),this._register((0,I.addDisposableListener)(this.screenElement,\"mousemove\",(e=>this.updateCursorStyle(e)))),this._helperContainer=this._document.createElement(\"div\"),this._helperContainer.classList.add(\"xterm-helpers\"),this.screenElement.appendChild(this._helperContainer),t.appendChild(this.screenElement);const i=this.textarea=this._document.createElement(\"textarea\");this.textarea.classList.add(\"xterm-helper-textarea\"),this.textarea.setAttribute(\"aria-label\",r.promptLabel.get()),y.isChromeOS||this.textarea.setAttribute(\"aria-multiline\",\"false\"),this.textarea.setAttribute(\"autocorrect\",\"off\"),this.textarea.setAttribute(\"autocapitalize\",\"off\"),this.textarea.setAttribute(\"spellcheck\",\"false\"),this.textarea.tabIndex=0,this._register(this.optionsService.onSpecificOptionChange(\"disableStdin\",(()=>i.readOnly=this.optionsService.rawOptions.disableStdin))),this.textarea.readOnly=this.optionsService.rawOptions.disableStdin,this._coreBrowserService=this._register(this._instantiationService.createInstance(_.CoreBrowserService,this.textarea,e.ownerDocument.defaultView??window,this._document??\"undefined\"!=typeof window?window.document:null)),this._instantiationService.setService(v.ICoreBrowserService,this._coreBrowserService),this._register((0,I.addDisposableListener)(this.textarea,\"focus\",(e=>this._handleTextAreaFocus(e)))),this._register((0,I.addDisposableListener)(this.textarea,\"blur\",(()=>this._handleTextAreaBlur()))),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(d.CharSizeService,this._document,this._helperContainer),this._instantiationService.setService(v.ICharSizeService,this._charSizeService),this._themeService=this._instantiationService.createInstance(S.ThemeService),this._instantiationService.setService(v.IThemeService,this._themeService),this._characterJoinerService=this._instantiationService.createInstance(u.CharacterJoinerService),this._instantiationService.setService(v.ICharacterJoinerService,this._characterJoinerService),this._renderService=this._register(this._instantiationService.createInstance(g.RenderService,this.rows,this.screenElement)),this._instantiationService.setService(v.IRenderService,this._renderService),this._register(this._renderService.onRenderedViewportChange((e=>this._onRender.fire(e)))),this.onResize((e=>this._renderService.resize(e.cols,e.rows))),this._compositionView=this._document.createElement(\"div\"),this._compositionView.classList.add(\"composition-view\"),this._compositionHelper=this._instantiationService.createInstance(h.CompositionHelper,this.textarea,this._compositionView),this._helperContainer.appendChild(this._compositionView),this._mouseService=this._instantiationService.createInstance(p.MouseService),this._instantiationService.setService(v.IMouseService,this._mouseService);const s=this._linkifier.value=this._register(this._instantiationService.createInstance(M.Linkifier,this.screenElement));this.element.appendChild(t);try{this._onWillOpen.fire(this.element)}catch{}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._register(this.onCursorMove((()=>{this._renderService.handleCursorMove(),this._syncTextArea()}))),this._register(this.onResize((()=>this._renderService.handleResize(this.cols,this.rows)))),this._register(this.onBlur((()=>this._renderService.handleBlur()))),this._register(this.onFocus((()=>this._renderService.handleFocus()))),this._viewport=this._register(this._instantiationService.createInstance(o.Viewport,this.element,this.screenElement)),this._register(this._viewport.onRequestScrollLines((e=>{super.scrollLines(e,!1),this.refresh(0,this.rows-1)}))),this._selectionService=this._register(this._instantiationService.createInstance(m.SelectionService,this.element,this.screenElement,s)),this._instantiationService.setService(v.ISelectionService,this._selectionService),this._register(this._selectionService.onRequestScrollLines((e=>this.scrollLines(e.amount,e.suppressScrollEvent)))),this._register(this._selectionService.onSelectionChange((()=>this._onSelectionChange.fire()))),this._register(this._selectionService.onRequestRedraw((e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode)))),this._register(this._selectionService.onLinuxMouseSelection((e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()}))),this._register(O.Event.any(this._onScroll.event,this._inputHandler.onScroll)((()=>{this._selectionService.refresh(),this._viewport?.queueSync()}))),this._register(this._instantiationService.createInstance(a.BufferDecorationRenderer,this.screenElement)),this._register((0,I.addDisposableListener)(this.element,\"mousedown\",(e=>this._selectionService.handleMouseDown(e)))),this.coreMouseService.areMouseEventsActive?(this._selectionService.disable(),this.element.classList.add(\"enable-mouse-events\")):this._selectionService.enable(),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(k.AccessibilityManager,this)),this._register(this.optionsService.onSpecificOptionChange(\"screenReaderMode\",(e=>this._handleScreenReaderModeOptionChange(e)))),this.options.overviewRuler.width&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(l.OverviewRulerRenderer,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange(\"overviewRuler\",(e=>{!this._overviewRulerRenderer&&e&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(l.OverviewRulerRenderer,this._viewportElement,this.screenElement)))})),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this.bindMouse()}_createRenderer(){return this._instantiationService.createInstance(c.DomRenderer,this,this._document,this.element,this.screenElement,this._viewportElement,this._helperContainer,this.linkifier)}bindMouse(){const e=this,t=this.element;function i(t){const i=e._mouseService.getMouseReportCoords(t,e.screenElement);if(!i)return!1;let s,r;switch(t.overrideType||t.type){case\"mousemove\":r=32,void 0===t.buttons?(s=3,void 0!==t.button&&(s=t.button<3?t.button:3)):s=1&t.buttons?0:4&t.buttons?1:2&t.buttons?2:3;break;case\"mouseup\":r=0,s=t.button<3?t.button:3;break;case\"mousedown\":r=1,s=t.button<3?t.button:3;break;case\"wheel\":if(e._customWheelEventHandler&&!1===e._customWheelEventHandler(t))return!1;const i=t.deltaY;if(0===i)return!1;if(0===e.coreMouseService.consumeWheelEvent(t,e._renderService?.dimensions?.device?.cell?.height,e._coreBrowserService?.dpr))return!1;r=i<0?0:1,s=4;break;default:return!1}return!(void 0===r||void 0===s||s>4)&&e.coreMouseService.triggerMouseEvent({col:i.col,row:i.row,x:i.x,y:i.y,button:s,action:r,ctrl:t.ctrlKey,alt:t.altKey,shift:t.shiftKey})}const s={mouseup:null,wheel:null,mousedrag:null,mousemove:null},r={mouseup:e=>(i(e),e.buttons||(this._document.removeEventListener(\"mouseup\",s.mouseup),s.mousedrag&&this._document.removeEventListener(\"mousemove\",s.mousedrag)),this.cancel(e)),wheel:e=>(i(e),this.cancel(e,!0)),mousedrag:e=>{e.buttons&&i(e)},mousemove:e=>{e.buttons||i(e)}};this._register(this.coreMouseService.onProtocolChange((e=>{e?(\"debug\"===this.optionsService.rawOptions.logLevel&&this._logService.debug(\"Binding to mouse events:\",this.coreMouseService.explainEvents(e)),this.element.classList.add(\"enable-mouse-events\"),this._selectionService.disable()):(this._logService.debug(\"Unbinding from mouse events.\"),this.element.classList.remove(\"enable-mouse-events\"),this._selectionService.enable()),8&e?s.mousemove||(t.addEventListener(\"mousemove\",r.mousemove),s.mousemove=r.mousemove):(t.removeEventListener(\"mousemove\",s.mousemove),s.mousemove=null),16&e?s.wheel||(t.addEventListener(\"wheel\",r.wheel,{passive:!1}),s.wheel=r.wheel):(t.removeEventListener(\"wheel\",s.wheel),s.wheel=null),2&e?s.mouseup||(s.mouseup=r.mouseup):(this._document.removeEventListener(\"mouseup\",s.mouseup),s.mouseup=null),4&e?s.mousedrag||(s.mousedrag=r.mousedrag):(this._document.removeEventListener(\"mousemove\",s.mousedrag),s.mousedrag=null)}))),this.coreMouseService.activeProtocol=this.coreMouseService.activeProtocol,this._register((0,I.addDisposableListener)(t,\"mousedown\",(e=>{if(e.preventDefault(),this.focus(),this.coreMouseService.areMouseEventsActive&&!this._selectionService.shouldForceSelection(e))return i(e),s.mouseup&&this._document.addEventListener(\"mouseup\",s.mouseup),s.mousedrag&&this._document.addEventListener(\"mousemove\",s.mousedrag),this.cancel(e)}))),this._register((0,I.addDisposableListener)(t,\"wheel\",(t=>{if(!s.wheel){if(this._customWheelEventHandler&&!1===this._customWheelEventHandler(t))return!1;if(!this.buffer.hasScrollback){if(0===t.deltaY)return!1;if(0===e.coreMouseService.consumeWheelEvent(t,e._renderService?.dimensions?.device?.cell?.height,e._coreBrowserService?.dpr))return this.cancel(t,!0);const i=E.C0.ESC+(this.coreService.decPrivateModes.applicationCursorKeys?\"O\":\"[\")+(t.deltaY<0?\"A\":\"B\");return this.coreService.triggerDataEvent(i,!0),this.cancel(t,!0)}}}),{passive:!1}))}refresh(e,t){this._renderService?.refreshRows(e,t)}updateCursorStyle(e){this._selectionService?.shouldColumnSelect(e)?this.element.classList.add(\"column-select\"):this.element.classList.remove(\"column-select\")}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t){this._viewport?this._viewport.scrollLines(e):super.scrollLines(e,t),this.refresh(0,this.rows-1)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){e&&this._viewport?this._viewport.scrollToLine(this.buffer.ybase,!0):this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}paste(e){(0,s.paste)(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}attachCustomWheelEventHandler(e){this._customWheelEventHandler=e}registerLinkProvider(e){return this._linkProviderService.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw new Error(\"Terminal must be opened first\");const t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw new Error(\"Terminal must be opened first\");this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return!!this._selectionService&&this._selectionService.hasSelection}select(e,t,i){this._selectionService.setSelection(e,t,i)}getSelection(){return this._selectionService?this._selectionService.selectionText:\"\"}getSelectionPosition(){if(this._selectionService&&this._selectionService.hasSelection)return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){this._selectionService?.clearSelection()}selectAll(){this._selectionService?.selectAll()}selectLines(e,t){this._selectionService?.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;const t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(!0),!1;t||\"Dead\"!==e.key&&\"AltGraph\"!==e.key||(this._unprocessedDeadKey=!0);const i=(0,D.evaluateKeyboardEvent)(e,this.coreService.decPrivateModes.applicationCursorKeys,this.browser.isMac,this.options.macOptionIsMeta);if(this.updateCursorStyle(e),3===i.type||2===i.type){const t=this.rows-1;return this.scrollLines(2===i.type?-t:t),this.cancel(e,!0)}return 1===i.type&&this.selectAll(),!!this._isThirdLevelShift(this.browser,e)||(i.cancel&&this.cancel(e,!0),!i.key||!!(e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&1===e.key.length&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)||(this._unprocessedDeadKey?(this._unprocessedDeadKey=!1,!0):(i.key!==E.C0.ETX&&i.key!==E.C0.CR||(this.textarea.value=\"\"),this._onKey.fire({key:i.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(i.key,!0),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey?this.cancel(e,!0):void(this._keyDownHandled=!0))))}_isThirdLevelShift(e,t){const i=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState(\"AltGraph\");return\"keypress\"===t.type?i:i&&(!t.keyCode||t.keyCode>47)}_keyUp(e){this._keyDownSeen=!1,this._customKeyEventHandler&&!1===this._customKeyEventHandler(e)||(function(e){return 16===e.keyCode||17===e.keyCode||18===e.keyCode}(e)||this.focus(),this.updateCursorStyle(e),this._keyPressHandled=!1)}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled)return!1;if(this._customKeyEventHandler&&!1===this._customKeyEventHandler(e))return!1;if(this.cancel(e),e.charCode)t=e.charCode;else if(null===e.which||void 0===e.which)t=e.keyCode;else{if(0===e.which||0===e.charCode)return!1;t=e.which}return!(!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)||(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,0))}_inputEvent(e){if(e.data&&\"insertText\"===e.inputType&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;const t=e.data;return this.coreService.triggerDataEvent(t,!0),this.cancel(e),!0}return!1}resize(e,t){e!==this.cols||t!==this.rows?super.resize(e,t):this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure()}_afterResize(e,t){this._charSizeService?.measure()}clear(){if(0!==this.buffer.ybase||0!==this.buffer.y){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;e=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.Linkifier=void 0;const n=i(7150),o=i(6501),a=i(7098),l=i(802),h=i(7093);let c=class extends n.Disposable{get currentLink(){return this._currentLink}constructor(e,t,i,s,r){super(),this._element=e,this._mouseService=t,this._renderService=i,this._bufferService=s,this._linkProviderService=r,this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this._register(new l.Emitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this._register(new l.Emitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this._register((0,n.toDisposable)((()=>{(0,n.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0,this._lastMouseEvent=void 0,this._activeProviderReplies?.clear()}))),this._register(this._bufferService.onResize((()=>{this._clearCurrentLink(),this._wasResized=!0}))),this._register((0,h.addDisposableListener)(this._element,\"mouseleave\",(()=>{this._isMouseOut=!0,this._clearCurrentLink()}))),this._register((0,h.addDisposableListener)(this._element,\"mousemove\",this._handleMouseMove.bind(this))),this._register((0,h.addDisposableListener)(this._element,\"mousedown\",this._handleMouseDown.bind(this))),this._register((0,h.addDisposableListener)(this._element,\"mouseup\",this._handleMouseUp.bind(this)))}_handleMouseMove(e){this._lastMouseEvent=e;const t=this._positionFromMouseEvent(e,this._element,this._mouseService);if(!t)return;this._isMouseOut=!1;const i=e.composedPath();for(let e=0;e{e?.forEach((e=>{e.link.dispose&&e.link.dispose()}))})),this._activeProviderReplies=new Map,this._activeLine=e.y);let i=!1;for(const[s,r]of this._linkProviderService.linkProviders.entries())if(t){const t=this._activeProviderReplies?.get(s);t&&(i=this._checkLinkProviderResult(s,e,i))}else r.provideLinks(e.y,(t=>{if(this._isMouseOut)return;const r=t?.map((e=>({link:e})));this._activeProviderReplies?.set(s,r),i=this._checkLinkProviderResult(s,e,i),this._activeProviderReplies?.size===this._linkProviderService.linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)}))}_removeIntersectingLinks(e,t){const i=new Set;for(let s=0;se?this._bufferService.cols:s.link.range.end.x;for(let e=n;e<=o;e++){if(i.has(e)){r.splice(t--,1);break}i.add(e)}}}}_checkLinkProviderResult(e,t,i){if(!this._activeProviderReplies)return i;const s=this._activeProviderReplies.get(e);let r=!1;for(let t=0;tthis._linkAtPosition(e.link,t)));e&&(i=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviderService.linkProviders.length&&!i)for(let e=0;ethis._linkAtPosition(e.link,t)));if(s){i=!0,this._handleNewLink(s);break}}return i}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._currentLink)return;const t=this._positionFromMouseEvent(e,this._element,this._mouseService);var i,s;t&&this._mouseDownLink&&(i=this._mouseDownLink.link,s=this._currentLink.link,i.text===s.text&&i.range.start.x===s.range.start.x&&i.range.start.y===s.range.start.y&&i.range.end.x===s.range.end.x&&i.range.end.y===s.range.end.y)&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){this._currentLink&&this._lastMouseEvent&&(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,n.dispose)(this._linkCacheDisposables),this._linkCacheDisposables.length=0)}_handleNewLink(e){if(!this._lastMouseEvent)return;const t=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:void 0===e.link.decorations||e.link.decorations.underline,pointerCursor:void 0===e.link.decorations||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>this._currentLink?.state?.decorations.pointerCursor,set:e=>{this._currentLink?.state&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&this._element.classList.toggle(\"xterm-cursor-pointer\",e))}},underline:{get:()=>this._currentLink?.state?.decorations.underline,set:t=>{this._currentLink?.state&&this._currentLink?.state?.decorations.underline!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange((e=>{if(!this._currentLink)return;const t=0===e.start?0:e.start+1+this._bufferService.buffer.ydisp,i=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=i&&(this._clearCurrentLink(t,i),this._lastMouseEvent)){const e=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);e&&this._askForLink(e,!1)}}))))}_linkHover(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add(\"xterm-cursor-pointer\")),t.hover&&t.hover(i,t.text)}_fireUnderlineEvent(e,t){const i=e.range,s=this._bufferService.buffer.ydisp,r=this._createLinkUnderlineEvent(i.start.x-1,i.start.y-s-1,i.end.x,i.end.y-s-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(r)}_linkLeave(e,t,i){this._currentLink?.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove(\"xterm-cursor-pointer\")),t.leave&&t.leave(i,t.text)}_linkAtPosition(e,t){const i=e.range.start.y*this._bufferService.cols+e.range.start.x,s=e.range.end.y*this._bufferService.cols+e.range.end.x,r=t.y*this._bufferService.cols+t.x;return i<=r&&r<=s}_positionFromMouseEvent(e,t,i){const s=i.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(s)return{x:s[0],y:s[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,i,s,r){return{x1:e,y1:t,x2:i,y2:s,cols:this._bufferService.cols,fg:r}}};t.Linkifier=c,t.Linkifier=c=s([r(1,a.IMouseService),r(2,a.IRenderService),r(3,o.IBufferService),r(4,a.ILinkProviderService)],c)},7721:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.tooMuchOutput=t.promptLabel=void 0;let i=\"Terminal input\";const s={get:()=>i,set:e=>i=e};t.promptLabel=s;let r=\"Too much output to announce, navigate to rows manually to read\";const n={get:()=>r,set:e=>r=e};t.tooMuchOutput=n},3285:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.OscLinkProvider=void 0;const n=i(3055),o=i(6501);let a=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i}provideLinks(e,t){const i=this._bufferService.buffer.lines.get(e-1);if(!i)return void t(void 0);const s=[],r=this._optionsService.rawOptions.linkHandler,o=new n.CellData,a=i.getTrimmedLength();let h=-1,c=-1,d=!1;for(let t=0;tr?r.activate(e,t,n):l(0,t),hover:(e,t)=>r?.hover?.(e,t,n),leave:(e,t)=>r?.leave?.(e,t,n)})}d=!1,o.hasExtendedAttrs()&&o.extended.urlId?(c=t,h=o.extended.urlId):(c=-1,h=-1)}}t(s)}};function l(e,t){if(confirm(`Do you want to navigate to ${t}?\\n\\nWARNING: This link could potentially be dangerous`)){const e=window.open();if(e){try{e.opener=null}catch{}e.location.href=t}else console.warn(\"Opening link blocked as opener could not be cleared\")}}t.OscLinkProvider=a,t.OscLinkProvider=a=s([r(0,o.IBufferService),r(1,o.IOptionsService),r(2,o.IOscLinkService)],a)},4852:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.RenderDebouncer=void 0,t.RenderDebouncer=class{constructor(e,t){this._renderCallback=e,this._coreBrowserService=t,this._refreshCallbacks=[]}dispose(){this._animationFrame&&(this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame),this._animationFrame=void 0)}addRefreshCallback(e){return this._refreshCallbacks.push(e),this._animationFrame||(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>this._innerRefresh()))),this._animationFrame}refresh(e,t,i){this._rowCount=i,e=void 0!==e?e:0,t=void 0!==t?t:this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t,this._animationFrame||(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>this._innerRefresh())))}_innerRefresh(){if(this._animationFrame=void 0,void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return void this._runRefreshCallbacks();const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t),this._runRefreshCallbacks()}_runRefreshCallbacks(){for(const e of this._refreshCallbacks)e(0);this._refreshCallbacks=[]}}},4292:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.TimeBasedDebouncer=void 0,t.TimeBasedDebouncer=class{constructor(e,t=1e3){this._renderCallback=e,this._debounceThresholdMS=t,this._lastRefreshMs=0,this._additionalRefreshRequested=!1}dispose(){this._refreshTimeoutID&&clearTimeout(this._refreshTimeoutID)}refresh(e,t,i){this._rowCount=i,e=void 0!==e?e:0,t=void 0!==t?t:this._rowCount-1,this._rowStart=void 0!==this._rowStart?Math.min(this._rowStart,e):e,this._rowEnd=void 0!==this._rowEnd?Math.max(this._rowEnd,t):t;const s=performance.now();if(s-this._lastRefreshMs>=this._debounceThresholdMS)this._lastRefreshMs=s,this._innerRefresh();else if(!this._additionalRefreshRequested){const e=s-this._lastRefreshMs,t=this._debounceThresholdMS-e;this._additionalRefreshRequested=!0,this._refreshTimeoutID=window.setTimeout((()=>{this._lastRefreshMs=performance.now(),this._innerRefresh(),this._additionalRefreshRequested=!1,this._refreshTimeoutID=void 0}),t)}}_innerRefresh(){if(void 0===this._rowStart||void 0===this._rowEnd||void 0===this._rowCount)return;const e=Math.max(this._rowStart,0),t=Math.min(this._rowEnd,this._rowCount-1);this._rowStart=void 0,this._rowEnd=void 0,this._renderCallback(e,t)}}},9302:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DEFAULT_ANSI_COLORS=void 0;const s=i(4103);t.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const e=[s.css.toColor(\"#2e3436\"),s.css.toColor(\"#cc0000\"),s.css.toColor(\"#4e9a06\"),s.css.toColor(\"#c4a000\"),s.css.toColor(\"#3465a4\"),s.css.toColor(\"#75507b\"),s.css.toColor(\"#06989a\"),s.css.toColor(\"#d3d7cf\"),s.css.toColor(\"#555753\"),s.css.toColor(\"#ef2929\"),s.css.toColor(\"#8ae234\"),s.css.toColor(\"#fce94f\"),s.css.toColor(\"#729fcf\"),s.css.toColor(\"#ad7fa8\"),s.css.toColor(\"#34e2e2\"),s.css.toColor(\"#eeeeec\")],t=[0,95,135,175,215,255];for(let i=0;i<216;i++){const r=t[i/36%6|0],n=t[i/6%6|0],o=t[i%6];e.push({css:s.channels.toCss(r,n,o),rgba:s.channels.toRgba(r,n,o)})}for(let t=0;t<24;t++){const i=8+10*t;e.push({css:s.channels.toCss(i,i,i),rgba:s.channels.toRgba(i,i,i)})}return e})())},4017:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.Viewport=void 0;const n=i(7098),o=i(7150),a=i(6501),l=i(7093),h=i(8234),c=i(802),d=i(9881);let u=class extends o.Disposable{constructor(e,t,i,s,r,n,a,u){super(),this._bufferService=i,this._optionsService=a,this._renderService=u,this._onRequestScrollLines=this._register(new c.Emitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._isSyncing=!1,this._isHandlingScroll=!1,this._suppressOnScrollHandler=!1;const _=this._register(new d.Scrollable({forceIntegerValues:!1,smoothScrollDuration:this._optionsService.rawOptions.smoothScrollDuration,scheduleAtNextAnimationFrame:e=>(0,l.scheduleAtNextAnimationFrame)(s.window,e)}));this._register(this._optionsService.onSpecificOptionChange(\"smoothScrollDuration\",(()=>{_.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration)}))),this._scrollableElement=this._register(new h.SmoothScrollableElement(t,{vertical:1,horizontal:2,useShadows:!1,mouseWheelSmoothScroll:!0,...this._getChangeOptions()},_)),this._register(this._optionsService.onMultipleOptionChange([\"scrollSensitivity\",\"fastScrollSensitivity\",\"overviewRuler\"],(()=>this._scrollableElement.updateOptions(this._getChangeOptions())))),this._register(r.onProtocolChange((e=>{this._scrollableElement.updateOptions({handleMouseWheel:!(16&e)})}))),this._scrollableElement.setScrollDimensions({height:0,scrollHeight:0}),this._register(c.Event.runAndSubscribe(n.onChangeColors,(()=>{this._scrollableElement.getDomNode().style.backgroundColor=n.colors.background.css}))),e.appendChild(this._scrollableElement.getDomNode()),this._register((0,o.toDisposable)((()=>this._scrollableElement.getDomNode().remove()))),this._styleElement=s.mainDocument.createElement(\"style\"),t.appendChild(this._styleElement),this._register((0,o.toDisposable)((()=>this._styleElement.remove()))),this._register(c.Event.runAndSubscribe(n.onChangeColors,(()=>{this._styleElement.textContent=[\".xterm .xterm-scrollable-element > .scrollbar > .slider {\",` background: ${n.colors.scrollbarSliderBackground.css};`,\"}\",\".xterm .xterm-scrollable-element > .scrollbar > .slider:hover {\",` background: ${n.colors.scrollbarSliderHoverBackground.css};`,\"}\",\".xterm .xterm-scrollable-element > .scrollbar > .slider.active {\",` background: ${n.colors.scrollbarSliderActiveBackground.css};`,\"}\"].join(\"\\n\")}))),this._register(this._bufferService.onResize((()=>this.queueSync()))),this._register(this._bufferService.buffers.onBufferActivate((()=>{this._latestYDisp=void 0,this.queueSync()}))),this._register(this._bufferService.onScroll((()=>this._sync()))),this._register(this._scrollableElement.onScroll((e=>this._handleScroll(e))))}scrollLines(e){const t=this._scrollableElement.getScrollPosition();this._scrollableElement.setScrollPosition({reuseAnimation:!0,scrollTop:t.scrollTop+e*this._renderService.dimensions.css.cell.height})}scrollToLine(e,t){t&&(this._latestYDisp=e),this._scrollableElement.setScrollPosition({reuseAnimation:!t,scrollTop:e*this._renderService.dimensions.css.cell.height})}_getChangeOptions(){return{mouseWheelScrollSensitivity:this._optionsService.rawOptions.scrollSensitivity,fastScrollSensitivity:this._optionsService.rawOptions.fastScrollSensitivity,verticalScrollbarSize:this._optionsService.rawOptions.overviewRuler?.width||14}}queueSync(e){void 0!==e&&(this._latestYDisp=e),void 0===this._queuedAnimationFrame&&(this._queuedAnimationFrame=this._renderService.addRefreshCallback((()=>{this._queuedAnimationFrame=void 0,this._sync(this._latestYDisp)})))}_sync(e=this._bufferService.buffer.ydisp){this._renderService&&!this._isSyncing&&(this._isSyncing=!0,this._suppressOnScrollHandler=!0,this._scrollableElement.setScrollDimensions({height:this._renderService.dimensions.css.canvas.height,scrollHeight:this._renderService.dimensions.css.cell.height*this._bufferService.buffer.lines.length}),this._suppressOnScrollHandler=!1,e!==this._latestYDisp&&this._scrollableElement.setScrollPosition({scrollTop:e*this._renderService.dimensions.css.cell.height}),this._isSyncing=!1)}_handleScroll(e){if(!this._renderService)return;if(this._isHandlingScroll||this._suppressOnScrollHandler)return;this._isHandlingScroll=!0;const t=Math.round(e.scrollTop/this._renderService.dimensions.css.cell.height),i=t-this._bufferService.buffer.ydisp;0!==i&&(this._latestYDisp=t,this._onRequestScrollLines.fire(i)),this._isHandlingScroll=!1}};t.Viewport=u,t.Viewport=u=s([r(2,a.IBufferService),r(3,n.ICoreBrowserService),r(4,a.ICoreMouseService),r(5,n.IThemeService),r(6,a.IOptionsService),r(7,n.IRenderService)],u)},4196:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferDecorationRenderer=void 0;const n=i(7098),o=i(7150),a=i(6501);let l=class extends o.Disposable{constructor(e,t,i,s,r){super(),this._screenElement=e,this._bufferService=t,this._coreBrowserService=i,this._decorationService=s,this._renderService=r,this._decorationElements=new Map,this._altBufferIsActive=!1,this._dimensionsChanged=!1,this._container=document.createElement(\"div\"),this._container.classList.add(\"xterm-decoration-container\"),this._screenElement.appendChild(this._container),this._register(this._renderService.onRenderedViewportChange((()=>this._doRefreshDecorations()))),this._register(this._renderService.onDimensionsChange((()=>{this._dimensionsChanged=!0,this._queueRefresh()}))),this._register(this._coreBrowserService.onDprChange((()=>this._queueRefresh()))),this._register(this._bufferService.buffers.onBufferActivate((()=>{this._altBufferIsActive=this._bufferService.buffer===this._bufferService.buffers.alt}))),this._register(this._decorationService.onDecorationRegistered((()=>this._queueRefresh()))),this._register(this._decorationService.onDecorationRemoved((e=>this._removeDecoration(e)))),this._register((0,o.toDisposable)((()=>{this._container.remove(),this._decorationElements.clear()})))}_queueRefresh(){void 0===this._animationFrame&&(this._animationFrame=this._renderService.addRefreshCallback((()=>{this._doRefreshDecorations(),this._animationFrame=void 0})))}_doRefreshDecorations(){for(const e of this._decorationService.decorations)this._renderDecoration(e);this._dimensionsChanged=!1}_renderDecoration(e){this._refreshStyle(e),this._dimensionsChanged&&this._refreshXPosition(e)}_createElement(e){const t=this._coreBrowserService.mainDocument.createElement(\"div\");t.classList.add(\"xterm-decoration\"),t.classList.toggle(\"xterm-decoration-top-layer\",\"top\"===e?.options?.layer),t.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,t.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+\"px\",t.style.top=(e.marker.line-this._bufferService.buffers.active.ydisp)*this._renderService.dimensions.css.cell.height+\"px\",t.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`;const i=e.options.x??0;return i&&i>this._bufferService.cols&&(t.style.display=\"none\"),this._refreshXPosition(e,t),t}_refreshStyle(e){const t=e.marker.line-this._bufferService.buffers.active.ydisp;if(t<0||t>=this._bufferService.rows)e.element&&(e.element.style.display=\"none\",e.onRenderEmitter.fire(e.element));else{let i=this._decorationElements.get(e);i||(i=this._createElement(e),e.element=i,this._decorationElements.set(e,i),this._container.appendChild(i),e.onDispose((()=>{this._decorationElements.delete(e),i.remove()}))),i.style.display=this._altBufferIsActive?\"none\":\"block\",this._altBufferIsActive||(i.style.width=`${Math.round((e.options.width||1)*this._renderService.dimensions.css.cell.width)}px`,i.style.height=(e.options.height||1)*this._renderService.dimensions.css.cell.height+\"px\",i.style.top=t*this._renderService.dimensions.css.cell.height+\"px\",i.style.lineHeight=`${this._renderService.dimensions.css.cell.height}px`),e.onRenderEmitter.fire(i)}}_refreshXPosition(e,t=e.element){if(!t)return;const i=e.options.x??0;\"right\"===(e.options.anchor||\"left\")?t.style.right=i?i*this._renderService.dimensions.css.cell.width+\"px\":\"\":t.style.left=i?i*this._renderService.dimensions.css.cell.width+\"px\":\"\"}_removeDecoration(e){this._decorationElements.get(e)?.remove(),this._decorationElements.delete(e),e.dispose()}};t.BufferDecorationRenderer=l,t.BufferDecorationRenderer=l=s([r(1,a.IBufferService),r(2,n.ICoreBrowserService),r(3,a.IDecorationService),r(4,n.IRenderService)],l)},957:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ColorZoneStore=void 0,t.ColorZoneStore=class{constructor(){this._zones=[],this._zonePool=[],this._zonePoolIndex=0,this._linePadding={full:0,left:0,center:0,right:0}}get zones(){return this._zonePool.length=Math.min(this._zonePool.length,this._zones.length),this._zones}clear(){this._zones.length=0,this._zonePoolIndex=0}addDecoration(e){if(e.options.overviewRulerOptions){for(const t of this._zones)if(t.color===e.options.overviewRulerOptions.color&&t.position===e.options.overviewRulerOptions.position){if(this._lineIntersectsZone(t,e.marker.line))return;if(this._lineAdjacentToZone(t,e.marker.line,e.options.overviewRulerOptions.position))return void this._addLineToZone(t,e.marker.line)}if(this._zonePoolIndex=e.startBufferLine&&t<=e.endBufferLine}_lineAdjacentToZone(e,t,i){return t>=e.startBufferLine-this._linePadding[i||\"full\"]&&t<=e.endBufferLine+this._linePadding[i||\"full\"]}_addLineToZone(e,t){e.startBufferLine=Math.min(e.startBufferLine,t),e.endBufferLine=Math.max(e.endBufferLine,t)}}},9925:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.OverviewRulerRenderer=void 0;const n=i(957),o=i(7098),a=i(7150),l=i(6501),h={full:0,left:0,center:0,right:0},c={full:0,left:0,center:0,right:0},d={full:0,left:0,center:0,right:0};let u=class extends a.Disposable{get _width(){return this._optionsService.options.overviewRuler?.width||0}constructor(e,t,i,s,r,o,l,h){super(),this._viewportElement=e,this._screenElement=t,this._bufferService=i,this._decorationService=s,this._renderService=r,this._optionsService=o,this._themeService=l,this._coreBrowserService=h,this._colorZoneStore=new n.ColorZoneStore,this._shouldUpdateDimensions=!0,this._shouldUpdateAnchor=!0,this._lastKnownBufferLength=0,this._canvas=this._coreBrowserService.mainDocument.createElement(\"canvas\"),this._canvas.classList.add(\"xterm-decoration-overview-ruler\"),this._refreshCanvasDimensions(),this._viewportElement.parentElement?.insertBefore(this._canvas,this._viewportElement),this._register((0,a.toDisposable)((()=>this._canvas?.remove())));const c=this._canvas.getContext(\"2d\");if(!c)throw new Error(\"Ctx cannot be null\");this._ctx=c,this._register(this._decorationService.onDecorationRegistered((()=>this._queueRefresh(void 0,!0)))),this._register(this._decorationService.onDecorationRemoved((()=>this._queueRefresh(void 0,!0)))),this._register(this._renderService.onRenderedViewportChange((()=>this._queueRefresh()))),this._register(this._bufferService.buffers.onBufferActivate((()=>{this._canvas.style.display=this._bufferService.buffer===this._bufferService.buffers.alt?\"none\":\"block\"}))),this._register(this._bufferService.onScroll((()=>{this._lastKnownBufferLength!==this._bufferService.buffers.normal.lines.length&&(this._refreshDrawHeightConstants(),this._refreshColorZonePadding())}))),this._register(this._renderService.onRender((()=>{this._containerHeight&&this._containerHeight===this._screenElement.clientHeight||(this._queueRefresh(!0),this._containerHeight=this._screenElement.clientHeight)}))),this._register(this._coreBrowserService.onDprChange((()=>this._queueRefresh(!0)))),this._register(this._optionsService.onSpecificOptionChange(\"overviewRuler\",(()=>this._queueRefresh(!0)))),this._register(this._themeService.onChangeColors((()=>this._queueRefresh()))),this._queueRefresh(!0)}_refreshDrawConstants(){const e=Math.floor((this._canvas.width-1)/3),t=Math.ceil((this._canvas.width-1)/3);c.full=this._canvas.width,c.left=e,c.center=t,c.right=e,this._refreshDrawHeightConstants(),d.full=1,d.left=1,d.center=1+c.left,d.right=1+c.left+c.center}_refreshDrawHeightConstants(){h.full=Math.round(2*this._coreBrowserService.dpr);const e=this._canvas.height/this._bufferService.buffer.lines.length,t=Math.round(Math.max(Math.min(e,12),6)*this._coreBrowserService.dpr);h.left=t,h.center=t,h.right=t}_refreshColorZonePadding(){this._colorZoneStore.setPadding({full:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*h.full),left:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*h.left),center:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*h.center),right:Math.floor(this._bufferService.buffers.active.lines.length/(this._canvas.height-1)*h.right)}),this._lastKnownBufferLength=this._bufferService.buffers.normal.lines.length}_refreshCanvasDimensions(){this._canvas.style.width=`${this._width}px`,this._canvas.width=Math.round(this._width*this._coreBrowserService.dpr),this._canvas.style.height=`${this._screenElement.clientHeight}px`,this._canvas.height=Math.round(this._screenElement.clientHeight*this._coreBrowserService.dpr),this._refreshDrawConstants(),this._refreshColorZonePadding()}_refreshDecorations(){this._shouldUpdateDimensions&&this._refreshCanvasDimensions(),this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._colorZoneStore.clear();for(const e of this._decorationService.decorations)this._colorZoneStore.addDecoration(e);this._ctx.lineWidth=1,this._renderRulerOutline();const e=this._colorZoneStore.zones;for(const t of e)\"full\"!==t.position&&this._renderColorZone(t);for(const t of e)\"full\"===t.position&&this._renderColorZone(t);this._shouldUpdateDimensions=!1,this._shouldUpdateAnchor=!1}_renderRulerOutline(){this._ctx.fillStyle=this._themeService.colors.overviewRulerBorder.css,this._ctx.fillRect(0,0,1,this._canvas.height),this._optionsService.rawOptions.overviewRuler.showTopBorder&&this._ctx.fillRect(1,0,this._canvas.width-1,1),this._optionsService.rawOptions.overviewRuler.showBottomBorder&&this._ctx.fillRect(1,this._canvas.height-1,this._canvas.width-1,this._canvas.height)}_renderColorZone(e){this._ctx.fillStyle=e.color,this._ctx.fillRect(d[e.position||\"full\"],Math.round((this._canvas.height-1)*(e.startBufferLine/this._bufferService.buffers.active.lines.length)-h[e.position||\"full\"]/2),c[e.position||\"full\"],Math.round((this._canvas.height-1)*((e.endBufferLine-e.startBufferLine)/this._bufferService.buffers.active.lines.length)+h[e.position||\"full\"]))}_queueRefresh(e,t){this._shouldUpdateDimensions=e||this._shouldUpdateDimensions,this._shouldUpdateAnchor=t||this._shouldUpdateAnchor,void 0===this._animationFrame&&(this._animationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>{this._refreshDecorations(),this._animationFrame=void 0})))}};t.OverviewRulerRenderer=u,t.OverviewRulerRenderer=u=s([r(2,l.IBufferService),r(3,l.IDecorationService),r(4,o.IRenderService),r(5,l.IOptionsService),r(6,o.IThemeService),r(7,o.ICoreBrowserService)],u)},3618:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CompositionHelper=void 0;const n=i(7098),o=i(6501),a=i(3534);let l=class{get isComposing(){return this._isComposing}constructor(e,t,i,s,r,n){this._textarea=e,this._compositionView=t,this._bufferService=i,this._optionsService=s,this._coreService=r,this._renderService=n,this._isComposing=!1,this._isSendingComposition=!1,this._compositionPosition={start:0,end:0},this._dataAlreadySent=\"\"}compositionstart(){this._isComposing=!0,this._compositionPosition.start=this._textarea.value.length,this._compositionView.textContent=\"\",this._dataAlreadySent=\"\",this._compositionView.classList.add(\"active\")}compositionupdate(e){this._compositionView.textContent=e.data,this.updateCompositionElements(),setTimeout((()=>{this._compositionPosition.end=this._textarea.value.length}),0)}compositionend(){this._finalizeComposition(!0)}keydown(e){if(this._isComposing||this._isSendingComposition){if(20===e.keyCode||229===e.keyCode)return!1;if(16===e.keyCode||17===e.keyCode||18===e.keyCode)return!1;this._finalizeComposition(!1)}return 229!==e.keyCode||(this._handleAnyTextareaChanges(),!1)}_finalizeComposition(e){if(this._compositionView.classList.remove(\"active\"),this._isComposing=!1,e){const e={start:this._compositionPosition.start,end:this._compositionPosition.end};this._isSendingComposition=!0,setTimeout((()=>{if(this._isSendingComposition){let t;this._isSendingComposition=!1,e.start+=this._dataAlreadySent.length,t=this._isComposing?this._textarea.value.substring(e.start,this._compositionPosition.start):this._textarea.value.substring(e.start),t.length>0&&this._coreService.triggerDataEvent(t,!0)}}),0)}else{this._isSendingComposition=!1;const e=this._textarea.value.substring(this._compositionPosition.start,this._compositionPosition.end);this._coreService.triggerDataEvent(e,!0)}}_handleAnyTextareaChanges(){const e=this._textarea.value;setTimeout((()=>{if(!this._isComposing){const t=this._textarea.value,i=t.replace(e,\"\");this._dataAlreadySent=i,t.length>e.length?this._coreService.triggerDataEvent(i,!0):t.lengththis.updateCompositionElements(!0)),0)}}};t.CompositionHelper=l,t.CompositionHelper=l=s([r(2,o.IBufferService),r(3,o.IOptionsService),r(4,o.ICoreService),r(5,n.IRenderService)],l)},5251:(e,t)=>{function i(e,t,i){const s=i.getBoundingClientRect(),r=e.getComputedStyle(i),n=parseInt(r.getPropertyValue(\"padding-left\")),o=parseInt(r.getPropertyValue(\"padding-top\"));return[t.clientX-s.left-n,t.clientY-s.top-o]}Object.defineProperty(t,\"__esModule\",{value:!0}),t.getCoordsRelativeToElement=i,t.getCoords=function(e,t,s,r,n,o,a,l,h){if(!o)return;const c=i(e,t,s);return c?(c[0]=Math.ceil((c[0]+(h?a/2:0))/a),c[1]=Math.ceil(c[1]/l),c[0]=Math.min(Math.max(c[0],1),r+(h?1:0)),c[1]=Math.min(Math.max(c[1],1),n),c):void 0}},9686:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.moveToCellSequence=function(e,t,i,s){const o=i.buffer.x,c=i.buffer.y;if(!i.buffer.hasScrollback)return function(e,t,i,s,o,c){return 0===r(t,s,o,c).length?\"\":h(a(e,t,e,t-n(t,o),!1,o).length,l(\"D\",c))}(o,c,0,t,i,s)+r(c,t,i,s)+function(e,t,i,s,o,c){let d;d=r(t,s,o,c).length>0?s-n(s,o):t;const u=s,_=function(e,t,i,s,o,a){let l;return l=r(i,s,o,a).length>0?s-n(s,o):t,e=i&&le?\"D\":\"C\",h(Math.abs(o-e),l(d,s));d=c>t?\"D\":\"C\";const u=Math.abs(c-t);return h(function(e,t){return t.cols-e}(c>t?e:o,i)+(u-1)*i.cols+1+((c>t?o:e)-1),l(d,s))};const s=i(3534);function r(e,t,i,s){const r=e-n(e,i),a=t-n(t,i),c=Math.abs(r-a)-function(e,t,i){let s=0;const r=e-n(e,i),a=t-n(t,i);for(let n=0;n=0&&et?\"A\":\"B\"}function a(e,t,i,s,r,n){let o=e,a=t,l=\"\";for(;(o!==i||a!==s)&&a>=0&&an.cols-1?(l+=n.buffer.translateBufferLineToString(a,!1,e,o),o=0,e=0,a++):!r&&o<0&&(l+=n.buffer.translateBufferLineToString(a,!1,0,e+1),o=n.cols-1,e=o,a--);return l+n.buffer.translateBufferLineToString(a,!1,e,o)}function l(e,t){const i=t?\"O\":\"[\";return s.C0.ESC+i+e}function h(e,t){e=Math.floor(e);let i=\"\";for(let s=0;s=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.DomRenderer=void 0;const n=i(1433),o=i(2744),a=i(9176),l=i(6181),h=i(2274),c=i(7098),d=i(4103),u=i(7150),_=i(6501),f=i(802),p=\"xterm-dom-renderer-owner-\",g=\"xterm-rows\",m=\"xterm-fg-\",v=\"xterm-bg-\",S=\"xterm-focus\",b=\"xterm-selection\";let C=1,y=class extends u.Disposable{constructor(e,t,i,s,r,a,c,d,_,m,v,S,y,w){super(),this._terminal=e,this._document=t,this._element=i,this._screenElement=s,this._viewportElement=r,this._helperContainer=a,this._linkifier2=c,this._charSizeService=_,this._optionsService=m,this._bufferService=v,this._coreService=S,this._coreBrowserService=y,this._themeService=w,this._terminalClass=C++,this._rowElements=[],this._selectionRenderModel=(0,h.createSelectionRenderModel)(),this.onRequestRedraw=this._register(new f.Emitter).event,this._rowContainer=this._document.createElement(\"div\"),this._rowContainer.classList.add(g),this._rowContainer.style.lineHeight=\"normal\",this._rowContainer.setAttribute(\"aria-hidden\",\"true\"),this._refreshRowElements(this._bufferService.cols,this._bufferService.rows),this._selectionContainer=this._document.createElement(\"div\"),this._selectionContainer.classList.add(b),this._selectionContainer.setAttribute(\"aria-hidden\",\"true\"),this.dimensions=(0,l.createRenderDimensions)(),this._updateDimensions(),this._register(this._optionsService.onOptionChange((()=>this._handleOptionsChanged()))),this._register(this._themeService.onChangeColors((e=>this._injectCss(e)))),this._injectCss(this._themeService.colors),this._rowFactory=d.createInstance(n.DomRendererRowFactory,document),this._element.classList.add(p+this._terminalClass),this._screenElement.appendChild(this._rowContainer),this._screenElement.appendChild(this._selectionContainer),this._register(this._linkifier2.onShowLinkUnderline((e=>this._handleLinkHover(e)))),this._register(this._linkifier2.onHideLinkUnderline((e=>this._handleLinkLeave(e)))),this._register((0,u.toDisposable)((()=>{this._element.classList.remove(p+this._terminalClass),this._rowContainer.remove(),this._selectionContainer.remove(),this._widthCache.dispose(),this._themeStyleElement.remove(),this._dimensionsStyleElement.remove()}))),this._widthCache=new o.WidthCache(this._document,this._helperContainer),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}_updateDimensions(){const e=this._coreBrowserService.dpr;this.dimensions.device.char.width=this._charSizeService.width*e,this.dimensions.device.char.height=Math.ceil(this._charSizeService.height*e),this.dimensions.device.cell.width=this.dimensions.device.char.width+Math.round(this._optionsService.rawOptions.letterSpacing),this.dimensions.device.cell.height=Math.floor(this.dimensions.device.char.height*this._optionsService.rawOptions.lineHeight),this.dimensions.device.char.left=0,this.dimensions.device.char.top=0,this.dimensions.device.canvas.width=this.dimensions.device.cell.width*this._bufferService.cols,this.dimensions.device.canvas.height=this.dimensions.device.cell.height*this._bufferService.rows,this.dimensions.css.canvas.width=Math.round(this.dimensions.device.canvas.width/e),this.dimensions.css.canvas.height=Math.round(this.dimensions.device.canvas.height/e),this.dimensions.css.cell.width=this.dimensions.css.canvas.width/this._bufferService.cols,this.dimensions.css.cell.height=this.dimensions.css.canvas.height/this._bufferService.rows;for(const e of this._rowElements)e.style.width=`${this.dimensions.css.canvas.width}px`,e.style.height=`${this.dimensions.css.cell.height}px`,e.style.lineHeight=`${this.dimensions.css.cell.height}px`,e.style.overflow=\"hidden\";this._dimensionsStyleElement||(this._dimensionsStyleElement=this._document.createElement(\"style\"),this._screenElement.appendChild(this._dimensionsStyleElement));const t=`${this._terminalSelector} .${g} span { display: inline-block; height: 100%; vertical-align: top;}`;this._dimensionsStyleElement.textContent=t,this._selectionContainer.style.height=this._viewportElement.style.height,this._screenElement.style.width=`${this.dimensions.css.canvas.width}px`,this._screenElement.style.height=`${this.dimensions.css.canvas.height}px`}_injectCss(e){this._themeStyleElement||(this._themeStyleElement=this._document.createElement(\"style\"),this._screenElement.appendChild(this._themeStyleElement));let t=`${this._terminalSelector} .${g} { pointer-events: none; color: ${e.foreground.css}; font-family: ${this._optionsService.rawOptions.fontFamily}; font-size: ${this._optionsService.rawOptions.fontSize}px; font-kerning: none; white-space: pre}`;t+=`${this._terminalSelector} .${g} .xterm-dim { color: ${d.color.multiplyOpacity(e.foreground,.5).css};}`,t+=`${this._terminalSelector} span:not(.xterm-bold) { font-weight: ${this._optionsService.rawOptions.fontWeight};}${this._terminalSelector} span.xterm-bold { font-weight: ${this._optionsService.rawOptions.fontWeightBold};}${this._terminalSelector} span.xterm-italic { font-style: italic;}`;const i=`blink_underline_${this._terminalClass}`,s=`blink_bar_${this._terminalClass}`,r=`blink_block_${this._terminalClass}`;t+=`@keyframes ${i} { 50% { border-bottom-style: hidden; }}`,t+=`@keyframes ${s} { 50% { box-shadow: none; }}`,t+=`@keyframes ${r} { 0% { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css}; } 50% { background-color: inherit; color: ${e.cursor.css}; }}`,t+=`${this._terminalSelector} .${g}.${S} .xterm-cursor.xterm-cursor-blink.xterm-cursor-underline { animation: ${i} 1s step-end infinite;}${this._terminalSelector} .${g}.${S} .xterm-cursor.xterm-cursor-blink.xterm-cursor-bar { animation: ${s} 1s step-end infinite;}${this._terminalSelector} .${g}.${S} .xterm-cursor.xterm-cursor-blink.xterm-cursor-block { animation: ${r} 1s step-end infinite;}${this._terminalSelector} .${g} .xterm-cursor.xterm-cursor-block { background-color: ${e.cursor.css}; color: ${e.cursorAccent.css};}${this._terminalSelector} .${g} .xterm-cursor.xterm-cursor-block:not(.xterm-cursor-blink) { background-color: ${e.cursor.css} !important; color: ${e.cursorAccent.css} !important;}${this._terminalSelector} .${g} .xterm-cursor.xterm-cursor-outline { outline: 1px solid ${e.cursor.css}; outline-offset: -1px;}${this._terminalSelector} .${g} .xterm-cursor.xterm-cursor-bar { box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${e.cursor.css} inset;}${this._terminalSelector} .${g} .xterm-cursor.xterm-cursor-underline { border-bottom: 1px ${e.cursor.css}; border-bottom-style: solid; height: calc(100% - 1px);}`,t+=`${this._terminalSelector} .${b} { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none;}${this._terminalSelector}.focus .${b} div { position: absolute; background-color: ${e.selectionBackgroundOpaque.css};}${this._terminalSelector} .${b} div { position: absolute; background-color: ${e.selectionInactiveBackgroundOpaque.css};}`;for(const[i,s]of e.ansi.entries())t+=`${this._terminalSelector} .${m}${i} { color: ${s.css}; }${this._terminalSelector} .${m}${i}.xterm-dim { color: ${d.color.multiplyOpacity(s,.5).css}; }${this._terminalSelector} .${v}${i} { background-color: ${s.css}; }`;t+=`${this._terminalSelector} .${m}${a.INVERTED_DEFAULT_COLOR} { color: ${d.color.opaque(e.background).css}; }${this._terminalSelector} .${m}${a.INVERTED_DEFAULT_COLOR}.xterm-dim { color: ${d.color.multiplyOpacity(d.color.opaque(e.background),.5).css}; }${this._terminalSelector} .${v}${a.INVERTED_DEFAULT_COLOR} { background-color: ${e.foreground.css}; }`,this._themeStyleElement.textContent=t}_setDefaultSpacing(){const e=this.dimensions.css.cell.width-this._widthCache.get(\"W\",!1,!1);this._rowContainer.style.letterSpacing=`${e}px`,this._rowFactory.defaultSpacing=e}handleDevicePixelRatioChange(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}_refreshRowElements(e,t){for(let e=this._rowElements.length;e<=t;e++){const e=this._document.createElement(\"div\");this._rowContainer.appendChild(e),this._rowElements.push(e)}for(;this._rowElements.length>t;)this._rowContainer.removeChild(this._rowElements.pop())}handleResize(e,t){this._refreshRowElements(e,t),this._updateDimensions(),this.handleSelectionChanged(this._selectionRenderModel.selectionStart,this._selectionRenderModel.selectionEnd,this._selectionRenderModel.columnSelectMode)}handleCharSizeChanged(){this._updateDimensions(),this._widthCache.clear(),this._setDefaultSpacing()}handleBlur(){this._rowContainer.classList.remove(S),this.renderRows(0,this._bufferService.rows-1)}handleFocus(){this._rowContainer.classList.add(S),this.renderRows(this._bufferService.buffer.y,this._bufferService.buffer.y)}handleSelectionChanged(e,t,i){if(this._selectionContainer.replaceChildren(),this._rowFactory.handleSelectionChanged(e,t,i),this.renderRows(0,this._bufferService.rows-1),!e||!t)return;if(this._selectionRenderModel.update(this._terminal,e,t,i),!this._selectionRenderModel.hasSelection)return;const s=this._selectionRenderModel.viewportStartRow,r=this._selectionRenderModel.viewportEndRow,n=this._selectionRenderModel.viewportCappedStartRow,o=this._selectionRenderModel.viewportCappedEndRow,a=this._document.createDocumentFragment();if(i){const i=e[0]>t[0];a.appendChild(this._createSelectionElement(n,i?t[0]:e[0],i?e[0]:t[0],o-n+1))}else{const i=s===n?e[0]:0,l=n===r?t[0]:this._bufferService.cols;a.appendChild(this._createSelectionElement(n,i,l));const h=o-n-1;if(a.appendChild(this._createSelectionElement(n+1,0,this._bufferService.cols,h)),n!==o){const e=r===o?t[0]:this._bufferService.cols;a.appendChild(this._createSelectionElement(o,0,e))}}this._selectionContainer.appendChild(a)}_createSelectionElement(e,t,i,s=1){const r=this._document.createElement(\"div\"),n=t*this.dimensions.css.cell.width;let o=this.dimensions.css.cell.width*(i-t);return n+o>this.dimensions.css.canvas.width&&(o=this.dimensions.css.canvas.width-n),r.style.height=s*this.dimensions.css.cell.height+\"px\",r.style.top=e*this.dimensions.css.cell.height+\"px\",r.style.left=`${n}px`,r.style.width=`${o}px`,r}handleCursorMove(){}_handleOptionsChanged(){this._updateDimensions(),this._injectCss(this._themeService.colors),this._widthCache.setFont(this._optionsService.rawOptions.fontFamily,this._optionsService.rawOptions.fontSize,this._optionsService.rawOptions.fontWeight,this._optionsService.rawOptions.fontWeightBold),this._setDefaultSpacing()}clear(){for(const e of this._rowElements)e.replaceChildren()}renderRows(e,t){const i=this._bufferService.buffer,s=i.ybase+i.y,r=Math.min(i.x,this._bufferService.cols-1),n=this._coreService.decPrivateModes.cursorBlink??this._optionsService.rawOptions.cursorBlink,o=this._coreService.decPrivateModes.cursorStyle??this._optionsService.rawOptions.cursorStyle,a=this._optionsService.rawOptions.cursorInactiveStyle;for(let l=e;l<=t;l++){const e=l+i.ydisp,t=this._rowElements[l],h=i.lines.get(e);if(!t||!h)break;t.replaceChildren(...this._rowFactory.createRow(h,e,e===s,o,a,r,n,this.dimensions.css.cell.width,this._widthCache,-1,-1))}}get _terminalSelector(){return`.${p}${this._terminalClass}`}_handleLinkHover(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!0)}_handleLinkLeave(e){this._setCellUnderline(e.x1,e.x2,e.y1,e.y2,e.cols,!1)}_setCellUnderline(e,t,i,s,r,n){i<0&&(e=0),s<0&&(t=0);const o=this._bufferService.rows-1;i=Math.max(Math.min(i,o),0),s=Math.max(Math.min(s,o),0),r=Math.min(r,this._bufferService.cols);const a=this._bufferService.buffer,l=a.ybase+a.y,h=Math.min(a.x,r-1),c=this._optionsService.rawOptions.cursorBlink,d=this._optionsService.rawOptions.cursorStyle,u=this._optionsService.rawOptions.cursorInactiveStyle;for(let o=i;o<=s;++o){const _=o+a.ydisp,f=this._rowElements[o],p=a.lines.get(_);if(!f||!p)break;f.replaceChildren(...this._rowFactory.createRow(p,_,_===l,d,u,h,c,this.dimensions.css.cell.width,this._widthCache,n?o===i?e:0:-1,n?(o===s?t:r)-1:-1))}}};t.DomRenderer=y,t.DomRenderer=y=s([r(7,_.IInstantiationService),r(8,c.ICharSizeService),r(9,_.IOptionsService),r(10,_.IBufferService),r(11,_.ICoreService),r(12,c.ICoreBrowserService),r(13,c.IThemeService)],y)},1433:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.DomRendererRowFactory=void 0;const n=i(9176),o=i(8938),a=i(3055),l=i(6501),h=i(4103),c=i(7098),d=i(945),u=i(6181),_=i(5451);let f=class{constructor(e,t,i,s,r,n,o){this._document=e,this._characterJoinerService=t,this._optionsService=i,this._coreBrowserService=s,this._coreService=r,this._decorationService=n,this._themeService=o,this._workCell=new a.CellData,this._columnSelectMode=!1,this.defaultSpacing=0}handleSelectionChanged(e,t,i){this._selectionStart=e,this._selectionEnd=t,this._columnSelectMode=i}createRow(e,t,i,s,r,a,l,c,u,f,g){const m=[],v=this._characterJoinerService.getJoinedCharacters(t),S=this._themeService.colors;let b,C=e.getNoBgTrimmedLength();i&&C=O,U=x,F=this._workCell;if(v.length>0&&x===v[0][0]&&N){const s=v.shift(),r=this._isCellInSelection(s[0],t);for(E=s[0]+1;E=s[1],N?(B=!0,F=new d.JoinedCellData(this._workCell,e.translateToString(!0,s[0],s[1]),s[1]-s[0]),U=s[1]-1,C=F.getWidth()):O=s[1]}const W=this._isCellInSelection(x,t),H=i&&x===a,K=P&&x>=f&&x<=g;let z=!1;this._decorationService.forEachDecorationAtCell(x,t,void 0,(e=>{z=!0}));let j=F.getChars()||o.WHITESPACE_CELL_CHAR;if(\" \"===j&&(F.isUnderline()||F.isOverline())&&(j=\" \"),M=C*c-u.get(j,F.isBold(),F.isItalic()),b){if(y&&(W&&k||!W&&!k&&F.bg===D)&&(W&&k&&S.selectionForeground||F.fg===L)&&F.extended.ext===R&&K===A&&M===T&&!H&&!B&&!z&&N){F.isInvisible()?w+=o.WHITESPACE_CELL_CHAR:w+=j,y++;continue}y&&(b.textContent=w),b=this._document.createElement(\"span\"),y=0,w=\"\"}else b=this._document.createElement(\"span\");if(D=F.bg,L=F.fg,R=F.extended.ext,A=K,T=M,k=W,B&&a>=x&&a<=U&&(a=x),!this._coreService.isCursorHidden&&H&&this._coreService.isCursorInitialized)if(I.push(\"xterm-cursor\"),this._coreBrowserService.isFocused)l&&I.push(\"xterm-cursor-blink\"),I.push(\"bar\"===s?\"xterm-cursor-bar\":\"underline\"===s?\"xterm-cursor-underline\":\"xterm-cursor-block\");else if(r)switch(r){case\"outline\":I.push(\"xterm-cursor-outline\");break;case\"block\":I.push(\"xterm-cursor-block\");break;case\"bar\":I.push(\"xterm-cursor-bar\");break;case\"underline\":I.push(\"xterm-cursor-underline\")}if(F.isBold()&&I.push(\"xterm-bold\"),F.isItalic()&&I.push(\"xterm-italic\"),F.isDim()&&I.push(\"xterm-dim\"),w=F.isInvisible()?o.WHITESPACE_CELL_CHAR:F.getChars()||o.WHITESPACE_CELL_CHAR,F.isUnderline()&&(I.push(`xterm-underline-${F.extended.underlineStyle}`),\" \"===w&&(w=\" \"),!F.isUnderlineColorDefault()))if(F.isUnderlineColorRGB())b.style.textDecorationColor=`rgb(${_.AttributeData.toColorRGB(F.getUnderlineColor()).join(\",\")})`;else{let e=F.getUnderlineColor();this._optionsService.rawOptions.drawBoldTextInBrightColors&&F.isBold()&&e<8&&(e+=8),b.style.textDecorationColor=S.ansi[e].css}F.isOverline()&&(I.push(\"xterm-overline\"),\" \"===w&&(w=\" \")),F.isStrikethrough()&&I.push(\"xterm-strikethrough\"),K&&(b.style.textDecoration=\"underline\");let $=F.getFgColor(),V=F.getFgColorMode(),G=F.getBgColor(),q=F.getBgColorMode();const X=!!F.isInverse();if(X){const e=$;$=G,G=e;const t=V;V=q,q=t}let Y,Z,J,Q=!1;switch(this._decorationService.forEachDecorationAtCell(x,t,void 0,(e=>{\"top\"!==e.options.layer&&Q||(e.backgroundColorRGB&&(q=50331648,G=e.backgroundColorRGB.rgba>>8&16777215,Y=e.backgroundColorRGB),e.foregroundColorRGB&&(V=50331648,$=e.foregroundColorRGB.rgba>>8&16777215,Z=e.foregroundColorRGB),Q=\"top\"===e.options.layer)})),!Q&&W&&(Y=this._coreBrowserService.isFocused?S.selectionBackgroundOpaque:S.selectionInactiveBackgroundOpaque,G=Y.rgba>>8&16777215,q=50331648,Q=!0,S.selectionForeground&&(V=50331648,$=S.selectionForeground.rgba>>8&16777215,Z=S.selectionForeground)),Q&&I.push(\"xterm-decoration-top\"),q){case 16777216:case 33554432:J=S.ansi[G],I.push(`xterm-bg-${G}`);break;case 50331648:J=h.channels.toColor(G>>16,G>>8&255,255&G),this._addStyle(b,`background-color:#${p((G>>>0).toString(16),\"0\",6)}`);break;default:X?(J=S.foreground,I.push(`xterm-bg-${n.INVERTED_DEFAULT_COLOR}`)):J=S.background}switch(Y||F.isDim()&&(Y=h.color.multiplyOpacity(J,.5)),V){case 16777216:case 33554432:F.isBold()&&$<8&&this._optionsService.rawOptions.drawBoldTextInBrightColors&&($+=8),this._applyMinimumContrast(b,J,S.ansi[$],F,Y,void 0)||I.push(`xterm-fg-${$}`);break;case 50331648:const e=h.channels.toColor($>>16&255,$>>8&255,255&$);this._applyMinimumContrast(b,J,e,F,Y,Z)||this._addStyle(b,`color:#${p($.toString(16),\"0\",6)}`);break;default:this._applyMinimumContrast(b,J,S.foreground,F,Y,Z)||X&&I.push(`xterm-fg-${n.INVERTED_DEFAULT_COLOR}`)}I.length&&(b.className=I.join(\" \"),I.length=0),H||B||z||!N?b.textContent=w:y++,M!==this.defaultSpacing&&(b.style.letterSpacing=`${M}px`),m.push(b),x=U}return b&&y&&(b.textContent=w),m}_applyMinimumContrast(e,t,i,s,r,n){if(1===this._optionsService.rawOptions.minimumContrastRatio||(0,u.treatGlyphAsBackgroundColor)(s.getCode()))return!1;const o=this._getContrastCache(s);let a;if(r||n||(a=o.getColor(t.rgba,i.rgba)),void 0===a){const e=this._optionsService.rawOptions.minimumContrastRatio/(s.isDim()?2:1);a=h.color.ensureContrastRatio(r||t,n||i,e),o.setColor((r||t).rgba,(n||i).rgba,a??null)}return!!a&&(this._addStyle(e,`color:${a.css}`),!0)}_getContrastCache(e){return e.isDim()?this._themeService.colors.halfContrastCache:this._themeService.colors.contrastCache}_addStyle(e,t){e.setAttribute(\"style\",`${e.getAttribute(\"style\")||\"\"}${t};`)}_isCellInSelection(e,t){const i=this._selectionStart,s=this._selectionEnd;return!(!i||!s)&&(this._columnSelectMode?i[0]<=s[0]?e>=i[0]&&t>=i[1]&&e=i[1]&&e>=s[0]&&t<=s[1]:t>i[1]&&t=i[0]&&e=i[0])}};function p(e,t,i){for(;e.length{Object.defineProperty(t,\"__esModule\",{value:!0}),t.WidthCache=void 0,t.WidthCache=class{constructor(e,t){this._flat=new Float32Array(256),this._font=\"\",this._fontSize=0,this._weight=\"normal\",this._weightBold=\"bold\",this._measureElements=[],this._container=e.createElement(\"div\"),this._container.classList.add(\"xterm-width-cache-measure-container\"),this._container.setAttribute(\"aria-hidden\",\"true\"),this._container.style.whiteSpace=\"pre\",this._container.style.fontKerning=\"none\";const i=e.createElement(\"span\");i.classList.add(\"xterm-char-measure-element\");const s=e.createElement(\"span\");s.classList.add(\"xterm-char-measure-element\"),s.style.fontWeight=\"bold\";const r=e.createElement(\"span\");r.classList.add(\"xterm-char-measure-element\"),r.style.fontStyle=\"italic\";const n=e.createElement(\"span\");n.classList.add(\"xterm-char-measure-element\"),n.style.fontWeight=\"bold\",n.style.fontStyle=\"italic\",this._measureElements=[i,s,r,n],this._container.appendChild(i),this._container.appendChild(s),this._container.appendChild(r),this._container.appendChild(n),t.appendChild(this._container),this.clear()}dispose(){this._container.remove(),this._measureElements.length=0,this._holey=void 0}clear(){this._flat.fill(-9999),this._holey=new Map}setFont(e,t,i,s){e===this._font&&t===this._fontSize&&i===this._weight&&s===this._weightBold||(this._font=e,this._fontSize=t,this._weight=i,this._weightBold=s,this._container.style.fontFamily=this._font,this._container.style.fontSize=`${this._fontSize}px`,this._measureElements[0].style.fontWeight=`${i}`,this._measureElements[1].style.fontWeight=`${s}`,this._measureElements[2].style.fontWeight=`${i}`,this._measureElements[3].style.fontWeight=`${s}`,this.clear())}get(e,t,i){let s=0;if(!t&&!i&&1===e.length&&(s=e.charCodeAt(0))<256){if(-9999!==this._flat[s])return this._flat[s];const t=this._measure(e,0);return t>0&&(this._flat[s]=t),t}let r=e;t&&(r+=\"B\"),i&&(r+=\"I\");let n=this._holey.get(r);if(void 0===n){let s=0;t&&(s|=1),i&&(s|=2),n=this._measure(e,s),n>0&&this._holey.set(r,n)}return n}_measure(e,t){const i=this._measureElements[t];return i.textContent=e.repeat(32),i.offsetWidth/32}}},9176:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.INVERTED_DEFAULT_COLOR=void 0,t.INVERTED_DEFAULT_COLOR=257},6181:(e,t)=>{function i(e){return 57508<=e&&e<=57558}function s(e){return e>=128512&&e<=128591||e>=127744&&e<=128511||e>=128640&&e<=128767||e>=9728&&e<=9983||e>=9984&&e<=10175||e>=65024&&e<=65039||e>=129280&&e<=129535||e>=127462&&e<=127487}Object.defineProperty(t,\"__esModule\",{value:!0}),t.throwIfFalsy=function(e){if(!e)throw new Error(\"value must not be falsy\");return e},t.isPowerlineGlyph=i,t.isRestrictedPowerlineGlyph=function(e){return 57520<=e&&e<=57527},t.isEmoji=s,t.allowRescaling=function(e,t,r,n){return 1===t&&r>Math.ceil(1.5*n)&&void 0!==e&&e>255&&!s(e)&&!i(e)&&!function(e){return 57344<=e&&e<=63743}(e)},t.treatGlyphAsBackgroundColor=function(e){return i(e)||function(e){return 9472<=e&&e<=9631}(e)},t.createRenderDimensions=function(){return{css:{canvas:{width:0,height:0},cell:{width:0,height:0}},device:{canvas:{width:0,height:0},cell:{width:0,height:0},char:{width:0,height:0,left:0,top:0}}}},t.computeNextVariantOffset=function(e,t,i=0){return(e-(2*Math.round(t)-i))%(2*Math.round(t))}},2274:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.createSelectionRenderModel=function(){return new i};class i{constructor(){this.clear()}clear(){this.hasSelection=!1,this.columnSelectMode=!1,this.viewportStartRow=0,this.viewportEndRow=0,this.viewportCappedStartRow=0,this.viewportCappedEndRow=0,this.startCol=0,this.endCol=0,this.selectionStart=void 0,this.selectionEnd=void 0}update(e,t,i,s=!1){if(this.selectionStart=t,this.selectionEnd=i,!t||!i||t[0]===i[0]&&t[1]===i[1])return void this.clear();const r=e.buffers.active.ydisp,n=t[1]-r,o=i[1]-r,a=Math.max(n,0),l=Math.min(o,e.rows-1);a>=e.rows||l<0?this.clear():(this.hasSelection=!0,this.columnSelectMode=s,this.viewportStartRow=n,this.viewportEndRow=o,this.viewportCappedStartRow=a,this.viewportCappedEndRow=l,this.startCol=t[0],this.endCol=i[0])}isCellSelected(e,t,i){return!!this.hasSelection&&(i-=e.buffer.active.viewportY,this.columnSelectMode?this.startCol<=this.endCol?t>=this.startCol&&i>=this.viewportCappedStartRow&&t=this.viewportCappedStartRow&&t>=this.endCol&&i<=this.viewportCappedEndRow:i>this.viewportStartRow&&i=this.startCol&&t=this.startCol)}}},5959:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.SelectionModel=void 0,t.SelectionModel=class{constructor(e){this._bufferService=e,this.isSelectAllActive=!1,this.selectionStartLength=0}clearSelection(){this.selectionStart=void 0,this.selectionEnd=void 0,this.isSelectAllActive=!1,this.selectionStartLength=0}get finalSelectionStart(){return this.isSelectAllActive?[0,0]:this.selectionEnd&&this.selectionStart&&this.areSelectionValuesReversed()?this.selectionEnd:this.selectionStart}get finalSelectionEnd(){if(this.isSelectAllActive)return[this._bufferService.cols,this._bufferService.buffer.ybase+this._bufferService.rows-1];if(this.selectionStart){if(!this.selectionEnd||this.areSelectionValuesReversed()){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?e%this._bufferService.cols==0?[this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)-1]:[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[e,this.selectionStart[1]]}if(this.selectionStartLength&&this.selectionEnd[1]===this.selectionStart[1]){const e=this.selectionStart[0]+this.selectionStartLength;return e>this._bufferService.cols?[e%this._bufferService.cols,this.selectionStart[1]+Math.floor(e/this._bufferService.cols)]:[Math.max(e,this.selectionEnd[0]),this.selectionEnd[1]]}return this.selectionEnd}}areSelectionValuesReversed(){const e=this.selectionStart,t=this.selectionEnd;return!(!e||!t)&&(e[1]>t[1]||e[1]===t[1]&&e[0]>t[0])}handleTrim(e){return this.selectionStart&&(this.selectionStart[1]-=e),this.selectionEnd&&(this.selectionEnd[1]-=e),this.selectionEnd&&this.selectionEnd[1]<0?(this.clearSelection(),!0):(this.selectionStart&&this.selectionStart[1]<0&&(this.selectionStart[1]=0),!1)}}},4792:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CharSizeService=void 0;const n=i(6501),o=i(7150),a=i(802);let l=class extends o.Disposable{get hasValidSize(){return this.width>0&&this.height>0}constructor(e,t,i){super(),this._optionsService=i,this.width=0,this.height=0,this._onCharSizeChange=this._register(new a.Emitter),this.onCharSizeChange=this._onCharSizeChange.event;try{this._measureStrategy=this._register(new d(this._optionsService))}catch{this._measureStrategy=this._register(new c(e,t,this._optionsService))}this._register(this._optionsService.onMultipleOptionChange([\"fontFamily\",\"fontSize\"],(()=>this.measure())))}measure(){const e=this._measureStrategy.measure();e.width===this.width&&e.height===this.height||(this.width=e.width,this.height=e.height,this._onCharSizeChange.fire())}};t.CharSizeService=l,t.CharSizeService=l=s([r(2,n.IOptionsService)],l);class h extends o.Disposable{constructor(){super(...arguments),this._result={width:0,height:0}}_validateAndSet(e,t){void 0!==e&&e>0&&void 0!==t&&t>0&&(this._result.width=e,this._result.height=t)}}class c extends h{constructor(e,t,i){super(),this._document=e,this._parentElement=t,this._optionsService=i,this._measureElement=this._document.createElement(\"span\"),this._measureElement.classList.add(\"xterm-char-measure-element\"),this._measureElement.textContent=\"W\".repeat(32),this._measureElement.setAttribute(\"aria-hidden\",\"true\"),this._measureElement.style.whiteSpace=\"pre\",this._measureElement.style.fontKerning=\"none\",this._parentElement.appendChild(this._measureElement)}measure(){return this._measureElement.style.fontFamily=this._optionsService.rawOptions.fontFamily,this._measureElement.style.fontSize=`${this._optionsService.rawOptions.fontSize}px`,this._validateAndSet(Number(this._measureElement.offsetWidth)/32,Number(this._measureElement.offsetHeight)),this._result}}class d extends h{constructor(e){super(),this._optionsService=e,this._canvas=new OffscreenCanvas(100,100),this._ctx=this._canvas.getContext(\"2d\");const t=this._ctx.measureText(\"W\");if(!(\"width\"in t&&\"fontBoundingBoxAscent\"in t&&\"fontBoundingBoxDescent\"in t))throw new Error(\"Required font metrics not supported\")}measure(){this._ctx.font=`${this._optionsService.rawOptions.fontSize}px ${this._optionsService.rawOptions.fontFamily}`;const e=this._ctx.measureText(\"W\");return this._validateAndSet(e.width,e.fontBoundingBoxAscent+e.fontBoundingBoxDescent),this._result}}},945:function(e,t,i){var s,r=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},n=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CharacterJoinerService=t.JoinedCellData=void 0;const o=i(5451),a=i(8938),l=i(3055),h=i(6501);class c extends o.AttributeData{constructor(e,t,i){super(),this.content=0,this.combinedData=\"\",this.fg=e.fg,this.bg=e.bg,this.combinedData=t,this._width=i}isCombined(){return 2097152}getWidth(){return this._width}getChars(){return this.combinedData}getCode(){return 2097151}setFromCharData(e){throw new Error(\"not implemented\")}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.JoinedCellData=c;let d=s=class{constructor(e){this._bufferService=e,this._characterJoiners=[],this._nextCharacterJoinerId=0,this._workCell=new l.CellData}register(e){const t={id:this._nextCharacterJoinerId++,handler:e};return this._characterJoiners.push(t),t.id}deregister(e){for(let t=0;t1){const e=this._getJoinedRanges(s,o,n,t,r);for(let t=0;t1){const e=this._getJoinedRanges(s,o,n,t,r);for(let t=0;t{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CoreBrowserService=void 0;const s=i(802),r=i(7093),n=i(7150);class o extends n.Disposable{constructor(e,t,i){super(),this._textarea=e,this._window=t,this.mainDocument=i,this._isFocused=!1,this._cachedIsFocused=void 0,this._screenDprMonitor=this._register(new a(this._window)),this._onDprChange=this._register(new s.Emitter),this.onDprChange=this._onDprChange.event,this._onWindowChange=this._register(new s.Emitter),this.onWindowChange=this._onWindowChange.event,this._register(this.onWindowChange((e=>this._screenDprMonitor.setWindow(e)))),this._register(s.Event.forward(this._screenDprMonitor.onDprChange,this._onDprChange)),this._register((0,r.addDisposableListener)(this._textarea,\"focus\",(()=>this._isFocused=!0))),this._register((0,r.addDisposableListener)(this._textarea,\"blur\",(()=>this._isFocused=!1)))}get window(){return this._window}set window(e){this._window!==e&&(this._window=e,this._onWindowChange.fire(this._window))}get dpr(){return this.window.devicePixelRatio}get isFocused(){return void 0===this._cachedIsFocused&&(this._cachedIsFocused=this._isFocused&&this._textarea.ownerDocument.hasFocus(),queueMicrotask((()=>this._cachedIsFocused=void 0))),this._cachedIsFocused}}t.CoreBrowserService=o;class a extends n.Disposable{constructor(e){super(),this._parentWindow=e,this._windowResizeListener=this._register(new n.MutableDisposable),this._onDprChange=this._register(new s.Emitter),this.onDprChange=this._onDprChange.event,this._outerListener=()=>this._setDprAndFireIfDiffers(),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._updateDpr(),this._setWindowResizeListener(),this._register((0,n.toDisposable)((()=>this.clearListener())))}setWindow(e){this._parentWindow=e,this._setWindowResizeListener(),this._setDprAndFireIfDiffers()}_setWindowResizeListener(){this._windowResizeListener.value=(0,r.addDisposableListener)(this._parentWindow,\"resize\",(()=>this._setDprAndFireIfDiffers()))}_setDprAndFireIfDiffers(){this._parentWindow.devicePixelRatio!==this._currentDevicePixelRatio&&this._onDprChange.fire(this._parentWindow.devicePixelRatio),this._updateDpr()}_updateDpr(){this._outerListener&&(this._resolutionMediaMatchList?.removeListener(this._outerListener),this._currentDevicePixelRatio=this._parentWindow.devicePixelRatio,this._resolutionMediaMatchList=this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`),this._resolutionMediaMatchList.addListener(this._outerListener))}clearListener(){this._resolutionMediaMatchList&&this._outerListener&&(this._resolutionMediaMatchList.removeListener(this._outerListener),this._resolutionMediaMatchList=void 0,this._outerListener=void 0)}}},9820:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LinkProviderService=void 0;const s=i(7150);class r extends s.Disposable{constructor(){super(),this.linkProviders=[],this._register((0,s.toDisposable)((()=>this.linkProviders.length=0)))}registerLinkProvider(e){return this.linkProviders.push(e),{dispose:()=>{const t=this.linkProviders.indexOf(e);-1!==t&&this.linkProviders.splice(t,1)}}}}t.LinkProviderService=r},9784:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.MouseService=void 0;const n=i(7098),o=i(5251);let a=class{constructor(e,t){this._renderService=e,this._charSizeService=t}getCoords(e,t,i,s,r){return(0,o.getCoords)(window,e,t,i,s,this._charSizeService.hasValidSize,this._renderService.dimensions.css.cell.width,this._renderService.dimensions.css.cell.height,r)}getMouseReportCoords(e,t){const i=(0,o.getCoordsRelativeToElement)(window,e,t);if(this._charSizeService.hasValidSize)return i[0]=Math.min(Math.max(i[0],0),this._renderService.dimensions.css.canvas.width-1),i[1]=Math.min(Math.max(i[1],0),this._renderService.dimensions.css.canvas.height-1),{col:Math.floor(i[0]/this._renderService.dimensions.css.cell.width),row:Math.floor(i[1]/this._renderService.dimensions.css.cell.height),x:Math.floor(i[0]),y:Math.floor(i[1])}}};t.MouseService=a,t.MouseService=a=s([r(0,n.IRenderService),r(1,n.ICharSizeService)],a)},5783:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.RenderService=void 0;const n=i(4852),o=i(7098),a=i(7150),l=i(6168),h=i(6501),c=i(802);let d=class extends a.Disposable{get dimensions(){return this._renderer.value.dimensions}constructor(e,t,i,s,r,o,h,d,_){super(),this._rowCount=e,this._optionsService=i,this._charSizeService=s,this._coreService=r,this._coreBrowserService=d,this._renderer=this._register(new a.MutableDisposable),this._pausedResizeTask=new l.DebouncedIdleTask,this._observerDisposable=this._register(new a.MutableDisposable),this._isPaused=!1,this._needsFullRefresh=!1,this._isNextRenderRedrawOnly=!0,this._needsSelectionRefresh=!1,this._canvasWidth=0,this._canvasHeight=0,this._selectionState={start:void 0,end:void 0,columnSelectMode:!1},this._onDimensionsChange=this._register(new c.Emitter),this.onDimensionsChange=this._onDimensionsChange.event,this._onRenderedViewportChange=this._register(new c.Emitter),this.onRenderedViewportChange=this._onRenderedViewportChange.event,this._onRender=this._register(new c.Emitter),this.onRender=this._onRender.event,this._onRefreshRequest=this._register(new c.Emitter),this.onRefreshRequest=this._onRefreshRequest.event,this._renderDebouncer=new n.RenderDebouncer(((e,t)=>this._renderRows(e,t)),this._coreBrowserService),this._register(this._renderDebouncer),this._syncOutputHandler=new u(this._coreBrowserService,this._coreService,(()=>this._fullRefresh())),this._register((0,a.toDisposable)((()=>this._syncOutputHandler.dispose()))),this._register(this._coreBrowserService.onDprChange((()=>this.handleDevicePixelRatioChange()))),this._register(h.onResize((()=>this._fullRefresh()))),this._register(h.buffers.onBufferActivate((()=>this._renderer.value?.clear()))),this._register(this._optionsService.onOptionChange((()=>this._handleOptionsChanged()))),this._register(this._charSizeService.onCharSizeChange((()=>this.handleCharSizeChanged()))),this._register(o.onDecorationRegistered((()=>this._fullRefresh()))),this._register(o.onDecorationRemoved((()=>this._fullRefresh()))),this._register(this._optionsService.onMultipleOptionChange([\"customGlyphs\",\"drawBoldTextInBrightColors\",\"letterSpacing\",\"lineHeight\",\"fontFamily\",\"fontSize\",\"fontWeight\",\"fontWeightBold\",\"minimumContrastRatio\",\"rescaleOverlappingGlyphs\"],(()=>{this.clear(),this.handleResize(h.cols,h.rows),this._fullRefresh()}))),this._register(this._optionsService.onMultipleOptionChange([\"cursorBlink\",\"cursorStyle\"],(()=>this.refreshRows(h.buffer.y,h.buffer.y,!0)))),this._register(_.onChangeColors((()=>this._fullRefresh()))),this._registerIntersectionObserver(this._coreBrowserService.window,t),this._register(this._coreBrowserService.onWindowChange((e=>this._registerIntersectionObserver(e,t))))}_registerIntersectionObserver(e,t){if(\"IntersectionObserver\"in e){const i=new e.IntersectionObserver((e=>this._handleIntersectionChange(e[e.length-1])),{threshold:0});i.observe(t),this._observerDisposable.value=(0,a.toDisposable)((()=>i.disconnect()))}}_handleIntersectionChange(e){this._isPaused=void 0===e.isIntersecting?0===e.intersectionRatio:!e.isIntersecting,this._isPaused||this._charSizeService.hasValidSize||this._charSizeService.measure(),!this._isPaused&&this._needsFullRefresh&&(this._pausedResizeTask.flush(),this.refreshRows(0,this._rowCount-1),this._needsFullRefresh=!1)}refreshRows(e,t,i=!1){if(this._isPaused)return void(this._needsFullRefresh=!0);if(this._coreService.decPrivateModes.synchronizedOutput)return void this._syncOutputHandler.bufferRows(e,t);const s=this._syncOutputHandler.flush();s&&(e=Math.min(e,s.start),t=Math.max(t,s.end)),i||(this._isNextRenderRedrawOnly=!1),this._renderDebouncer.refresh(e,t,this._rowCount)}_renderRows(e,t){this._renderer.value&&(this._coreService.decPrivateModes.synchronizedOutput?this._syncOutputHandler.bufferRows(e,t):(e=Math.min(e,this._rowCount-1),t=Math.min(t,this._rowCount-1),this._renderer.value.renderRows(e,t),this._needsSelectionRefresh&&(this._renderer.value.handleSelectionChanged(this._selectionState.start,this._selectionState.end,this._selectionState.columnSelectMode),this._needsSelectionRefresh=!1),this._isNextRenderRedrawOnly||this._onRenderedViewportChange.fire({start:e,end:t}),this._onRender.fire({start:e,end:t}),this._isNextRenderRedrawOnly=!0))}resize(e,t){this._rowCount=t,this._fireOnCanvasResize()}_handleOptionsChanged(){this._renderer.value&&(this.refreshRows(0,this._rowCount-1),this._fireOnCanvasResize())}_fireOnCanvasResize(){this._renderer.value&&(this._renderer.value.dimensions.css.canvas.width===this._canvasWidth&&this._renderer.value.dimensions.css.canvas.height===this._canvasHeight||this._onDimensionsChange.fire(this._renderer.value.dimensions))}hasRenderer(){return!!this._renderer.value}setRenderer(e){this._renderer.value=e,this._renderer.value&&(this._renderer.value.onRequestRedraw((e=>this.refreshRows(e.start,e.end,!0))),this._needsSelectionRefresh=!0,this._fullRefresh())}addRefreshCallback(e){return this._renderDebouncer.addRefreshCallback(e)}_fullRefresh(){this._isPaused?this._needsFullRefresh=!0:this.refreshRows(0,this._rowCount-1)}clearTextureAtlas(){this._renderer.value&&(this._renderer.value.clearTextureAtlas?.(),this._fullRefresh())}handleDevicePixelRatioChange(){this._charSizeService.measure(),this._renderer.value&&(this._renderer.value.handleDevicePixelRatioChange(),this.refreshRows(0,this._rowCount-1))}handleResize(e,t){this._renderer.value&&(this._isPaused?this._pausedResizeTask.set((()=>this._renderer.value?.handleResize(e,t))):this._renderer.value.handleResize(e,t),this._fullRefresh())}handleCharSizeChanged(){this._renderer.value?.handleCharSizeChanged()}handleBlur(){this._renderer.value?.handleBlur()}handleFocus(){this._renderer.value?.handleFocus()}handleSelectionChanged(e,t,i){this._selectionState.start=e,this._selectionState.end=t,this._selectionState.columnSelectMode=i,this._renderer.value?.handleSelectionChanged(e,t,i)}handleCursorMove(){this._renderer.value?.handleCursorMove()}clear(){this._renderer.value?.clear()}};t.RenderService=d,t.RenderService=d=s([r(2,h.IOptionsService),r(3,o.ICharSizeService),r(4,h.ICoreService),r(5,h.IDecorationService),r(6,h.IBufferService),r(7,o.ICoreBrowserService),r(8,o.IThemeService)],d);class u{constructor(e,t,i){this._coreBrowserService=e,this._coreService=t,this._onTimeout=i,this._start=0,this._end=0,this._isBuffering=!1}bufferRows(e,t){this._isBuffering?(this._start=Math.min(this._start,e),this._end=Math.max(this._end,t)):(this._start=e,this._end=t,this._isBuffering=!0),void 0===this._timeout&&(this._timeout=this._coreBrowserService.window.setTimeout((()=>{this._timeout=void 0,this._coreService.decPrivateModes.synchronizedOutput=!1,this._onTimeout()}),1e3))}flush(){if(void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0),!this._isBuffering)return;const e={start:this._start,end:this._end};return this._isBuffering=!1,e}dispose(){void 0!==this._timeout&&(this._coreBrowserService.window.clearTimeout(this._timeout),this._timeout=void 0)}}},2079:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.SelectionService=void 0;const n=i(5251),o=i(9686),a=i(5959),l=i(7098),h=i(7150),c=i(701),d=i(9384),u=i(3055),_=i(6501),f=i(802),p=String.fromCharCode(160),g=new RegExp(p,\"g\");let m=class extends h.Disposable{constructor(e,t,i,s,r,n,o,l,c){super(),this._element=e,this._screenElement=t,this._linkifier=i,this._bufferService=s,this._coreService=r,this._mouseService=n,this._optionsService=o,this._renderService=l,this._coreBrowserService=c,this._dragScrollAmount=0,this._enabled=!0,this._workCell=new u.CellData,this._mouseDownTimeStamp=0,this._oldHasSelection=!1,this._oldSelectionStart=void 0,this._oldSelectionEnd=void 0,this._onLinuxMouseSelection=this._register(new f.Emitter),this.onLinuxMouseSelection=this._onLinuxMouseSelection.event,this._onRedrawRequest=this._register(new f.Emitter),this.onRequestRedraw=this._onRedrawRequest.event,this._onSelectionChange=this._register(new f.Emitter),this.onSelectionChange=this._onSelectionChange.event,this._onRequestScrollLines=this._register(new f.Emitter),this.onRequestScrollLines=this._onRequestScrollLines.event,this._mouseMoveListener=e=>this._handleMouseMove(e),this._mouseUpListener=e=>this._handleMouseUp(e),this._coreService.onUserInput((()=>{this.hasSelection&&this.clearSelection()})),this._trimListener=this._bufferService.buffer.lines.onTrim((e=>this._handleTrim(e))),this._register(this._bufferService.buffers.onBufferActivate((e=>this._handleBufferActivate(e)))),this.enable(),this._model=new a.SelectionModel(this._bufferService),this._activeSelectionMode=0,this._register((0,h.toDisposable)((()=>{this._removeMouseDownListeners()}))),this._register(this._bufferService.onResize((e=>{e.rowsChanged&&this.clearSelection()})))}reset(){this.clearSelection()}disable(){this.clearSelection(),this._enabled=!1}enable(){this._enabled=!0}get selectionStart(){return this._model.finalSelectionStart}get selectionEnd(){return this._model.finalSelectionEnd}get hasSelection(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;return!(!e||!t||e[0]===t[0]&&e[1]===t[1])}get selectionText(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd;if(!e||!t)return\"\";const i=this._bufferService.buffer,s=[];if(3===this._activeSelectionMode){if(e[0]===t[0])return\"\";const r=e[0]e.replace(g,\" \"))).join(c.isWindows?\"\\r\\n\":\"\\n\")}clearSelection(){this._model.clearSelection(),this._removeMouseDownListeners(),this.refresh(),this._onSelectionChange.fire()}refresh(e){this._refreshAnimationFrame||(this._refreshAnimationFrame=this._coreBrowserService.window.requestAnimationFrame((()=>this._refresh()))),c.isLinux&&e&&this.selectionText.length&&this._onLinuxMouseSelection.fire(this.selectionText)}_refresh(){this._refreshAnimationFrame=void 0,this._onRedrawRequest.fire({start:this._model.finalSelectionStart,end:this._model.finalSelectionEnd,columnSelectMode:3===this._activeSelectionMode})}_isClickInSelection(e){const t=this._getMouseBufferCoords(e),i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!!(i&&s&&t)&&this._areCoordsInSelection(t,i,s)}isCellInSelection(e,t){const i=this._model.finalSelectionStart,s=this._model.finalSelectionEnd;return!(!i||!s)&&this._areCoordsInSelection([e,t],i,s)}_areCoordsInSelection(e,t,i){return e[1]>t[1]&&e[1]=t[0]&&e[0]=t[0]}_selectWordAtCursor(e,t){const i=this._linkifier.currentLink?.link?.range;if(i)return this._model.selectionStart=[i.start.x-1,i.start.y-1],this._model.selectionStartLength=(0,d.getRangeLength)(i,this._bufferService.cols),this._model.selectionEnd=void 0,!0;const s=this._getMouseBufferCoords(e);return!!s&&(this._selectWordAt(s,t),this._model.selectionEnd=void 0,!0)}selectAll(){this._model.isSelectAllActive=!0,this.refresh(),this._onSelectionChange.fire()}selectLines(e,t){this._model.clearSelection(),e=Math.max(e,0),t=Math.min(t,this._bufferService.buffer.lines.length-1),this._model.selectionStart=[0,e],this._model.selectionEnd=[this._bufferService.cols,t],this.refresh(),this._onSelectionChange.fire()}_handleTrim(e){this._model.handleTrim(e)&&this.refresh()}_getMouseBufferCoords(e){const t=this._mouseService.getCoords(e,this._screenElement,this._bufferService.cols,this._bufferService.rows,!0);if(t)return t[0]--,t[1]--,t[1]+=this._bufferService.buffer.ydisp,t}_getMouseEventScrollAmount(e){let t=(0,n.getCoordsRelativeToElement)(this._coreBrowserService.window,e,this._screenElement)[1];const i=this._renderService.dimensions.css.canvas.height;return t>=0&&t<=i?0:(t>i&&(t-=i),t=Math.min(Math.max(t,-50),50),t/=50,t/Math.abs(t)+Math.round(14*t))}shouldForceSelection(e){return c.isMac?e.altKey&&this._optionsService.rawOptions.macOptionClickForcesSelection:e.shiftKey}handleMouseDown(e){if(this._mouseDownTimeStamp=e.timeStamp,(2!==e.button||!this.hasSelection)&&0===e.button){if(!this._enabled){if(!this.shouldForceSelection(e))return;e.stopPropagation()}e.preventDefault(),this._dragScrollAmount=0,this._enabled&&e.shiftKey?this._handleIncrementalClick(e):1===e.detail?this._handleSingleClick(e):2===e.detail?this._handleDoubleClick(e):3===e.detail&&this._handleTripleClick(e),this._addMouseDownListeners(),this.refresh(!0)}}_addMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.addEventListener(\"mousemove\",this._mouseMoveListener),this._screenElement.ownerDocument.addEventListener(\"mouseup\",this._mouseUpListener)),this._dragScrollIntervalTimer=this._coreBrowserService.window.setInterval((()=>this._dragScroll()),50)}_removeMouseDownListeners(){this._screenElement.ownerDocument&&(this._screenElement.ownerDocument.removeEventListener(\"mousemove\",this._mouseMoveListener),this._screenElement.ownerDocument.removeEventListener(\"mouseup\",this._mouseUpListener)),this._coreBrowserService.window.clearInterval(this._dragScrollIntervalTimer),this._dragScrollIntervalTimer=void 0}_handleIncrementalClick(e){this._model.selectionStart&&(this._model.selectionEnd=this._getMouseBufferCoords(e))}_handleSingleClick(e){if(this._model.selectionStartLength=0,this._model.isSelectAllActive=!1,this._activeSelectionMode=this.shouldColumnSelect(e)?3:0,this._model.selectionStart=this._getMouseBufferCoords(e),!this._model.selectionStart)return;this._model.selectionEnd=void 0;const t=this._bufferService.buffer.lines.get(this._model.selectionStart[1]);t&&t.length!==this._model.selectionStart[0]&&0===t.hasWidth(this._model.selectionStart[0])&&this._model.selectionStart[0]++}_handleDoubleClick(e){this._selectWordAtCursor(e,!0)&&(this._activeSelectionMode=1)}_handleTripleClick(e){const t=this._getMouseBufferCoords(e);t&&(this._activeSelectionMode=2,this._selectLineAt(t[1]))}shouldColumnSelect(e){return e.altKey&&!(c.isMac&&this._optionsService.rawOptions.macOptionClickForcesSelection)}_handleMouseMove(e){if(e.stopImmediatePropagation(),!this._model.selectionStart)return;const t=this._model.selectionEnd?[this._model.selectionEnd[0],this._model.selectionEnd[1]]:null;if(this._model.selectionEnd=this._getMouseBufferCoords(e),!this._model.selectionEnd)return void this.refresh(!0);2===this._activeSelectionMode?this._model.selectionEnd[1]0?this._model.selectionEnd[0]=this._bufferService.cols:this._dragScrollAmount<0&&(this._model.selectionEnd[0]=0));const i=this._bufferService.buffer;if(this._model.selectionEnd[1]0?(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=this._bufferService.cols),this._model.selectionEnd[1]=Math.min(e.ydisp+this._bufferService.rows,e.lines.length-1)):(3!==this._activeSelectionMode&&(this._model.selectionEnd[0]=0),this._model.selectionEnd[1]=e.ydisp),this.refresh()}}_handleMouseUp(e){const t=e.timeStamp-this._mouseDownTimeStamp;if(this._removeMouseDownListeners(),this.selectionText.length<=1&&t<500&&e.altKey&&this._optionsService.rawOptions.altClickMovesCursor){if(this._bufferService.buffer.ybase===this._bufferService.buffer.ydisp){const t=this._mouseService.getCoords(e,this._element,this._bufferService.cols,this._bufferService.rows,!1);if(t&&void 0!==t[0]&&void 0!==t[1]){const e=(0,o.moveToCellSequence)(t[0]-1,t[1]-1,this._bufferService,this._coreService.decPrivateModes.applicationCursorKeys);this._coreService.triggerDataEvent(e,!0)}}}else this._fireEventIfSelectionChanged()}_fireEventIfSelectionChanged(){const e=this._model.finalSelectionStart,t=this._model.finalSelectionEnd,i=!(!e||!t||e[0]===t[0]&&e[1]===t[1]);i?e&&t&&(this._oldSelectionStart&&this._oldSelectionEnd&&e[0]===this._oldSelectionStart[0]&&e[1]===this._oldSelectionStart[1]&&t[0]===this._oldSelectionEnd[0]&&t[1]===this._oldSelectionEnd[1]||this._fireOnSelectionChange(e,t,i)):this._oldHasSelection&&this._fireOnSelectionChange(e,t,i)}_fireOnSelectionChange(e,t,i){this._oldSelectionStart=e,this._oldSelectionEnd=t,this._oldHasSelection=i,this._onSelectionChange.fire()}_handleBufferActivate(e){this.clearSelection(),this._trimListener.dispose(),this._trimListener=e.activeBuffer.lines.onTrim((e=>this._handleTrim(e)))}_convertViewportColToCharacterIndex(e,t){let i=t;for(let s=0;t>=s;s++){const r=e.loadCell(s,this._workCell).getChars().length;0===this._workCell.getWidth()?i--:r>1&&t!==s&&(i+=r-1)}return i}setSelection(e,t,i){this._model.clearSelection(),this._removeMouseDownListeners(),this._model.selectionStart=[e,t],this._model.selectionStartLength=i,this.refresh(),this._fireEventIfSelectionChanged()}rightClickSelect(e){this._isClickInSelection(e)||(this._selectWordAtCursor(e,!1)&&this.refresh(!0),this._fireEventIfSelectionChanged())}_getWordAt(e,t,i=!0,s=!0){if(e[0]>=this._bufferService.cols)return;const r=this._bufferService.buffer,n=r.lines.get(e[1]);if(!n)return;const o=r.translateBufferLineToString(e[1],!1);let a=this._convertViewportColToCharacterIndex(n,e[0]),l=a;const h=e[0]-a;let c=0,d=0,u=0,_=0;if(\" \"===o.charAt(a)){for(;a>0&&\" \"===o.charAt(a-1);)a--;for(;l1&&(_+=s-1,l+=s-1);t>0&&a>0&&!this._isCharWordSeparator(n.loadCell(t-1,this._workCell));){n.loadCell(t-1,this._workCell);const e=this._workCell.getChars().length;0===this._workCell.getWidth()?(c++,t--):e>1&&(u+=e-1,a-=e-1),a--,t--}for(;i1&&(_+=e-1,l+=e-1),l++,i++}}l++;let f=a+h-c+u,p=Math.min(this._bufferService.cols,l-a+c+d-u-_);if(t||\"\"!==o.slice(a,l).trim()){if(i&&0===f&&32!==n.getCodePoint(0)){const t=r.lines.get(e[1]-1);if(t&&n.isWrapped&&32!==t.getCodePoint(this._bufferService.cols-1)){const t=this._getWordAt([this._bufferService.cols-1,e[1]-1],!1,!0,!1);if(t){const e=this._bufferService.cols-t.start;f-=e,p+=e}}}if(s&&f+p===this._bufferService.cols&&32!==n.getCodePoint(this._bufferService.cols-1)){const t=r.lines.get(e[1]+1);if(t?.isWrapped&&32!==t.getCodePoint(0)){const t=this._getWordAt([0,e[1]+1],!1,!1,!0);t&&(p+=t.length)}}return{start:f,length:p}}}_selectWordAt(e,t){const i=this._getWordAt(e,t);if(i){for(;i.start<0;)i.start+=this._bufferService.cols,e[1]--;this._model.selectionStart=[i.start,e[1]],this._model.selectionStartLength=i.length}}_selectToWordAt(e){const t=this._getWordAt(e,!0);if(t){let i=e[1];for(;t.start<0;)t.start+=this._bufferService.cols,i--;if(!this._model.areSelectionValuesReversed())for(;t.start+t.length>this._bufferService.cols;)t.length-=this._bufferService.cols,i++;this._model.selectionEnd=[this._model.areSelectionValuesReversed()?t.start:t.start+t.length,i]}}_isCharWordSeparator(e){return 0!==e.getWidth()&&this._optionsService.rawOptions.wordSeparator.indexOf(e.getChars())>=0}_selectLineAt(e){const t=this._bufferService.buffer.getWrappedRangeForLine(e),i={start:{x:0,y:t.first},end:{x:this._bufferService.cols-1,y:t.last}};this._model.selectionStart=[0,t.first],this._model.selectionEnd=void 0,this._model.selectionStartLength=(0,d.getRangeLength)(i,this._bufferService.cols)}};t.SelectionService=m,t.SelectionService=m=s([r(3,_.IBufferService),r(4,_.ICoreService),r(5,l.IMouseService),r(6,_.IOptionsService),r(7,l.IRenderService),r(8,l.ICoreBrowserService)],m)},7098:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ILinkProviderService=t.IThemeService=t.ICharacterJoinerService=t.ISelectionService=t.IRenderService=t.IMouseService=t.ICoreBrowserService=t.ICharSizeService=void 0;const s=i(6201);t.ICharSizeService=(0,s.createDecorator)(\"CharSizeService\"),t.ICoreBrowserService=(0,s.createDecorator)(\"CoreBrowserService\"),t.IMouseService=(0,s.createDecorator)(\"MouseService\"),t.IRenderService=(0,s.createDecorator)(\"RenderService\"),t.ISelectionService=(0,s.createDecorator)(\"SelectionService\"),t.ICharacterJoinerService=(0,s.createDecorator)(\"CharacterJoinerService\"),t.IThemeService=(0,s.createDecorator)(\"ThemeService\"),t.ILinkProviderService=(0,s.createDecorator)(\"LinkProviderService\")},9078:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.ThemeService=void 0;const n=i(7174),o=i(9302),a=i(4103),l=i(7150),h=i(6501),c=i(802),d=a.css.toColor(\"#ffffff\"),u=a.css.toColor(\"#000000\"),_=a.css.toColor(\"#ffffff\"),f=u,p={css:\"rgba(255, 255, 255, 0.3)\",rgba:4294967117},g=d;let m=class extends l.Disposable{get colors(){return this._colors}constructor(e){super(),this._optionsService=e,this._contrastCache=new n.ColorContrastCache,this._halfContrastCache=new n.ColorContrastCache,this._onChangeColors=this._register(new c.Emitter),this.onChangeColors=this._onChangeColors.event,this._colors={foreground:d,background:u,cursor:_,cursorAccent:f,selectionForeground:void 0,selectionBackgroundTransparent:p,selectionBackgroundOpaque:a.color.blend(u,p),selectionInactiveBackgroundTransparent:p,selectionInactiveBackgroundOpaque:a.color.blend(u,p),scrollbarSliderBackground:a.color.opacity(d,.2),scrollbarSliderHoverBackground:a.color.opacity(d,.4),scrollbarSliderActiveBackground:a.color.opacity(d,.5),overviewRulerBorder:d,ansi:o.DEFAULT_ANSI_COLORS.slice(),contrastCache:this._contrastCache,halfContrastCache:this._halfContrastCache},this._updateRestoreColors(),this._setTheme(this._optionsService.rawOptions.theme),this._register(this._optionsService.onSpecificOptionChange(\"minimumContrastRatio\",(()=>this._contrastCache.clear()))),this._register(this._optionsService.onSpecificOptionChange(\"theme\",(()=>this._setTheme(this._optionsService.rawOptions.theme))))}_setTheme(e={}){const t=this._colors;if(t.foreground=v(e.foreground,d),t.background=v(e.background,u),t.cursor=a.color.blend(t.background,v(e.cursor,_)),t.cursorAccent=a.color.blend(t.background,v(e.cursorAccent,f)),t.selectionBackgroundTransparent=v(e.selectionBackground,p),t.selectionBackgroundOpaque=a.color.blend(t.background,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundTransparent=v(e.selectionInactiveBackground,t.selectionBackgroundTransparent),t.selectionInactiveBackgroundOpaque=a.color.blend(t.background,t.selectionInactiveBackgroundTransparent),t.selectionForeground=e.selectionForeground?v(e.selectionForeground,a.NULL_COLOR):void 0,t.selectionForeground===a.NULL_COLOR&&(t.selectionForeground=void 0),a.color.isOpaque(t.selectionBackgroundTransparent)){const e=.3;t.selectionBackgroundTransparent=a.color.opacity(t.selectionBackgroundTransparent,e)}if(a.color.isOpaque(t.selectionInactiveBackgroundTransparent)){const e=.3;t.selectionInactiveBackgroundTransparent=a.color.opacity(t.selectionInactiveBackgroundTransparent,e)}if(t.scrollbarSliderBackground=v(e.scrollbarSliderBackground,a.color.opacity(t.foreground,.2)),t.scrollbarSliderHoverBackground=v(e.scrollbarSliderHoverBackground,a.color.opacity(t.foreground,.4)),t.scrollbarSliderActiveBackground=v(e.scrollbarSliderActiveBackground,a.color.opacity(t.foreground,.5)),t.overviewRulerBorder=v(e.overviewRulerBorder,g),t.ansi=o.DEFAULT_ANSI_COLORS.slice(),t.ansi[0]=v(e.black,o.DEFAULT_ANSI_COLORS[0]),t.ansi[1]=v(e.red,o.DEFAULT_ANSI_COLORS[1]),t.ansi[2]=v(e.green,o.DEFAULT_ANSI_COLORS[2]),t.ansi[3]=v(e.yellow,o.DEFAULT_ANSI_COLORS[3]),t.ansi[4]=v(e.blue,o.DEFAULT_ANSI_COLORS[4]),t.ansi[5]=v(e.magenta,o.DEFAULT_ANSI_COLORS[5]),t.ansi[6]=v(e.cyan,o.DEFAULT_ANSI_COLORS[6]),t.ansi[7]=v(e.white,o.DEFAULT_ANSI_COLORS[7]),t.ansi[8]=v(e.brightBlack,o.DEFAULT_ANSI_COLORS[8]),t.ansi[9]=v(e.brightRed,o.DEFAULT_ANSI_COLORS[9]),t.ansi[10]=v(e.brightGreen,o.DEFAULT_ANSI_COLORS[10]),t.ansi[11]=v(e.brightYellow,o.DEFAULT_ANSI_COLORS[11]),t.ansi[12]=v(e.brightBlue,o.DEFAULT_ANSI_COLORS[12]),t.ansi[13]=v(e.brightMagenta,o.DEFAULT_ANSI_COLORS[13]),t.ansi[14]=v(e.brightCyan,o.DEFAULT_ANSI_COLORS[14]),t.ansi[15]=v(e.brightWhite,o.DEFAULT_ANSI_COLORS[15]),e.extendedAnsi){const i=Math.min(t.ansi.length-16,e.extendedAnsi.length);for(let s=0;s{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CircularList=void 0;const s=i(7150),r=i(802);class n extends s.Disposable{constructor(e){super(),this._maxLength=e,this.onDeleteEmitter=this._register(new r.Emitter),this.onDelete=this.onDeleteEmitter.event,this.onInsertEmitter=this._register(new r.Emitter),this.onInsert=this.onInsertEmitter.event,this.onTrimEmitter=this._register(new r.Emitter),this.onTrim=this.onTrimEmitter.event,this._array=new Array(this._maxLength),this._startIndex=0,this._length=0}get maxLength(){return this._maxLength}set maxLength(e){if(this._maxLength===e)return;const t=new Array(e);for(let i=0;ithis._length)for(let t=this._length;t=e;t--)this._array[this._getCyclicIndex(t+i.length)]=this._array[this._getCyclicIndex(t)];for(let t=0;tthis._maxLength){const e=this._length+i.length-this._maxLength;this._startIndex+=e,this._length=this._maxLength,this.onTrimEmitter.fire(e)}else this._length+=i.length}trimStart(e){e>this._length&&(e=this._length),this._startIndex+=e,this._length-=e,this.onTrimEmitter.fire(e)}shiftElements(e,t,i){if(!(t<=0)){if(e<0||e>=this._length)throw new Error(\"start argument out of range\");if(e+i<0)throw new Error(\"Cannot shift elements in list beyond index 0\");if(i>0){for(let s=t-1;s>=0;s--)this.set(e+s+i,this.get(e+s));const s=e+t+i-this._length;if(s>0)for(this._length+=s;this._length>this._maxLength;)this._length--,this._startIndex++,this.onTrimEmitter.fire(1)}else for(let s=0;s{Object.defineProperty(t,\"__esModule\",{value:!0}),t.clone=function e(t,i=5){if(\"object\"!=typeof t)return t;const s=Array.isArray(t)?[]:{};for(const r in t)s[r]=i<=1?t[r]:t[r]&&e(t[r],i-1);return s}},4103:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.rgba=t.rgb=t.css=t.color=t.channels=t.NULL_COLOR=void 0,t.toPaddedHex=d,t.contrastRatio=u;let i=0,s=0,r=0,n=0;var o,a,l,h,c;function d(e){const t=e.toString(16);return t.length<2?\"0\"+t:t}function u(e,t){return e>>0},e.toColor=function(t,i,s,r){return{css:e.toCss(t,i,s,r),rgba:e.toRgba(t,i,s,r)}}}(o||(t.channels=o={})),function(e){function t(e,t){return n=Math.round(255*t),[i,s,r]=c.toChannels(e.rgba),{css:o.toCss(i,s,r,n),rgba:o.toRgba(i,s,r,n)}}e.blend=function(e,t){if(n=(255&t.rgba)/255,1===n)return{css:t.css,rgba:t.rgba};const a=t.rgba>>24&255,l=t.rgba>>16&255,h=t.rgba>>8&255,c=e.rgba>>24&255,d=e.rgba>>16&255,u=e.rgba>>8&255;return i=c+Math.round((a-c)*n),s=d+Math.round((l-d)*n),r=u+Math.round((h-u)*n),{css:o.toCss(i,s,r),rgba:o.toRgba(i,s,r)}},e.isOpaque=function(e){return!(255&~e.rgba)},e.ensureContrastRatio=function(e,t,i){const s=c.ensureContrastRatio(e.rgba,t.rgba,i);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},e.opaque=function(e){const t=(255|e.rgba)>>>0;return[i,s,r]=c.toChannels(t),{css:o.toCss(i,s,r),rgba:t}},e.opacity=t,e.multiplyOpacity=function(e,i){return n=255&e.rgba,t(e,n*i/255)},e.toColorRGB=function(e){return[e.rgba>>24&255,e.rgba>>16&255,e.rgba>>8&255]}}(a||(t.color=a={})),function(e){let t,a;try{const e=document.createElement(\"canvas\");e.width=1,e.height=1;const i=e.getContext(\"2d\",{willReadFrequently:!0});i&&(t=i,t.globalCompositeOperation=\"copy\",a=t.createLinearGradient(0,0,1,1))}catch{}e.toColor=function(e){if(e.match(/#[\\da-f]{3,8}/i))switch(e.length){case 4:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),o.toColor(i,s,r);case 5:return i=parseInt(e.slice(1,2).repeat(2),16),s=parseInt(e.slice(2,3).repeat(2),16),r=parseInt(e.slice(3,4).repeat(2),16),n=parseInt(e.slice(4,5).repeat(2),16),o.toColor(i,s,r,n);case 7:return{css:e,rgba:(parseInt(e.slice(1),16)<<8|255)>>>0};case 9:return{css:e,rgba:parseInt(e.slice(1),16)>>>0}}const l=e.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);if(l)return i=parseInt(l[1]),s=parseInt(l[2]),r=parseInt(l[3]),n=Math.round(255*(void 0===l[5]?1:parseFloat(l[5]))),o.toColor(i,s,r,n);if(!t||!a)throw new Error(\"css.toColor: Unsupported css format\");if(t.fillStyle=a,t.fillStyle=e,\"string\"!=typeof t.fillStyle)throw new Error(\"css.toColor: Unsupported css format\");if(t.fillRect(0,0,1,1),[i,s,r,n]=t.getImageData(0,0,1,1).data,255!==n)throw new Error(\"css.toColor: Unsupported css format\");return{rgba:o.toRgba(i,s,r,n),css:e}}}(l||(t.css=l={})),function(e){function t(e,t,i){const s=e/255,r=t/255,n=i/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:Math.pow((r+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}e.relativeLuminance=function(e){return t(e>>16&255,e>>8&255,255&e)},e.relativeLuminance2=t}(h||(t.rgb=h={})),function(e){function t(e,t,i){const s=e>>24&255,r=e>>16&255,n=e>>8&255;let o=t>>24&255,a=t>>16&255,l=t>>8&255,c=u(h.relativeLuminance2(o,a,l),h.relativeLuminance2(s,r,n));for(;c0||a>0||l>0);)o-=Math.max(0,Math.ceil(.1*o)),a-=Math.max(0,Math.ceil(.1*a)),l-=Math.max(0,Math.ceil(.1*l)),c=u(h.relativeLuminance2(o,a,l),h.relativeLuminance2(s,r,n));return(o<<24|a<<16|l<<8|255)>>>0}function a(e,t,i){const s=e>>24&255,r=e>>16&255,n=e>>8&255;let o=t>>24&255,a=t>>16&255,l=t>>8&255,c=u(h.relativeLuminance2(o,a,l),h.relativeLuminance2(s,r,n));for(;c>>0}e.blend=function(e,t){if(n=(255&t)/255,1===n)return t;const a=t>>24&255,l=t>>16&255,h=t>>8&255,c=e>>24&255,d=e>>16&255,u=e>>8&255;return i=c+Math.round((a-c)*n),s=d+Math.round((l-d)*n),r=u+Math.round((h-u)*n),o.toRgba(i,s,r)},e.ensureContrastRatio=function(e,i,s){const r=h.relativeLuminance(e>>8),n=h.relativeLuminance(i>>8);if(u(r,n)>8));if(ou(r,h.relativeLuminance(t>>8))?n:t}return n}const o=a(e,i,s),l=u(r,h.relativeLuminance(o>>8));if(lu(r,h.relativeLuminance(n>>8))?o:n}return o}},e.reduceLuminance=t,e.increaseLuminance=a,e.toChannels=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}}(c||(t.rgba=c={}))},5777:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CoreTerminal=void 0;const s=i(6501),r=i(6025),n=i(7276),o=i(9640),a=i(56),l=i(4071),h=i(7792),c=i(6415),d=i(5746),u=i(5882),_=i(2486),f=i(3562),p=i(8811),g=i(802),m=i(7150);let v=!1;class S extends m.Disposable{get onScroll(){return this._onScrollApi||(this._onScrollApi=this._register(new g.Emitter),this._onScroll.event((e=>{this._onScrollApi?.fire(e.position)}))),this._onScrollApi.event}get cols(){return this._bufferService.cols}get rows(){return this._bufferService.rows}get buffers(){return this._bufferService.buffers}get options(){return this.optionsService.options}set options(e){for(const t in e)this.optionsService.options[t]=e[t]}constructor(e){super(),this._windowsWrappingHeuristics=this._register(new m.MutableDisposable),this._onBinary=this._register(new g.Emitter),this.onBinary=this._onBinary.event,this._onData=this._register(new g.Emitter),this.onData=this._onData.event,this._onLineFeed=this._register(new g.Emitter),this.onLineFeed=this._onLineFeed.event,this._onResize=this._register(new g.Emitter),this.onResize=this._onResize.event,this._onWriteParsed=this._register(new g.Emitter),this.onWriteParsed=this._onWriteParsed.event,this._onScroll=this._register(new g.Emitter),this._instantiationService=new r.InstantiationService,this.optionsService=this._register(new a.OptionsService(e)),this._instantiationService.setService(s.IOptionsService,this.optionsService),this._bufferService=this._register(this._instantiationService.createInstance(o.BufferService)),this._instantiationService.setService(s.IBufferService,this._bufferService),this._logService=this._register(this._instantiationService.createInstance(n.LogService)),this._instantiationService.setService(s.ILogService,this._logService),this.coreService=this._register(this._instantiationService.createInstance(l.CoreService)),this._instantiationService.setService(s.ICoreService,this.coreService),this.coreMouseService=this._register(this._instantiationService.createInstance(h.CoreMouseService)),this._instantiationService.setService(s.ICoreMouseService,this.coreMouseService),this.unicodeService=this._register(this._instantiationService.createInstance(c.UnicodeService)),this._instantiationService.setService(s.IUnicodeService,this.unicodeService),this._charsetService=this._instantiationService.createInstance(d.CharsetService),this._instantiationService.setService(s.ICharsetService,this._charsetService),this._oscLinkService=this._instantiationService.createInstance(p.OscLinkService),this._instantiationService.setService(s.IOscLinkService,this._oscLinkService),this._inputHandler=this._register(new _.InputHandler(this._bufferService,this._charsetService,this.coreService,this._logService,this.optionsService,this._oscLinkService,this.coreMouseService,this.unicodeService)),this._register(g.Event.forward(this._inputHandler.onLineFeed,this._onLineFeed)),this._register(this._inputHandler),this._register(g.Event.forward(this._bufferService.onResize,this._onResize)),this._register(g.Event.forward(this.coreService.onData,this._onData)),this._register(g.Event.forward(this.coreService.onBinary,this._onBinary)),this._register(this.coreService.onRequestScrollToBottom((()=>this.scrollToBottom(!0)))),this._register(this.coreService.onUserInput((()=>this._writeBuffer.handleUserInput()))),this._register(this.optionsService.onMultipleOptionChange([\"windowsMode\",\"windowsPty\"],(()=>this._handleWindowsPtyOptionChange()))),this._register(this._bufferService.onScroll((()=>{this._onScroll.fire({position:this._bufferService.buffer.ydisp}),this._inputHandler.markRangeDirty(this._bufferService.buffer.scrollTop,this._bufferService.buffer.scrollBottom)}))),this._writeBuffer=this._register(new f.WriteBuffer(((e,t)=>this._inputHandler.parse(e,t)))),this._register(g.Event.forward(this._writeBuffer.onWriteParsed,this._onWriteParsed))}write(e,t){this._writeBuffer.write(e,t)}writeSync(e,t){this._logService.logLevel<=s.LogLevelEnum.WARN&&!v&&(this._logService.warn(\"writeSync is unreliable and will be removed soon.\"),v=!0),this._writeBuffer.writeSync(e,t)}input(e,t=!0){this.coreService.triggerDataEvent(e,t)}resize(e,t){isNaN(e)||isNaN(t)||(e=Math.max(e,o.MINIMUM_COLS),t=Math.max(t,o.MINIMUM_ROWS),this._bufferService.resize(e,t))}scroll(e,t=!1){this._bufferService.scroll(e,t)}scrollLines(e,t){this._bufferService.scrollLines(e,t)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){const t=e-this._bufferService.buffer.ydisp;0!==t&&this.scrollLines(t)}registerEscHandler(e,t){return this._inputHandler.registerEscHandler(e,t)}registerDcsHandler(e,t){return this._inputHandler.registerDcsHandler(e,t)}registerCsiHandler(e,t){return this._inputHandler.registerCsiHandler(e,t)}registerOscHandler(e,t){return this._inputHandler.registerOscHandler(e,t)}_setup(){this._handleWindowsPtyOptionChange()}reset(){this._inputHandler.reset(),this._bufferService.reset(),this._charsetService.reset(),this.coreService.reset(),this.coreMouseService.reset()}_handleWindowsPtyOptionChange(){let e=!1;const t=this.optionsService.rawOptions.windowsPty;t&&void 0!==t.buildNumber&&void 0!==t.buildNumber?e=!!(\"conpty\"===t.backend&&t.buildNumber<21376):this.optionsService.rawOptions.windowsMode&&(e=!0),e?this._enableWindowsWrappingHeuristics():this._windowsWrappingHeuristics.clear()}_enableWindowsWrappingHeuristics(){if(!this._windowsWrappingHeuristics.value){const e=[];e.push(this.onLineFeed(u.updateWindowsModeWrappedState.bind(null,this._bufferService))),e.push(this.registerCsiHandler({final:\"H\"},(()=>((0,u.updateWindowsModeWrappedState)(this._bufferService),!1)))),this._windowsWrappingHeuristics.value=(0,m.toDisposable)((()=>{for(const t of e)t.dispose()}))}}}t.CoreTerminal=S},2486:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.InputHandler=t.WindowsOptionsReportType=void 0,t.isValidColorIndex=R;const n=i(3534),o=i(6760),a=i(6717),l=i(7150),h=i(726),c=i(6107),d=i(8938),u=i(3055),_=i(5451),f=i(6501),p=i(6415),g=i(1346),m=i(9823),v=i(8693),S=i(802),b={\"(\":0,\")\":1,\"*\":2,\"+\":3,\"-\":1,\".\":2},C=131072;function y(e,t){if(e>24)return t.setWinLines||!1;switch(e){case 1:return!!t.restoreWin;case 2:return!!t.minimizeWin;case 3:return!!t.setWinPosition;case 4:return!!t.setWinSizePixels;case 5:return!!t.raiseWin;case 6:return!!t.lowerWin;case 7:return!!t.refreshWin;case 8:return!!t.setWinSizeChars;case 9:return!!t.maximizeWin;case 10:return!!t.fullscreenWin;case 11:return!!t.getWinState;case 13:return!!t.getWinPosition;case 14:return!!t.getWinSizePixels;case 15:return!!t.getScreenSizePixels;case 16:return!!t.getCellSizePixels;case 18:return!!t.getWinSizeChars;case 19:return!!t.getScreenSizeChars;case 20:return!!t.getIconTitle;case 21:return!!t.getWinTitle;case 22:return!!t.pushTitle;case 23:return!!t.popTitle;case 24:return!!t.setWinLines}return!1}var w;!function(e){e[e.GET_WIN_SIZE_PIXELS=0]=\"GET_WIN_SIZE_PIXELS\",e[e.GET_CELL_SIZE_PIXELS=1]=\"GET_CELL_SIZE_PIXELS\"}(w||(t.WindowsOptionsReportType=w={}));let E=0;class D extends l.Disposable{getAttrData(){return this._curAttrData}constructor(e,t,i,s,r,l,d,u,_=new a.EscapeSequenceParser){super(),this._bufferService=e,this._charsetService=t,this._coreService=i,this._logService=s,this._optionsService=r,this._oscLinkService=l,this._coreMouseService=d,this._unicodeService=u,this._parser=_,this._parseBuffer=new Uint32Array(4096),this._stringDecoder=new h.StringToUtf32,this._utf8Decoder=new h.Utf8ToUtf32,this._windowTitle=\"\",this._iconName=\"\",this._windowTitleStack=[],this._iconNameStack=[],this._curAttrData=c.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=c.DEFAULT_ATTR_DATA.clone(),this._onRequestBell=this._register(new S.Emitter),this.onRequestBell=this._onRequestBell.event,this._onRequestRefreshRows=this._register(new S.Emitter),this.onRequestRefreshRows=this._onRequestRefreshRows.event,this._onRequestReset=this._register(new S.Emitter),this.onRequestReset=this._onRequestReset.event,this._onRequestSendFocus=this._register(new S.Emitter),this.onRequestSendFocus=this._onRequestSendFocus.event,this._onRequestSyncScrollBar=this._register(new S.Emitter),this.onRequestSyncScrollBar=this._onRequestSyncScrollBar.event,this._onRequestWindowsOptionsReport=this._register(new S.Emitter),this.onRequestWindowsOptionsReport=this._onRequestWindowsOptionsReport.event,this._onA11yChar=this._register(new S.Emitter),this.onA11yChar=this._onA11yChar.event,this._onA11yTab=this._register(new S.Emitter),this.onA11yTab=this._onA11yTab.event,this._onCursorMove=this._register(new S.Emitter),this.onCursorMove=this._onCursorMove.event,this._onLineFeed=this._register(new S.Emitter),this.onLineFeed=this._onLineFeed.event,this._onScroll=this._register(new S.Emitter),this.onScroll=this._onScroll.event,this._onTitleChange=this._register(new S.Emitter),this.onTitleChange=this._onTitleChange.event,this._onColor=this._register(new S.Emitter),this.onColor=this._onColor.event,this._parseStack={paused:!1,cursorStartX:0,cursorStartY:0,decodedLength:0,position:0},this._specialColors=[256,257,258],this._register(this._parser),this._dirtyRowTracker=new L(this._bufferService),this._activeBuffer=this._bufferService.buffer,this._register(this._bufferService.buffers.onBufferActivate((e=>this._activeBuffer=e.activeBuffer))),this._parser.setCsiHandlerFallback(((e,t)=>{this._logService.debug(\"Unknown CSI code: \",{identifier:this._parser.identToString(e),params:t.toArray()})})),this._parser.setEscHandlerFallback((e=>{this._logService.debug(\"Unknown ESC code: \",{identifier:this._parser.identToString(e)})})),this._parser.setExecuteHandlerFallback((e=>{this._logService.debug(\"Unknown EXECUTE code: \",{code:e})})),this._parser.setOscHandlerFallback(((e,t,i)=>{this._logService.debug(\"Unknown OSC code: \",{identifier:e,action:t,data:i})})),this._parser.setDcsHandlerFallback(((e,t,i)=>{\"HOOK\"===t&&(i=i.toArray()),this._logService.debug(\"Unknown DCS code: \",{identifier:this._parser.identToString(e),action:t,payload:i})})),this._parser.setPrintHandler(((e,t,i)=>this.print(e,t,i))),this._parser.registerCsiHandler({final:\"@\"},(e=>this.insertChars(e))),this._parser.registerCsiHandler({intermediates:\" \",final:\"@\"},(e=>this.scrollLeft(e))),this._parser.registerCsiHandler({final:\"A\"},(e=>this.cursorUp(e))),this._parser.registerCsiHandler({intermediates:\" \",final:\"A\"},(e=>this.scrollRight(e))),this._parser.registerCsiHandler({final:\"B\"},(e=>this.cursorDown(e))),this._parser.registerCsiHandler({final:\"C\"},(e=>this.cursorForward(e))),this._parser.registerCsiHandler({final:\"D\"},(e=>this.cursorBackward(e))),this._parser.registerCsiHandler({final:\"E\"},(e=>this.cursorNextLine(e))),this._parser.registerCsiHandler({final:\"F\"},(e=>this.cursorPrecedingLine(e))),this._parser.registerCsiHandler({final:\"G\"},(e=>this.cursorCharAbsolute(e))),this._parser.registerCsiHandler({final:\"H\"},(e=>this.cursorPosition(e))),this._parser.registerCsiHandler({final:\"I\"},(e=>this.cursorForwardTab(e))),this._parser.registerCsiHandler({final:\"J\"},(e=>this.eraseInDisplay(e,!1))),this._parser.registerCsiHandler({prefix:\"?\",final:\"J\"},(e=>this.eraseInDisplay(e,!0))),this._parser.registerCsiHandler({final:\"K\"},(e=>this.eraseInLine(e,!1))),this._parser.registerCsiHandler({prefix:\"?\",final:\"K\"},(e=>this.eraseInLine(e,!0))),this._parser.registerCsiHandler({final:\"L\"},(e=>this.insertLines(e))),this._parser.registerCsiHandler({final:\"M\"},(e=>this.deleteLines(e))),this._parser.registerCsiHandler({final:\"P\"},(e=>this.deleteChars(e))),this._parser.registerCsiHandler({final:\"S\"},(e=>this.scrollUp(e))),this._parser.registerCsiHandler({final:\"T\"},(e=>this.scrollDown(e))),this._parser.registerCsiHandler({final:\"X\"},(e=>this.eraseChars(e))),this._parser.registerCsiHandler({final:\"Z\"},(e=>this.cursorBackwardTab(e))),this._parser.registerCsiHandler({final:\"`\"},(e=>this.charPosAbsolute(e))),this._parser.registerCsiHandler({final:\"a\"},(e=>this.hPositionRelative(e))),this._parser.registerCsiHandler({final:\"b\"},(e=>this.repeatPrecedingCharacter(e))),this._parser.registerCsiHandler({final:\"c\"},(e=>this.sendDeviceAttributesPrimary(e))),this._parser.registerCsiHandler({prefix:\">\",final:\"c\"},(e=>this.sendDeviceAttributesSecondary(e))),this._parser.registerCsiHandler({final:\"d\"},(e=>this.linePosAbsolute(e))),this._parser.registerCsiHandler({final:\"e\"},(e=>this.vPositionRelative(e))),this._parser.registerCsiHandler({final:\"f\"},(e=>this.hVPosition(e))),this._parser.registerCsiHandler({final:\"g\"},(e=>this.tabClear(e))),this._parser.registerCsiHandler({final:\"h\"},(e=>this.setMode(e))),this._parser.registerCsiHandler({prefix:\"?\",final:\"h\"},(e=>this.setModePrivate(e))),this._parser.registerCsiHandler({final:\"l\"},(e=>this.resetMode(e))),this._parser.registerCsiHandler({prefix:\"?\",final:\"l\"},(e=>this.resetModePrivate(e))),this._parser.registerCsiHandler({final:\"m\"},(e=>this.charAttributes(e))),this._parser.registerCsiHandler({final:\"n\"},(e=>this.deviceStatus(e))),this._parser.registerCsiHandler({prefix:\"?\",final:\"n\"},(e=>this.deviceStatusPrivate(e))),this._parser.registerCsiHandler({intermediates:\"!\",final:\"p\"},(e=>this.softReset(e))),this._parser.registerCsiHandler({intermediates:\" \",final:\"q\"},(e=>this.setCursorStyle(e))),this._parser.registerCsiHandler({final:\"r\"},(e=>this.setScrollRegion(e))),this._parser.registerCsiHandler({final:\"s\"},(e=>this.saveCursor(e))),this._parser.registerCsiHandler({final:\"t\"},(e=>this.windowOptions(e))),this._parser.registerCsiHandler({final:\"u\"},(e=>this.restoreCursor(e))),this._parser.registerCsiHandler({intermediates:\"'\",final:\"}\"},(e=>this.insertColumns(e))),this._parser.registerCsiHandler({intermediates:\"'\",final:\"~\"},(e=>this.deleteColumns(e))),this._parser.registerCsiHandler({intermediates:'\"',final:\"q\"},(e=>this.selectProtected(e))),this._parser.registerCsiHandler({intermediates:\"$\",final:\"p\"},(e=>this.requestMode(e,!0))),this._parser.registerCsiHandler({prefix:\"?\",intermediates:\"$\",final:\"p\"},(e=>this.requestMode(e,!1))),this._parser.setExecuteHandler(n.C0.BEL,(()=>this.bell())),this._parser.setExecuteHandler(n.C0.LF,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.VT,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.FF,(()=>this.lineFeed())),this._parser.setExecuteHandler(n.C0.CR,(()=>this.carriageReturn())),this._parser.setExecuteHandler(n.C0.BS,(()=>this.backspace())),this._parser.setExecuteHandler(n.C0.HT,(()=>this.tab())),this._parser.setExecuteHandler(n.C0.SO,(()=>this.shiftOut())),this._parser.setExecuteHandler(n.C0.SI,(()=>this.shiftIn())),this._parser.setExecuteHandler(n.C1.IND,(()=>this.index())),this._parser.setExecuteHandler(n.C1.NEL,(()=>this.nextLine())),this._parser.setExecuteHandler(n.C1.HTS,(()=>this.tabSet())),this._parser.registerOscHandler(0,new g.OscHandler((e=>(this.setTitle(e),this.setIconName(e),!0)))),this._parser.registerOscHandler(1,new g.OscHandler((e=>this.setIconName(e)))),this._parser.registerOscHandler(2,new g.OscHandler((e=>this.setTitle(e)))),this._parser.registerOscHandler(4,new g.OscHandler((e=>this.setOrReportIndexedColor(e)))),this._parser.registerOscHandler(8,new g.OscHandler((e=>this.setHyperlink(e)))),this._parser.registerOscHandler(10,new g.OscHandler((e=>this.setOrReportFgColor(e)))),this._parser.registerOscHandler(11,new g.OscHandler((e=>this.setOrReportBgColor(e)))),this._parser.registerOscHandler(12,new g.OscHandler((e=>this.setOrReportCursorColor(e)))),this._parser.registerOscHandler(104,new g.OscHandler((e=>this.restoreIndexedColor(e)))),this._parser.registerOscHandler(110,new g.OscHandler((e=>this.restoreFgColor(e)))),this._parser.registerOscHandler(111,new g.OscHandler((e=>this.restoreBgColor(e)))),this._parser.registerOscHandler(112,new g.OscHandler((e=>this.restoreCursorColor(e)))),this._parser.registerEscHandler({final:\"7\"},(()=>this.saveCursor())),this._parser.registerEscHandler({final:\"8\"},(()=>this.restoreCursor())),this._parser.registerEscHandler({final:\"D\"},(()=>this.index())),this._parser.registerEscHandler({final:\"E\"},(()=>this.nextLine())),this._parser.registerEscHandler({final:\"H\"},(()=>this.tabSet())),this._parser.registerEscHandler({final:\"M\"},(()=>this.reverseIndex())),this._parser.registerEscHandler({final:\"=\"},(()=>this.keypadApplicationMode())),this._parser.registerEscHandler({final:\">\"},(()=>this.keypadNumericMode())),this._parser.registerEscHandler({final:\"c\"},(()=>this.fullReset())),this._parser.registerEscHandler({final:\"n\"},(()=>this.setgLevel(2))),this._parser.registerEscHandler({final:\"o\"},(()=>this.setgLevel(3))),this._parser.registerEscHandler({final:\"|\"},(()=>this.setgLevel(3))),this._parser.registerEscHandler({final:\"}\"},(()=>this.setgLevel(2))),this._parser.registerEscHandler({final:\"~\"},(()=>this.setgLevel(1))),this._parser.registerEscHandler({intermediates:\"%\",final:\"@\"},(()=>this.selectDefaultCharset())),this._parser.registerEscHandler({intermediates:\"%\",final:\"G\"},(()=>this.selectDefaultCharset()));for(const e in o.CHARSETS)this._parser.registerEscHandler({intermediates:\"(\",final:e},(()=>this.selectCharset(\"(\"+e))),this._parser.registerEscHandler({intermediates:\")\",final:e},(()=>this.selectCharset(\")\"+e))),this._parser.registerEscHandler({intermediates:\"*\",final:e},(()=>this.selectCharset(\"*\"+e))),this._parser.registerEscHandler({intermediates:\"+\",final:e},(()=>this.selectCharset(\"+\"+e))),this._parser.registerEscHandler({intermediates:\"-\",final:e},(()=>this.selectCharset(\"-\"+e))),this._parser.registerEscHandler({intermediates:\".\",final:e},(()=>this.selectCharset(\".\"+e))),this._parser.registerEscHandler({intermediates:\"/\",final:e},(()=>this.selectCharset(\"/\"+e)));this._parser.registerEscHandler({intermediates:\"#\",final:\"8\"},(()=>this.screenAlignmentPattern())),this._parser.setErrorHandler((e=>(this._logService.error(\"Parsing error: \",e),e))),this._parser.registerDcsHandler({intermediates:\"$\",final:\"q\"},new m.DcsHandler(((e,t)=>this.requestStatusString(e,t))))}_preserveStack(e,t,i,s){this._parseStack.paused=!0,this._parseStack.cursorStartX=e,this._parseStack.cursorStartY=t,this._parseStack.decodedLength=i,this._parseStack.position=s}_logSlowResolvingAsync(e){this._logService.logLevel<=f.LogLevelEnum.WARN&&Promise.race([e,new Promise(((e,t)=>setTimeout((()=>t(\"#SLOW_TIMEOUT\")),5e3)))]).catch((e=>{if(\"#SLOW_TIMEOUT\"!==e)throw e;console.warn(\"async parser handler taking longer than 5000 ms\")}))}_getCurrentLinkId(){return this._curAttrData.extended.urlId}parse(e,t){let i,s=this._activeBuffer.x,r=this._activeBuffer.y,n=0;const o=this._parseStack.paused;if(o){if(i=this._parser.parse(this._parseBuffer,this._parseStack.decodedLength,t))return this._logSlowResolvingAsync(i),i;s=this._parseStack.cursorStartX,r=this._parseStack.cursorStartY,this._parseStack.paused=!1,e.length>C&&(n=this._parseStack.position+C)}if(this._logService.logLevel<=f.LogLevelEnum.DEBUG&&this._logService.debug(\"parsing data \"+(\"string\"==typeof e?` \"${e}\"`:` \"${Array.prototype.map.call(e,(e=>String.fromCharCode(e))).join(\"\")}\"`)),this._logService.logLevel===f.LogLevelEnum.TRACE&&this._logService.trace(\"parsing data (codes)\",\"string\"==typeof e?e.split(\"\").map((e=>e.charCodeAt(0))):e),this._parseBuffer.lengthC)for(let t=n;t0&&2===f.getWidth(this._activeBuffer.x-1)&&f.setCellFromCodepoint(this._activeBuffer.x-1,0,1,_);let g=this._parser.precedingJoinState;for(let m=t;ma)if(l){const e=f;let t=this._activeBuffer.x-v;for(this._activeBuffer.x=v,this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData(),!0)):(this._activeBuffer.y>=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!0),f=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y),v>0&&f instanceof c.BufferLine&&f.copyCellsFrom(e,t,0,v,!1);t=0;)f.setCellFromCodepoint(this._activeBuffer.x++,0,0,_)}else if(u&&(f.insertCells(this._activeBuffer.x,r-v,this._activeBuffer.getNullCell(_)),2===f.getWidth(a-1)&&f.setCellFromCodepoint(a-1,d.NULL_CELL_CODE,d.NULL_CELL_WIDTH,_)),f.setCellFromCodepoint(this._activeBuffer.x++,s,r,_),r>0)for(;--r;)f.setCellFromCodepoint(this._activeBuffer.x++,0,0,_)}this._parser.precedingJoinState=g,this._activeBuffer.x0&&0===f.getWidth(this._activeBuffer.x)&&!f.hasContent(this._activeBuffer.x)&&f.setCellFromCodepoint(this._activeBuffer.x,0,1,_),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}registerCsiHandler(e,t){return\"t\"!==e.final||e.prefix||e.intermediates?this._parser.registerCsiHandler(e,t):this._parser.registerCsiHandler(e,(e=>!y(e.params[0],this._optionsService.rawOptions.windowOptions)||t(e)))}registerDcsHandler(e,t){return this._parser.registerDcsHandler(e,new m.DcsHandler(t))}registerEscHandler(e,t){return this._parser.registerEscHandler(e,t)}registerOscHandler(e,t){return this._parser.registerOscHandler(e,new g.OscHandler(t))}bell(){return this._onRequestBell.fire(),!0}lineFeed(){return this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._optionsService.rawOptions.convertEol&&(this._activeBuffer.x=0),this._activeBuffer.y++,this._activeBuffer.y===this._activeBuffer.scrollBottom+1?(this._activeBuffer.y--,this._bufferService.scroll(this._eraseAttrData())):this._activeBuffer.y>=this._bufferService.rows?this._activeBuffer.y=this._bufferService.rows-1:this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.x>=this._bufferService.cols&&this._activeBuffer.x--,this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._onLineFeed.fire(),!0}carriageReturn(){return this._activeBuffer.x=0,!0}backspace(){if(!this._coreService.decPrivateModes.reverseWraparound)return this._restrictCursor(),this._activeBuffer.x>0&&this._activeBuffer.x--,!0;if(this._restrictCursor(this._bufferService.cols),this._activeBuffer.x>0)this._activeBuffer.x--;else if(0===this._activeBuffer.x&&this._activeBuffer.y>this._activeBuffer.scrollTop&&this._activeBuffer.y<=this._activeBuffer.scrollBottom&&this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y)?.isWrapped){this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y).isWrapped=!1,this._activeBuffer.y--,this._activeBuffer.x=this._bufferService.cols-1;const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+this._activeBuffer.y);e.hasWidth(this._activeBuffer.x)&&!e.hasContent(this._activeBuffer.x)&&this._activeBuffer.x--}return this._restrictCursor(),!0}tab(){if(this._activeBuffer.x>=this._bufferService.cols)return!0;const e=this._activeBuffer.x;return this._activeBuffer.x=this._activeBuffer.nextStop(),this._optionsService.rawOptions.screenReaderMode&&this._onA11yTab.fire(this._activeBuffer.x-e),!0}shiftOut(){return this._charsetService.setgLevel(1),!0}shiftIn(){return this._charsetService.setgLevel(0),!0}_restrictCursor(e=this._bufferService.cols-1){this._activeBuffer.x=Math.min(e,Math.max(0,this._activeBuffer.x)),this._activeBuffer.y=this._coreService.decPrivateModes.origin?Math.min(this._activeBuffer.scrollBottom,Math.max(this._activeBuffer.scrollTop,this._activeBuffer.y)):Math.min(this._bufferService.rows-1,Math.max(0,this._activeBuffer.y)),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_setCursor(e,t){this._dirtyRowTracker.markDirty(this._activeBuffer.y),this._coreService.decPrivateModes.origin?(this._activeBuffer.x=e,this._activeBuffer.y=this._activeBuffer.scrollTop+t):(this._activeBuffer.x=e,this._activeBuffer.y=t),this._restrictCursor(),this._dirtyRowTracker.markDirty(this._activeBuffer.y)}_moveCursor(e,t){this._restrictCursor(),this._setCursor(this._activeBuffer.x+e,this._activeBuffer.y+t)}cursorUp(e){const t=this._activeBuffer.y-this._activeBuffer.scrollTop;return t>=0?this._moveCursor(0,-Math.min(t,e.params[0]||1)):this._moveCursor(0,-(e.params[0]||1)),!0}cursorDown(e){const t=this._activeBuffer.scrollBottom-this._activeBuffer.y;return t>=0?this._moveCursor(0,Math.min(t,e.params[0]||1)):this._moveCursor(0,e.params[0]||1),!0}cursorForward(e){return this._moveCursor(e.params[0]||1,0),!0}cursorBackward(e){return this._moveCursor(-(e.params[0]||1),0),!0}cursorNextLine(e){return this.cursorDown(e),this._activeBuffer.x=0,!0}cursorPrecedingLine(e){return this.cursorUp(e),this._activeBuffer.x=0,!0}cursorCharAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}cursorPosition(e){return this._setCursor(e.length>=2?(e.params[1]||1)-1:0,(e.params[0]||1)-1),!0}charPosAbsolute(e){return this._setCursor((e.params[0]||1)-1,this._activeBuffer.y),!0}hPositionRelative(e){return this._moveCursor(e.params[0]||1,0),!0}linePosAbsolute(e){return this._setCursor(this._activeBuffer.x,(e.params[0]||1)-1),!0}vPositionRelative(e){return this._moveCursor(0,e.params[0]||1),!0}hVPosition(e){return this.cursorPosition(e),!0}tabClear(e){const t=e.params[0];return 0===t?delete this._activeBuffer.tabs[this._activeBuffer.x]:3===t&&(this._activeBuffer.tabs={}),!0}cursorForwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.nextStop();return!0}cursorBackwardTab(e){if(this._activeBuffer.x>=this._bufferService.cols)return!0;let t=e.params[0]||1;for(;t--;)this._activeBuffer.x=this._activeBuffer.prevStop();return!0}selectProtected(e){const t=e.params[0];return 1===t&&(this._curAttrData.bg|=536870912),2!==t&&0!==t||(this._curAttrData.bg&=-536870913),!0}_eraseInBufferLine(e,t,i,s=!1,r=!1){const n=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);n.replaceCells(t,i,this._activeBuffer.getNullCell(this._eraseAttrData()),r),s&&(n.isWrapped=!1)}_resetBufferLine(e,t=!1){const i=this._activeBuffer.lines.get(this._activeBuffer.ybase+e);i&&(i.fill(this._activeBuffer.getNullCell(this._eraseAttrData()),t),this._bufferService.buffer.clearMarkers(this._activeBuffer.ybase+e),i.isWrapped=!1)}eraseInDisplay(e,t=!1){let i;switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:for(i=this._activeBuffer.y,this._dirtyRowTracker.markDirty(i),this._eraseInBufferLine(i++,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);i=this._bufferService.cols&&(this._activeBuffer.lines.get(i+1).isWrapped=!1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0);break;case 2:if(this._optionsService.rawOptions.scrollOnEraseInDisplay){for(i=this._bufferService.rows,this._dirtyRowTracker.markRangeDirty(0,i-1);i--;){const e=this._activeBuffer.lines.get(this._activeBuffer.ybase+i);if(e?.getTrimmedLength())break}for(;i>=0;i--)this._bufferService.scroll(this._eraseAttrData())}else{for(i=this._bufferService.rows,this._dirtyRowTracker.markDirty(i-1);i--;)this._resetBufferLine(i,t);this._dirtyRowTracker.markDirty(0)}break;case 3:const e=this._activeBuffer.lines.length-this._bufferService.rows;e>0&&(this._activeBuffer.lines.trimStart(e),this._activeBuffer.ybase=Math.max(this._activeBuffer.ybase-e,0),this._activeBuffer.ydisp=Math.max(this._activeBuffer.ydisp-e,0),this._onScroll.fire(0))}return!0}eraseInLine(e,t=!1){switch(this._restrictCursor(this._bufferService.cols),e.params[0]){case 0:this._eraseInBufferLine(this._activeBuffer.y,this._activeBuffer.x,this._bufferService.cols,0===this._activeBuffer.x,t);break;case 1:this._eraseInBufferLine(this._activeBuffer.y,0,this._activeBuffer.x+1,!1,t);break;case 2:this._eraseInBufferLine(this._activeBuffer.y,0,this._bufferService.cols,!0,t)}return this._dirtyRowTracker.markDirty(this._activeBuffer.y),!0}insertLines(e){this._restrictCursor();let t=e.params[0]||1;if(this._activeBuffer.y>this._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.ythis._activeBuffer.scrollBottom||this._activeBuffer.y65535?2:1}let l=a;for(let e=1;e0||(this._is(\"xterm\")||this._is(\"rxvt-unicode\")||this._is(\"screen\")?this._coreService.triggerDataEvent(n.C0.ESC+\"[?1;2c\"):this._is(\"linux\")&&this._coreService.triggerDataEvent(n.C0.ESC+\"[?6c\")),!0}sendDeviceAttributesSecondary(e){return e.params[0]>0||(this._is(\"xterm\")?this._coreService.triggerDataEvent(n.C0.ESC+\"[>0;276;0c\"):this._is(\"rxvt-unicode\")?this._coreService.triggerDataEvent(n.C0.ESC+\"[>85;95;0c\"):this._is(\"linux\")?this._coreService.triggerDataEvent(e.params[0]+\"c\"):this._is(\"screen\")&&this._coreService.triggerDataEvent(n.C0.ESC+\"[>83;40003;0c\")),!0}_is(e){return 0===(this._optionsService.rawOptions.termName+\"\").indexOf(e)}setMode(e){for(let t=0;te?1:2,_=e.params[0];return f=_,p=t?2===_?4:4===_?u(o.modes.insertMode):12===_?3:20===_?u(d.convertEol):0:1===_?u(i.applicationCursorKeys):3===_?d.windowOptions.setWinLines?80===l?2:132===l?1:0:0:6===_?u(i.origin):7===_?u(i.wraparound):8===_?3:9===_?u(\"X10\"===s):12===_?u(d.cursorBlink):25===_?u(!o.isCursorHidden):45===_?u(i.reverseWraparound):66===_?u(i.applicationKeypad):67===_?4:1e3===_?u(\"VT200\"===s):1002===_?u(\"DRAG\"===s):1003===_?u(\"ANY\"===s):1004===_?u(i.sendFocus):1005===_?4:1006===_?u(\"SGR\"===r):1015===_?4:1016===_?u(\"SGR_PIXELS\"===r):1048===_?1:47===_||1047===_||1049===_?u(h===c):2004===_?u(i.bracketedPasteMode):2026===_?u(i.synchronizedOutput):0,o.triggerDataEvent(`${n.C0.ESC}[${t?\"\":\"?\"}${f};${p}$y`),!0;var f,p}_updateAttrColor(e,t,i,s,r){return 2===t?(e|=50331648,e&=-16777216,e|=_.AttributeData.fromColorRGB([i,s,r])):5===t&&(e&=-50331904,e|=33554432|255&i),e}_extractColor(e,t,i){const s=[0,0,-1,0,0,0];let r=0,n=0;do{if(s[n+r]=e.params[t+n],e.hasSubParams(t+n)){const i=e.getSubParams(t+n);let o=0;do{5===s[1]&&(r=1),s[n+o+1+r]=i[o]}while(++o=2||2===s[1]&&n+r>=5)break;s[1]&&(r=1)}while(++n+t5)&&(e=1),t.extended.underlineStyle=e,t.fg|=268435456,0===e&&(t.fg&=-268435457),t.updateExtended()}_processSGR0(e){e.fg=c.DEFAULT_ATTR_DATA.fg,e.bg=c.DEFAULT_ATTR_DATA.bg,e.extended=e.extended.clone(),e.extended.underlineStyle=0,e.extended.underlineColor&=-67108864,e.updateExtended()}charAttributes(e){if(1===e.length&&0===e.params[0])return this._processSGR0(this._curAttrData),!0;const t=e.length;let i;const s=this._curAttrData;for(let r=0;r=30&&i<=37?(s.fg&=-50331904,s.fg|=16777216|i-30):i>=40&&i<=47?(s.bg&=-50331904,s.bg|=16777216|i-40):i>=90&&i<=97?(s.fg&=-50331904,s.fg|=16777224|i-90):i>=100&&i<=107?(s.bg&=-50331904,s.bg|=16777224|i-100):0===i?this._processSGR0(s):1===i?s.fg|=134217728:3===i?s.bg|=67108864:4===i?(s.fg|=268435456,this._processUnderline(e.hasSubParams(r)?e.getSubParams(r)[0]:1,s)):5===i?s.fg|=536870912:7===i?s.fg|=67108864:8===i?s.fg|=1073741824:9===i?s.fg|=2147483648:2===i?s.bg|=134217728:21===i?this._processUnderline(2,s):22===i?(s.fg&=-134217729,s.bg&=-134217729):23===i?s.bg&=-67108865:24===i?(s.fg&=-268435457,this._processUnderline(0,s)):25===i?s.fg&=-536870913:27===i?s.fg&=-67108865:28===i?s.fg&=-1073741825:29===i?s.fg&=2147483647:39===i?(s.fg&=-67108864,s.fg|=16777215&c.DEFAULT_ATTR_DATA.fg):49===i?(s.bg&=-67108864,s.bg|=16777215&c.DEFAULT_ATTR_DATA.bg):38===i||48===i||58===i?r+=this._extractColor(e,r,s):53===i?s.bg|=1073741824:55===i?s.bg&=-1073741825:59===i?(s.extended=s.extended.clone(),s.extended.underlineColor=-1,s.updateExtended()):100===i?(s.fg&=-67108864,s.fg|=16777215&c.DEFAULT_ATTR_DATA.fg,s.bg&=-67108864,s.bg|=16777215&c.DEFAULT_ATTR_DATA.bg):this._logService.debug(\"Unknown SGR attribute: %d.\",i);return!0}deviceStatus(e){switch(e.params[0]){case 5:this._coreService.triggerDataEvent(`${n.C0.ESC}[0n`);break;case 6:const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`${n.C0.ESC}[${e};${t}R`)}return!0}deviceStatusPrivate(e){if(6===e.params[0]){const e=this._activeBuffer.y+1,t=this._activeBuffer.x+1;this._coreService.triggerDataEvent(`${n.C0.ESC}[?${e};${t}R`)}return!0}softReset(e){return this._coreService.isCursorHidden=!1,this._onRequestSyncScrollBar.fire(),this._activeBuffer.scrollTop=0,this._activeBuffer.scrollBottom=this._bufferService.rows-1,this._curAttrData=c.DEFAULT_ATTR_DATA.clone(),this._coreService.reset(),this._charsetService.reset(),this._activeBuffer.savedX=0,this._activeBuffer.savedY=this._activeBuffer.ybase,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,this._coreService.decPrivateModes.origin=!1,!0}setCursorStyle(e){const t=0===e.length?1:e.params[0];if(0===t)this._coreService.decPrivateModes.cursorStyle=void 0,this._coreService.decPrivateModes.cursorBlink=void 0;else{switch(t){case 1:case 2:this._coreService.decPrivateModes.cursorStyle=\"block\";break;case 3:case 4:this._coreService.decPrivateModes.cursorStyle=\"underline\";break;case 5:case 6:this._coreService.decPrivateModes.cursorStyle=\"bar\"}const e=t%2==1;this._coreService.decPrivateModes.cursorBlink=e}return!0}setScrollRegion(e){const t=e.params[0]||1;let i;return(e.length<2||(i=e.params[1])>this._bufferService.rows||0===i)&&(i=this._bufferService.rows),i>t&&(this._activeBuffer.scrollTop=t-1,this._activeBuffer.scrollBottom=i-1,this._setCursor(0,0)),!0}windowOptions(e){if(!y(e.params[0],this._optionsService.rawOptions.windowOptions))return!0;const t=e.length>1?e.params[1]:0;switch(e.params[0]){case 14:2!==t&&this._onRequestWindowsOptionsReport.fire(w.GET_WIN_SIZE_PIXELS);break;case 16:this._onRequestWindowsOptionsReport.fire(w.GET_CELL_SIZE_PIXELS);break;case 18:this._bufferService&&this._coreService.triggerDataEvent(`${n.C0.ESC}[8;${this._bufferService.rows};${this._bufferService.cols}t`);break;case 22:0!==t&&2!==t||(this._windowTitleStack.push(this._windowTitle),this._windowTitleStack.length>10&&this._windowTitleStack.shift()),0!==t&&1!==t||(this._iconNameStack.push(this._iconName),this._iconNameStack.length>10&&this._iconNameStack.shift());break;case 23:0!==t&&2!==t||this._windowTitleStack.length&&this.setTitle(this._windowTitleStack.pop()),0!==t&&1!==t||this._iconNameStack.length&&this.setIconName(this._iconNameStack.pop())}return!0}saveCursor(e){return this._activeBuffer.savedX=this._activeBuffer.x,this._activeBuffer.savedY=this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.savedCurAttrData.fg=this._curAttrData.fg,this._activeBuffer.savedCurAttrData.bg=this._curAttrData.bg,this._activeBuffer.savedCharset=this._charsetService.charset,!0}restoreCursor(e){return this._activeBuffer.x=this._activeBuffer.savedX||0,this._activeBuffer.y=Math.max(this._activeBuffer.savedY-this._activeBuffer.ybase,0),this._curAttrData.fg=this._activeBuffer.savedCurAttrData.fg,this._curAttrData.bg=this._activeBuffer.savedCurAttrData.bg,this._charsetService.charset=this._savedCharset,this._activeBuffer.savedCharset&&(this._charsetService.charset=this._activeBuffer.savedCharset),this._restrictCursor(),!0}setTitle(e){return this._windowTitle=e,this._onTitleChange.fire(e),!0}setIconName(e){return this._iconName=e,!0}setOrReportIndexedColor(e){const t=[],i=e.split(\";\");for(;i.length>1;){const e=i.shift(),s=i.shift();if(/^\\d+$/.exec(e)){const i=parseInt(e);if(R(i))if(\"?\"===s)t.push({type:0,index:i});else{const e=(0,v.parseColor)(s);e&&t.push({type:1,index:i,color:e})}}}return t.length&&this._onColor.fire(t),!0}setHyperlink(e){const t=e.indexOf(\";\");if(-1===t)return!0;const i=e.slice(0,t).trim(),s=e.slice(t+1);return s?this._createHyperlink(i,s):!i.trim()&&this._finishHyperlink()}_createHyperlink(e,t){this._getCurrentLinkId()&&this._finishHyperlink();const i=e.split(\":\");let s;const r=i.findIndex((e=>e.startsWith(\"id=\")));return-1!==r&&(s=i[r].slice(3)||void 0),this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=this._oscLinkService.registerLink({id:s,uri:t}),this._curAttrData.updateExtended(),!0}_finishHyperlink(){return this._curAttrData.extended=this._curAttrData.extended.clone(),this._curAttrData.extended.urlId=0,this._curAttrData.updateExtended(),!0}_setOrReportSpecialColor(e,t){const i=e.split(\";\");for(let e=0;e=this._specialColors.length);++e,++t)if(\"?\"===i[e])this._onColor.fire([{type:0,index:this._specialColors[t]}]);else{const s=(0,v.parseColor)(i[e]);s&&this._onColor.fire([{type:1,index:this._specialColors[t],color:s}])}return!0}setOrReportFgColor(e){return this._setOrReportSpecialColor(e,0)}setOrReportBgColor(e){return this._setOrReportSpecialColor(e,1)}setOrReportCursorColor(e){return this._setOrReportSpecialColor(e,2)}restoreIndexedColor(e){if(!e)return this._onColor.fire([{type:2}]),!0;const t=[],i=e.split(\";\");for(let e=0;e=this._bufferService.rows&&(this._activeBuffer.y=this._bufferService.rows-1),this._restrictCursor(),!0}tabSet(){return this._activeBuffer.tabs[this._activeBuffer.x]=!0,!0}reverseIndex(){if(this._restrictCursor(),this._activeBuffer.y===this._activeBuffer.scrollTop){const e=this._activeBuffer.scrollBottom-this._activeBuffer.scrollTop;this._activeBuffer.lines.shiftElements(this._activeBuffer.ybase+this._activeBuffer.y,e,1),this._activeBuffer.lines.set(this._activeBuffer.ybase+this._activeBuffer.y,this._activeBuffer.getBlankLine(this._eraseAttrData())),this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop,this._activeBuffer.scrollBottom)}else this._activeBuffer.y--,this._restrictCursor();return!0}fullReset(){return this._parser.reset(),this._onRequestReset.fire(),!0}reset(){this._curAttrData=c.DEFAULT_ATTR_DATA.clone(),this._eraseAttrDataInternal=c.DEFAULT_ATTR_DATA.clone()}_eraseAttrData(){return this._eraseAttrDataInternal.bg&=-67108864,this._eraseAttrDataInternal.bg|=67108863&this._curAttrData.bg,this._eraseAttrDataInternal}setgLevel(e){return this._charsetService.setgLevel(e),!0}screenAlignmentPattern(){const e=new u.CellData;e.content=1<<22|\"E\".charCodeAt(0),e.fg=this._curAttrData.fg,e.bg=this._curAttrData.bg,this._setCursor(0,0);for(let t=0;t(this._coreService.triggerDataEvent(`${n.C0.ESC}${e}${n.C0.ESC}\\\\`),!0))('\"q'===e?`P1$r${this._curAttrData.isProtected()?1:0}\"q`:'\"p'===e?'P1$r61;1\"p':\"r\"===e?`P1$r${i.scrollTop+1};${i.scrollBottom+1}r`:\"m\"===e?\"P1$r0m\":\" q\"===e?`P1$r${{block:2,underline:4,bar:6}[s.cursorStyle]-(s.cursorBlink?1:0)} q`:\"P0$r\")}markRangeDirty(e,t){this._dirtyRowTracker.markRangeDirty(e,t)}}t.InputHandler=D;let L=class{constructor(e){this._bufferService=e,this.clearRange()}clearRange(){this.start=this._bufferService.buffer.y,this.end=this._bufferService.buffer.y}markDirty(e){ethis.end&&(this.end=e)}markRangeDirty(e,t){e>t&&(E=e,e=t,t=E),ethis.end&&(this.end=t)}markAllDirty(){this.markRangeDirty(0,this._bufferService.rows-1)}};function R(e){return 0<=e&&e<256}L=s([r(0,f.IBufferService)],L)},7710:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.FourKeyMap=t.TwoKeyMap=void 0;class i{constructor(){this._data={}}set(e,t,i){this._data[e]||(this._data[e]={}),this._data[e][t]=i}get(e,t){return this._data[e]?this._data[e][t]:void 0}clear(){this._data={}}}t.TwoKeyMap=i,t.FourKeyMap=class{constructor(){this._data=new i}set(e,t,s,r,n){this._data.get(e,t)||this._data.set(e,t,new i),this._data.get(e,t).set(s,r,n)}get(e,t,i,s){return this._data.get(e,t)?.get(i,s)}clear(){this._data.clear()}}},701:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.isChromeOS=t.isLinux=t.isWindows=t.isIphone=t.isIpad=t.isMac=t.isSafari=t.isLegacyEdge=t.isFirefox=t.isNode=void 0,t.getSafariVersion=function(){if(!t.isSafari)return 0;const e=i.match(/Version\\/(\\d+)/);return null===e||e.length<2?0:parseInt(e[1])},t.isNode=\"undefined\"!=typeof process&&\"title\"in process;const i=t.isNode?\"node\":navigator.userAgent,s=t.isNode?\"node\":navigator.platform;t.isFirefox=i.includes(\"Firefox\"),t.isLegacyEdge=i.includes(\"Edge\"),t.isSafari=/^((?!chrome|android).)*safari/i.test(i),t.isMac=[\"Macintosh\",\"MacIntel\",\"MacPPC\",\"Mac68K\"].includes(s),t.isIpad=\"iPad\"===s,t.isIphone=\"iPhone\"===s,t.isWindows=[\"Windows\",\"Win16\",\"Win32\",\"WinCE\"].includes(s),t.isLinux=s.indexOf(\"Linux\")>=0,t.isChromeOS=/\\bCrOS\\b/.test(i)},3087:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.SortedList=void 0;const s=i(6168);let r=0;t.SortedList=class{constructor(e){this._getKey=e,this._array=[],this._insertedValues=[],this._flushInsertedTask=new s.IdleTaskQueue,this._isFlushingInserted=!1,this._deletedIndices=[],this._flushDeletedTask=new s.IdleTaskQueue,this._isFlushingDeleted=!1}clear(){this._array.length=0,this._insertedValues.length=0,this._flushInsertedTask.clear(),this._isFlushingInserted=!1,this._deletedIndices.length=0,this._flushDeletedTask.clear(),this._isFlushingDeleted=!1}insert(e){this._flushCleanupDeleted(),0===this._insertedValues.length&&this._flushInsertedTask.enqueue((()=>this._flushInserted())),this._insertedValues.push(e)}_flushInserted(){const e=this._insertedValues.sort(((e,t)=>this._getKey(e)-this._getKey(t)));let t=0,i=0;const s=new Array(this._array.length+this._insertedValues.length);for(let r=0;r=this._array.length||this._getKey(e[t])<=this._getKey(this._array[i])?(s[r]=e[t],t++):s[r]=this._array[i++];this._array=s,this._insertedValues.length=0}_flushCleanupInserted(){!this._isFlushingInserted&&this._insertedValues.length>0&&this._flushInsertedTask.flush()}delete(e){if(this._flushCleanupInserted(),0===this._array.length)return!1;const t=this._getKey(e);if(void 0===t)return!1;if(r=this._search(t),-1===r)return!1;if(this._getKey(this._array[r])!==t)return!1;do{if(this._array[r]===e)return 0===this._deletedIndices.length&&this._flushDeletedTask.enqueue((()=>this._flushDeleted())),this._deletedIndices.push(r),!0}while(++re-t));let t=0;const i=new Array(this._array.length-e.length);let s=0;for(let r=0;r0&&this._flushDeletedTask.flush()}*getKeyIterator(e){if(this._flushCleanupInserted(),this._flushCleanupDeleted(),0!==this._array.length&&(r=this._search(e),!(r<0||r>=this._array.length)&&this._getKey(this._array[r])===e))do{yield this._array[r]}while(++r=this._array.length)&&this._getKey(this._array[r])===e))do{t(this._array[r])}while(++r=t;){let s=t+i>>1;const r=this._getKey(this._array[s]);if(r>e)i=s-1;else{if(!(r0&&this._getKey(this._array[s-1])===e;)s--;return s}t=s+1}}return t}}},6168:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DebouncedIdleTask=t.IdleTaskQueue=t.PriorityTaskQueue=void 0;const s=i(701);class r{constructor(){this._tasks=[],this._i=0}enqueue(e){this._tasks.push(e),this._start()}flush(){for(;this._ir)return s-t<-20&&console.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(s-t))}ms`),void this._start();s=r}this.clear()}}class n extends r{_requestCallback(e){return setTimeout((()=>e(this._createDeadline(16))))}_cancelCallback(e){clearTimeout(e)}_createDeadline(e){const t=performance.now()+e;return{timeRemaining:()=>Math.max(0,t-performance.now())}}}t.PriorityTaskQueue=n,t.IdleTaskQueue=!s.isNode&&\"requestIdleCallback\"in window?class extends r{_requestCallback(e){return requestIdleCallback(e)}_cancelCallback(e){cancelIdleCallback(e)}}:n,t.DebouncedIdleTask=class{constructor(){this._queue=new t.IdleTaskQueue}set(e){this._queue.clear(),this._queue.enqueue(e)}flush(){this._queue.flush()}}},5882:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.updateWindowsModeWrappedState=function(e){const t=e.buffer.lines.get(e.buffer.ybase+e.buffer.y-1),i=t?.get(e.cols-1),r=e.buffer.lines.get(e.buffer.ybase+e.buffer.y);r&&i&&(r.isWrapped=i[s.CHAR_DATA_CODE_INDEX]!==s.NULL_CELL_CODE&&i[s.CHAR_DATA_CODE_INDEX]!==s.WHITESPACE_CELL_CODE)};const s=i(8938)},5451:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ExtendedAttrs=t.AttributeData=void 0;class i{constructor(){this.fg=0,this.bg=0,this.extended=new s}static toColorRGB(e){return[e>>>16&255,e>>>8&255,255&e]}static fromColorRGB(e){return(255&e[0])<<16|(255&e[1])<<8|255&e[2]}clone(){const e=new i;return e.fg=this.fg,e.bg=this.bg,e.extended=this.extended.clone(),e}isInverse(){return 67108864&this.fg}isBold(){return 134217728&this.fg}isUnderline(){return this.hasExtendedAttrs()&&0!==this.extended.underlineStyle?1:268435456&this.fg}isBlink(){return 536870912&this.fg}isInvisible(){return 1073741824&this.fg}isItalic(){return 67108864&this.bg}isDim(){return 134217728&this.bg}isStrikethrough(){return 2147483648&this.fg}isProtected(){return 536870912&this.bg}isOverline(){return 1073741824&this.bg}getFgColorMode(){return 50331648&this.fg}getBgColorMode(){return 50331648&this.bg}isFgRGB(){return!(50331648&~this.fg)}isBgRGB(){return!(50331648&~this.bg)}isFgPalette(){return 16777216==(50331648&this.fg)||33554432==(50331648&this.fg)}isBgPalette(){return 16777216==(50331648&this.bg)||33554432==(50331648&this.bg)}isFgDefault(){return!(50331648&this.fg)}isBgDefault(){return!(50331648&this.bg)}isAttributeDefault(){return 0===this.fg&&0===this.bg}getFgColor(){switch(50331648&this.fg){case 16777216:case 33554432:return 255&this.fg;case 50331648:return 16777215&this.fg;default:return-1}}getBgColor(){switch(50331648&this.bg){case 16777216:case 33554432:return 255&this.bg;case 50331648:return 16777215&this.bg;default:return-1}}hasExtendedAttrs(){return 268435456&this.bg}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(268435456&this.bg&&~this.extended.underlineColor)switch(50331648&this.extended.underlineColor){case 16777216:case 33554432:return 255&this.extended.underlineColor;case 50331648:return 16777215&this.extended.underlineColor;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return 268435456&this.bg&&~this.extended.underlineColor?50331648&this.extended.underlineColor:this.getFgColorMode()}isUnderlineColorRGB(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&~this.extended.underlineColor):this.isFgRGB()}isUnderlineColorPalette(){return 268435456&this.bg&&~this.extended.underlineColor?16777216==(50331648&this.extended.underlineColor)||33554432==(50331648&this.extended.underlineColor):this.isFgPalette()}isUnderlineColorDefault(){return 268435456&this.bg&&~this.extended.underlineColor?!(50331648&this.extended.underlineColor):this.isFgDefault()}getUnderlineStyle(){return 268435456&this.fg?268435456&this.bg?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}}t.AttributeData=i;class s{get ext(){return this._urlId?-469762049&this._ext|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(469762048&this._ext)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return 67108863&this._ext}set underlineColor(e){this._ext&=-67108864,this._ext|=67108863&e}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){const e=(3758096384&this._ext)>>29;return e<0?4294967288^e:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}clone(){return new s(this._ext,this._urlId)}isEmpty(){return 0===this.underlineStyle&&0===this._urlId}}t.ExtendedAttrs=s},1073:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Buffer=t.MAX_BUFFER_SIZE=void 0;const s=i(5639),r=i(6168),n=i(5451),o=i(6107),a=i(732),l=i(3055),h=i(8938),c=i(8158),d=i(6760);t.MAX_BUFFER_SIZE=4294967295,t.Buffer=class{constructor(e,t,i){this._hasScrollback=e,this._optionsService=t,this._bufferService=i,this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.tabs={},this.savedY=0,this.savedX=0,this.savedCurAttrData=o.DEFAULT_ATTR_DATA.clone(),this.savedCharset=d.DEFAULT_CHARSET,this.markers=[],this._nullCell=l.CellData.fromCharData([0,h.NULL_CELL_CHAR,h.NULL_CELL_WIDTH,h.NULL_CELL_CODE]),this._whitespaceCell=l.CellData.fromCharData([0,h.WHITESPACE_CELL_CHAR,h.WHITESPACE_CELL_WIDTH,h.WHITESPACE_CELL_CODE]),this._isClearing=!1,this._memoryCleanupQueue=new r.IdleTaskQueue,this._memoryCleanupPosition=0,this._cols=this._bufferService.cols,this._rows=this._bufferService.rows,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}getNullCell(e){return e?(this._nullCell.fg=e.fg,this._nullCell.bg=e.bg,this._nullCell.extended=e.extended):(this._nullCell.fg=0,this._nullCell.bg=0,this._nullCell.extended=new n.ExtendedAttrs),this._nullCell}getWhitespaceCell(e){return e?(this._whitespaceCell.fg=e.fg,this._whitespaceCell.bg=e.bg,this._whitespaceCell.extended=e.extended):(this._whitespaceCell.fg=0,this._whitespaceCell.bg=0,this._whitespaceCell.extended=new n.ExtendedAttrs),this._whitespaceCell}getBlankLine(e,t){return new o.BufferLine(this._bufferService.cols,this.getNullCell(e),t)}get hasScrollback(){return this._hasScrollback&&this.lines.maxLength>this._rows}get isCursorInViewport(){const e=this.ybase+this.y-this.ydisp;return e>=0&&et.MAX_BUFFER_SIZE?t.MAX_BUFFER_SIZE:i}fillViewportRows(e){if(0===this.lines.length){void 0===e&&(e=o.DEFAULT_ATTR_DATA);let t=this._rows;for(;t--;)this.lines.push(this.getBlankLine(e))}}clear(){this.ydisp=0,this.ybase=0,this.y=0,this.x=0,this.lines=new s.CircularList(this._getCorrectBufferLength(this._rows)),this.scrollTop=0,this.scrollBottom=this._rows-1,this.setupTabStops()}resize(e,t){const i=this.getNullCell(o.DEFAULT_ATTR_DATA);let s=0;const r=this._getCorrectBufferLength(t);if(r>this.lines.maxLength&&(this.lines.maxLength=r),this.lines.length>0){if(this._cols0&&this.lines.length<=this.ybase+this.y+n+1?(this.ybase--,n++,this.ydisp>0&&this.ydisp--):this.lines.push(new o.BufferLine(e,i)));else for(let e=this._rows;e>t;e--)this.lines.length>t+this.ybase&&(this.lines.length>this.ybase+this.y+1?this.lines.pop():(this.ybase++,this.ydisp++));if(r0&&(this.lines.trimStart(e),this.ybase=Math.max(this.ybase-e,0),this.ydisp=Math.max(this.ydisp-e,0),this.savedY=Math.max(this.savedY-e,0)),this.lines.maxLength=r}this.x=Math.min(this.x,e-1),this.y=Math.min(this.y,t-1),n&&(this.y+=n),this.savedX=Math.min(this.savedX,e-1),this.scrollTop=0}if(this.scrollBottom=t-1,this._isReflowEnabled&&(this._reflow(e,t),this._cols>e))for(let t=0;t.1*this.lines.length&&(this._memoryCleanupPosition=0,this._memoryCleanupQueue.enqueue((()=>this._batchedMemoryCleanup())))}_batchedMemoryCleanup(){let e=!0;this._memoryCleanupPosition>=this.lines.length&&(this._memoryCleanupPosition=0,e=!1);let t=0;for(;this._memoryCleanupPosition100)return!0;return e}get _isReflowEnabled(){const e=this._optionsService.rawOptions.windowsPty;return e&&e.buildNumber?this._hasScrollback&&\"conpty\"===e.backend&&e.buildNumber>=21376:this._hasScrollback&&!this._optionsService.rawOptions.windowsMode}_reflow(e,t){this._cols!==e&&(e>this._cols?this._reflowLarger(e,t):this._reflowSmaller(e,t))}_reflowLarger(e,t){const i=this._optionsService.rawOptions.reflowCursorLine,s=(0,a.reflowLargerGetLinesToRemove)(this.lines,this._cols,e,this.ybase+this.y,this.getNullCell(o.DEFAULT_ATTR_DATA),i);if(s.length>0){const i=(0,a.reflowLargerCreateNewLayout)(this.lines,s);(0,a.reflowLargerApplyNewLayout)(this.lines,i.layout),this._reflowLargerAdjustViewport(e,t,i.countRemoved)}}_reflowLargerAdjustViewport(e,t,i){const s=this.getNullCell(o.DEFAULT_ATTR_DATA);let r=i;for(;r-- >0;)0===this.ybase?(this.y>0&&this.y--,this.lines.length=0;l--){let h=this.lines.get(l);if(!h||!h.isWrapped&&h.getTrimmedLength()<=e)continue;const c=[h];for(;h.isWrapped&&l>0;)h=this.lines.get(--l),c.unshift(h);if(!i){const e=this.ybase+this.y;if(e>=l&&e0&&(r.push({start:l+c.length+n,newLines:p}),n+=p.length),c.push(...p);let g=u.length-1,m=u[g];0===m&&(g--,m=u[g]);let v=c.length-_-1,S=d;for(;v>=0;){const e=Math.min(S,m);if(void 0===c[g])break;if(c[g].copyCellsFrom(c[v],S-e,m-e,e,!0),m-=e,0===m&&(g--,m=u[g]),S-=e,0===S){v--;const e=Math.max(v,0);S=(0,a.getWrappedLineTrimmedLength)(c,e,this._cols)}}for(let t=0;t0;)0===this.ybase?this.y0){const e=[],t=[];for(let e=0;e=0;h--)if(a&&a.start>s+l){for(let e=a.newLines.length-1;e>=0;e--)this.lines.set(h--,a.newLines[e]);h++,e.push({index:s+1,amount:a.newLines.length}),l+=a.newLines.length,a=r[++o]}else this.lines.set(h,t[s--]);let h=0;for(let t=e.length-1;t>=0;t--)e[t].index+=h,this.lines.onInsertEmitter.fire(e[t]),h+=e[t].amount;const c=Math.max(0,i+n-this.lines.maxLength);c>0&&this.lines.onTrimEmitter.fire(c)}}translateBufferLineToString(e,t,i=0,s){const r=this.lines.get(e);return r?r.translateToString(t,i,s):\"\"}getWrappedRangeForLine(e){let t=e,i=e;for(;t>0&&this.lines.get(t).isWrapped;)t--;for(;i+10;);return e>=this._cols?this._cols-1:e<0?0:e}nextStop(e){for(null==e&&(e=this.x);!this.tabs[++e]&&e=this._cols?this._cols-1:e<0?0:e}clearMarkers(e){this._isClearing=!0;for(let t=0;t{t.line-=e,t.line<0&&t.dispose()}))),t.register(this.lines.onInsert((e=>{t.line>=e.index&&(t.line+=e.amount)}))),t.register(this.lines.onDelete((e=>{t.line>=e.index&&t.linee.index&&(t.line-=e.amount)}))),t.register(t.onDispose((()=>this._removeMarker(t)))),t}_removeMarker(e){this._isClearing||this.markers.splice(this.markers.indexOf(e),1)}}},6107:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferLine=t.DEFAULT_ATTR_DATA=void 0;const s=i(5451),r=i(3055),n=i(8938),o=i(726);t.DEFAULT_ATTR_DATA=Object.freeze(new s.AttributeData);let a=0;class l{constructor(e,t,i=!1){this.isWrapped=i,this._combined={},this._extendedAttrs={},this._data=new Uint32Array(3*e);const s=t||r.CellData.fromCharData([0,n.NULL_CELL_CHAR,n.NULL_CELL_WIDTH,n.NULL_CELL_CODE]);for(let t=0;t>22,2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):i]}set(e,t){this._data[3*e+1]=t[n.CHAR_DATA_ATTR_INDEX],t[n.CHAR_DATA_CHAR_INDEX].length>1?(this._combined[e]=t[1],this._data[3*e+0]=2097152|e|t[n.CHAR_DATA_WIDTH_INDEX]<<22):this._data[3*e+0]=t[n.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|t[n.CHAR_DATA_WIDTH_INDEX]<<22}getWidth(e){return this._data[3*e+0]>>22}hasWidth(e){return 12582912&this._data[3*e+0]}getFg(e){return this._data[3*e+1]}getBg(e){return this._data[3*e+2]}hasContent(e){return 4194303&this._data[3*e+0]}getCodePoint(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e].charCodeAt(this._combined[e].length-1):2097151&t}isCombined(e){return 2097152&this._data[3*e+0]}getString(e){const t=this._data[3*e+0];return 2097152&t?this._combined[e]:2097151&t?(0,o.stringFromCodePoint)(2097151&t):\"\"}isProtected(e){return 536870912&this._data[3*e+2]}loadCell(e,t){return a=3*e,t.content=this._data[a+0],t.fg=this._data[a+1],t.bg=this._data[a+2],2097152&t.content&&(t.combinedData=this._combined[e]),268435456&t.bg&&(t.extended=this._extendedAttrs[e]),t}setCell(e,t){2097152&t.content&&(this._combined[e]=t.combinedData),268435456&t.bg&&(this._extendedAttrs[e]=t.extended),this._data[3*e+0]=t.content,this._data[3*e+1]=t.fg,this._data[3*e+2]=t.bg}setCellFromCodepoint(e,t,i,s){268435456&s.bg&&(this._extendedAttrs[e]=s.extended),this._data[3*e+0]=t|i<<22,this._data[3*e+1]=s.fg,this._data[3*e+2]=s.bg}addCodepointToCell(e,t,i){let s=this._data[3*e+0];2097152&s?this._combined[e]+=(0,o.stringFromCodePoint)(t):2097151&s?(this._combined[e]=(0,o.stringFromCodePoint)(2097151&s)+(0,o.stringFromCodePoint)(t),s&=-2097152,s|=2097152):s=t|1<<22,i&&(s&=-12582913,s|=i<<22),this._data[3*e+0]=s}insertCells(e,t,i){if((e%=this.length)&&2===this.getWidth(e-1)&&this.setCellFromCodepoint(e-1,0,1,i),t=0;--i)this.setCell(e+t+i,this.loadCell(e+i,s));for(let s=0;sthis.length){if(this._data.buffer.byteLength>=4*i)this._data=new Uint32Array(this._data.buffer,0,i);else{const e=new Uint32Array(i);e.set(this._data),this._data=e}for(let i=this.length;i=e&&delete this._combined[s]}const s=Object.keys(this._extendedAttrs);for(let t=0;t=e&&delete this._extendedAttrs[i]}}return this.length=e,4*i*2=0;--e)if(4194303&this._data[3*e+0])return e+(this._data[3*e+0]>>22);return 0}getNoBgTrimmedLength(){for(let e=this.length-1;e>=0;--e)if(4194303&this._data[3*e+0]||50331648&this._data[3*e+2])return e+(this._data[3*e+0]>>22);return 0}copyCellsFrom(e,t,i,s,r){const n=e._data;if(r)for(let r=s-1;r>=0;r--){for(let e=0;e<3;e++)this._data[3*(i+r)+e]=n[3*(t+r)+e];268435456&n[3*(t+r)+2]&&(this._extendedAttrs[i+r]=e._extendedAttrs[t+r])}else for(let r=0;r=t&&(this._combined[r-t+i]=e._combined[r])}}translateToString(e,t,i,s){t=t??0,i=i??this.length,e&&(i=Math.min(i,this.getTrimmedLength())),s&&(s.length=0);let r=\"\";for(;t>22||1}return s&&s.push(t),r}}t.BufferLine=l},9384:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.getRangeLength=function(e,t){if(e.start.y>e.end.y)throw new Error(`Buffer range end (${e.end.x}, ${e.end.y}) cannot be before start (${e.start.x}, ${e.start.y})`);return t*(e.end.y-e.start.y)+(e.end.x-e.start.x+1)}},732:(e,t)=>{function i(e,t,i){if(t===e.length-1)return e[t].getTrimmedLength();const s=!e[t].hasContent(i-1)&&1===e[t].getWidth(i-1),r=2===e[t+1].getWidth(0);return s&&r?i-1:i}Object.defineProperty(t,\"__esModule\",{value:!0}),t.reflowLargerGetLinesToRemove=function(e,t,s,r,n,o){const a=[];for(let l=0;l=l&&r0&&(e>u||0===d[e].getTrimmedLength());e--)g++;g>0&&(a.push(l+d.length-g),a.push(g)),l+=d.length-1}return a},t.reflowLargerCreateNewLayout=function(e,t){const i=[];let s=0,r=t[s],n=0;for(let o=0;oi(e,r,t))).reduce(((e,t)=>e+t));let o=0,a=0,l=0;for(;lh&&(o-=h,a++);const c=2===e[a].getWidth(o-1);c&&o--;const d=c?s-1:s;r.push(d),l+=d}return r},t.getWrappedLineTrimmedLength=i},4097:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferSet=void 0;const s=i(7150),r=i(1073),n=i(802);class o extends s.Disposable{constructor(e,t){super(),this._optionsService=e,this._bufferService=t,this._onBufferActivate=this._register(new n.Emitter),this.onBufferActivate=this._onBufferActivate.event,this.reset(),this._register(this._optionsService.onSpecificOptionChange(\"scrollback\",(()=>this.resize(this._bufferService.cols,this._bufferService.rows)))),this._register(this._optionsService.onSpecificOptionChange(\"tabStopWidth\",(()=>this.setupTabStops())))}reset(){this._normal=new r.Buffer(!0,this._optionsService,this._bufferService),this._normal.fillViewportRows(),this._alt=new r.Buffer(!1,this._optionsService,this._bufferService),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}),this.setupTabStops()}get alt(){return this._alt}get active(){return this._activeBuffer}get normal(){return this._normal}activateNormalBuffer(){this._activeBuffer!==this._normal&&(this._normal.x=this._alt.x,this._normal.y=this._alt.y,this._alt.clearAllMarkers(),this._alt.clear(),this._activeBuffer=this._normal,this._onBufferActivate.fire({activeBuffer:this._normal,inactiveBuffer:this._alt}))}activateAltBuffer(e){this._activeBuffer!==this._alt&&(this._alt.fillViewportRows(e),this._alt.x=this._normal.x,this._alt.y=this._normal.y,this._activeBuffer=this._alt,this._onBufferActivate.fire({activeBuffer:this._alt,inactiveBuffer:this._normal}))}resize(e,t){this._normal.resize(e,t),this._alt.resize(e,t),this.setupTabStops(e)}setupTabStops(e){this._normal.setupTabStops(e),this._alt.setupTabStops(e)}}t.BufferSet=o},3055:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CellData=void 0;const s=i(726),r=i(8938),n=i(5451);class o extends n.AttributeData{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new n.ExtendedAttrs,this.combinedData=\"\"}static fromCharData(e){const t=new o;return t.setFromCharData(e),t}isCombined(){return 2097152&this.content}getWidth(){return this.content>>22}getChars(){return 2097152&this.content?this.combinedData:2097151&this.content?(0,s.stringFromCodePoint)(2097151&this.content):\"\"}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):2097151&this.content}setFromCharData(e){this.fg=e[r.CHAR_DATA_ATTR_INDEX],this.bg=0;let t=!1;if(e[r.CHAR_DATA_CHAR_INDEX].length>2)t=!0;else if(2===e[r.CHAR_DATA_CHAR_INDEX].length){const i=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0);if(55296<=i&&i<=56319){const s=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(1);56320<=s&&s<=57343?this.content=1024*(i-55296)+s-56320+65536|e[r.CHAR_DATA_WIDTH_INDEX]<<22:t=!0}else t=!0}else this.content=e[r.CHAR_DATA_CHAR_INDEX].charCodeAt(0)|e[r.CHAR_DATA_WIDTH_INDEX]<<22;t&&(this.combinedData=e[r.CHAR_DATA_CHAR_INDEX],this.content=2097152|e[r.CHAR_DATA_WIDTH_INDEX]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}}t.CellData=o},8938:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.WHITESPACE_CELL_CODE=t.WHITESPACE_CELL_WIDTH=t.WHITESPACE_CELL_CHAR=t.NULL_CELL_CODE=t.NULL_CELL_WIDTH=t.NULL_CELL_CHAR=t.CHAR_DATA_CODE_INDEX=t.CHAR_DATA_WIDTH_INDEX=t.CHAR_DATA_CHAR_INDEX=t.CHAR_DATA_ATTR_INDEX=t.DEFAULT_EXT=t.DEFAULT_ATTR=t.DEFAULT_COLOR=void 0,t.DEFAULT_COLOR=0,t.DEFAULT_ATTR=t.DEFAULT_COLOR<<9|256,t.DEFAULT_EXT=0,t.CHAR_DATA_ATTR_INDEX=0,t.CHAR_DATA_CHAR_INDEX=1,t.CHAR_DATA_WIDTH_INDEX=2,t.CHAR_DATA_CODE_INDEX=3,t.NULL_CELL_CHAR=\"\",t.NULL_CELL_WIDTH=1,t.NULL_CELL_CODE=0,t.WHITESPACE_CELL_CHAR=\" \",t.WHITESPACE_CELL_WIDTH=1,t.WHITESPACE_CELL_CODE=32},8158:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Marker=void 0;const s=i(802),r=i(7150);class n{get id(){return this._id}constructor(e){this.line=e,this.isDisposed=!1,this._disposables=[],this._id=n._nextId++,this._onDispose=this.register(new s.Emitter),this.onDispose=this._onDispose.event}dispose(){this.isDisposed||(this.isDisposed=!0,this.line=-1,this._onDispose.fire(),(0,r.dispose)(this._disposables),this._disposables.length=0)}register(e){return this._disposables.push(e),e}}t.Marker=n,n._nextId=1},6760:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DEFAULT_CHARSET=t.CHARSETS=void 0,t.CHARSETS={},t.DEFAULT_CHARSET=t.CHARSETS.B,t.CHARSETS[0]={\"`\":\"◆\",a:\"▒\",b:\"␉\",c:\"␌\",d:\"␍\",e:\"␊\",f:\"°\",g:\"±\",h:\"␤\",i:\"␋\",j:\"┘\",k:\"┐\",l:\"┌\",m:\"└\",n:\"┼\",o:\"⎺\",p:\"⎻\",q:\"─\",r:\"⎼\",s:\"⎽\",t:\"├\",u:\"┤\",v:\"┴\",w:\"┬\",x:\"│\",y:\"≤\",z:\"≥\",\"{\":\"π\",\"|\":\"≠\",\"}\":\"£\",\"~\":\"·\"},t.CHARSETS.A={\"#\":\"£\"},t.CHARSETS.B=void 0,t.CHARSETS[4]={\"#\":\"£\",\"@\":\"¾\",\"[\":\"ij\",\"\\\\\":\"½\",\"]\":\"|\",\"{\":\"¨\",\"|\":\"f\",\"}\":\"¼\",\"~\":\"´\"},t.CHARSETS.C=t.CHARSETS[5]={\"[\":\"Ä\",\"\\\\\":\"Ö\",\"]\":\"Å\",\"^\":\"Ü\",\"`\":\"é\",\"{\":\"ä\",\"|\":\"ö\",\"}\":\"å\",\"~\":\"ü\"},t.CHARSETS.R={\"#\":\"£\",\"@\":\"à\",\"[\":\"°\",\"\\\\\":\"ç\",\"]\":\"§\",\"{\":\"é\",\"|\":\"ù\",\"}\":\"è\",\"~\":\"¨\"},t.CHARSETS.Q={\"@\":\"à\",\"[\":\"â\",\"\\\\\":\"ç\",\"]\":\"ê\",\"^\":\"î\",\"`\":\"ô\",\"{\":\"é\",\"|\":\"ù\",\"}\":\"è\",\"~\":\"û\"},t.CHARSETS.K={\"@\":\"§\",\"[\":\"Ä\",\"\\\\\":\"Ö\",\"]\":\"Ü\",\"{\":\"ä\",\"|\":\"ö\",\"}\":\"ü\",\"~\":\"ß\"},t.CHARSETS.Y={\"#\":\"£\",\"@\":\"§\",\"[\":\"°\",\"\\\\\":\"ç\",\"]\":\"é\",\"`\":\"ù\",\"{\":\"à\",\"|\":\"ò\",\"}\":\"è\",\"~\":\"ì\"},t.CHARSETS.E=t.CHARSETS[6]={\"@\":\"Ä\",\"[\":\"Æ\",\"\\\\\":\"Ø\",\"]\":\"Å\",\"^\":\"Ü\",\"`\":\"ä\",\"{\":\"æ\",\"|\":\"ø\",\"}\":\"å\",\"~\":\"ü\"},t.CHARSETS.Z={\"#\":\"£\",\"@\":\"§\",\"[\":\"¡\",\"\\\\\":\"Ñ\",\"]\":\"¿\",\"{\":\"°\",\"|\":\"ñ\",\"}\":\"ç\"},t.CHARSETS.H=t.CHARSETS[7]={\"@\":\"É\",\"[\":\"Ä\",\"\\\\\":\"Ö\",\"]\":\"Å\",\"^\":\"Ü\",\"`\":\"é\",\"{\":\"ä\",\"|\":\"ö\",\"}\":\"å\",\"~\":\"ü\"},t.CHARSETS[\"=\"]={\"#\":\"ù\",\"@\":\"à\",\"[\":\"é\",\"\\\\\":\"ç\",\"]\":\"ê\",\"^\":\"î\",_:\"è\",\"`\":\"ô\",\"{\":\"ä\",\"|\":\"ö\",\"}\":\"ü\",\"~\":\"û\"}},3534:(e,t)=>{var i,s,r;Object.defineProperty(t,\"__esModule\",{value:!0}),t.C1_ESCAPED=t.C1=t.C0=void 0,function(e){e.NUL=\"\\0\",e.SOH=\"\u0001\",e.STX=\"\u0002\",e.ETX=\"\u0003\",e.EOT=\"\u0004\",e.ENQ=\"\u0005\",e.ACK=\"\u0006\",e.BEL=\"\u0007\",e.BS=\"\\b\",e.HT=\"\\t\",e.LF=\"\\n\",e.VT=\"\\v\",e.FF=\"\\f\",e.CR=\"\\r\",e.SO=\"\u000e\",e.SI=\"\u000f\",e.DLE=\"\u0010\",e.DC1=\"\u0011\",e.DC2=\"\u0012\",e.DC3=\"\u0013\",e.DC4=\"\u0014\",e.NAK=\"\u0015\",e.SYN=\"\u0016\",e.ETB=\"\u0017\",e.CAN=\"\u0018\",e.EM=\"\u0019\",e.SUB=\"\u001a\",e.ESC=\"\u001b\",e.FS=\"\u001c\",e.GS=\"\u001d\",e.RS=\"\u001e\",e.US=\"\u001f\",e.SP=\" \",e.DEL=\"\"}(i||(t.C0=i={})),function(e){e.PAD=\"€\",e.HOP=\"\",e.BPH=\"‚\",e.NBH=\"ƒ\",e.IND=\"„\",e.NEL=\"…\",e.SSA=\"†\",e.ESA=\"‡\",e.HTS=\"ˆ\",e.HTJ=\"‰\",e.VTS=\"Š\",e.PLD=\"‹\",e.PLU=\"Œ\",e.RI=\"\",e.SS2=\"Ž\",e.SS3=\"\",e.DCS=\"\",e.PU1=\"‘\",e.PU2=\"’\",e.STS=\"“\",e.CCH=\"”\",e.MW=\"•\",e.SPA=\"–\",e.EPA=\"—\",e.SOS=\"˜\",e.SGCI=\"™\",e.SCI=\"š\",e.CSI=\"›\",e.ST=\"œ\",e.OSC=\"\",e.PM=\"ž\",e.APC=\"Ÿ\"}(s||(t.C1=s={})),function(e){e.ST=`${i.ESC}\\\\`}(r||(t.C1_ESCAPED=r={}))},706:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.evaluateKeyboardEvent=function(e,t,i,n){const o={type:0,cancel:!1,key:void 0},a=(e.shiftKey?1:0)|(e.altKey?2:0)|(e.ctrlKey?4:0)|(e.metaKey?8:0);switch(e.keyCode){case 0:\"UIKeyInputUpArrow\"===e.key?o.key=t?s.C0.ESC+\"OA\":s.C0.ESC+\"[A\":\"UIKeyInputLeftArrow\"===e.key?o.key=t?s.C0.ESC+\"OD\":s.C0.ESC+\"[D\":\"UIKeyInputRightArrow\"===e.key?o.key=t?s.C0.ESC+\"OC\":s.C0.ESC+\"[C\":\"UIKeyInputDownArrow\"===e.key&&(o.key=t?s.C0.ESC+\"OB\":s.C0.ESC+\"[B\");break;case 8:o.key=e.ctrlKey?\"\\b\":s.C0.DEL,e.altKey&&(o.key=s.C0.ESC+o.key);break;case 9:if(e.shiftKey){o.key=s.C0.ESC+\"[Z\";break}o.key=s.C0.HT,o.cancel=!0;break;case 13:o.key=e.altKey?s.C0.ESC+s.C0.CR:s.C0.CR,o.cancel=!0;break;case 27:o.key=s.C0.ESC,e.altKey&&(o.key=s.C0.ESC+s.C0.ESC),o.cancel=!0;break;case 37:if(e.metaKey)break;o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"D\":t?s.C0.ESC+\"OD\":s.C0.ESC+\"[D\";break;case 39:if(e.metaKey)break;o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"C\":t?s.C0.ESC+\"OC\":s.C0.ESC+\"[C\";break;case 38:if(e.metaKey)break;o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"A\":t?s.C0.ESC+\"OA\":s.C0.ESC+\"[A\";break;case 40:if(e.metaKey)break;o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"B\":t?s.C0.ESC+\"OB\":s.C0.ESC+\"[B\";break;case 45:e.shiftKey||e.ctrlKey||(o.key=s.C0.ESC+\"[2~\");break;case 46:o.key=a?s.C0.ESC+\"[3;\"+(a+1)+\"~\":s.C0.ESC+\"[3~\";break;case 36:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"H\":t?s.C0.ESC+\"OH\":s.C0.ESC+\"[H\";break;case 35:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"F\":t?s.C0.ESC+\"OF\":s.C0.ESC+\"[F\";break;case 33:e.shiftKey?o.type=2:e.ctrlKey?o.key=s.C0.ESC+\"[5;\"+(a+1)+\"~\":o.key=s.C0.ESC+\"[5~\";break;case 34:e.shiftKey?o.type=3:e.ctrlKey?o.key=s.C0.ESC+\"[6;\"+(a+1)+\"~\":o.key=s.C0.ESC+\"[6~\";break;case 112:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"P\":s.C0.ESC+\"OP\";break;case 113:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"Q\":s.C0.ESC+\"OQ\";break;case 114:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"R\":s.C0.ESC+\"OR\";break;case 115:o.key=a?s.C0.ESC+\"[1;\"+(a+1)+\"S\":s.C0.ESC+\"OS\";break;case 116:o.key=a?s.C0.ESC+\"[15;\"+(a+1)+\"~\":s.C0.ESC+\"[15~\";break;case 117:o.key=a?s.C0.ESC+\"[17;\"+(a+1)+\"~\":s.C0.ESC+\"[17~\";break;case 118:o.key=a?s.C0.ESC+\"[18;\"+(a+1)+\"~\":s.C0.ESC+\"[18~\";break;case 119:o.key=a?s.C0.ESC+\"[19;\"+(a+1)+\"~\":s.C0.ESC+\"[19~\";break;case 120:o.key=a?s.C0.ESC+\"[20;\"+(a+1)+\"~\":s.C0.ESC+\"[20~\";break;case 121:o.key=a?s.C0.ESC+\"[21;\"+(a+1)+\"~\":s.C0.ESC+\"[21~\";break;case 122:o.key=a?s.C0.ESC+\"[23;\"+(a+1)+\"~\":s.C0.ESC+\"[23~\";break;case 123:o.key=a?s.C0.ESC+\"[24;\"+(a+1)+\"~\":s.C0.ESC+\"[24~\";break;default:if(!e.ctrlKey||e.shiftKey||e.altKey||e.metaKey)if(i&&!n||!e.altKey||e.metaKey)!i||e.altKey||e.ctrlKey||e.shiftKey||!e.metaKey?e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.keyCode>=48&&1===e.key.length?o.key=e.key:e.key&&e.ctrlKey&&(\"_\"===e.key&&(o.key=s.C0.US),\"@\"===e.key&&(o.key=s.C0.NUL)):65===e.keyCode&&(o.type=1);else{const t=r[e.keyCode],i=t?.[e.shiftKey?1:0];if(i)o.key=s.C0.ESC+i;else if(e.keyCode>=65&&e.keyCode<=90){const t=e.ctrlKey?e.keyCode-64:e.keyCode+32;let i=String.fromCharCode(t);e.shiftKey&&(i=i.toUpperCase()),o.key=s.C0.ESC+i}else if(32===e.keyCode)o.key=s.C0.ESC+(e.ctrlKey?s.C0.NUL:\" \");else if(\"Dead\"===e.key&&e.code.startsWith(\"Key\")){let t=e.code.slice(3,4);e.shiftKey||(t=t.toLowerCase()),o.key=s.C0.ESC+t,o.cancel=!0}}else e.keyCode>=65&&e.keyCode<=90?o.key=String.fromCharCode(e.keyCode-64):32===e.keyCode?o.key=s.C0.NUL:e.keyCode>=51&&e.keyCode<=55?o.key=String.fromCharCode(e.keyCode-51+27):56===e.keyCode?o.key=s.C0.DEL:219===e.keyCode?o.key=s.C0.ESC:220===e.keyCode?o.key=s.C0.FS:221===e.keyCode&&(o.key=s.C0.GS)}return o};const s=i(3534),r={48:[\"0\",\")\"],49:[\"1\",\"!\"],50:[\"2\",\"@\"],51:[\"3\",\"#\"],52:[\"4\",\"$\"],53:[\"5\",\"%\"],54:[\"6\",\"^\"],55:[\"7\",\"&\"],56:[\"8\",\"*\"],57:[\"9\",\"(\"],186:[\";\",\":\"],187:[\"=\",\"+\"],188:[\",\",\"<\"],189:[\"-\",\"_\"],190:[\".\",\">\"],191:[\"/\",\"?\"],192:[\"`\",\"~\"],219:[\"[\",\"{\"],220:[\"\\\\\",\"|\"],221:[\"]\",\"}\"],222:[\"'\",'\"']}},726:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Utf8ToUtf32=t.StringToUtf32=void 0,t.stringFromCodePoint=function(e){return e>65535?(e-=65536,String.fromCharCode(55296+(e>>10))+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)},t.utf32ToString=function(e,t=0,i=e.length){let s=\"\";for(let r=t;r65535?(t-=65536,s+=String.fromCharCode(55296+(t>>10))+String.fromCharCode(t%1024+56320)):s+=String.fromCharCode(t)}return s},t.StringToUtf32=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){const i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){const i=e.charCodeAt(r++);56320<=i&&i<=57343?t[s++]=1024*(this._interim-55296)+i-56320+65536:(t[s++]=this._interim,t[s++]=i),this._interim=0}for(let n=r;n=i)return this._interim=r,s;const o=e.charCodeAt(n);56320<=o&&o<=57343?t[s++]=1024*(r-55296)+o-56320+65536:(t[s++]=r,t[s++]=o)}else 65279!==r&&(t[s++]=r)}return s}},t.Utf8ToUtf32=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){const i=e.length;if(!i)return 0;let s,r,n,o,a=0,l=0,h=0;if(this.interim[0]){let s=!1,r=this.interim[0];r&=192==(224&r)?31:224==(240&r)?15:7;let n,o=0;for(;(n=63&this.interim[++o])&&o<4;)r<<=6,r|=n;const l=192==(224&this.interim[0])?2:224==(240&this.interim[0])?3:4,c=l-o;for(;h=i)return 0;if(n=e[h++],128!=(192&n)){h--,s=!0;break}this.interim[o++]=n,r<<=6,r|=63&n}s||(2===l?r<128?h--:t[a++]=r:3===l?r<2048||r>=55296&&r<=57343||65279===r||(t[a++]=r):r<65536||r>1114111||(t[a++]=r)),this.interim.fill(0)}const c=i-4;let d=h;for(;d=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(l=(31&s)<<6|63&r,l<128){d--;continue}t[a++]=l}else if(224==(240&s)){if(d>=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,a;if(n=e[d++],128!=(192&n)){d--;continue}if(l=(15&s)<<12|(63&r)<<6|63&n,l<2048||l>=55296&&l<=57343||65279===l)continue;t[a++]=l}else if(240==(248&s)){if(d>=i)return this.interim[0]=s,a;if(r=e[d++],128!=(192&r)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,a;if(n=e[d++],128!=(192&n)){d--;continue}if(d>=i)return this.interim[0]=s,this.interim[1]=r,this.interim[2]=n,a;if(o=e[d++],128!=(192&o)){d--;continue}if(l=(7&s)<<18|(63&r)<<12|(63&n)<<6|63&o,l<65536||l>1114111)continue;t[a++]=l}}return a}}},7428:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.UnicodeV6=void 0;const s=i(6415),r=[[768,879],[1155,1158],[1160,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1536,1539],[1552,1557],[1611,1630],[1648,1648],[1750,1764],[1767,1768],[1770,1773],[1807,1807],[1809,1809],[1840,1866],[1958,1968],[2027,2035],[2305,2306],[2364,2364],[2369,2376],[2381,2381],[2385,2388],[2402,2403],[2433,2433],[2492,2492],[2497,2500],[2509,2509],[2530,2531],[2561,2562],[2620,2620],[2625,2626],[2631,2632],[2635,2637],[2672,2673],[2689,2690],[2748,2748],[2753,2757],[2759,2760],[2765,2765],[2786,2787],[2817,2817],[2876,2876],[2879,2879],[2881,2883],[2893,2893],[2902,2902],[2946,2946],[3008,3008],[3021,3021],[3134,3136],[3142,3144],[3146,3149],[3157,3158],[3260,3260],[3263,3263],[3270,3270],[3276,3277],[3298,3299],[3393,3395],[3405,3405],[3530,3530],[3538,3540],[3542,3542],[3633,3633],[3636,3642],[3655,3662],[3761,3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893,3893],[3895,3895],[3897,3897],[3953,3966],[3968,3972],[3974,3975],[3984,3991],[3993,4028],[4038,4038],[4141,4144],[4146,4146],[4150,4151],[4153,4153],[4184,4185],[4448,4607],[4959,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6068,6069],[6071,6077],[6086,6086],[6089,6099],[6109,6109],[6155,6157],[6313,6313],[6432,6434],[6439,6440],[6450,6450],[6457,6459],[6679,6680],[6912,6915],[6964,6964],[6966,6970],[6972,6972],[6978,6978],[7019,7027],[7616,7626],[7678,7679],[8203,8207],[8234,8238],[8288,8291],[8298,8303],[8400,8431],[12330,12335],[12441,12442],[43014,43014],[43019,43019],[43045,43046],[64286,64286],[65024,65039],[65056,65059],[65279,65279],[65529,65531]],n=[[68097,68099],[68101,68102],[68108,68111],[68152,68154],[68159,68159],[119143,119145],[119155,119170],[119173,119179],[119210,119213],[119362,119364],[917505,917505],[917536,917631],[917760,917999]];let o;t.UnicodeV6=class{constructor(){if(this.version=\"6\",!o){o=new Uint8Array(65536),o.fill(1),o[0]=0,o.fill(0,1,32),o.fill(0,127,160),o.fill(2,4352,4448),o[9001]=2,o[9002]=2,o.fill(2,11904,42192),o[12351]=1,o.fill(2,44032,55204),o.fill(2,63744,64256),o.fill(2,65040,65050),o.fill(2,65072,65136),o.fill(2,65280,65377),o.fill(2,65504,65511);for(let e=0;et[r][1])return!1;for(;r>=s;)if(i=s+r>>1,e>t[i][1])s=i+1;else{if(!(e=131072&&e<=196605||e>=196608&&e<=262141?2:1}charProperties(e,t){let i=this.wcwidth(e),r=0===i&&0!==t;if(r){const e=s.UnicodeService.extractWidth(t);0===e?r=!1:e>i&&(i=e)}return s.UnicodeService.createPropertyValue(0,i,r)}}},3562:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.WriteBuffer=void 0;const s=i(7150),r=i(802);class n extends s.Disposable{constructor(e){super(),this._action=e,this._writeBuffer=[],this._callbacks=[],this._pendingData=0,this._bufferOffset=0,this._isSyncWriting=!1,this._syncCalls=0,this._didUserInput=!1,this._onWriteParsed=this._register(new r.Emitter),this.onWriteParsed=this._onWriteParsed.event}handleUserInput(){this._didUserInput=!0}writeSync(e,t){if(void 0!==t&&this._syncCalls>t)return void(this._syncCalls=0);if(this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(void 0),this._syncCalls++,this._isSyncWriting)return;let i;for(this._isSyncWriting=!0;i=this._writeBuffer.shift();){this._action(i);const e=this._callbacks.shift();e&&e()}this._pendingData=0,this._bufferOffset=2147483647,this._isSyncWriting=!1,this._syncCalls=0}write(e,t){if(this._pendingData>5e7)throw new Error(\"write data discarded, use flow control to avoid losing data\");if(!this._writeBuffer.length){if(this._bufferOffset=0,this._didUserInput)return this._didUserInput=!1,this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t),void this._innerWrite();setTimeout((()=>this._innerWrite()))}this._pendingData+=e.length,this._writeBuffer.push(e),this._callbacks.push(t)}_innerWrite(e=0,t=!0){const i=e||performance.now();for(;this._writeBuffer.length>this._bufferOffset;){const e=this._writeBuffer[this._bufferOffset],s=this._action(e,t);if(s){const e=e=>performance.now()-i>=12?setTimeout((()=>this._innerWrite(0,e))):this._innerWrite(i,e);return void s.catch((e=>(queueMicrotask((()=>{throw e})),Promise.resolve(!1)))).then(e)}const r=this._callbacks[this._bufferOffset];if(r&&r(),this._bufferOffset++,this._pendingData-=e.length,performance.now()-i>=12)break}this._writeBuffer.length>this._bufferOffset?(this._bufferOffset>50&&(this._writeBuffer=this._writeBuffer.slice(this._bufferOffset),this._callbacks=this._callbacks.slice(this._bufferOffset),this._bufferOffset=0),setTimeout((()=>this._innerWrite()))):(this._writeBuffer.length=0,this._callbacks.length=0,this._pendingData=0,this._bufferOffset=0),this._onWriteParsed.fire()}}t.WriteBuffer=n},8693:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.parseColor=function(e){if(!e)return;let t=e.toLowerCase();if(0===t.indexOf(\"rgb:\")){t=t.slice(4);const e=i.exec(t);if(e){const t=e[1]?15:e[4]?255:e[7]?4095:65535;return[Math.round(parseInt(e[1]||e[4]||e[7]||e[10],16)/t*255),Math.round(parseInt(e[2]||e[5]||e[8]||e[11],16)/t*255),Math.round(parseInt(e[3]||e[6]||e[9]||e[12],16)/t*255)]}}else if(0===t.indexOf(\"#\")&&(t=t.slice(1),s.exec(t)&&[3,6,9,12].includes(t.length))){const e=t.length/3,i=[0,0,0];for(let s=0;s<3;++s){const r=parseInt(t.slice(e*s,e*s+e),16);i[s]=1===e?r<<4:2===e?r:3===e?r>>4:r>>8}return i}},t.toRgbString=function(e,t=16){const[i,s,n]=e;return`rgb:${r(i,t)}/${r(s,t)}/${r(n,t)}`};const i=/^([\\da-f])\\/([\\da-f])\\/([\\da-f])$|^([\\da-f]{2})\\/([\\da-f]{2})\\/([\\da-f]{2})$|^([\\da-f]{3})\\/([\\da-f]{3})\\/([\\da-f]{3})$|^([\\da-f]{4})\\/([\\da-f]{4})\\/([\\da-f]{4})$/,s=/^[\\da-f]+$/;function r(e,t){const i=e.toString(16),s=i.length<2?\"0\"+i:i;switch(t){case 4:return i[0];case 8:return s;case 12:return(s+s).slice(0,3);default:return s+s}}},1263:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.PAYLOAD_LIMIT=void 0,t.PAYLOAD_LIMIT=1e7},9823:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DcsHandler=t.DcsParser=void 0;const s=i(726),r=i(7262),n=i(1263),o=[];t.DcsParser=class{constructor(){this._handlers=Object.create(null),this._active=o,this._ident=0,this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=o}registerHandler(e,t){void 0===this._handlers[e]&&(this._handlers[e]=[]);const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}reset(){if(this._active.length)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].unhook(!1);this._stack.paused=!1,this._active=o,this._ident=0}hook(e,t){if(this.reset(),this._ident=e,this._active=this._handlers[e]||o,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].hook(t);else this._handlerFb(this._ident,\"HOOK\",t)}put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._ident,\"PUT\",(0,s.utf32ToString)(e,t,i))}unhook(e,t=!0){if(this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].unhook(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].unhook(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._ident,\"UNHOOK\",e);this._active=o,this._ident=0}};const a=new r.Params;a.addParam(0),t.DcsHandler=class{constructor(e){this._handler=e,this._data=\"\",this._params=a,this._hitLimit=!1}hook(e){this._params=e.length>1||e.params[0]?e.clone():a,this._data=\"\",this._hitLimit=!1}put(e,t,i){this._hitLimit||(this._data+=(0,s.utf32ToString)(e,t,i),this._data.length>n.PAYLOAD_LIMIT&&(this._data=\"\",this._hitLimit=!0))}unhook(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data,this._params),t instanceof Promise))return t.then((e=>(this._params=a,this._data=\"\",this._hitLimit=!1,e)));return this._params=a,this._data=\"\",this._hitLimit=!1,t}}},6717:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.EscapeSequenceParser=t.VT500_TRANSITION_TABLE=t.TransitionTable=void 0;const s=i(7150),r=i(7262),n=i(1346),o=i(9823);class a{constructor(e){this.table=new Uint8Array(e)}setDefault(e,t){this.table.fill(e<<4|t)}add(e,t,i,s){this.table[t<<8|e]=i<<4|s}addMany(e,t,i,s){for(let r=0;rt)),i=(e,i)=>t.slice(e,i),s=i(32,127),r=i(0,24);r.push(25),r.push.apply(r,i(28,32));const n=i(0,14);let o;for(o in e.setDefault(1,0),e.addMany(s,0,2,0),n)e.addMany([24,26,153,154],o,3,0),e.addMany(i(128,144),o,3,0),e.addMany(i(144,152),o,3,0),e.add(156,o,0,0),e.add(27,o,11,1),e.add(157,o,4,8),e.addMany([152,158,159],o,0,7),e.add(155,o,11,3),e.add(144,o,11,9);return e.addMany(r,0,3,0),e.addMany(r,1,3,1),e.add(127,1,0,1),e.addMany(r,8,0,8),e.addMany(r,3,3,3),e.add(127,3,0,3),e.addMany(r,4,3,4),e.add(127,4,0,4),e.addMany(r,6,3,6),e.addMany(r,5,3,5),e.add(127,5,0,5),e.addMany(r,2,3,2),e.add(127,2,0,2),e.add(93,1,4,8),e.addMany(s,8,5,8),e.add(127,8,5,8),e.addMany([156,27,24,26,7],8,6,0),e.addMany(i(28,32),8,0,8),e.addMany([88,94,95],1,0,7),e.addMany(s,7,0,7),e.addMany(r,7,0,7),e.add(156,7,0,0),e.add(127,7,0,7),e.add(91,1,11,3),e.addMany(i(64,127),3,7,0),e.addMany(i(48,60),3,8,4),e.addMany([60,61,62,63],3,9,4),e.addMany(i(48,60),4,8,4),e.addMany(i(64,127),4,7,0),e.addMany([60,61,62,63],4,0,6),e.addMany(i(32,64),6,0,6),e.add(127,6,0,6),e.addMany(i(64,127),6,0,0),e.addMany(i(32,48),3,9,5),e.addMany(i(32,48),5,9,5),e.addMany(i(48,64),5,0,6),e.addMany(i(64,127),5,7,0),e.addMany(i(32,48),4,9,5),e.addMany(i(32,48),1,9,2),e.addMany(i(32,48),2,9,2),e.addMany(i(48,127),2,10,0),e.addMany(i(48,80),1,10,0),e.addMany(i(81,88),1,10,0),e.addMany([89,90,92],1,10,0),e.addMany(i(96,127),1,10,0),e.add(80,1,11,9),e.addMany(r,9,0,9),e.add(127,9,0,9),e.addMany(i(28,32),9,0,9),e.addMany(i(32,48),9,9,12),e.addMany(i(48,60),9,8,10),e.addMany([60,61,62,63],9,9,10),e.addMany(r,11,0,11),e.addMany(i(32,128),11,0,11),e.addMany(i(28,32),11,0,11),e.addMany(r,10,0,10),e.add(127,10,0,10),e.addMany(i(28,32),10,0,10),e.addMany(i(48,60),10,8,10),e.addMany([60,61,62,63],10,0,11),e.addMany(i(32,48),10,9,12),e.addMany(r,12,0,12),e.add(127,12,0,12),e.addMany(i(28,32),12,0,12),e.addMany(i(32,48),12,9,12),e.addMany(i(48,64),12,0,11),e.addMany(i(64,127),12,12,13),e.addMany(i(64,127),10,12,13),e.addMany(i(64,127),9,12,13),e.addMany(r,13,13,13),e.addMany(s,13,13,13),e.add(127,13,0,13),e.addMany([27,156,24,26],13,14,0),e.add(l,0,2,0),e.add(l,8,5,8),e.add(l,6,0,6),e.add(l,11,0,11),e.add(l,13,13,13),e}();class h extends s.Disposable{constructor(e=t.VT500_TRANSITION_TABLE){super(),this._transitions=e,this._parseStack={state:0,handlers:[],handlerPos:0,transition:0,chunkPos:0},this.initialState=0,this.currentState=this.initialState,this._params=new r.Params,this._params.addParam(0),this._collect=0,this.precedingJoinState=0,this._printHandlerFb=(e,t,i)=>{},this._executeHandlerFb=e=>{},this._csiHandlerFb=(e,t)=>{},this._escHandlerFb=e=>{},this._errorHandlerFb=e=>e,this._printHandler=this._printHandlerFb,this._executeHandlers=Object.create(null),this._csiHandlers=Object.create(null),this._escHandlers=Object.create(null),this._register((0,s.toDisposable)((()=>{this._csiHandlers=Object.create(null),this._executeHandlers=Object.create(null),this._escHandlers=Object.create(null)}))),this._oscParser=this._register(new n.OscParser),this._dcsParser=this._register(new o.DcsParser),this._errorHandler=this._errorHandlerFb,this.registerEscHandler({final:\"\\\\\"},(()=>!0))}_identifier(e,t=[64,126]){let i=0;if(e.prefix){if(e.prefix.length>1)throw new Error(\"only one byte as prefix supported\");if(i=e.prefix.charCodeAt(0),i&&60>i||i>63)throw new Error(\"prefix must be in range 0x3c .. 0x3f\")}if(e.intermediates){if(e.intermediates.length>2)throw new Error(\"only two bytes as intermediates are supported\");for(let t=0;ts||s>47)throw new Error(\"intermediate must be in range 0x20 .. 0x2f\");i<<=8,i|=s}}if(1!==e.final.length)throw new Error(\"final must be a single byte\");const s=e.final.charCodeAt(0);if(t[0]>s||s>t[1])throw new Error(`final must be in range ${t[0]} .. ${t[1]}`);return i<<=8,i|=s,i}identToString(e){const t=[];for(;e;)t.push(String.fromCharCode(255&e)),e>>=8;return t.reverse().join(\"\")}setPrintHandler(e){this._printHandler=e}clearPrintHandler(){this._printHandler=this._printHandlerFb}registerEscHandler(e,t){const i=this._identifier(e,[48,126]);void 0===this._escHandlers[i]&&(this._escHandlers[i]=[]);const s=this._escHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearEscHandler(e){this._escHandlers[this._identifier(e,[48,126])]&&delete this._escHandlers[this._identifier(e,[48,126])]}setEscHandlerFallback(e){this._escHandlerFb=e}setExecuteHandler(e,t){this._executeHandlers[e.charCodeAt(0)]=t}clearExecuteHandler(e){this._executeHandlers[e.charCodeAt(0)]&&delete this._executeHandlers[e.charCodeAt(0)]}setExecuteHandlerFallback(e){this._executeHandlerFb=e}registerCsiHandler(e,t){const i=this._identifier(e);void 0===this._csiHandlers[i]&&(this._csiHandlers[i]=[]);const s=this._csiHandlers[i];return s.push(t),{dispose:()=>{const e=s.indexOf(t);-1!==e&&s.splice(e,1)}}}clearCsiHandler(e){this._csiHandlers[this._identifier(e)]&&delete this._csiHandlers[this._identifier(e)]}setCsiHandlerFallback(e){this._csiHandlerFb=e}registerDcsHandler(e,t){return this._dcsParser.registerHandler(this._identifier(e),t)}clearDcsHandler(e){this._dcsParser.clearHandler(this._identifier(e))}setDcsHandlerFallback(e){this._dcsParser.setHandlerFallback(e)}registerOscHandler(e,t){return this._oscParser.registerHandler(e,t)}clearOscHandler(e){this._oscParser.clearHandler(e)}setOscHandlerFallback(e){this._oscParser.setHandlerFallback(e)}setErrorHandler(e){this._errorHandler=e}clearErrorHandler(){this._errorHandler=this._errorHandlerFb}reset(){this.currentState=this.initialState,this._oscParser.reset(),this._dcsParser.reset(),this._params.reset(),this._params.addParam(0),this._collect=0,this.precedingJoinState=0,0!==this._parseStack.state&&(this._parseStack.state=2,this._parseStack.handlers=[])}_preserveStack(e,t,i,s,r){this._parseStack.state=e,this._parseStack.handlers=t,this._parseStack.handlerPos=i,this._parseStack.transition=s,this._parseStack.chunkPos=r}parse(e,t,i){let s,r=0,n=0,o=0;if(this._parseStack.state)if(2===this._parseStack.state)this._parseStack.state=0,o=this._parseStack.chunkPos+1;else{if(void 0===i||1===this._parseStack.state)throw this._parseStack.state=1,new Error(\"improper continuation due to previous async handler, giving up parsing\");const t=this._parseStack.handlers;let n=this._parseStack.handlerPos-1;switch(this._parseStack.state){case 3:if(!1===i&&n>-1)for(;n>=0&&(s=t[n](this._params),!0!==s);n--)if(s instanceof Promise)return this._parseStack.handlerPos=n,s;this._parseStack.handlers=[];break;case 4:if(!1===i&&n>-1)for(;n>=0&&(s=t[n](),!0!==s);n--)if(s instanceof Promise)return this._parseStack.handlerPos=n,s;this._parseStack.handlers=[];break;case 6:if(r=e[this._parseStack.chunkPos],s=this._dcsParser.unhook(24!==r&&26!==r,i),s)return s;27===r&&(this._parseStack.transition|=1),this._params.reset(),this._params.addParam(0),this._collect=0;break;case 5:if(r=e[this._parseStack.chunkPos],s=this._oscParser.end(24!==r&&26!==r,i),s)return s;27===r&&(this._parseStack.transition|=1),this._params.reset(),this._params.addParam(0),this._collect=0}this._parseStack.state=0,o=this._parseStack.chunkPos+1,this.precedingJoinState=0,this.currentState=15&this._parseStack.transition}for(let i=o;i>4){case 2:for(let s=i+1;;++s){if(s>=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=t||(r=e[s])<32||r>126&&r=0&&(s=o[a](this._params),!0!==s);a--)if(s instanceof Promise)return this._preserveStack(3,o,a,n,i),s;a<0&&this._csiHandlerFb(this._collect<<8|r,this._params),this.precedingJoinState=0;break;case 8:do{switch(r){case 59:this._params.addParam(0);break;case 58:this._params.addSubParam(-1);break;default:this._params.addDigit(r-48)}}while(++i47&&r<60);i--;break;case 9:this._collect<<=8,this._collect|=r;break;case 10:const h=this._escHandlers[this._collect<<8|r];let c=h?h.length-1:-1;for(;c>=0&&(s=h[c](),!0!==s);c--)if(s instanceof Promise)return this._preserveStack(4,h,c,n,i),s;c<0&&this._escHandlerFb(this._collect<<8|r),this.precedingJoinState=0;break;case 11:this._params.reset(),this._params.addParam(0),this._collect=0;break;case 12:this._dcsParser.hook(this._collect<<8|r,this._params);break;case 13:for(let s=i+1;;++s)if(s>=t||24===(r=e[s])||26===r||27===r||r>127&&r=t||(r=e[s])<32||r>127&&r{Object.defineProperty(t,\"__esModule\",{value:!0}),t.OscHandler=t.OscParser=void 0;const s=i(1263),r=i(726),n=[];t.OscParser=class{constructor(){this._state=0,this._active=n,this._id=-1,this._handlers=Object.create(null),this._handlerFb=()=>{},this._stack={paused:!1,loopPosition:0,fallThrough:!1}}registerHandler(e,t){void 0===this._handlers[e]&&(this._handlers[e]=[]);const i=this._handlers[e];return i.push(t),{dispose:()=>{const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}}clearHandler(e){this._handlers[e]&&delete this._handlers[e]}setHandlerFallback(e){this._handlerFb=e}dispose(){this._handlers=Object.create(null),this._handlerFb=()=>{},this._active=n}reset(){if(2===this._state)for(let e=this._stack.paused?this._stack.loopPosition-1:this._active.length-1;e>=0;--e)this._active[e].end(!1);this._stack.paused=!1,this._active=n,this._id=-1,this._state=0}_start(){if(this._active=this._handlers[this._id]||n,this._active.length)for(let e=this._active.length-1;e>=0;e--)this._active[e].start();else this._handlerFb(this._id,\"START\")}_put(e,t,i){if(this._active.length)for(let s=this._active.length-1;s>=0;s--)this._active[s].put(e,t,i);else this._handlerFb(this._id,\"PUT\",(0,r.utf32ToString)(e,t,i))}start(){this.reset(),this._state=1}put(e,t,i){if(3!==this._state){if(1===this._state)for(;t0&&this._put(e,t,i)}}end(e,t=!0){if(0!==this._state){if(3!==this._state)if(1===this._state&&this._start(),this._active.length){let i=!1,s=this._active.length-1,r=!1;if(this._stack.paused&&(s=this._stack.loopPosition-1,i=t,r=this._stack.fallThrough,this._stack.paused=!1),!r&&!1===i){for(;s>=0&&(i=this._active[s].end(e),!0!==i);s--)if(i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!1,i;s--}for(;s>=0;s--)if(i=this._active[s].end(!1),i instanceof Promise)return this._stack.paused=!0,this._stack.loopPosition=s,this._stack.fallThrough=!0,i}else this._handlerFb(this._id,\"END\",e);this._active=n,this._id=-1,this._state=0}}},t.OscHandler=class{constructor(e){this._handler=e,this._data=\"\",this._hitLimit=!1}start(){this._data=\"\",this._hitLimit=!1}put(e,t,i){this._hitLimit||(this._data+=(0,r.utf32ToString)(e,t,i),this._data.length>s.PAYLOAD_LIMIT&&(this._data=\"\",this._hitLimit=!0))}end(e){let t=!1;if(this._hitLimit)t=!1;else if(e&&(t=this._handler(this._data),t instanceof Promise))return t.then((e=>(this._data=\"\",this._hitLimit=!1,e)));return this._data=\"\",this._hitLimit=!1,t}}},7262:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Params=void 0;const i=2147483647;class s{static fromArray(e){const t=new s;if(!e.length)return t;for(let i=Array.isArray(e[0])?1:0;i256)throw new Error(\"maxSubParamsLength must not be greater than 256\");this.params=new Int32Array(e),this.length=0,this._subParams=new Int32Array(t),this._subParamsLength=0,this._subParamsIdx=new Uint16Array(e),this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}clone(){const e=new s(this.maxLength,this.maxSubParamsLength);return e.params.set(this.params),e.length=this.length,e._subParams.set(this._subParams),e._subParamsLength=this._subParamsLength,e._subParamsIdx.set(this._subParamsIdx),e._rejectDigits=this._rejectDigits,e._rejectSubDigits=this._rejectSubDigits,e._digitIsSub=this._digitIsSub,e}toArray(){const e=[];for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&e.push(Array.prototype.slice.call(this._subParams,i,s))}return e}reset(){this.length=0,this._subParamsLength=0,this._rejectDigits=!1,this._rejectSubDigits=!1,this._digitIsSub=!1}addParam(e){if(this._digitIsSub=!1,this.length>=this.maxLength)this._rejectDigits=!0;else{if(e<-1)throw new Error(\"values lesser than -1 are not allowed\");this._subParamsIdx[this.length]=this._subParamsLength<<8|this._subParamsLength,this.params[this.length++]=e>i?i:e}}addSubParam(e){if(this._digitIsSub=!0,this.length)if(this._rejectDigits||this._subParamsLength>=this.maxSubParamsLength)this._rejectSubDigits=!0;else{if(e<-1)throw new Error(\"values lesser than -1 are not allowed\");this._subParams[this._subParamsLength++]=e>i?i:e,this._subParamsIdx[this.length-1]++}}hasSubParams(e){return(255&this._subParamsIdx[e])-(this._subParamsIdx[e]>>8)>0}getSubParams(e){const t=this._subParamsIdx[e]>>8,i=255&this._subParamsIdx[e];return i-t>0?this._subParams.subarray(t,i):null}getSubParamsAll(){const e={};for(let t=0;t>8,s=255&this._subParamsIdx[t];s-i>0&&(e[t]=this._subParams.slice(i,s))}return e}addDigit(e){let t;if(this._rejectDigits||!(t=this._digitIsSub?this._subParamsLength:this.length)||this._digitIsSub&&this._rejectSubDigits)return;const s=this._digitIsSub?this._subParams:this.params,r=s[t-1];s[t-1]=~r?Math.min(10*r+e,i):e}}t.Params=s},3027:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.AddonManager=void 0,t.AddonManager=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){const i={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(i),t.dispose=()=>this._wrappedAddonDispose(i),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let i=0;i{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferApiView=void 0;const s=i(793),r=i(3055);t.BufferApiView=class{constructor(e,t){this._buffer=e,this.type=t}init(e){return this._buffer=e,this}get cursorY(){return this._buffer.y}get cursorX(){return this._buffer.x}get viewportY(){return this._buffer.ydisp}get baseY(){return this._buffer.ybase}get length(){return this._buffer.lines.length}getLine(e){const t=this._buffer.lines.get(e);if(t)return new s.BufferLineApiView(t)}getNullCell(){return new r.CellData}}},793:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferLineApiView=void 0;const s=i(3055);t.BufferLineApiView=class{constructor(e){this._line=e}get isWrapped(){return this._line.isWrapped}get length(){return this._line.length}getCell(e,t){if(!(e<0||e>=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new s.CellData)}translateToString(e,t,i){return this._line.translateToString(e,t,i)}}},5101:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferNamespaceApi=void 0;const s=i(3235),r=i(7150),n=i(802);class o extends r.Disposable{constructor(e){super(),this._core=e,this._onBufferChange=this._register(new n.Emitter),this.onBufferChange=this._onBufferChange.event,this._normal=new s.BufferApiView(this._core.buffers.normal,\"normal\"),this._alternate=new s.BufferApiView(this._core.buffers.alt,\"alternate\"),this._core.buffers.onBufferActivate((()=>this._onBufferChange.fire(this.active)))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw new Error(\"Active buffer is neither normal nor alternate\")}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}}t.BufferNamespaceApi=o},6097:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ParserApi=void 0,t.ParserApi=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,(e=>t(e.toArray())))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,((e,i)=>t(e,i.toArray())))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}}},4335:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.UnicodeApi=void 0,t.UnicodeApi=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}}},9640:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.BufferService=t.MINIMUM_ROWS=t.MINIMUM_COLS=void 0;const n=i(7150),o=i(4097),a=i(6501),l=i(802);t.MINIMUM_COLS=2,t.MINIMUM_ROWS=1;let h=class extends n.Disposable{get buffer(){return this.buffers.active}constructor(e){super(),this.isUserScrolling=!1,this._onResize=this._register(new l.Emitter),this.onResize=this._onResize.event,this._onScroll=this._register(new l.Emitter),this.onScroll=this._onScroll.event,this.cols=Math.max(e.rawOptions.cols||0,t.MINIMUM_COLS),this.rows=Math.max(e.rawOptions.rows||0,t.MINIMUM_ROWS),this.buffers=this._register(new o.BufferSet(e,this)),this._register(this.buffers.onBufferActivate((e=>{this._onScroll.fire(e.activeBuffer.ydisp)})))}resize(e,t){const i=this.cols!==e,s=this.rows!==t;this.cols=e,this.rows=t,this.buffers.resize(e,t),this._onResize.fire({cols:e,rows:t,colsChanged:i,rowsChanged:s})}reset(){this.buffers.reset(),this.isUserScrolling=!1}scroll(e,t=!1){const i=this.buffer;let s;s=this._cachedBlankLine,s&&s.length===this.cols&&s.getFg(0)===e.fg&&s.getBg(0)===e.bg||(s=i.getBlankLine(e,t),this._cachedBlankLine=s),s.isWrapped=t;const r=i.ybase+i.scrollTop,n=i.ybase+i.scrollBottom;if(0===i.scrollTop){const e=i.lines.isFull;n===i.lines.length-1?e?i.lines.recycle().copyFrom(s):i.lines.push(s.clone()):i.lines.splice(n+1,0,s.clone()),e?this.isUserScrolling&&(i.ydisp=Math.max(i.ydisp-1,0)):(i.ybase++,this.isUserScrolling||i.ydisp++)}else{const e=n-r+1;i.lines.shiftElements(r+1,e-1,-1),i.lines.set(n,s.clone())}this.isUserScrolling||(i.ydisp=i.ybase),this._onScroll.fire(i.ydisp)}scrollLines(e,t){const i=this.buffer;if(e<0){if(0===i.ydisp)return;this.isUserScrolling=!0}else e+i.ydisp>=i.ybase&&(this.isUserScrolling=!1);const s=i.ydisp;i.ydisp=Math.max(Math.min(i.ydisp+e,i.ybase),0),s!==i.ydisp&&(t||this._onScroll.fire(i.ydisp))}};t.BufferService=h,t.BufferService=h=s([r(0,a.IOptionsService)],h)},5746:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CharsetService=void 0,t.CharsetService=class{constructor(){this.glevel=0,this._charsets=[]}reset(){this.charset=void 0,this._charsets=[],this.glevel=0}setgLevel(e){this.glevel=e,this.charset=this._charsets[e]}setgCharset(e,t){this._charsets[e]=t,this.glevel===e&&(this.charset=t)}}},7792:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CoreMouseService=void 0;const n=i(6501),o=i(7150),a=i(802),l={NONE:{events:0,restrict:()=>!1},X10:{events:1,restrict:e=>4!==e.button&&1===e.action&&(e.ctrl=!1,e.alt=!1,e.shift=!1,!0)},VT200:{events:19,restrict:e=>32!==e.action},DRAG:{events:23,restrict:e=>32!==e.action||3!==e.button},ANY:{events:31,restrict:e=>!0}};function h(e,t){let i=(e.ctrl?16:0)|(e.shift?4:0)|(e.alt?8:0);return 4===e.button?(i|=64,i|=e.action):(i|=3&e.button,4&e.button&&(i|=64),8&e.button&&(i|=128),32===e.action?i|=32:0!==e.action||t||(i|=3)),i}const c=String.fromCharCode,d={DEFAULT:e=>{const t=[h(e,!1)+32,e.col+32,e.row+32];return t[0]>255||t[1]>255||t[2]>255?\"\":`\u001b[M${c(t[0])}${c(t[1])}${c(t[2])}`},SGR:e=>{const t=0===e.action&&4!==e.button?\"m\":\"M\";return`\u001b[<${h(e,!0)};${e.col};${e.row}${t}`},SGR_PIXELS:e=>{const t=0===e.action&&4!==e.button?\"m\":\"M\";return`\u001b[<${h(e,!0)};${e.x};${e.y}${t}`}};let u=class extends o.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._coreService=t,this._optionsService=i,this._protocols={},this._encodings={},this._activeProtocol=\"\",this._activeEncoding=\"\",this._lastEvent=null,this._wheelPartialScroll=0,this._onProtocolChange=this._register(new a.Emitter),this.onProtocolChange=this._onProtocolChange.event;for(const e of Object.keys(l))this.addProtocol(e,l[e]);for(const e of Object.keys(d))this.addEncoding(e,d[e]);this.reset()}addProtocol(e,t){this._protocols[e]=t}addEncoding(e,t){this._encodings[e]=t}get activeProtocol(){return this._activeProtocol}get areMouseEventsActive(){return 0!==this._protocols[this._activeProtocol].events}set activeProtocol(e){if(!this._protocols[e])throw new Error(`unknown protocol \"${e}\"`);this._activeProtocol=e,this._onProtocolChange.fire(this._protocols[e].events)}get activeEncoding(){return this._activeEncoding}set activeEncoding(e){if(!this._encodings[e])throw new Error(`unknown encoding \"${e}\"`);this._activeEncoding=e}reset(){this.activeProtocol=\"NONE\",this.activeEncoding=\"DEFAULT\",this._lastEvent=null,this._wheelPartialScroll=0}consumeWheelEvent(e,t,i){if(0===e.deltaY||e.shiftKey)return 0;if(void 0===t||void 0===i)return 0;const s=t/i;let r=this._applyScrollModifier(e.deltaY,e);return e.deltaMode===WheelEvent.DOM_DELTA_PIXEL?(r/=s+0,Math.abs(e.deltaY)<50&&(r*=.3),this._wheelPartialScroll+=r,r=Math.floor(Math.abs(this._wheelPartialScroll))*(this._wheelPartialScroll>0?1:-1),this._wheelPartialScroll%=1):e.deltaMode===WheelEvent.DOM_DELTA_PAGE&&(r*=this._bufferService.rows),r}_applyScrollModifier(e,t){return t.altKey||t.ctrlKey||t.shiftKey?e*this._optionsService.rawOptions.fastScrollSensitivity*this._optionsService.rawOptions.scrollSensitivity:e*this._optionsService.rawOptions.scrollSensitivity}triggerMouseEvent(e){if(e.col<0||e.col>=this._bufferService.cols||e.row<0||e.row>=this._bufferService.rows)return!1;if(4===e.button&&32===e.action)return!1;if(3===e.button&&32!==e.action)return!1;if(4!==e.button&&(2===e.action||3===e.action))return!1;if(e.col++,e.row++,32===e.action&&this._lastEvent&&this._equalEvents(this._lastEvent,e,\"SGR_PIXELS\"===this._activeEncoding))return!1;if(!this._protocols[this._activeProtocol].restrict(e))return!1;const t=this._encodings[this._activeEncoding](e);return t&&(\"DEFAULT\"===this._activeEncoding?this._coreService.triggerBinaryEvent(t):this._coreService.triggerDataEvent(t,!0)),this._lastEvent=e,!0}explainEvents(e){return{down:!!(1&e),up:!!(2&e),drag:!!(4&e),move:!!(8&e),wheel:!!(16&e)}}_equalEvents(e,t,i){if(i){if(e.x!==t.x)return!1;if(e.y!==t.y)return!1}else{if(e.col!==t.col)return!1;if(e.row!==t.row)return!1}return e.button===t.button&&e.action===t.action&&e.ctrl===t.ctrl&&e.alt===t.alt&&e.shift===t.shift}};t.CoreMouseService=u,t.CoreMouseService=u=s([r(0,n.IBufferService),r(1,n.ICoreService),r(2,n.IOptionsService)],u)},4071:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CoreService=void 0;const n=i(7453),o=i(7150),a=i(6501),l=i(802),h=Object.freeze({insertMode:!1}),c=Object.freeze({applicationCursorKeys:!1,applicationKeypad:!1,bracketedPasteMode:!1,cursorBlink:void 0,cursorStyle:void 0,origin:!1,reverseWraparound:!1,sendFocus:!1,synchronizedOutput:!1,wraparound:!0});let d=class extends o.Disposable{constructor(e,t,i){super(),this._bufferService=e,this._logService=t,this._optionsService=i,this.isCursorInitialized=!1,this.isCursorHidden=!1,this._onData=this._register(new l.Emitter),this.onData=this._onData.event,this._onUserInput=this._register(new l.Emitter),this.onUserInput=this._onUserInput.event,this._onBinary=this._register(new l.Emitter),this.onBinary=this._onBinary.event,this._onRequestScrollToBottom=this._register(new l.Emitter),this.onRequestScrollToBottom=this._onRequestScrollToBottom.event,this.modes=(0,n.clone)(h),this.decPrivateModes=(0,n.clone)(c)}reset(){this.modes=(0,n.clone)(h),this.decPrivateModes=(0,n.clone)(c)}triggerDataEvent(e,t=!1){if(this._optionsService.rawOptions.disableStdin)return;const i=this._bufferService.buffer;t&&this._optionsService.rawOptions.scrollOnUserInput&&i.ybase!==i.ydisp&&this._onRequestScrollToBottom.fire(),t&&this._onUserInput.fire(),this._logService.debug(`sending data \"${e}\"`),this._logService.trace(\"sending data (codes)\",(()=>e.split(\"\").map((e=>e.charCodeAt(0))))),this._onData.fire(e)}triggerBinaryEvent(e){this._optionsService.rawOptions.disableStdin||(this._logService.debug(`sending binary \"${e}\"`),this._logService.trace(\"sending binary (codes)\",(()=>e.split(\"\").map((e=>e.charCodeAt(0))))),this._onBinary.fire(e))}};t.CoreService=d,t.CoreService=d=s([r(0,a.IBufferService),r(1,a.ILogService),r(2,a.IOptionsService)],d)},4720:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DecorationService=void 0;const s=i(4103),r=i(7150),n=i(3087),o=i(802);let a=0,l=0;class h extends r.Disposable{get decorations(){return this._decorations.values()}constructor(){super(),this._decorations=new n.SortedList((e=>e?.marker.line)),this._onDecorationRegistered=this._register(new o.Emitter),this.onDecorationRegistered=this._onDecorationRegistered.event,this._onDecorationRemoved=this._register(new o.Emitter),this.onDecorationRemoved=this._onDecorationRemoved.event,this._register((0,r.toDisposable)((()=>this.reset())))}registerDecoration(e){if(e.marker.isDisposed)return;const t=new c(e);if(t){const e=t.marker.onDispose((()=>t.dispose())),i=t.onDispose((()=>{i.dispose(),t&&(this._decorations.delete(t)&&this._onDecorationRemoved.fire(t),e.dispose())}));this._decorations.insert(t),this._onDecorationRegistered.fire(t)}return t}reset(){for(const e of this._decorations.values())e.dispose();this._decorations.clear()}*getDecorationsAtCell(e,t,i){let s=0,r=0;for(const n of this._decorations.getKeyIterator(t))s=n.options.x??0,r=s+(n.options.width??1),e>=s&&e{a=t.options.x??0,l=a+(t.options.width??1),e>=a&&e{Object.defineProperty(t,\"__esModule\",{value:!0}),t.InstantiationService=t.ServiceCollection=void 0;const s=i(6501),r=i(6201);class n{constructor(...e){this._entries=new Map;for(const[t,i]of e)this.set(t,i)}set(e,t){const i=this._entries.get(e);return this._entries.set(e,t),i}forEach(e){for(const[t,i]of this._entries.entries())e(t,i)}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)}}t.ServiceCollection=n,t.InstantiationService=class{constructor(){this._services=new n,this._services.set(s.IInstantiationService,this)}setService(e,t){this._services.set(e,t)}getService(e){return this._services.get(e)}createInstance(e,...t){const i=(0,r.getServiceDependencies)(e).sort(((e,t)=>e.index-t.index)),s=[];for(const t of i){const i=this._services.get(t.id);if(!i)throw new Error(`[createInstance] ${e.name} depends on UNKNOWN service ${t.id._id}.`);s.push(i)}const n=i.length>0?i[0].index:t.length;if(t.length!==n)throw new Error(`[createInstance] First service dependency of ${e.name} at position ${n+1} conflicts with ${t.length} static arguments`);return new e(...[...t,...s])}}},7276:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.LogService=void 0,t.setTraceLogger=function(e){l=e},t.traceCall=function(e,t,i){if(\"function\"!=typeof i.value)throw new Error(\"not supported\");const s=i.value;i.value=function(...e){if(l.logLevel!==o.LogLevelEnum.TRACE)return s.apply(this,e);l.trace(`GlyphRenderer#${s.name}(${e.map((e=>JSON.stringify(e))).join(\", \")})`);const t=s.apply(this,e);return l.trace(`GlyphRenderer#${s.name} return`,t),t}};const n=i(7150),o=i(6501),a={trace:o.LogLevelEnum.TRACE,debug:o.LogLevelEnum.DEBUG,info:o.LogLevelEnum.INFO,warn:o.LogLevelEnum.WARN,error:o.LogLevelEnum.ERROR,off:o.LogLevelEnum.OFF};let l,h=class extends n.Disposable{get logLevel(){return this._logLevel}constructor(e){super(),this._optionsService=e,this._logLevel=o.LogLevelEnum.OFF,this._updateLogLevel(),this._register(this._optionsService.onSpecificOptionChange(\"logLevel\",(()=>this._updateLogLevel()))),l=this}_updateLogLevel(){this._logLevel=a[this._optionsService.rawOptions.logLevel]}_evalLazyOptionalParams(e){for(let t=0;t{Object.defineProperty(t,\"__esModule\",{value:!0}),t.OptionsService=t.DEFAULT_OPTIONS=void 0;const s=i(7150),r=i(701),n=i(802);t.DEFAULT_OPTIONS={cols:80,rows:24,cursorBlink:!1,cursorStyle:\"block\",cursorWidth:1,cursorInactiveStyle:\"outline\",customGlyphs:!0,drawBoldTextInBrightColors:!0,documentOverride:null,fastScrollModifier:\"alt\",fastScrollSensitivity:5,fontFamily:\"monospace\",fontSize:15,fontWeight:\"normal\",fontWeightBold:\"bold\",ignoreBracketedPasteMode:!1,lineHeight:1,letterSpacing:0,linkHandler:null,logLevel:\"info\",logger:null,scrollback:1e3,scrollOnEraseInDisplay:!1,scrollOnUserInput:!0,scrollSensitivity:1,screenReaderMode:!1,smoothScrollDuration:0,macOptionIsMeta:!1,macOptionClickForcesSelection:!1,minimumContrastRatio:1,disableStdin:!1,allowProposedApi:!1,allowTransparency:!1,tabStopWidth:8,theme:{},reflowCursorLine:!1,rescaleOverlappingGlyphs:!1,rightClickSelectsWord:r.isMac,windowOptions:{},windowsMode:!1,windowsPty:{},wordSeparator:\" ()[]{}',\\\"`\",altClickMovesCursor:!0,convertEol:!1,termName:\"xterm\",cancelEvents:!1,overviewRuler:{}};const o=[\"normal\",\"bold\",\"100\",\"200\",\"300\",\"400\",\"500\",\"600\",\"700\",\"800\",\"900\"];class a extends s.Disposable{constructor(e){super(),this._onOptionChange=this._register(new n.Emitter),this.onOptionChange=this._onOptionChange.event;const i={...t.DEFAULT_OPTIONS};for(const t in e)if(t in i)try{const s=e[t];i[t]=this._sanitizeAndValidateOption(t,s)}catch(e){console.error(e)}this.rawOptions=i,this.options={...i},this._setupOptions(),this._register((0,s.toDisposable)((()=>{this.rawOptions.linkHandler=null,this.rawOptions.documentOverride=null})))}onSpecificOptionChange(e,t){return this.onOptionChange((i=>{i===e&&t(this.rawOptions[e])}))}onMultipleOptionChange(e,t){return this.onOptionChange((i=>{-1!==e.indexOf(i)&&t()}))}_setupOptions(){const e=e=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key \"${e}\"`);return this.rawOptions[e]},i=(e,i)=>{if(!(e in t.DEFAULT_OPTIONS))throw new Error(`No option with key \"${e}\"`);i=this._sanitizeAndValidateOption(e,i),this.rawOptions[e]!==i&&(this.rawOptions[e]=i,this._onOptionChange.fire(e))};for(const t in this.rawOptions){const s={get:e.bind(this,t),set:i.bind(this,t)};Object.defineProperty(this.options,t,s)}}_sanitizeAndValidateOption(e,i){switch(e){case\"cursorStyle\":if(i||(i=t.DEFAULT_OPTIONS[e]),!function(e){return\"block\"===e||\"underline\"===e||\"bar\"===e}(i))throw new Error(`\"${i}\" is not a valid value for ${e}`);break;case\"wordSeparator\":i||(i=t.DEFAULT_OPTIONS[e]);break;case\"fontWeight\":case\"fontWeightBold\":if(\"number\"==typeof i&&1<=i&&i<=1e3)break;i=o.includes(i)?i:t.DEFAULT_OPTIONS[e];break;case\"cursorWidth\":i=Math.floor(i);case\"lineHeight\":case\"tabStopWidth\":if(i<1)throw new Error(`${e} cannot be less than 1, value: ${i}`);break;case\"minimumContrastRatio\":i=Math.max(1,Math.min(21,Math.round(10*i)/10));break;case\"scrollback\":if((i=Math.min(i,4294967295))<0)throw new Error(`${e} cannot be less than 0, value: ${i}`);break;case\"fastScrollSensitivity\":case\"scrollSensitivity\":if(i<=0)throw new Error(`${e} cannot be less than or equal to 0, value: ${i}`);break;case\"rows\":case\"cols\":if(!i&&0!==i)throw new Error(`${e} must be numeric, value: ${i}`);break;case\"windowsPty\":i=i??{}}return i}}t.OptionsService=a},8811:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.OscLinkService=void 0;const n=i(6501);let o=class{constructor(e){this._bufferService=e,this._nextId=1,this._entriesWithId=new Map,this._dataByLinkId=new Map}registerLink(e){const t=this._bufferService.buffer;if(void 0===e.id){const i=t.addMarker(t.ybase+t.y),s={data:e,id:this._nextId++,lines:[i]};return i.onDispose((()=>this._removeMarkerFromLink(s,i))),this._dataByLinkId.set(s.id,s),s.id}const i=e,s=this._getEntryIdKey(i),r=this._entriesWithId.get(s);if(r)return this.addLineToLink(r.id,t.ybase+t.y),r.id;const n=t.addMarker(t.ybase+t.y),o={id:this._nextId++,key:this._getEntryIdKey(i),data:i,lines:[n]};return n.onDispose((()=>this._removeMarkerFromLink(o,n))),this._entriesWithId.set(o.key,o),this._dataByLinkId.set(o.id,o),o.id}addLineToLink(e,t){const i=this._dataByLinkId.get(e);if(i&&i.lines.every((e=>e.line!==t))){const e=this._bufferService.buffer.addMarker(t);i.lines.push(e),e.onDispose((()=>this._removeMarkerFromLink(i,e)))}}getLinkData(e){return this._dataByLinkId.get(e)?.data}_getEntryIdKey(e){return`${e.id};;${e.uri}`}_removeMarkerFromLink(e,t){const i=e.lines.indexOf(t);-1!==i&&(e.lines.splice(i,1),0===e.lines.length&&(void 0!==e.data.id&&this._entriesWithId.delete(e.key),this._dataByLinkId.delete(e.id)))}};t.OscLinkService=o,t.OscLinkService=o=s([r(0,n.IBufferService)],o)},6201:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.serviceRegistry=void 0,t.getServiceDependencies=function(e){return e[s]||[]},t.createDecorator=function(e){if(t.serviceRegistry.has(e))return t.serviceRegistry.get(e);const r=function(e,t,n){if(3!==arguments.length)throw new Error(\"@IServiceName-decorator can only be used to decorate a parameter\");!function(e,t,r){t[i]===t?t[s].push({id:e,index:r}):(t[s]=[{id:e,index:r}],t[i]=t)}(r,e,n)};return r._id=e,t.serviceRegistry.set(e,r),r};const i=\"di$target\",s=\"di$dependencies\";t.serviceRegistry=new Map},6501:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.IDecorationService=t.IUnicodeService=t.IOscLinkService=t.IOptionsService=t.ILogService=t.LogLevelEnum=t.IInstantiationService=t.ICharsetService=t.ICoreService=t.ICoreMouseService=t.IBufferService=void 0;const s=i(6201);var r;t.IBufferService=(0,s.createDecorator)(\"BufferService\"),t.ICoreMouseService=(0,s.createDecorator)(\"CoreMouseService\"),t.ICoreService=(0,s.createDecorator)(\"CoreService\"),t.ICharsetService=(0,s.createDecorator)(\"CharsetService\"),t.IInstantiationService=(0,s.createDecorator)(\"InstantiationService\"),function(e){e[e.TRACE=0]=\"TRACE\",e[e.DEBUG=1]=\"DEBUG\",e[e.INFO=2]=\"INFO\",e[e.WARN=3]=\"WARN\",e[e.ERROR=4]=\"ERROR\",e[e.OFF=5]=\"OFF\"}(r||(t.LogLevelEnum=r={})),t.ILogService=(0,s.createDecorator)(\"LogService\"),t.IOptionsService=(0,s.createDecorator)(\"OptionsService\"),t.IOscLinkService=(0,s.createDecorator)(\"OscLinkService\"),t.IUnicodeService=(0,s.createDecorator)(\"UnicodeService\"),t.IDecorationService=(0,s.createDecorator)(\"DecorationService\")},6415:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.UnicodeService=void 0;const s=i(7428),r=i(802);class n{static extractShouldJoin(e){return!!(1&e)}static extractWidth(e){return e>>1&3}static extractCharKind(e){return e>>3}static createPropertyValue(e,t,i=!1){return(16777215&e)<<3|(3&t)<<1|(i?1:0)}constructor(){this._providers=Object.create(null),this._active=\"\",this._onChange=new r.Emitter,this.onChange=this._onChange.event;const e=new s.UnicodeV6;this.register(e),this._active=e.version,this._activeProvider=e}dispose(){this._onChange.dispose()}get versions(){return Object.keys(this._providers)}get activeVersion(){return this._active}set activeVersion(e){if(!this._providers[e])throw new Error(`unknown Unicode version \"${e}\"`);this._active=e,this._activeProvider=this._providers[e],this._onChange.fire(e)}register(e){this._providers[e.version]=e}wcwidth(e){return this._activeProvider.wcwidth(e)}getStringCellWidth(e){let t=0,i=0;const s=e.length;for(let r=0;r=s)return t+this.wcwidth(o);const i=e.charCodeAt(r);56320<=i&&i<=57343?o=1024*(o-55296)+i-56320+65536:t+=this.wcwidth(i)}const a=this.charProperties(o,i);let l=n.extractWidth(a);n.extractShouldJoin(a)&&(l-=n.extractWidth(i)),t+=l,i=a}return t}charProperties(e,t){return this._activeProvider.charProperties(e,t)}}t.UnicodeService=n},4333:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.isAndroid=t.isElectron=t.isWebkitWebView=t.isSafari=t.isChrome=t.isWebKit=t.isFirefox=t.onDidChangeFullscreen=t.onDidChangeZoomLevel=void 0,t.addMatchMediaChangeListener=o,t.setZoomLevel=function(e,t){n.INSTANCE.setZoomLevel(e,t)},t.getZoomLevel=function(e){return n.INSTANCE.getZoomLevel(e)},t.getZoomFactor=function(e){return n.INSTANCE.getZoomFactor(e)},t.setZoomFactor=function(e,t){n.INSTANCE.setZoomFactor(e,t)},t.setFullscreen=function(e,t){n.INSTANCE.setFullscreen(e,t)},t.isFullscreen=function(e){return n.INSTANCE.isFullscreen(e)},t.isStandalone=function(){return l},t.isWCOEnabled=function(){return navigator?.windowControlsOverlay?.visible},t.getWCOBoundingRect=function(){return navigator?.windowControlsOverlay?.getTitlebarAreaRect()};const s=i(4693),r=i(802);class n{constructor(){this.mapWindowIdToZoomLevel=new Map,this._onDidChangeZoomLevel=new r.Emitter,this.onDidChangeZoomLevel=this._onDidChangeZoomLevel.event,this.mapWindowIdToZoomFactor=new Map,this._onDidChangeFullscreen=new r.Emitter,this.onDidChangeFullscreen=this._onDidChangeFullscreen.event,this.mapWindowIdToFullScreen=new Map}static{this.INSTANCE=new n}getZoomLevel(e){return this.mapWindowIdToZoomLevel.get(this.getWindowId(e))??0}setZoomLevel(e,t){if(this.getZoomLevel(t)===e)return;const i=this.getWindowId(t);this.mapWindowIdToZoomLevel.set(i,e),this._onDidChangeZoomLevel.fire(i)}getZoomFactor(e){return this.mapWindowIdToZoomFactor.get(this.getWindowId(e))??1}setZoomFactor(e,t){this.mapWindowIdToZoomFactor.set(this.getWindowId(t),e)}setFullscreen(e,t){if(this.isFullscreen(t)===e)return;const i=this.getWindowId(t);this.mapWindowIdToFullScreen.set(i,e),this._onDidChangeFullscreen.fire(i)}isFullscreen(e){return!!this.mapWindowIdToFullScreen.get(this.getWindowId(e))}getWindowId(e){return e.vscodeWindowId}}function o(e,t,i){\"string\"==typeof t&&(t=e.matchMedia(t)),t.addEventListener(\"change\",i)}t.onDidChangeZoomLevel=n.INSTANCE.onDidChangeZoomLevel,t.onDidChangeFullscreen=n.INSTANCE.onDidChangeFullscreen;const a=\"object\"==typeof navigator?navigator.userAgent:\"\";t.isFirefox=a.indexOf(\"Firefox\")>=0,t.isWebKit=a.indexOf(\"AppleWebKit\")>=0,t.isChrome=a.indexOf(\"Chrome\")>=0,t.isSafari=!t.isChrome&&a.indexOf(\"Safari\")>=0,t.isWebkitWebView=!t.isChrome&&!t.isSafari&&t.isWebKit,t.isElectron=a.indexOf(\"Electron/\")>=0,t.isAndroid=a.indexOf(\"Android\")>=0;let l=!1;if(\"function\"==typeof s.mainWindow.matchMedia){const e=s.mainWindow.matchMedia(\"(display-mode: standalone) or (display-mode: window-controls-overlay)\"),t=s.mainWindow.matchMedia(\"(display-mode: fullscreen)\");l=e.matches,o(s.mainWindow,e,(({matches:e})=>{l&&t.matches||(l=e)}))}},7745:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.BrowserFeatures=t.KeyboardSupport=void 0;const o=n(i(4333)),a=i(4693),l=n(i(8163));var h;!function(e){e[e.Always=0]=\"Always\",e[e.FullScreen=1]=\"FullScreen\",e[e.None=2]=\"None\"}(h||(t.KeyboardSupport=h={}));const c=\"object\"==typeof navigator?navigator:{};t.BrowserFeatures={clipboard:{writeText:l.isNative||document.queryCommandSupported&&document.queryCommandSupported(\"copy\")||!!(c&&c.clipboard&&c.clipboard.writeText),readText:l.isNative||!!(c&&c.clipboard&&c.clipboard.readText)},keyboard:l.isNative||o.isStandalone()?h.Always:c.keyboard||o.isSafari?h.FullScreen:h.None,touch:\"ontouchstart\"in a.mainWindow||c.maxTouchPoints>0,pointerEvents:a.mainWindow.PointerEvent&&(\"ontouchstart\"in a.mainWindow||navigator.maxTouchPoints>0)}},7093:function(e,t,i){var s,r=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&r(t,e,i);return n(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.SafeTriangle=t.DragAndDropObserver=t.ModifierKeyEmitter=t.DetectedFullscreenMode=t.Namespace=t.EventHelper=t.EventType=t.sharedMutationObserver=t.Dimension=t.WindowIntervalTimer=t.scheduleAtNextAnimationFrame=t.runAtThisOrScheduleAtNextAnimationFrame=t.WindowIdleValue=t.addStandardDisposableGenericMouseUpListener=t.addStandardDisposableGenericMouseDownListener=t.addStandardDisposableListener=t.onDidUnregisterWindow=t.onWillUnregisterWindow=t.onDidRegisterWindow=t.hasWindow=t.getWindowById=t.getWindowId=t.getWindowsCount=t.getWindows=t.getDocument=t.getWindow=t.registerWindow=void 0,t.clearNode=function(e){for(;e.firstChild;)e.firstChild.remove()},t.clearNodeRecursively=function e(t){for(;t.firstChild;){const i=t.firstChild;i.remove(),e(i)}},t.addDisposableListener=C,t.addDisposableGenericMouseDownListener=w,t.addDisposableGenericMouseMoveListener=function(e,i,s){return C(e,g.isIOS&&l.BrowserFeatures.pointerEvents?t.EventType.POINTER_MOVE:t.EventType.MOUSE_MOVE,i,s)},t.addDisposableGenericMouseUpListener=E,t.runWhenWindowIdle=function(e,t,i){return(0,d._runWhenIdle)(e,t,i)},t.disposableWindowInterval=function(e,t,i,s){let r=0;const n=e.setInterval((()=>{r++,(\"number\"==typeof s&&r>=s||!0===t())&&o.dispose()}),i),o=(0,p.toDisposable)((()=>{e.clearInterval(n)}));return o},t.measure=function(e,i){return(0,t.scheduleAtNextAnimationFrame)(e,i,1e4)},t.modify=function(e,i){return(0,t.scheduleAtNextAnimationFrame)(e,i,-1e4)},t.addDisposableThrottledListener=function(e,t,i,s,r){return new T(e,t,i,s,r)},t.getComputedStyle=k,t.getClientArea=function e(i,s){const r=(0,t.getWindow)(i),n=r.document;if(i!==n.body)return new O(i.clientWidth,i.clientHeight);if(g.isIOS&&r?.visualViewport)return new O(r.visualViewport.width,r.visualViewport.height);if(r?.innerWidth&&r.innerHeight)return new O(r.innerWidth,r.innerHeight);if(n.body&&n.body.clientWidth&&n.body.clientHeight)return new O(n.body.clientWidth,n.body.clientHeight);if(n.documentElement&&n.documentElement.clientWidth&&n.documentElement.clientHeight)return new O(n.documentElement.clientWidth,n.documentElement.clientHeight);if(s)return e(s);throw new Error(\"Unable to figure out browser width and height\")},t.getTopLeftOffset=I,t.size=function(e,t,i){\"number\"==typeof t&&(e.style.width=`${t}px`),\"number\"==typeof i&&(e.style.height=`${i}px`)},t.position=function(e,t,i,s,r,n=\"absolute\"){\"number\"==typeof t&&(e.style.top=`${t}px`),\"number\"==typeof i&&(e.style.right=`${i}px`),\"number\"==typeof s&&(e.style.bottom=`${s}px`),\"number\"==typeof r&&(e.style.left=`${r}px`),e.style.position=n},t.getDomNodePagePosition=function(e){const i=e.getBoundingClientRect(),s=(0,t.getWindow)(e);return{left:i.left+s.scrollX,top:i.top+s.scrollY,width:i.width,height:i.height}},t.getDomNodeZoomLevel=function(e){let t=e,i=1;do{const e=k(t).zoom;null!=e&&\"1\"!==e&&(i*=e),t=t.parentElement}while(null!==t&&t!==t.ownerDocument.documentElement);return i},t.getTotalWidth=P,t.getContentWidth=function(e){const t=M.getBorderLeftWidth(e)+M.getBorderRightWidth(e),i=M.getPaddingLeft(e)+M.getPaddingRight(e);return e.offsetWidth-t-i},t.getTotalScrollWidth=x,t.getContentHeight=function(e){const t=M.getBorderTopWidth(e)+M.getBorderBottomWidth(e),i=M.getPaddingTop(e)+M.getPaddingBottom(e);return e.offsetHeight-t-i},t.getTotalHeight=function(e){const t=M.getMarginTop(e)+M.getMarginBottom(e);return e.offsetHeight+t},t.getLargestChildWidth=function(e,t){const i=t.map((t=>Math.max(x(t),P(t))+function(e,t){if(null===e)return 0;const i=I(e),s=I(t);return i.left-s.left}(t,e)||0));return Math.max(...i)},t.isAncestor=B,t.setParentFlowTo=function(e,t){e.dataset[N]=t.id},t.isAncestorUsingFlowTo=function(e,t){let i=e;for(;i;){if(i===t)return!0;if(Q(i)){const e=U(i);if(e){i=e;continue}}i=i.parentNode}return!1},t.findParentWithClass=F,t.hasParentWithClass=function(e,t,i){return!!F(e,t,i)},t.isShadowRoot=W,t.isInShadowDOM=function(e){return!!H(e)},t.getShadowRoot=H,t.getActiveElement=K,t.isActiveElement=function(e){return K()===e},t.isAncestorOfActiveElement=function(e){return B(K(),e)},t.isActiveDocument=function(e){return e.ownerDocument===z()},t.getActiveDocument=z,t.getActiveWindow=function(){const e=z();return e.defaultView?.window??v.mainWindow},t.isGlobalStylesheet=function(e){return j.has(e)},t.createStyleSheet2=function(){return new $},t.createStyleSheet=V,t.cloneGlobalStylesheets=function(e){const t=new p.DisposableStore;for(const[i,s]of j)t.add(G(i,s,e));return t},t.createMetaElement=function(e=v.mainWindow.document.head){return q(\"meta\",e)},t.createLinkElement=function(e=v.mainWindow.document.head){return q(\"link\",e)},t.createCSSRule=function e(t,i,s=Y()){if(s&&i){s.sheet?.insertRule(`${t} {${i}}`,0);for(const r of j.get(s)??[])e(t,i,r)}},t.removeCSSRulesContainingSelector=function e(t,i=Y()){if(!i)return;const s=Z(i),r=[];for(let e=0;e=0;e--)i.sheet?.deleteRule(r[e]);for(const s of j.get(i)??[])e(t,s)},t.isHTMLElement=Q,t.isHTMLAnchorElement=function(e){return e instanceof HTMLAnchorElement||e instanceof(0,t.getWindow)(e).HTMLAnchorElement},t.isHTMLSpanElement=function(e){return e instanceof HTMLSpanElement||e instanceof(0,t.getWindow)(e).HTMLSpanElement},t.isHTMLTextAreaElement=function(e){return e instanceof HTMLTextAreaElement||e instanceof(0,t.getWindow)(e).HTMLTextAreaElement},t.isHTMLInputElement=function(e){return e instanceof HTMLInputElement||e instanceof(0,t.getWindow)(e).HTMLInputElement},t.isHTMLButtonElement=function(e){return e instanceof HTMLButtonElement||e instanceof(0,t.getWindow)(e).HTMLButtonElement},t.isHTMLDivElement=function(e){return e instanceof HTMLDivElement||e instanceof(0,t.getWindow)(e).HTMLDivElement},t.isSVGElement=function(e){return e instanceof SVGElement||e instanceof(0,t.getWindow)(e).SVGElement},t.isMouseEvent=function(e){return e instanceof MouseEvent||e instanceof(0,t.getWindow)(e).MouseEvent},t.isKeyboardEvent=function(e){return e instanceof KeyboardEvent||e instanceof(0,t.getWindow)(e).KeyboardEvent},t.isPointerEvent=function(e){return e instanceof PointerEvent||e instanceof(0,t.getWindow)(e).PointerEvent},t.isDragEvent=function(e){return e instanceof DragEvent||e instanceof(0,t.getWindow)(e).DragEvent},t.isEventLike=function(e){const t=e;return!(!t||\"function\"!=typeof t.preventDefault||\"function\"!=typeof t.stopPropagation)},t.saveParentsScrollTop=function(e){const t=[];for(let i=0;e&&e.nodeType===e.ELEMENT_NODE;i++)t[i]=e.scrollTop,e=e.parentNode;return t},t.restoreParentsScrollTop=function(e,t){for(let i=0;e&&e.nodeType===e.ELEMENT_NODE;i++)e.scrollTop!==t[i]&&(e.scrollTop=t[i]),e=e.parentNode},t.trackFocus=function(e){return new ee(e)},t.after=function(e,t){return e.after(t),t},t.append=te,t.prepend=function(e,t){return e.insertBefore(t,e.firstChild),t},t.reset=function(e,...t){e.innerText=\"\",te(e,...t)},t.$=ne,t.join=function(e,t){const i=[];return e.forEach(((e,s)=>{s>0&&(t instanceof Node?i.push(t.cloneNode()):i.push(document.createTextNode(t))),i.push(e)})),i},t.setVisibility=function(e,...t){e?oe(...t):ae(...t)},t.show=oe,t.hide=ae,t.removeTabIndexAndUpdateFocus=function(e){if(e&&e.hasAttribute(\"tabIndex\")){if(e.ownerDocument.activeElement===e){const t=function(e){for(;e&&e.nodeType===e.ELEMENT_NODE;){if(Q(e)&&e.hasAttribute(\"tabIndex\"))return e;e=e.parentNode}return null}(e.parentElement);t?.focus()}e.removeAttribute(\"tabindex\")}},t.finalHandler=function(e){return t=>{t.preventDefault(),t.stopPropagation(),e(t)}},t.domContentLoaded=function(e){return new Promise((t=>{if(\"complete\"===e.document.readyState||e.document&&null!==e.document.body)t(void 0);else{const i=()=>{e.window.removeEventListener(\"DOMContentLoaded\",i,!1),t()};e.window.addEventListener(\"DOMContentLoaded\",i,!1)}}))},t.computeScreenAwareSize=function(e,t){const i=e.devicePixelRatio*t;return Math.max(1,Math.floor(i))/e.devicePixelRatio},t.windowOpenNoOpener=function(e){v.mainWindow.open(e,\"_blank\",\"noopener\")},t.windowOpenPopup=function(e){const t=Math.floor(v.mainWindow.screenLeft+v.mainWindow.innerWidth/2-le/2),i=Math.floor(v.mainWindow.screenTop+v.mainWindow.innerHeight/2-he/2);v.mainWindow.open(e,\"_blank\",`width=${le},height=${he},top=${i},left=${t}`)},t.windowOpenWithSuccess=function(e,t=!0){const i=v.mainWindow.open();return!!i&&(t&&(i.opener=null),i.location.href=e,!0)},t.animate=function(e,i){const s=()=>{i(),r=(0,t.scheduleAtNextAnimationFrame)(e,s)};let r=(0,t.scheduleAtNextAnimationFrame)(e,s);return(0,p.toDisposable)((()=>r.dispose()))},t.asCSSPropertyValue=function(e){return`'${e.replace(/'/g,\"%27\")}'`},t.asCssValueWithDefault=function e(t,i){if(void 0!==t){const s=t.match(/^\\s*var\\((.+)\\)$/);if(s){const t=s[1].split(\",\",2);return 2===t.length&&(i=e(t[1].trim(),i)),`var(${t[0]}, ${i})`}return t}return i},t.detectFullscreen=function(e){return e.document.fullscreenElement||e.document.webkitFullscreenElement||e.document.webkitIsFullScreen?{mode:ce.DOCUMENT,guess:!1}:e.innerHeight===e.screen.height?{mode:ce.BROWSER,guess:!1}:(g.isMacintosh||g.isLinux)&&e.outerHeight===e.screen.height&&e.outerWidth===e.screen.width?{mode:ce.BROWSER,guess:!0}:null},t.multibyteAwareBtoa=function(e){return btoa(function(e){const t=new Uint16Array(e.length);for(let i=0;i0&&(o.className=a.join(\" \"));const l={};if(r.groups.name&&(l[r.groups.name]=o),s)for(const e of s)Q(e)?o.appendChild(e):\"string\"==typeof e?o.append(e):\"root\"in e&&(Object.assign(l,e),o.appendChild(e.root));for(const[e,t]of Object.entries(i))if(\"className\"!==e)if(\"style\"===e)for(const[e,i]of Object.entries(t))o.style.setProperty(fe(e),\"number\"==typeof i?i+\"px\":\"\"+i);else\"tabIndex\"===e?o.tabIndex=t:o.setAttribute(fe(e),t.toString());return l.root=o,l},t.svgElem=function(e,...t){let i,s;Array.isArray(t[0])?(i={},s=t[0]):(i=t[0]||{},s=t[1]);const r=_e.exec(e);if(!r||!r.groups)throw new Error(\"Bad use of h\");const n=r.groups.tag||\"div\",o=document.createElementNS(\"http://www.w3.org/2000/svg\",n);r.groups.id&&(o.id=r.groups.id);const a=[];if(r.groups.class)for(const e of r.groups.class.split(\".\"))\"\"!==e&&a.push(e);if(void 0!==i.className)for(const e of i.className.split(\".\"))\"\"!==e&&a.push(e);a.length>0&&(o.className=a.join(\" \"));const l={};if(r.groups.name&&(l[r.groups.name]=o),s)for(const e of s)Q(e)?o.appendChild(e):\"string\"==typeof e?o.append(e):\"root\"in e&&(Object.assign(l,e),o.appendChild(e.root));for(const[e,t]of Object.entries(i))if(\"className\"!==e)if(\"style\"===e)for(const[e,i]of Object.entries(t))o.style.setProperty(fe(e),\"number\"==typeof i?i+\"px\":\"\"+i);else\"tabIndex\"===e?o.tabIndex=t:o.setAttribute(fe(e),t.toString());return l.root=o,l},t.copyAttributes=pe,t.trackAttributes=function(e,i,s){pe(e,i,s);const r=new p.DisposableStore;return r.add(t.sharedMutationObserver.observe(e,r,{attributes:!0,attributeFilter:s})((t=>{for(const s of t)\"attributes\"===s.type&&s.attributeName&&ge(e,i,s.attributeName)}))),r};const a=o(i(4333)),l=i(7745),h=i(5394),c=i(5964),d=i(1758),u=i(9807),_=o(i(802)),f=i(7883),p=i(7150),g=o(i(8163)),m=i(6304),v=i(4693),S=i(7704);s=function(){const e=new Map;(0,v.ensureCodeWindow)(v.mainWindow,1);const i={window:v.mainWindow,disposables:new p.DisposableStore};e.set(v.mainWindow.vscodeWindowId,i);const s=new _.Emitter,r=new _.Emitter,n=new _.Emitter;return{onDidRegisterWindow:s.event,onWillUnregisterWindow:n.event,onDidUnregisterWindow:r.event,registerWindow(i){if(e.has(i.vscodeWindowId))return p.Disposable.None;const o=new p.DisposableStore,a={window:i,disposables:o.add(new p.DisposableStore)};return e.set(i.vscodeWindowId,a),o.add((0,p.toDisposable)((()=>{e.delete(i.vscodeWindowId),r.fire(i)}))),o.add(C(i,t.EventType.BEFORE_UNLOAD,(()=>{n.fire(i)}))),s.fire(a),o},getWindows:()=>e.values(),getWindowsCount:()=>e.size,getWindowId:e=>e.vscodeWindowId,hasWindow:t=>e.has(t),getWindowById:function(t,s){return(\"number\"==typeof t?e.get(t):void 0)??(s?i:void 0)},getWindow(e){const t=e;if(t?.ownerDocument?.defaultView)return t.ownerDocument.defaultView.window;const i=e;return i?.view?i.view.window:v.mainWindow},getDocument(e){const i=e;return(0,t.getWindow)(i).document}}}(),t.registerWindow=s.registerWindow,t.getWindow=s.getWindow,t.getDocument=s.getDocument,t.getWindows=s.getWindows,t.getWindowsCount=s.getWindowsCount,t.getWindowId=s.getWindowId,t.getWindowById=s.getWindowById,t.hasWindow=s.hasWindow,t.onDidRegisterWindow=s.onDidRegisterWindow,t.onWillUnregisterWindow=s.onWillUnregisterWindow,t.onDidUnregisterWindow=s.onDidUnregisterWindow;class b{constructor(e,t,i,s){this._node=e,this._type=t,this._handler=i,this._options=s||!1,this._node.addEventListener(this._type,this._handler,this._options)}dispose(){this._handler&&(this._node.removeEventListener(this._type,this._handler,this._options),this._node=null,this._handler=null)}}function C(e,t,i,s){return new b(e,t,i,s)}function y(e,t){return function(i){return t(new c.StandardMouseEvent(e,i))}}function w(e,i,s){return C(e,g.isIOS&&l.BrowserFeatures.pointerEvents?t.EventType.POINTER_DOWN:t.EventType.MOUSE_DOWN,i,s)}function E(e,i,s){return C(e,g.isIOS&&l.BrowserFeatures.pointerEvents?t.EventType.POINTER_UP:t.EventType.MOUSE_UP,i,s)}t.addStandardDisposableListener=function(e,i,s,r){let n=s;return\"click\"===i||\"mousedown\"===i||\"contextmenu\"===i?n=y((0,t.getWindow)(e),s):\"keydown\"!==i&&\"keypress\"!==i&&\"keyup\"!==i||(n=function(e){return function(t){return e(new h.StandardKeyboardEvent(t))}}(s)),C(e,i,n,r)},t.addStandardDisposableGenericMouseDownListener=function(e,i,s){return w(e,y((0,t.getWindow)(e),i),s)},t.addStandardDisposableGenericMouseUpListener=function(e,i,s){return E(e,y((0,t.getWindow)(e),i),s)};class D extends d.AbstractIdleValue{constructor(e,t){super(e,t)}}t.WindowIdleValue=D;class L extends d.IntervalTimer{constructor(e){super(),this.defaultTarget=e&&(0,t.getWindow)(e)}cancelAndSet(e,t,i){return super.cancelAndSet(e,t,i??this.defaultTarget)}}t.WindowIntervalTimer=L;class R{constructor(e,t=0){this._runner=e,this.priority=t,this._canceled=!1}dispose(){this._canceled=!0}execute(){if(!this._canceled)try{this._runner()}catch(e){(0,u.onUnexpectedError)(e)}}static sort(e,t){return t.priority-e.priority}}!function(){const e=new Map,i=new Map,s=new Map,r=new Map;t.scheduleAtNextAnimationFrame=(n,o,a=0)=>{const l=(0,t.getWindowId)(n),h=new R(o,a);let c=e.get(l);return c||(c=[],e.set(l,c)),c.push(h),s.get(l)||(s.set(l,!0),n.requestAnimationFrame((()=>(t=>{s.set(t,!1);const n=e.get(t)??[];for(i.set(t,n),e.set(t,[]),r.set(t,!0);n.length>0;)n.sort(R.sort),n.shift().execute();r.set(t,!1)})(l)))),h},t.runAtThisOrScheduleAtNextAnimationFrame=(e,s,n)=>{const o=(0,t.getWindowId)(e);if(r.get(o)){const e=new R(s,n);let t=i.get(o);return t||(t=[],i.set(o,t)),t.push(e),e}return(0,t.scheduleAtNextAnimationFrame)(e,s,n)}}();const A=function(e,t){return t};class T extends p.Disposable{constructor(e,t,i,s=A,r=8){super();let n=null,o=0;const a=this._register(new d.TimeoutTimer),l=()=>{o=(new Date).getTime(),i(n),n=null};this._register(C(e,t,(e=>{n=s(n,e);const t=(new Date).getTime()-o;t>=r?(a.cancel(),l()):a.setIfNotSet(l,r-t)})))}}function k(e){return(0,t.getWindow)(e).getComputedStyle(e,null)}class M{static convertToPixels(e,t){return parseFloat(t)||0}static getDimension(e,t,i){const s=k(e),r=s?s.getPropertyValue(t):\"0\";return M.convertToPixels(e,r)}static getBorderLeftWidth(e){return M.getDimension(e,\"border-left-width\",\"borderLeftWidth\")}static getBorderRightWidth(e){return M.getDimension(e,\"border-right-width\",\"borderRightWidth\")}static getBorderTopWidth(e){return M.getDimension(e,\"border-top-width\",\"borderTopWidth\")}static getBorderBottomWidth(e){return M.getDimension(e,\"border-bottom-width\",\"borderBottomWidth\")}static getPaddingLeft(e){return M.getDimension(e,\"padding-left\",\"paddingLeft\")}static getPaddingRight(e){return M.getDimension(e,\"padding-right\",\"paddingRight\")}static getPaddingTop(e){return M.getDimension(e,\"padding-top\",\"paddingTop\")}static getPaddingBottom(e){return M.getDimension(e,\"padding-bottom\",\"paddingBottom\")}static getMarginLeft(e){return M.getDimension(e,\"margin-left\",\"marginLeft\")}static getMarginTop(e){return M.getDimension(e,\"margin-top\",\"marginTop\")}static getMarginRight(e){return M.getDimension(e,\"margin-right\",\"marginRight\")}static getMarginBottom(e){return M.getDimension(e,\"margin-bottom\",\"marginBottom\")}}class O{static{this.None=new O(0,0)}constructor(e,t){this.width=e,this.height=t}with(e=this.width,t=this.height){return e!==this.width||t!==this.height?new O(e,t):this}static is(e){return\"object\"==typeof e&&\"number\"==typeof e.height&&\"number\"==typeof e.width}static lift(e){return e instanceof O?e:new O(e.width,e.height)}static equals(e,t){return e===t||!(!e||!t)&&e.width===t.width&&e.height===t.height}}function I(e){let t=e.offsetParent,i=e.offsetTop,s=e.offsetLeft;for(;null!==(e=e.parentNode)&&e!==e.ownerDocument.body&&e!==e.ownerDocument.documentElement;){i-=e.scrollTop;const r=W(e)?null:k(e);r&&(s-=\"rtl\"!==r.direction?e.scrollLeft:-e.scrollLeft),e===t&&(s+=M.getBorderLeftWidth(e),i+=M.getBorderTopWidth(e),i+=e.offsetTop,s+=e.offsetLeft,t=e.offsetParent)}return{left:s,top:i}}function P(e){const t=M.getMarginLeft(e)+M.getMarginRight(e);return e.offsetWidth+t}function x(e){const t=M.getMarginLeft(e)+M.getMarginRight(e);return e.scrollWidth+t}function B(e,t){return Boolean(t?.contains(e))}t.Dimension=O;const N=\"parentFlowToElementId\";function U(e){const t=e.dataset[N];return\"string\"==typeof t?e.ownerDocument.getElementById(t):null}function F(e,t,i){for(;e&&e.nodeType===e.ELEMENT_NODE;){if(e.classList.contains(t))return e;if(i)if(\"string\"==typeof i){if(e.classList.contains(i))return null}else if(e===i)return null;e=e.parentNode}return null}function W(e){return e&&!!e.host&&!!e.mode}function H(e){for(;e.parentNode;){if(e===e.ownerDocument?.body)return null;e=e.parentNode}return W(e)?e:null}function K(){let e=z().activeElement;for(;e?.shadowRoot;)e=e.shadowRoot.activeElement;return e}function z(){return(0,t.getWindowsCount)()<=1?v.mainWindow.document:Array.from((0,t.getWindows)()).map((({window:e})=>e.document)).find((e=>e.hasFocus()))??v.mainWindow.document}const j=new Map;class ${constructor(){this._currentCssStyle=\"\",this._styleSheet=void 0}setStyle(e){e!==this._currentCssStyle&&(this._currentCssStyle=e,this._styleSheet?this._styleSheet.innerText=e:this._styleSheet=V(v.mainWindow.document.head,(t=>t.innerText=e)))}dispose(){this._styleSheet&&(this._styleSheet.remove(),this._styleSheet=void 0)}}function V(e=v.mainWindow.document.head,i,s){const r=document.createElement(\"style\");if(r.type=\"text/css\",r.media=\"screen\",i?.(r),e.appendChild(r),s&&s.add((0,p.toDisposable)((()=>r.remove()))),e===v.mainWindow.document.head){const e=new Set;j.set(r,e);for(const{window:i,disposables:n}of(0,t.getWindows)()){if(i===v.mainWindow)continue;const t=n.add(G(r,e,i));s?.add(t)}}return r}function G(e,i,s){const r=new p.DisposableStore,n=e.cloneNode(!0);s.document.head.appendChild(n),r.add((0,p.toDisposable)((()=>n.remove())));for(const t of Z(e))n.sheet?.insertRule(t.cssText,n.sheet?.cssRules.length);return r.add(t.sharedMutationObserver.observe(e,r,{childList:!0})((()=>{n.textContent=e.textContent}))),i.add(n),r.add((0,p.toDisposable)((()=>i.delete(n)))),r}function q(e,t=v.mainWindow.document.head){const i=document.createElement(e);return t.appendChild(i),i}t.sharedMutationObserver=new class{constructor(){this.mutationObservers=new Map}observe(e,t,i){let s=this.mutationObservers.get(e);s||(s=new Map,this.mutationObservers.set(e,s));const r=(0,m.hash)(i);let n=s.get(r);if(n)n.users+=1;else{const o=new _.Emitter,a=new MutationObserver((e=>o.fire(e)));a.observe(e,i);const l=n={users:1,observer:a,onDidMutate:o.event};t.add((0,p.toDisposable)((()=>{l.users-=1,0===l.users&&(o.dispose(),a.disconnect(),s?.delete(r),0===s?.size&&this.mutationObservers.delete(e))}))),s.set(r,n)}return n.onDidMutate}};let X=null;function Y(){return X||(X=V()),X}function Z(e){return e?.sheet?.rules?e.sheet.rules:e?.sheet?.cssRules?e.sheet.cssRules:[]}function J(e){return\"string\"==typeof e.selectorText}function Q(e){return e instanceof HTMLElement||e instanceof(0,t.getWindow)(e).HTMLElement}t.EventType={CLICK:\"click\",AUXCLICK:\"auxclick\",DBLCLICK:\"dblclick\",MOUSE_UP:\"mouseup\",MOUSE_DOWN:\"mousedown\",MOUSE_OVER:\"mouseover\",MOUSE_MOVE:\"mousemove\",MOUSE_OUT:\"mouseout\",MOUSE_ENTER:\"mouseenter\",MOUSE_LEAVE:\"mouseleave\",MOUSE_WHEEL:\"wheel\",POINTER_UP:\"pointerup\",POINTER_DOWN:\"pointerdown\",POINTER_MOVE:\"pointermove\",POINTER_LEAVE:\"pointerleave\",CONTEXT_MENU:\"contextmenu\",WHEEL:\"wheel\",KEY_DOWN:\"keydown\",KEY_PRESS:\"keypress\",KEY_UP:\"keyup\",LOAD:\"load\",BEFORE_UNLOAD:\"beforeunload\",UNLOAD:\"unload\",PAGE_SHOW:\"pageshow\",PAGE_HIDE:\"pagehide\",PASTE:\"paste\",ABORT:\"abort\",ERROR:\"error\",RESIZE:\"resize\",SCROLL:\"scroll\",FULLSCREEN_CHANGE:\"fullscreenchange\",WK_FULLSCREEN_CHANGE:\"webkitfullscreenchange\",SELECT:\"select\",CHANGE:\"change\",SUBMIT:\"submit\",RESET:\"reset\",FOCUS:\"focus\",FOCUS_IN:\"focusin\",FOCUS_OUT:\"focusout\",BLUR:\"blur\",INPUT:\"input\",STORAGE:\"storage\",DRAG_START:\"dragstart\",DRAG:\"drag\",DRAG_ENTER:\"dragenter\",DRAG_LEAVE:\"dragleave\",DRAG_OVER:\"dragover\",DROP:\"drop\",DRAG_END:\"dragend\",ANIMATION_START:a.isWebKit?\"webkitAnimationStart\":\"animationstart\",ANIMATION_END:a.isWebKit?\"webkitAnimationEnd\":\"animationend\",ANIMATION_ITERATION:a.isWebKit?\"webkitAnimationIteration\":\"animationiteration\"},t.EventHelper={stop:(e,t)=>(e.preventDefault(),t&&e.stopPropagation(),e)};class ee extends p.Disposable{static hasFocusWithin(e){if(Q(e)){const t=H(e);return B(t?t.activeElement:e.ownerDocument.activeElement,e)}{const t=e;return B(t.document.activeElement,t.document)}}constructor(e){super(),this._onDidFocus=this._register(new _.Emitter),this.onDidFocus=this._onDidFocus.event,this._onDidBlur=this._register(new _.Emitter),this.onDidBlur=this._onDidBlur.event;let i=ee.hasFocusWithin(e),s=!1;const r=()=>{s=!1,i||(i=!0,this._onDidFocus.fire())},n=()=>{i&&(s=!0,(Q(e)?(0,t.getWindow)(e):e).setTimeout((()=>{s&&(s=!1,i=!1,this._onDidBlur.fire())}),0))};this._refreshStateHandler=()=>{ee.hasFocusWithin(e)!==i&&(i?n():r())},this._register(C(e,t.EventType.FOCUS,r,!0)),this._register(C(e,t.EventType.BLUR,n,!0)),Q(e)&&(this._register(C(e,t.EventType.FOCUS_IN,(()=>this._refreshStateHandler()))),this._register(C(e,t.EventType.FOCUS_OUT,(()=>this._refreshStateHandler()))))}refreshState(){this._refreshStateHandler()}}function te(e,...t){if(e.append(...t),1===t.length&&\"string\"!=typeof t[0])return t[0]}const ie=/([\\w\\-]+)?(#([\\w\\-]+))?((\\.([\\w\\-]+))*)/;var se;function re(e,t,i,...s){const r=ie.exec(t);if(!r)throw new Error(\"Bad use of emmet\");const n=r[1]||\"div\";let o;return o=e!==se.HTML?document.createElementNS(e,n):document.createElement(n),r[3]&&(o.id=r[3]),r[4]&&(o.className=r[4].replace(/\\./g,\" \").trim()),i&&Object.entries(i).forEach((([e,t])=>{void 0!==t&&(/^on\\w+$/.test(e)?o[e]=t:\"selected\"===e?t&&o.setAttribute(e,\"true\"):o.setAttribute(e,t))})),o.append(...s),o}function ne(e,t,...i){return re(se.HTML,e,t,...i)}function oe(...e){for(const t of e)t.style.display=\"\",t.removeAttribute(\"aria-hidden\")}function ae(...e){for(const t of e)t.style.display=\"none\",t.setAttribute(\"aria-hidden\",\"true\")}!function(e){e.HTML=\"http://www.w3.org/1999/xhtml\",e.SVG=\"http://www.w3.org/2000/svg\"}(se||(t.Namespace=se={})),ne.SVG=function(e,t,...i){return re(se.SVG,e,t,...i)};const le=780,he=640;var ce;!function(e){e[e.DOCUMENT=1]=\"DOCUMENT\",e[e.BROWSER=2]=\"BROWSER\"}(ce||(t.DetectedFullscreenMode=ce={}));class de extends _.Emitter{constructor(){super(),this._subscriptions=new p.DisposableStore,this._keyStatus={altKey:!1,shiftKey:!1,ctrlKey:!1,metaKey:!1},this._subscriptions.add(_.Event.runAndSubscribe(t.onDidRegisterWindow,(({window:e,disposables:t})=>this.registerListeners(e,t)),{window:v.mainWindow,disposables:this._subscriptions}))}registerListeners(e,t){t.add(C(e,\"keydown\",(e=>{if(e.defaultPrevented)return;const t=new h.StandardKeyboardEvent(e);if(t.keyCode!==f.KeyCode.Alt||!e.repeat){if(e.altKey&&!this._keyStatus.altKey)this._keyStatus.lastKeyPressed=\"alt\";else if(e.ctrlKey&&!this._keyStatus.ctrlKey)this._keyStatus.lastKeyPressed=\"ctrl\";else if(e.metaKey&&!this._keyStatus.metaKey)this._keyStatus.lastKeyPressed=\"meta\";else if(e.shiftKey&&!this._keyStatus.shiftKey)this._keyStatus.lastKeyPressed=\"shift\";else{if(t.keyCode===f.KeyCode.Alt)return;this._keyStatus.lastKeyPressed=void 0}this._keyStatus.altKey=e.altKey,this._keyStatus.ctrlKey=e.ctrlKey,this._keyStatus.metaKey=e.metaKey,this._keyStatus.shiftKey=e.shiftKey,this._keyStatus.lastKeyPressed&&(this._keyStatus.event=e,this.fire(this._keyStatus))}}),!0)),t.add(C(e,\"keyup\",(e=>{e.defaultPrevented||(!e.altKey&&this._keyStatus.altKey?this._keyStatus.lastKeyReleased=\"alt\":!e.ctrlKey&&this._keyStatus.ctrlKey?this._keyStatus.lastKeyReleased=\"ctrl\":!e.metaKey&&this._keyStatus.metaKey?this._keyStatus.lastKeyReleased=\"meta\":!e.shiftKey&&this._keyStatus.shiftKey?this._keyStatus.lastKeyReleased=\"shift\":this._keyStatus.lastKeyReleased=void 0,this._keyStatus.lastKeyPressed!==this._keyStatus.lastKeyReleased&&(this._keyStatus.lastKeyPressed=void 0),this._keyStatus.altKey=e.altKey,this._keyStatus.ctrlKey=e.ctrlKey,this._keyStatus.metaKey=e.metaKey,this._keyStatus.shiftKey=e.shiftKey,this._keyStatus.lastKeyReleased&&(this._keyStatus.event=e,this.fire(this._keyStatus)))}),!0)),t.add(C(e.document.body,\"mousedown\",(()=>{this._keyStatus.lastKeyPressed=void 0}),!0)),t.add(C(e.document.body,\"mouseup\",(()=>{this._keyStatus.lastKeyPressed=void 0}),!0)),t.add(C(e.document.body,\"mousemove\",(e=>{e.buttons&&(this._keyStatus.lastKeyPressed=void 0)}),!0)),t.add(C(e,\"blur\",(()=>{this.resetKeyStatus()})))}get keyStatus(){return this._keyStatus}get isModifierPressed(){return this._keyStatus.altKey||this._keyStatus.ctrlKey||this._keyStatus.metaKey||this._keyStatus.shiftKey}resetKeyStatus(){this.doResetKeyStatus(),this.fire(this._keyStatus)}doResetKeyStatus(){this._keyStatus={altKey:!1,shiftKey:!1,ctrlKey:!1,metaKey:!1}}static getInstance(){return de.instance||(de.instance=new de),de.instance}dispose(){super.dispose(),this._subscriptions.dispose()}}t.ModifierKeyEmitter=de;class ue extends p.Disposable{constructor(e,t){super(),this.element=e,this.callbacks=t,this.counter=0,this.dragStartTime=0,this.registerListeners()}registerListeners(){this.callbacks.onDragStart&&this._register(C(this.element,t.EventType.DRAG_START,(e=>{this.callbacks.onDragStart?.(e)}))),this.callbacks.onDrag&&this._register(C(this.element,t.EventType.DRAG,(e=>{this.callbacks.onDrag?.(e)}))),this._register(C(this.element,t.EventType.DRAG_ENTER,(e=>{this.counter++,this.dragStartTime=e.timeStamp,this.callbacks.onDragEnter?.(e)}))),this._register(C(this.element,t.EventType.DRAG_OVER,(e=>{e.preventDefault(),this.callbacks.onDragOver?.(e,e.timeStamp-this.dragStartTime)}))),this._register(C(this.element,t.EventType.DRAG_LEAVE,(e=>{this.counter--,0===this.counter&&(this.dragStartTime=0,this.callbacks.onDragLeave?.(e))}))),this._register(C(this.element,t.EventType.DRAG_END,(e=>{this.counter=0,this.dragStartTime=0,this.callbacks.onDragEnd?.(e)}))),this._register(C(this.element,t.EventType.DROP,(e=>{this.counter=0,this.dragStartTime=0,this.callbacks.onDrop?.(e)})))}}t.DragAndDropObserver=ue;const _e=/(?[\\w\\-]+)?(?:#(?[\\w\\-]+))?(?(?:\\.(?:[\\w\\-]+))*)(?:@(?(?:[\\w\\_])+))?/;function fe(e){return e.replace(/([a-z])([A-Z])/g,\"$1-$2\").toLowerCase()}function pe(e,t,i){for(const{name:s,value:r}of e.attributes)i&&!i.includes(s)||t.setAttribute(s,r)}function ge(e,t,i){const s=e.getAttribute(i);s?t.setAttribute(i,s):t.removeAttribute(i)}t.SafeTriangle=class{constructor(e,t,i){this.originX=e,this.originY=t,this.triangles=[];const{top:s,left:r,right:n,bottom:o}=i.getBoundingClientRect(),a=this.triangles;let l=0;a[l++]=r,a[l++]=s,a[l++]=n,a[l++]=s,a[l++]=r,a[l++]=s,a[l++]=r,a[l++]=o,a[l++]=n,a[l++]=s,a[l++]=n,a[l++]=o,a[l++]=r,a[l++]=o,a[l++]=n,a[l++]=o}contains(e,t){const{triangles:i,originX:s,originY:r}=this;for(let n=0;n<4;n++)if((0,S.isPointWithinTriangle)(e,t,s,r,i[2*n],i[2*n+1],i[2*n+2],i[2*n+3]))return!0;return!1}}},9675:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.FastDomNode=void 0,t.createFastDomNode=function(e){return new i(e)};class i{constructor(e){this.domNode=e,this._maxWidth=\"\",this._width=\"\",this._height=\"\",this._top=\"\",this._left=\"\",this._bottom=\"\",this._right=\"\",this._paddingTop=\"\",this._paddingLeft=\"\",this._paddingBottom=\"\",this._paddingRight=\"\",this._fontFamily=\"\",this._fontWeight=\"\",this._fontSize=\"\",this._fontStyle=\"\",this._fontFeatureSettings=\"\",this._fontVariationSettings=\"\",this._textDecoration=\"\",this._lineHeight=\"\",this._letterSpacing=\"\",this._className=\"\",this._display=\"\",this._position=\"\",this._visibility=\"\",this._color=\"\",this._backgroundColor=\"\",this._layerHint=!1,this._contain=\"none\",this._boxShadow=\"\"}setMaxWidth(e){const t=s(e);this._maxWidth!==t&&(this._maxWidth=t,this.domNode.style.maxWidth=this._maxWidth)}setWidth(e){const t=s(e);this._width!==t&&(this._width=t,this.domNode.style.width=this._width)}setHeight(e){const t=s(e);this._height!==t&&(this._height=t,this.domNode.style.height=this._height)}setTop(e){const t=s(e);this._top!==t&&(this._top=t,this.domNode.style.top=this._top)}setLeft(e){const t=s(e);this._left!==t&&(this._left=t,this.domNode.style.left=this._left)}setBottom(e){const t=s(e);this._bottom!==t&&(this._bottom=t,this.domNode.style.bottom=this._bottom)}setRight(e){const t=s(e);this._right!==t&&(this._right=t,this.domNode.style.right=this._right)}setPaddingTop(e){const t=s(e);this._paddingTop!==t&&(this._paddingTop=t,this.domNode.style.paddingTop=this._paddingTop)}setPaddingLeft(e){const t=s(e);this._paddingLeft!==t&&(this._paddingLeft=t,this.domNode.style.paddingLeft=this._paddingLeft)}setPaddingBottom(e){const t=s(e);this._paddingBottom!==t&&(this._paddingBottom=t,this.domNode.style.paddingBottom=this._paddingBottom)}setPaddingRight(e){const t=s(e);this._paddingRight!==t&&(this._paddingRight=t,this.domNode.style.paddingRight=this._paddingRight)}setFontFamily(e){this._fontFamily!==e&&(this._fontFamily=e,this.domNode.style.fontFamily=this._fontFamily)}setFontWeight(e){this._fontWeight!==e&&(this._fontWeight=e,this.domNode.style.fontWeight=this._fontWeight)}setFontSize(e){const t=s(e);this._fontSize!==t&&(this._fontSize=t,this.domNode.style.fontSize=this._fontSize)}setFontStyle(e){this._fontStyle!==e&&(this._fontStyle=e,this.domNode.style.fontStyle=this._fontStyle)}setFontFeatureSettings(e){this._fontFeatureSettings!==e&&(this._fontFeatureSettings=e,this.domNode.style.fontFeatureSettings=this._fontFeatureSettings)}setFontVariationSettings(e){this._fontVariationSettings!==e&&(this._fontVariationSettings=e,this.domNode.style.fontVariationSettings=this._fontVariationSettings)}setTextDecoration(e){this._textDecoration!==e&&(this._textDecoration=e,this.domNode.style.textDecoration=this._textDecoration)}setLineHeight(e){const t=s(e);this._lineHeight!==t&&(this._lineHeight=t,this.domNode.style.lineHeight=this._lineHeight)}setLetterSpacing(e){const t=s(e);this._letterSpacing!==t&&(this._letterSpacing=t,this.domNode.style.letterSpacing=this._letterSpacing)}setClassName(e){this._className!==e&&(this._className=e,this.domNode.className=this._className)}toggleClassName(e,t){this.domNode.classList.toggle(e,t),this._className=this.domNode.className}setDisplay(e){this._display!==e&&(this._display=e,this.domNode.style.display=this._display)}setPosition(e){this._position!==e&&(this._position=e,this.domNode.style.position=this._position)}setVisibility(e){this._visibility!==e&&(this._visibility=e,this.domNode.style.visibility=this._visibility)}setColor(e){this._color!==e&&(this._color=e,this.domNode.style.color=this._color)}setBackgroundColor(e){this._backgroundColor!==e&&(this._backgroundColor=e,this.domNode.style.backgroundColor=this._backgroundColor)}setLayerHinting(e){this._layerHint!==e&&(this._layerHint=e,this.domNode.style.transform=this._layerHint?\"translate3d(0px, 0px, 0px)\":\"\")}setBoxShadow(e){this._boxShadow!==e&&(this._boxShadow=e,this.domNode.style.boxShadow=e)}setContain(e){this._contain!==e&&(this._contain=e,this.domNode.style.contain=this._contain)}setAttribute(e,t){this.domNode.setAttribute(e,t)}removeAttribute(e){this.domNode.removeAttribute(e)}appendChild(e){this.domNode.appendChild(e.domNode)}removeChild(e){this.domNode.removeChild(e.domNode)}}function s(e){return\"number\"==typeof e?`${e}px`:e}t.FastDomNode=i},8328:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.GlobalPointerMoveMonitor=void 0;const o=n(i(7093)),a=i(7150);t.GlobalPointerMoveMonitor=class{constructor(){this._hooks=new a.DisposableStore,this._pointerMoveCallback=null,this._onStopCallback=null}dispose(){this.stopMonitoring(!1),this._hooks.dispose()}stopMonitoring(e,t){if(!this.isMonitoring())return;this._hooks.clear(),this._pointerMoveCallback=null;const i=this._onStopCallback;this._onStopCallback=null,e&&i&&i(t)}isMonitoring(){return!!this._pointerMoveCallback}startMonitoring(e,t,i,s,r){this.isMonitoring()&&this.stopMonitoring(!1),this._pointerMoveCallback=s,this._onStopCallback=r;let n=e;try{e.setPointerCapture(t),this._hooks.add((0,a.toDisposable)((()=>{try{e.releasePointerCapture(t)}catch(e){}})))}catch(t){n=o.getWindow(e)}this._hooks.add(o.addDisposableListener(n,o.EventType.POINTER_MOVE,(e=>{e.buttons===i?(e.preventDefault(),this._pointerMoveCallback(e)):this.stopMonitoring(!0)}))),this._hooks.add(o.addDisposableListener(n,o.EventType.POINTER_UP,(e=>this.stopMonitoring(!0))))}}},6609:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.IframeUtils=void 0,t.parentOriginHash=async function(e,t){if(!crypto.subtle)throw new Error(\"'crypto.subtle' is not available so webviews will not work. This is likely because the editor is not running in a secure context (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).\");const i=JSON.stringify({parentOrigin:e,salt:t}),s=(new TextEncoder).encode(i);return function(e){const t=Array.from(new Uint8Array(e)).map((e=>e.toString(16).padStart(2,\"0\"))).join(\"\");return BigInt(`0x${t}`).toString(32).padStart(52,\"0\")}(await crypto.subtle.digest(\"sha-256\",s))};const i=new WeakMap;function s(e){if(!e.parent||e.parent===e)return null;try{const t=e.location,i=e.parent.location;if(\"null\"!==t.origin&&\"null\"!==i.origin&&t.origin!==i.origin)return null}catch(e){return null}return e.parent}t.IframeUtils=class{static getSameOriginWindowChain(e){let t=i.get(e);if(!t){t=[],i.set(e,t);let r,n=e;do{r=s(n),r?t.push({window:new WeakRef(n),iframeElement:n.frameElement||null}):t.push({window:new WeakRef(n),iframeElement:null}),n=r}while(n)}return t.slice(0)}static getPositionOfChildWindowRelativeToAncestorWindow(e,t){if(!t||e===t)return{top:0,left:0};let i=0,s=0;const r=this.getSameOriginWindowChain(e);for(const e of r){const r=e.window.deref();if(i+=r?.scrollY??0,s+=r?.scrollX??0,r===t)break;if(!e.iframeElement)break;const n=e.iframeElement.getBoundingClientRect();i+=n.top,s+=n.left}return{top:i,left:s}}}},5394:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.StandardKeyboardEvent=void 0,t.printKeyboardEvent=function(e){const t=[];return e.ctrlKey&&t.push(\"ctrl\"),e.shiftKey&&t.push(\"shift\"),e.altKey&&t.push(\"alt\"),e.metaKey&&t.push(\"meta\"),`modifiers: [${t.join(\",\")}], code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`},t.printStandardKeyboardEvent=function(e){const t=[];return e.ctrlKey&&t.push(\"ctrl\"),e.shiftKey&&t.push(\"shift\"),e.altKey&&t.push(\"alt\"),e.metaKey&&t.push(\"meta\"),`modifiers: [${t.join(\",\")}], code: ${e.code}, keyCode: ${e.keyCode} ('${a.KeyCodeUtils.toString(e.keyCode)}')`};const o=n(i(4333)),a=i(7883),l=i(2811),h=n(i(8163)),c=h.isMacintosh?a.KeyMod.WinCtrl:a.KeyMod.CtrlCmd,d=a.KeyMod.Alt,u=a.KeyMod.Shift,_=h.isMacintosh?a.KeyMod.CtrlCmd:a.KeyMod.WinCtrl;t.StandardKeyboardEvent=class{constructor(e){this._standardKeyboardEventBrand=!0;const t=e;this.browserEvent=t,this.target=t.target,this.ctrlKey=t.ctrlKey,this.shiftKey=t.shiftKey,this.altKey=t.altKey,this.metaKey=t.metaKey,this.altGraphKey=t.getModifierState?.(\"AltGraph\"),this.keyCode=function(e){if(e.charCode){const t=String.fromCharCode(e.charCode).toUpperCase();return a.KeyCodeUtils.fromString(t)}const t=e.keyCode;if(3===t)return a.KeyCode.PauseBreak;if(o.isFirefox)switch(t){case 59:return a.KeyCode.Semicolon;case 60:if(h.isLinux)return a.KeyCode.IntlBackslash;break;case 61:return a.KeyCode.Equal;case 107:return a.KeyCode.NumpadAdd;case 109:return a.KeyCode.NumpadSubtract;case 173:return a.KeyCode.Minus;case 224:if(h.isMacintosh)return a.KeyCode.Meta}else if(o.isWebKit){if(h.isMacintosh&&93===t)return a.KeyCode.Meta;if(!h.isMacintosh&&92===t)return a.KeyCode.Meta}return a.EVENT_KEY_CODE_MAP[t]||a.KeyCode.Unknown}(t),this.code=t.code,this.ctrlKey=this.ctrlKey||this.keyCode===a.KeyCode.Ctrl,this.altKey=this.altKey||this.keyCode===a.KeyCode.Alt,this.shiftKey=this.shiftKey||this.keyCode===a.KeyCode.Shift,this.metaKey=this.metaKey||this.keyCode===a.KeyCode.Meta,this._asKeybinding=this._computeKeybinding(),this._asKeyCodeChord=this._computeKeyCodeChord()}preventDefault(){this.browserEvent&&this.browserEvent.preventDefault&&this.browserEvent.preventDefault()}stopPropagation(){this.browserEvent&&this.browserEvent.stopPropagation&&this.browserEvent.stopPropagation()}toKeyCodeChord(){return this._asKeyCodeChord}equals(e){return this._asKeybinding===e}_computeKeybinding(){let e=a.KeyCode.Unknown;this.keyCode!==a.KeyCode.Ctrl&&this.keyCode!==a.KeyCode.Shift&&this.keyCode!==a.KeyCode.Alt&&this.keyCode!==a.KeyCode.Meta&&(e=this.keyCode);let t=0;return this.ctrlKey&&(t|=c),this.altKey&&(t|=d),this.shiftKey&&(t|=u),this.metaKey&&(t|=_),t|=e,t}_computeKeyCodeChord(){let e=a.KeyCode.Unknown;return this.keyCode!==a.KeyCode.Ctrl&&this.keyCode!==a.KeyCode.Shift&&this.keyCode!==a.KeyCode.Alt&&this.keyCode!==a.KeyCode.Meta&&(e=this.keyCode),new l.KeyCodeChord(this.ctrlKey,this.shiftKey,this.altKey,this.metaKey,e)}}},5964:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.StandardWheelEvent=t.DragMouseEvent=t.StandardMouseEvent=void 0;const o=n(i(4333)),a=i(6609),l=n(i(8163));class h{constructor(e,t){this.timestamp=Date.now(),this.browserEvent=t,this.leftButton=0===t.button,this.middleButton=1===t.button,this.rightButton=2===t.button,this.buttons=t.buttons,this.target=t.target,this.detail=t.detail||1,\"dblclick\"===t.type&&(this.detail=2),this.ctrlKey=t.ctrlKey,this.shiftKey=t.shiftKey,this.altKey=t.altKey,this.metaKey=t.metaKey,\"number\"==typeof t.pageX?(this.posx=t.pageX,this.posy=t.pageY):(this.posx=t.clientX+this.target.ownerDocument.body.scrollLeft+this.target.ownerDocument.documentElement.scrollLeft,this.posy=t.clientY+this.target.ownerDocument.body.scrollTop+this.target.ownerDocument.documentElement.scrollTop);const i=a.IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(e,t.view);this.posx-=i.left,this.posy-=i.top}preventDefault(){this.browserEvent.preventDefault()}stopPropagation(){this.browserEvent.stopPropagation()}}t.StandardMouseEvent=h,t.DragMouseEvent=class extends h{constructor(e,t){super(e,t),this.dataTransfer=t.dataTransfer}},t.StandardWheelEvent=class{constructor(e,t=0,i=0){this.browserEvent=e||null,this.target=e?e.target||e.targetNode||e.srcElement:null,this.deltaY=i,this.deltaX=t;let s=!1;if(o.isChrome){const e=navigator.userAgent.match(/Chrome\\/(\\d+)/);s=(e?parseInt(e[1]):123)<=122}if(e){const t=e,i=e,r=e.view?.devicePixelRatio||1;if(void 0!==t.wheelDeltaY)this.deltaY=s?t.wheelDeltaY/(120*r):t.wheelDeltaY/120;else if(void 0!==i.VERTICAL_AXIS&&i.axis===i.VERTICAL_AXIS)this.deltaY=-i.detail/3;else if(\"wheel\"===e.type){const t=e;t.deltaMode===t.DOM_DELTA_LINE?o.isFirefox&&!l.isMacintosh?this.deltaY=-e.deltaY/3:this.deltaY=-e.deltaY:this.deltaY=-e.deltaY/40}if(void 0!==t.wheelDeltaX)o.isSafari&&l.isWindows?this.deltaX=-t.wheelDeltaX/120:this.deltaX=s?t.wheelDeltaX/(120*r):t.wheelDeltaX/120;else if(void 0!==i.HORIZONTAL_AXIS&&i.axis===i.HORIZONTAL_AXIS)this.deltaX=-e.detail/3;else if(\"wheel\"===e.type){const t=e;t.deltaMode===t.DOM_DELTA_LINE?o.isFirefox&&!l.isMacintosh?this.deltaX=-e.deltaX/3:this.deltaX=-e.deltaX:this.deltaX=-e.deltaX/40}0===this.deltaY&&0===this.deltaX&&e.wheelDelta&&(this.deltaY=s?e.wheelDelta/(120*r):e.wheelDelta/120)}}preventDefault(){this.browserEvent?.preventDefault()}stopPropagation(){this.browserEvent?.stopPropagation()}}},8594:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.Gesture=t.EventType=void 0;const a=o(i(7093)),l=i(4693),h=o(i(3058)),c=i(4838),d=i(802),u=i(7150),_=i(6317);var f;!function(e){e.Tap=\"-xterm-gesturetap\",e.Change=\"-xterm-gesturechange\",e.Start=\"-xterm-gesturestart\",e.End=\"-xterm-gesturesend\",e.Contextmenu=\"-xterm-gesturecontextmenu\"}(f||(t.EventType=f={}));class p extends u.Disposable{static{this.SCROLL_FRICTION=-.005}static{this.HOLD_DELAY=700}static{this.CLEAR_TAP_COUNT_TIME=400}constructor(){super(),this.dispatched=!1,this.targets=new _.LinkedList,this.ignoreTargets=new _.LinkedList,this.activeTouches={},this.handle=null,this._lastSetTapCountTime=0,this._register(d.Event.runAndSubscribe(a.onDidRegisterWindow,(({window:e,disposables:t})=>{t.add(a.addDisposableListener(e.document,\"touchstart\",(e=>this.onTouchStart(e)),{passive:!1})),t.add(a.addDisposableListener(e.document,\"touchend\",(t=>this.onTouchEnd(e,t)))),t.add(a.addDisposableListener(e.document,\"touchmove\",(e=>this.onTouchMove(e)),{passive:!1}))}),{window:l.mainWindow,disposables:this._store}))}static addTarget(e){if(!p.isTouchDevice())return u.Disposable.None;p.INSTANCE||(p.INSTANCE=(0,u.markAsSingleton)(new p));const t=p.INSTANCE.targets.push(e);return(0,u.toDisposable)(t)}static ignoreTarget(e){if(!p.isTouchDevice())return u.Disposable.None;p.INSTANCE||(p.INSTANCE=(0,u.markAsSingleton)(new p));const t=p.INSTANCE.ignoreTargets.push(e);return(0,u.toDisposable)(t)}static isTouchDevice(){return\"ontouchstart\"in l.mainWindow||navigator.maxTouchPoints>0}dispose(){this.handle&&(this.handle.dispose(),this.handle=null),super.dispose()}onTouchStart(e){const t=Date.now();this.handle&&(this.handle.dispose(),this.handle=null);for(let i=0,s=e.targetTouches.length;i=p.HOLD_DELAY&&Math.abs(o.initialPageX-h.tail(o.rollingPageX))<30&&Math.abs(o.initialPageY-h.tail(o.rollingPageY))<30){const e=this.newGestureEvent(f.Contextmenu,o.initialTarget);e.pageX=h.tail(o.rollingPageX),e.pageY=h.tail(o.rollingPageY),this.dispatchEvent(e)}else if(1===s){const t=h.tail(o.rollingPageX),s=h.tail(o.rollingPageY),r=h.tail(o.rollingTimestamps)-o.rollingTimestamps[0],n=t-o.rollingPageX[0],a=s-o.rollingPageY[0],l=[...this.targets].filter((e=>o.initialTarget instanceof Node&&e.contains(o.initialTarget)));this.inertia(e,l,i,Math.abs(n)/r,n>0?1:-1,t,Math.abs(a)/r,a>0?1:-1,s)}this.dispatchEvent(this.newGestureEvent(f.End,o.initialTarget)),delete this.activeTouches[n.identifier]}this.dispatched&&(t.preventDefault(),t.stopPropagation(),this.dispatched=!1)}newGestureEvent(e,t){const i=document.createEvent(\"CustomEvent\");return i.initEvent(e,!1,!0),i.initialTarget=t,i.tapCount=0,i}dispatchEvent(e){if(e.type===f.Tap){const t=(new Date).getTime();let i=0;i=t-this._lastSetTapCountTime>p.CLEAR_TAP_COUNT_TIME?1:2,this._lastSetTapCountTime=t,e.tapCount=i}else e.type!==f.Change&&e.type!==f.Contextmenu||(this._lastSetTapCountTime=0);if(e.initialTarget instanceof Node){for(const t of this.ignoreTargets)if(t.contains(e.initialTarget))return;const t=[];for(const i of this.targets)if(i.contains(e.initialTarget)){let s=0,r=e.initialTarget;for(;r&&r!==i;)s++,r=r.parentElement;t.push([s,i])}t.sort(((e,t)=>e[0]-t[0]));for(const[i,s]of t)s.dispatchEvent(e),this.dispatched=!0}}inertia(e,t,i,s,r,n,o,l,h){this.handle=a.scheduleAtNextAnimationFrame(e,(()=>{const a=Date.now(),c=a-i;let d=0,u=0,_=!0;s+=p.SCROLL_FRICTION*c,o+=p.SCROLL_FRICTION*c,s>0&&(_=!1,d=r*s*c),o>0&&(_=!1,u=l*o*c);const g=this.newGestureEvent(f.Change);g.translationX=d,g.translationY=u,t.forEach((e=>e.dispatchEvent(g))),_||this.inertia(e,t,a,s,r,n+d,o,l,h+u)}))}onTouchMove(e){const t=Date.now();for(let i=0,s=e.changedTouches.length;i3&&(r.rollingPageX.shift(),r.rollingPageY.shift(),r.rollingTimestamps.shift()),r.rollingPageX.push(s.pageX),r.rollingPageY.push(s.pageY),r.rollingTimestamps.push(t)}this.dispatched&&(e.preventDefault(),e.stopPropagation(),this.dispatched=!1)}}t.Gesture=p,n([c.memoize],p,\"isTouchDevice\",null)},8801:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.AbstractScrollbar=void 0;const o=n(i(7093)),a=i(9675),l=i(8328),h=i(8974),c=i(79),d=i(8286),u=n(i(8163));class _ extends d.Widget{constructor(e){super(),this._lazyRender=e.lazyRender,this._host=e.host,this._scrollable=e.scrollable,this._scrollByPage=e.scrollByPage,this._scrollbarState=e.scrollbarState,this._visibilityController=this._register(new c.ScrollbarVisibilityController(e.visibility,\"visible scrollbar \"+e.extraScrollbarClassName,\"invisible scrollbar \"+e.extraScrollbarClassName)),this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._pointerMoveMonitor=this._register(new l.GlobalPointerMoveMonitor),this._shouldRender=!0,this.domNode=(0,a.createFastDomNode)(document.createElement(\"div\")),this.domNode.setAttribute(\"role\",\"presentation\"),this.domNode.setAttribute(\"aria-hidden\",\"true\"),this._visibilityController.setDomNode(this.domNode),this.domNode.setPosition(\"absolute\"),this._register(o.addDisposableListener(this.domNode.domNode,o.EventType.POINTER_DOWN,(e=>this._domNodePointerDown(e))))}_createArrow(e){const t=this._register(new h.ScrollbarArrow(e));this.domNode.domNode.appendChild(t.bgDomNode),this.domNode.domNode.appendChild(t.domNode)}_createSlider(e,t,i,s){this.slider=(0,a.createFastDomNode)(document.createElement(\"div\")),this.slider.setClassName(\"slider\"),this.slider.setPosition(\"absolute\"),this.slider.setTop(e),this.slider.setLeft(t),\"number\"==typeof i&&this.slider.setWidth(i),\"number\"==typeof s&&this.slider.setHeight(s),this.slider.setLayerHinting(!0),this.slider.setContain(\"strict\"),this.domNode.domNode.appendChild(this.slider.domNode),this._register(o.addDisposableListener(this.slider.domNode,o.EventType.POINTER_DOWN,(e=>{0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))}))),this.onclick(this.slider.domNode,(e=>{e.leftButton&&e.stopPropagation()}))}_onElementSize(e){return this._scrollbarState.setVisibleSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_onElementScrollSize(e){return this._scrollbarState.setScrollSize(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}_onElementScrollPosition(e){return this._scrollbarState.setScrollPosition(e)&&(this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()),this._shouldRender=!0,this._lazyRender||this.render()),this._shouldRender}beginReveal(){this._visibilityController.setShouldBeVisible(!0)}beginHide(){this._visibilityController.setShouldBeVisible(!1)}render(){this._shouldRender&&(this._shouldRender=!1,this._renderDomNode(this._scrollbarState.getRectangleLargeSize(),this._scrollbarState.getRectangleSmallSize()),this._updateSlider(this._scrollbarState.getSliderSize(),this._scrollbarState.getArrowSize()+this._scrollbarState.getSliderPosition()))}_domNodePointerDown(e){e.target===this.domNode.domNode&&this._onPointerDown(e)}delegatePointerDown(e){const t=this.domNode.domNode.getClientRects()[0].top,i=t+this._scrollbarState.getSliderPosition(),s=t+this._scrollbarState.getSliderPosition()+this._scrollbarState.getSliderSize(),r=this._sliderPointerPosition(e);i<=r&&r<=s?0===e.button&&(e.preventDefault(),this._sliderPointerDown(e)):this._onPointerDown(e)}_onPointerDown(e){let t,i;if(e.target===this.domNode.domNode&&\"number\"==typeof e.offsetX&&\"number\"==typeof e.offsetY)t=e.offsetX,i=e.offsetY;else{const s=o.getDomNodePagePosition(this.domNode.domNode);t=e.pageX-s.left,i=e.pageY-s.top}const s=this._pointerDownRelativePosition(t,i);this._setDesiredScrollPositionNow(this._scrollByPage?this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(s):this._scrollbarState.getDesiredScrollPositionFromOffset(s)),0===e.button&&(e.preventDefault(),this._sliderPointerDown(e))}_sliderPointerDown(e){if(!(e.target&&e.target instanceof Element))return;const t=this._sliderPointerPosition(e),i=this._sliderOrthogonalPointerPosition(e),s=this._scrollbarState.clone();this.slider.toggleClassName(\"active\",!0),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,(e=>{const r=this._sliderOrthogonalPointerPosition(e),n=Math.abs(r-i);if(u.isWindows&&n>140)return void this._setDesiredScrollPositionNow(s.getScrollPosition());const o=this._sliderPointerPosition(e)-t;this._setDesiredScrollPositionNow(s.getDesiredScrollPositionFromDelta(o))}),(()=>{this.slider.toggleClassName(\"active\",!1),this._host.onDragEnd()})),this._host.onDragStart()}_setDesiredScrollPositionNow(e){const t={};this.writeScrollPosition(t,e),this._scrollable.setScrollPositionNow(t)}updateScrollbarSize(e){this._updateScrollbarSize(e),this._scrollbarState.setScrollbarSize(e),this._shouldRender=!0,this._lazyRender||this.render()}isNeeded(){return this._scrollbarState.isNeeded()}}t.AbstractScrollbar=_},151:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.HorizontalScrollbar=void 0;const s=i(8801),r=i(8245),n=i(9881);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition();if(super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(t.horizontalHasArrows?t.arrowSize:0,t.horizontal===n.ScrollbarVisibility.Hidden?0:t.horizontalScrollbarSize,t.vertical===n.ScrollbarVisibility.Hidden?0:t.verticalScrollbarSize,s.width,s.scrollWidth,o.scrollLeft),visibility:t.horizontal,extraScrollbarClassName:\"horizontal\",scrollable:e,scrollByPage:t.scrollByPage}),t.horizontalHasArrows)throw new Error(\"horizontalHasArrows is not supported in xterm.js\");this._createSlider(Math.floor((t.horizontalScrollbarSize-t.horizontalSliderSize)/2),0,void 0,t.horizontalSliderSize)}_updateSlider(e,t){this.slider.setWidth(e),this.slider.setLeft(t)}_renderDomNode(e,t){this.domNode.setWidth(e),this.domNode.setHeight(t),this.domNode.setLeft(0),this.domNode.setBottom(0)}onDidScroll(e){return this._shouldRender=this._onElementScrollSize(e.scrollWidth)||this._shouldRender,this._shouldRender=this._onElementScrollPosition(e.scrollLeft)||this._shouldRender,this._shouldRender=this._onElementSize(e.width)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return e}_sliderPointerPosition(e){return e.pageX}_sliderOrthogonalPointerPosition(e){return e.pageY}_updateScrollbarSize(e){this.slider.setHeight(e)}writeScrollPosition(e,t){e.scrollLeft=t}updateOptions(e){this.updateScrollbarSize(e.horizontal===n.ScrollbarVisibility.Hidden?0:e.horizontalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(e.vertical===n.ScrollbarVisibility.Hidden?0:e.verticalScrollbarSize),this._visibilityController.setVisibility(e.horizontal),this._scrollByPage=e.scrollByPage}}t.HorizontalScrollbar=o},8234:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.DomScrollableElement=t.SmoothScrollableElement=t.ScrollableElement=t.AbstractScrollableElement=t.MouseWheelClassifier=void 0;const o=i(4333),a=n(i(7093)),l=i(9675),h=i(5964),c=i(151),d=i(5473),u=i(8286),_=i(1758),f=i(802),p=i(7150),g=n(i(8163)),m=i(9881);class v{constructor(e,t,i){this.timestamp=e,this.deltaX=t,this.deltaY=i,this.score=0}}class S{static{this.INSTANCE=new S}constructor(){this._capacity=5,this._memory=[],this._front=-1,this._rear=-1}isPhysicalMouseWheel(){if(-1===this._front&&-1===this._rear)return!1;let e=1,t=0,i=1,s=this._rear;for(;;){const r=s===this._front?e:Math.pow(2,-i);if(e-=r,t+=this._memory[s].score*r,s===this._front)break;s=(this._capacity+s-1)%this._capacity,i++}return t<=.5}acceptStandardWheelEvent(e){if(o.isChrome){const t=a.getWindow(e.browserEvent),i=(0,o.getZoomFactor)(t);this.accept(Date.now(),e.deltaX*i,e.deltaY*i)}else this.accept(Date.now(),e.deltaX,e.deltaY)}accept(e,t,i){let s=null;const r=new v(e,t,i);-1===this._front&&-1===this._rear?(this._memory[0]=r,this._front=0,this._rear=0):(s=this._memory[this._rear],this._rear=(this._rear+1)%this._capacity,this._rear===this._front&&(this._front=(this._front+1)%this._capacity),this._memory[this._rear]=r),r.score=this._computeScore(r,s)}_computeScore(e,t){if(Math.abs(e.deltaX)>0&&Math.abs(e.deltaY)>0)return 1;let i=.5;if(this._isAlmostInt(e.deltaX)&&this._isAlmostInt(e.deltaY)||(i+=.25),t){const s=Math.abs(e.deltaX),r=Math.abs(e.deltaY),n=Math.abs(t.deltaX),o=Math.abs(t.deltaY),a=Math.max(Math.min(s,n),1),l=Math.max(Math.min(r,o),1),h=Math.max(s,n),c=Math.max(r,o);h%a==0&&c%l==0&&(i-=.5)}return Math.min(Math.max(i,0),1)}_isAlmostInt(e){return Math.abs(Math.round(e)-e)<.01}}t.MouseWheelClassifier=S;class b extends u.Widget{get options(){return this._options}constructor(e,t,i){super(),this._onScroll=this._register(new f.Emitter),this.onScroll=this._onScroll.event,this._onWillScroll=this._register(new f.Emitter),this.onWillScroll=this._onWillScroll.event,this._options=function(e){const t={lazyRender:void 0!==e.lazyRender&&e.lazyRender,className:void 0!==e.className?e.className:\"\",useShadows:void 0===e.useShadows||e.useShadows,handleMouseWheel:void 0===e.handleMouseWheel||e.handleMouseWheel,flipAxes:void 0!==e.flipAxes&&e.flipAxes,consumeMouseWheelIfScrollbarIsNeeded:void 0!==e.consumeMouseWheelIfScrollbarIsNeeded&&e.consumeMouseWheelIfScrollbarIsNeeded,alwaysConsumeMouseWheel:void 0!==e.alwaysConsumeMouseWheel&&e.alwaysConsumeMouseWheel,scrollYToX:void 0!==e.scrollYToX&&e.scrollYToX,mouseWheelScrollSensitivity:void 0!==e.mouseWheelScrollSensitivity?e.mouseWheelScrollSensitivity:1,fastScrollSensitivity:void 0!==e.fastScrollSensitivity?e.fastScrollSensitivity:5,scrollPredominantAxis:void 0===e.scrollPredominantAxis||e.scrollPredominantAxis,mouseWheelSmoothScroll:void 0===e.mouseWheelSmoothScroll||e.mouseWheelSmoothScroll,arrowSize:void 0!==e.arrowSize?e.arrowSize:11,listenOnDomNode:void 0!==e.listenOnDomNode?e.listenOnDomNode:null,horizontal:void 0!==e.horizontal?e.horizontal:m.ScrollbarVisibility.Auto,horizontalScrollbarSize:void 0!==e.horizontalScrollbarSize?e.horizontalScrollbarSize:10,horizontalSliderSize:void 0!==e.horizontalSliderSize?e.horizontalSliderSize:0,horizontalHasArrows:void 0!==e.horizontalHasArrows&&e.horizontalHasArrows,vertical:void 0!==e.vertical?e.vertical:m.ScrollbarVisibility.Auto,verticalScrollbarSize:void 0!==e.verticalScrollbarSize?e.verticalScrollbarSize:10,verticalHasArrows:void 0!==e.verticalHasArrows&&e.verticalHasArrows,verticalSliderSize:void 0!==e.verticalSliderSize?e.verticalSliderSize:0,scrollByPage:void 0!==e.scrollByPage&&e.scrollByPage};return t.horizontalSliderSize=void 0!==e.horizontalSliderSize?e.horizontalSliderSize:t.horizontalScrollbarSize,t.verticalSliderSize=void 0!==e.verticalSliderSize?e.verticalSliderSize:t.verticalScrollbarSize,g.isMacintosh&&(t.className+=\" mac\"),t}(t),this._scrollable=i,this._register(this._scrollable.onScroll((e=>{this._onWillScroll.fire(e),this._onDidScroll(e),this._onScroll.fire(e)})));const s={onMouseWheel:e=>this._onMouseWheel(e),onDragStart:()=>this._onDragStart(),onDragEnd:()=>this._onDragEnd()};this._verticalScrollbar=this._register(new d.VerticalScrollbar(this._scrollable,this._options,s)),this._horizontalScrollbar=this._register(new c.HorizontalScrollbar(this._scrollable,this._options,s)),this._domNode=document.createElement(\"div\"),this._domNode.className=\"xterm-scrollable-element \"+this._options.className,this._domNode.setAttribute(\"role\",\"presentation\"),this._domNode.style.position=\"relative\",this._domNode.appendChild(e),this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode),this._domNode.appendChild(this._verticalScrollbar.domNode.domNode),this._options.useShadows?(this._leftShadowDomNode=(0,l.createFastDomNode)(document.createElement(\"div\")),this._leftShadowDomNode.setClassName(\"shadow\"),this._domNode.appendChild(this._leftShadowDomNode.domNode),this._topShadowDomNode=(0,l.createFastDomNode)(document.createElement(\"div\")),this._topShadowDomNode.setClassName(\"shadow\"),this._domNode.appendChild(this._topShadowDomNode.domNode),this._topLeftShadowDomNode=(0,l.createFastDomNode)(document.createElement(\"div\")),this._topLeftShadowDomNode.setClassName(\"shadow\"),this._domNode.appendChild(this._topLeftShadowDomNode.domNode)):(this._leftShadowDomNode=null,this._topShadowDomNode=null,this._topLeftShadowDomNode=null),this._listenOnDomNode=this._options.listenOnDomNode||this._domNode,this._mouseWheelToDispose=[],this._setListeningToMouseWheel(this._options.handleMouseWheel),this.onmouseover(this._listenOnDomNode,(e=>this._onMouseOver(e))),this.onmouseleave(this._listenOnDomNode,(e=>this._onMouseLeave(e))),this._hideTimeout=this._register(new _.TimeoutTimer),this._isDragging=!1,this._mouseIsOver=!1,this._shouldRender=!0,this._revealOnScroll=!0}dispose(){this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),super.dispose()}getDomNode(){return this._domNode}getOverviewRulerLayoutInfo(){return{parent:this._domNode,insertBefore:this._verticalScrollbar.domNode.domNode}}delegateVerticalScrollbarPointerDown(e){this._verticalScrollbar.delegatePointerDown(e)}getScrollDimensions(){return this._scrollable.getScrollDimensions()}setScrollDimensions(e){this._scrollable.setScrollDimensions(e,!1)}updateClassName(e){this._options.className=e,g.isMacintosh&&(this._options.className+=\" mac\"),this._domNode.className=\"xterm-scrollable-element \"+this._options.className}updateOptions(e){void 0!==e.handleMouseWheel&&(this._options.handleMouseWheel=e.handleMouseWheel,this._setListeningToMouseWheel(this._options.handleMouseWheel)),void 0!==e.mouseWheelScrollSensitivity&&(this._options.mouseWheelScrollSensitivity=e.mouseWheelScrollSensitivity),void 0!==e.fastScrollSensitivity&&(this._options.fastScrollSensitivity=e.fastScrollSensitivity),void 0!==e.scrollPredominantAxis&&(this._options.scrollPredominantAxis=e.scrollPredominantAxis),void 0!==e.horizontal&&(this._options.horizontal=e.horizontal),void 0!==e.vertical&&(this._options.vertical=e.vertical),void 0!==e.horizontalScrollbarSize&&(this._options.horizontalScrollbarSize=e.horizontalScrollbarSize),void 0!==e.verticalScrollbarSize&&(this._options.verticalScrollbarSize=e.verticalScrollbarSize),void 0!==e.scrollByPage&&(this._options.scrollByPage=e.scrollByPage),this._horizontalScrollbar.updateOptions(this._options),this._verticalScrollbar.updateOptions(this._options),this._options.lazyRender||this._render()}setRevealOnScroll(e){this._revealOnScroll=e}delegateScrollFromMouseWheelEvent(e){this._onMouseWheel(new h.StandardWheelEvent(e))}_setListeningToMouseWheel(e){if(this._mouseWheelToDispose.length>0!==e&&(this._mouseWheelToDispose=(0,p.dispose)(this._mouseWheelToDispose),e)){const e=e=>{this._onMouseWheel(new h.StandardWheelEvent(e))};this._mouseWheelToDispose.push(a.addDisposableListener(this._listenOnDomNode,a.EventType.MOUSE_WHEEL,e,{passive:!1}))}}_onMouseWheel(e){if(e.browserEvent?.defaultPrevented)return;const t=S.INSTANCE;t.acceptStandardWheelEvent(e);let i=!1;if(e.deltaY||e.deltaX){let s=e.deltaY*this._options.mouseWheelScrollSensitivity,r=e.deltaX*this._options.mouseWheelScrollSensitivity;this._options.scrollPredominantAxis&&(this._options.scrollYToX&&r+s===0?r=s=0:Math.abs(s)>=Math.abs(r)?r=0:s=0),this._options.flipAxes&&([s,r]=[r,s]);const n=!g.isMacintosh&&e.browserEvent&&e.browserEvent.shiftKey;!this._options.scrollYToX&&!n||r||(r=s,s=0),e.browserEvent&&e.browserEvent.altKey&&(r*=this._options.fastScrollSensitivity,s*=this._options.fastScrollSensitivity);const o=this._scrollable.getFutureScrollPosition();let a={};if(s){const e=50*s,t=o.scrollTop-(e<0?Math.floor(e):Math.ceil(e));this._verticalScrollbar.writeScrollPosition(a,t)}if(r){const e=50*r,t=o.scrollLeft-(e<0?Math.floor(e):Math.ceil(e));this._horizontalScrollbar.writeScrollPosition(a,t)}a=this._scrollable.validateScrollPosition(a),(o.scrollLeft!==a.scrollLeft||o.scrollTop!==a.scrollTop)&&(this._options.mouseWheelSmoothScroll&&t.isPhysicalMouseWheel()?this._scrollable.setScrollPositionSmooth(a):this._scrollable.setScrollPositionNow(a),i=!0)}let s=i;!s&&this._options.alwaysConsumeMouseWheel&&(s=!0),!s&&this._options.consumeMouseWheelIfScrollbarIsNeeded&&(this._verticalScrollbar.isNeeded()||this._horizontalScrollbar.isNeeded())&&(s=!0),s&&(e.preventDefault(),e.stopPropagation())}_onDidScroll(e){this._shouldRender=this._horizontalScrollbar.onDidScroll(e)||this._shouldRender,this._shouldRender=this._verticalScrollbar.onDidScroll(e)||this._shouldRender,this._options.useShadows&&(this._shouldRender=!0),this._revealOnScroll&&this._reveal(),this._options.lazyRender||this._render()}renderNow(){if(!this._options.lazyRender)throw new Error(\"Please use `lazyRender` together with `renderNow`!\");this._render()}_render(){if(this._shouldRender&&(this._shouldRender=!1,this._horizontalScrollbar.render(),this._verticalScrollbar.render(),this._options.useShadows)){const e=this._scrollable.getCurrentScrollPosition(),t=e.scrollTop>0,i=e.scrollLeft>0,s=i?\" left\":\"\",r=t?\" top\":\"\",n=i||t?\" top-left-corner\":\"\";this._leftShadowDomNode.setClassName(`shadow${s}`),this._topShadowDomNode.setClassName(`shadow${r}`),this._topLeftShadowDomNode.setClassName(`shadow${n}${r}${s}`)}}_onDragStart(){this._isDragging=!0,this._reveal()}_onDragEnd(){this._isDragging=!1,this._hide()}_onMouseLeave(e){this._mouseIsOver=!1,this._hide()}_onMouseOver(e){this._mouseIsOver=!0,this._reveal()}_reveal(){this._verticalScrollbar.beginReveal(),this._horizontalScrollbar.beginReveal(),this._scheduleHide()}_hide(){this._mouseIsOver||this._isDragging||(this._verticalScrollbar.beginHide(),this._horizontalScrollbar.beginHide())}_scheduleHide(){this._mouseIsOver||this._isDragging||this._hideTimeout.cancelAndSet((()=>this._hide()),500)}}t.AbstractScrollableElement=b,t.ScrollableElement=class extends b{constructor(e,t){(t=t||{}).mouseWheelSmoothScroll=!1;const i=new m.Scrollable({forceIntegerValues:!0,smoothScrollDuration:0,scheduleAtNextAnimationFrame:t=>a.scheduleAtNextAnimationFrame(a.getWindow(e),t)});super(e,t,i),this._register(i)}setScrollPosition(e){this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}},t.SmoothScrollableElement=class extends b{constructor(e,t,i){super(e,t,i)}setScrollPosition(e){e.reuseAnimation?this._scrollable.setScrollPositionSmooth(e,e.reuseAnimation):this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}},t.DomScrollableElement=class extends b{constructor(e,t){(t=t||{}).mouseWheelSmoothScroll=!1;const i=new m.Scrollable({forceIntegerValues:!1,smoothScrollDuration:0,scheduleAtNextAnimationFrame:t=>a.scheduleAtNextAnimationFrame(a.getWindow(e),t)});super(e,t,i),this._register(i),this._element=e,this._register(this.onScroll((e=>{e.scrollTopChanged&&(this._element.scrollTop=e.scrollTop),e.scrollLeftChanged&&(this._element.scrollLeft=e.scrollLeft)}))),this.scanDomNode()}setScrollPosition(e){this._scrollable.setScrollPositionNow(e)}getScrollPosition(){return this._scrollable.getCurrentScrollPosition()}scanDomNode(){this.setScrollDimensions({width:this._element.clientWidth,scrollWidth:this._element.scrollWidth,height:this._element.clientHeight,scrollHeight:this._element.scrollHeight}),this.setScrollPosition({scrollLeft:this._element.scrollLeft,scrollTop:this._element.scrollTop})}}},8974:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.ScrollbarArrow=t.ARROW_IMG_SIZE=void 0;const o=i(8328),a=i(8286),l=i(1758),h=n(i(7093));t.ARROW_IMG_SIZE=11;class c extends a.Widget{constructor(e){super(),this._onActivate=e.onActivate,this.bgDomNode=document.createElement(\"div\"),this.bgDomNode.className=\"arrow-background\",this.bgDomNode.style.position=\"absolute\",this.bgDomNode.style.width=e.bgWidth+\"px\",this.bgDomNode.style.height=e.bgHeight+\"px\",void 0!==e.top&&(this.bgDomNode.style.top=\"0px\"),void 0!==e.left&&(this.bgDomNode.style.left=\"0px\"),void 0!==e.bottom&&(this.bgDomNode.style.bottom=\"0px\"),void 0!==e.right&&(this.bgDomNode.style.right=\"0px\"),this.domNode=document.createElement(\"div\"),this.domNode.className=e.className,this.domNode.style.position=\"absolute\",this.domNode.style.width=t.ARROW_IMG_SIZE+\"px\",this.domNode.style.height=t.ARROW_IMG_SIZE+\"px\",void 0!==e.top&&(this.domNode.style.top=e.top+\"px\"),void 0!==e.left&&(this.domNode.style.left=e.left+\"px\"),void 0!==e.bottom&&(this.domNode.style.bottom=e.bottom+\"px\"),void 0!==e.right&&(this.domNode.style.right=e.right+\"px\"),this._pointerMoveMonitor=this._register(new o.GlobalPointerMoveMonitor),this._register(h.addStandardDisposableListener(this.bgDomNode,h.EventType.POINTER_DOWN,(e=>this._arrowPointerDown(e)))),this._register(h.addStandardDisposableListener(this.domNode,h.EventType.POINTER_DOWN,(e=>this._arrowPointerDown(e)))),this._pointerdownRepeatTimer=this._register(new h.WindowIntervalTimer),this._pointerdownScheduleRepeatTimer=this._register(new l.TimeoutTimer)}_arrowPointerDown(e){e.target&&e.target instanceof Element&&(this._onActivate(),this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancelAndSet((()=>{this._pointerdownRepeatTimer.cancelAndSet((()=>this._onActivate()),1e3/24,h.getWindow(e))}),200),this._pointerMoveMonitor.startMonitoring(e.target,e.pointerId,e.buttons,(e=>{}),(()=>{this._pointerdownRepeatTimer.cancel(),this._pointerdownScheduleRepeatTimer.cancel()})),e.preventDefault())}}t.ScrollbarArrow=c},8245:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ScrollbarState=void 0;class i{constructor(e,t,i,s,r,n){this._scrollbarSize=Math.round(t),this._oppositeScrollbarSize=Math.round(i),this._arrowSize=Math.round(e),this._visibleSize=s,this._scrollSize=r,this._scrollPosition=n,this._computedAvailableSize=0,this._computedIsNeeded=!1,this._computedSliderSize=0,this._computedSliderRatio=0,this._computedSliderPosition=0,this._refreshComputedValues()}clone(){return new i(this._arrowSize,this._scrollbarSize,this._oppositeScrollbarSize,this._visibleSize,this._scrollSize,this._scrollPosition)}setVisibleSize(e){const t=Math.round(e);return this._visibleSize!==t&&(this._visibleSize=t,this._refreshComputedValues(),!0)}setScrollSize(e){const t=Math.round(e);return this._scrollSize!==t&&(this._scrollSize=t,this._refreshComputedValues(),!0)}setScrollPosition(e){const t=Math.round(e);return this._scrollPosition!==t&&(this._scrollPosition=t,this._refreshComputedValues(),!0)}setScrollbarSize(e){this._scrollbarSize=Math.round(e)}setOppositeScrollbarSize(e){this._oppositeScrollbarSize=Math.round(e)}static _computeValues(e,t,i,s,r){const n=Math.max(0,i-e),o=Math.max(0,n-2*t),a=s>0&&s>i;if(!a)return{computedAvailableSize:Math.round(n),computedIsNeeded:a,computedSliderSize:Math.round(o),computedSliderRatio:0,computedSliderPosition:0};const l=Math.round(Math.max(20,Math.floor(i*o/s))),h=(o-l)/(s-i),c=r*h;return{computedAvailableSize:Math.round(n),computedIsNeeded:a,computedSliderSize:Math.round(l),computedSliderRatio:h,computedSliderPosition:Math.round(c)}}_refreshComputedValues(){const e=i._computeValues(this._oppositeScrollbarSize,this._arrowSize,this._visibleSize,this._scrollSize,this._scrollPosition);this._computedAvailableSize=e.computedAvailableSize,this._computedIsNeeded=e.computedIsNeeded,this._computedSliderSize=e.computedSliderSize,this._computedSliderRatio=e.computedSliderRatio,this._computedSliderPosition=e.computedSliderPosition}getArrowSize(){return this._arrowSize}getScrollPosition(){return this._scrollPosition}getRectangleLargeSize(){return this._computedAvailableSize}getRectangleSmallSize(){return this._scrollbarSize}isNeeded(){return this._computedIsNeeded}getSliderSize(){return this._computedSliderSize}getSliderPosition(){return this._computedSliderPosition}getDesiredScrollPositionFromOffset(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize-this._computedSliderSize/2;return Math.round(t/this._computedSliderRatio)}getDesiredScrollPositionFromOffsetPaged(e){if(!this._computedIsNeeded)return 0;const t=e-this._arrowSize;let i=this._scrollPosition;return t{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ScrollbarVisibilityController=void 0;const s=i(1758),r=i(7150),n=i(9881);class o extends r.Disposable{constructor(e,t,i){super(),this._visibility=e,this._visibleClassName=t,this._invisibleClassName=i,this._domNode=null,this._isVisible=!1,this._isNeeded=!1,this._rawShouldBeVisible=!1,this._shouldBeVisible=!1,this._revealTimer=this._register(new s.TimeoutTimer)}setVisibility(e){this._visibility!==e&&(this._visibility=e,this._updateShouldBeVisible())}setShouldBeVisible(e){this._rawShouldBeVisible=e,this._updateShouldBeVisible()}_applyVisibilitySetting(){return this._visibility!==n.ScrollbarVisibility.Hidden&&(this._visibility===n.ScrollbarVisibility.Visible||this._rawShouldBeVisible)}_updateShouldBeVisible(){const e=this._applyVisibilitySetting();this._shouldBeVisible!==e&&(this._shouldBeVisible=e,this.ensureVisibility())}setIsNeeded(e){this._isNeeded!==e&&(this._isNeeded=e,this.ensureVisibility())}setDomNode(e){this._domNode=e,this._domNode.setClassName(this._invisibleClassName),this.setShouldBeVisible(!1)}ensureVisibility(){this._isNeeded?this._shouldBeVisible?this._reveal():this._hide(!0):this._hide(!1)}_reveal(){this._isVisible||(this._isVisible=!0,this._revealTimer.setIfNotSet((()=>{this._domNode?.setClassName(this._visibleClassName)}),0))}_hide(e){this._revealTimer.cancel(),this._isVisible&&(this._isVisible=!1,this._domNode?.setClassName(this._invisibleClassName+(e?\" fade\":\"\")))}}t.ScrollbarVisibilityController=o},5473:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.VerticalScrollbar=void 0;const s=i(8801),r=i(8245),n=i(9881);class o extends s.AbstractScrollbar{constructor(e,t,i){const s=e.getScrollDimensions(),o=e.getCurrentScrollPosition();if(super({lazyRender:t.lazyRender,host:i,scrollbarState:new r.ScrollbarState(t.verticalHasArrows?t.arrowSize:0,t.vertical===n.ScrollbarVisibility.Hidden?0:t.verticalScrollbarSize,0,s.height,s.scrollHeight,o.scrollTop),visibility:t.vertical,extraScrollbarClassName:\"vertical\",scrollable:e,scrollByPage:t.scrollByPage}),t.verticalHasArrows)throw new Error(\"horizontalHasArrows is not supported in xterm.js\");this._createSlider(0,Math.floor((t.verticalScrollbarSize-t.verticalSliderSize)/2),t.verticalSliderSize,void 0)}_updateSlider(e,t){this.slider.setHeight(e),this.slider.setTop(t)}_renderDomNode(e,t){this.domNode.setWidth(t),this.domNode.setHeight(e),this.domNode.setRight(0),this.domNode.setTop(0)}onDidScroll(e){return this._shouldRender=this._onElementScrollSize(e.scrollHeight)||this._shouldRender,this._shouldRender=this._onElementScrollPosition(e.scrollTop)||this._shouldRender,this._shouldRender=this._onElementSize(e.height)||this._shouldRender,this._shouldRender}_pointerDownRelativePosition(e,t){return t}_sliderPointerPosition(e){return e.pageY}_sliderOrthogonalPointerPosition(e){return e.pageX}_updateScrollbarSize(e){this.slider.setWidth(e)}writeScrollPosition(e,t){e.scrollTop=t}updateOptions(e){this.updateScrollbarSize(e.vertical===n.ScrollbarVisibility.Hidden?0:e.verticalScrollbarSize),this._scrollbarState.setOppositeScrollbarSize(0),this._visibilityController.setVisibility(e.vertical),this._scrollByPage=e.scrollByPage}}t.VerticalScrollbar=o},8286:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.Widget=void 0;const o=n(i(7093)),a=i(5394),l=i(5964),h=i(8594),c=i(7150);class d extends c.Disposable{onclick(e,t){this._register(o.addDisposableListener(e,o.EventType.CLICK,(i=>t(new l.StandardMouseEvent(o.getWindow(e),i)))))}onmousedown(e,t){this._register(o.addDisposableListener(e,o.EventType.MOUSE_DOWN,(i=>t(new l.StandardMouseEvent(o.getWindow(e),i)))))}onmouseover(e,t){this._register(o.addDisposableListener(e,o.EventType.MOUSE_OVER,(i=>t(new l.StandardMouseEvent(o.getWindow(e),i)))))}onmouseleave(e,t){this._register(o.addDisposableListener(e,o.EventType.MOUSE_LEAVE,(i=>t(new l.StandardMouseEvent(o.getWindow(e),i)))))}onkeydown(e,t){this._register(o.addDisposableListener(e,o.EventType.KEY_DOWN,(e=>t(new a.StandardKeyboardEvent(e)))))}onkeyup(e,t){this._register(o.addDisposableListener(e,o.EventType.KEY_UP,(e=>t(new a.StandardKeyboardEvent(e)))))}oninput(e,t){this._register(o.addDisposableListener(e,o.EventType.INPUT,t))}onblur(e,t){this._register(o.addDisposableListener(e,o.EventType.BLUR,t))}onfocus(e,t){this._register(o.addDisposableListener(e,o.EventType.FOCUS,t))}onchange(e,t){this._register(o.addDisposableListener(e,o.EventType.CHANGE,t))}ignoreGesture(e){return h.Gesture.ignoreTarget(e)}}t.Widget=d},4693:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.mainWindow=void 0,t.ensureCodeWindow=function(e,t){},t.mainWindow=\"object\"==typeof window?window:globalThis},3058:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Permutation=t.CallbackIterable=t.ArrayQueue=t.booleanComparator=t.numberComparator=t.CompareResult=void 0,t.tail=function(e,t=0){return e[e.length-(1+t)]},t.tail2=function(e){if(0===e.length)throw new Error(\"Invalid tail call\");return[e.slice(0,e.length-1),e[e.length-1]]},t.equals=function(e,t,i=(e,t)=>e===t){if(e===t)return!0;if(!e||!t)return!1;if(e.length!==t.length)return!1;for(let s=0,r=e.length;si(e[s],t)))},t.binarySearch2=n,t.quickSelect=function e(t,i,s){if((t|=0)>=i.length)throw new TypeError(\"invalid index\");const r=i[Math.floor(i.length*Math.random())],n=[],o=[],a=[];for(const e of i){const t=s(e,r);t<0?n.push(e):t>0?o.push(e):a.push(e)}return t{(async()=>{const o=e.length,l=e.slice(0,i).sort(t);for(let h=i,c=Math.min(i+r,o);hi&&await new Promise((e=>setTimeout(e))),n&&n.isCancellationRequested)throw new s.CancellationError;a(e,t,l,h,c)}return l})().then(o,l)}))},t.coalesce=function(e){return e.filter((e=>!!e))},t.coalesceInPlace=function(e){let t=0;for(let i=0;i0},t.distinct=function(e,t=e=>e){const i=new Set;return e.filter((e=>{const s=t(e);return!i.has(s)&&(i.add(s),!0)}))},t.uniqueFilter=function(e){const t=new Set;return i=>{const s=e(i);return!t.has(s)&&(t.add(s),!0)}},t.firstOrDefault=function(e,t){return e.length>0?e[0]:t},t.lastOrDefault=function(e,t){return e.length>0?e[e.length-1]:t},t.commonPrefixLength=function(e,t,i=(e,t)=>e===t){let s=0;for(let r=0,n=Math.min(e.length,t.length);rt;e--)s.push(e);return s},t.index=function(e,t,i){return e.reduce(((e,s)=>(e[t(s)]=i?i(s):s,e)),Object.create(null))},t.insert=function(e,t){return e.push(t),()=>l(e,t)},t.remove=l,t.arrayInsert=function(e,t,i){const s=e.slice(0,t),r=e.slice(t);return s.concat(i,r)},t.shuffle=function(e,t){let i;if(\"number\"==typeof t){let e=t;i=()=>{const t=179426549*Math.sin(e++);return t-Math.floor(t)}}else i=Math.random;for(let t=e.length-1;t>0;t-=1){const s=Math.floor(i()*(t+1)),r=e[t];e[t]=e[s],e[s]=r}},t.pushToStart=function(e,t){const i=e.indexOf(t);i>-1&&(e.splice(i,1),e.unshift(t))},t.pushToEnd=function(e,t){const i=e.indexOf(t);i>-1&&(e.splice(i,1),e.push(t))},t.pushMany=function(e,t){for(const i of t)e.push(i)},t.mapArrayOrNot=function(e,t){return Array.isArray(e)?e.map(t):t(e)},t.asArray=function(e){return Array.isArray(e)?e:[e]},t.getRandomElement=function(e){return e[Math.floor(Math.random()*e.length)]},t.insertInto=h,t.splice=function(e,t,i,s){const r=c(e,t);let n=e.splice(r,i);return void 0===n&&(n=[]),h(e,r,s),n},t.compareBy=function(e,t){return(i,s)=>t(e(i),e(s))},t.tieBreakComparators=function(...e){return(t,i)=>{for(const s of e){const e=s(t,i);if(!d.isNeitherLessOrGreaterThan(e))return e}return d.neitherLessOrGreaterThan}},t.reverseOrder=function(e){return(t,i)=>-e(t,i)};const s=i(9807),r=i(8297);function n(e,t){let i=0,s=e-1;for(;i<=s;){const e=(i+s)/2|0,r=t(e);if(r<0)i=e+1;else{if(!(r>0))return e;s=e-1}}return-(i+1)}function o(e,t,i){const s=[];function r(e,t,i){if(0===t&&0===i.length)return;const r=s[s.length-1];r&&r.start+r.deleteCount===e?(r.deleteCount+=t,r.toInsert.push(...i)):s.push({start:e,deleteCount:t,toInsert:i})}let n=0,o=0;for(;;){if(n===e.length){r(n,0,t.slice(o));break}if(o===t.length){r(n,e.length-n,[]);break}const s=e[n],a=t[o],l=i(s,a);0===l?(n+=1,o+=1):l<0?(r(n,1,[]),n+=1):l>0&&(r(n,0,[a]),o+=1)}return s}function a(e,t,i,s,n){for(const o=i.length;st(n,e)<0));i.splice(e,0,n)}}}function l(e,t){const i=e.indexOf(t);if(i>-1)return e.splice(i,1),t}function h(e,t,i){const s=c(e,t),r=e.length,n=i.length;e.length=r+n;for(let t=r-1;t>=s;t--)e[t+n]=e[t];for(let t=0;t0},e.isNeitherLessOrGreaterThan=function(e){return 0===e},e.greaterThan=1,e.lessThan=-1,e.neitherLessOrGreaterThan=0}(d||(t.CompareResult=d={})),t.numberComparator=(e,t)=>e-t,t.booleanComparator=(e,i)=>(0,t.numberComparator)(e?1:0,i?1:0),t.ArrayQueue=class{constructor(e){this.items=e,this.firstIdx=0,this.lastIdx=this.items.length-1}get length(){return this.lastIdx-this.firstIdx+1}takeWhile(e){let t=this.firstIdx;for(;t=0&&e(this.items[t]);)t--;const i=t===this.lastIdx?null:this.items.slice(t+1,this.lastIdx+1);return this.lastIdx=t,i}peek(){if(0!==this.length)return this.items[this.firstIdx]}peekLast(){if(0!==this.length)return this.items[this.lastIdx]}dequeue(){const e=this.items[this.firstIdx];return this.firstIdx++,e}removeLast(){const e=this.items[this.lastIdx];return this.lastIdx--,e}takeCount(e){const t=this.items.slice(this.firstIdx,this.firstIdx+e);return this.firstIdx+=e,t}};class u{static{this.empty=new u((e=>{}))}constructor(e){this.iterate=e}forEach(e){this.iterate((t=>(e(t),!0)))}toArray(){const e=[];return this.iterate((t=>(e.push(t),!0))),e}filter(e){return new u((t=>this.iterate((i=>!e(i)||t(i)))))}map(e){return new u((t=>this.iterate((i=>t(e(i))))))}some(e){let t=!1;return this.iterate((i=>(t=e(i),!t))),t}findFirst(e){let t;return this.iterate((i=>!e(i)||(t=i,!1))),t}findLast(e){let t;return this.iterate((i=>(e(i)&&(t=i),!0))),t}findLastMaxBy(e){let t,i=!0;return this.iterate((s=>((i||d.isGreaterThan(e(s,t)))&&(i=!1,t=s),!0))),t}}t.CallbackIterable=u;class _{constructor(e){this._indexMap=e}static createSortPermutation(e,t){const i=Array.from(e.keys()).sort(((i,s)=>t(e[i],e[s])));return new _(i)}apply(e){return e.map(((t,i)=>e[this._indexMap[i]]))}inverse(){const e=this._indexMap.slice();for(let t=0;t{function i(e,t,i=e.length-1){for(let s=i;s>=0;s--)if(t(e[s]))return s;return-1}function s(e,t,i=0,s=e.length){let r=i,n=s;for(;r=0&&(i=r)}return i},t.findFirstMin=function(e,t){return o(e,((e,i)=>-t(e,i)))},t.findMaxIdx=function(e,t){if(0===e.length)return-1;let i=0;for(let s=1;s0&&(i=s);return i},t.mapFindFirst=function(e,t){for(const i of e){const e=t(i);if(void 0!==e)return e}};class n{static{this.assertInvariants=!1}constructor(e){this._array=e,this._findLastMonotonousLastIdx=0}findLastMonotonous(e){if(n.assertInvariants){if(this._prevFindLastPredicate)for(const t of this._array)if(this._prevFindLastPredicate(t)&&!e(t))throw new Error(\"MonotonousArray: current predicate must be weaker than (or equal to) the previous predicate.\");this._prevFindLastPredicate=e}const t=s(this._array,e,this._findLastMonotonousLastIdx);return this._findLastMonotonousLastIdx=t+1,-1===t?void 0:this._array[t]}}function o(e,t){if(0===e.length)return;let i=e[0];for(let s=1;s0&&(i=r)}return i}t.MonotonousArray=n},1758:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.AsyncIterableSource=t.CancelableAsyncIterableObject=t.AsyncIterableObject=t.LazyStatefulPromise=t.StatefulPromise=t.Promises=t.DeferredPromise=t.IntervalCounter=t.TaskSequentializer=t.GlobalIdleValue=t.AbstractIdleValue=t._runWhenIdle=t.runWhenGlobalIdle=t.ThrottledWorker=t.RunOnceWorker=t.ProcessTimeRunOnceScheduler=t.RunOnceScheduler=t.IntervalTimer=t.TimeoutTimer=t.LimitedQueue=t.Queue=t.Limiter=t.AutoOpenBarrier=t.Barrier=t.ThrottledDelayer=t.Delayer=t.SequencerByKey=t.Sequencer=t.Throttler=void 0,t.isThenable=c,t.createCancelablePromise=d,t.raceCancellation=function(e,t,i){return new Promise(((s,r)=>{const n=t.onCancellationRequested((()=>{n.dispose(),s(i)}));e.then(s,r).finally((()=>n.dispose()))}))},t.raceCancellationError=function(e,t){return new Promise(((i,s)=>{const n=t.onCancellationRequested((()=>{n.dispose(),s(new r.CancellationError)}));e.then(i,s).finally((()=>n.dispose()))}))},t.raceCancellablePromises=async function(e){let t=-1;const i=e.map(((e,i)=>e.then((e=>(t=i,e)))));try{return await Promise.race(i)}finally{e.forEach(((e,i)=>{i!==t&&e.cancel()}))}},t.raceTimeout=function(e,t,i){let s;const r=setTimeout((()=>{s?.(void 0),i?.()}),t);return Promise.race([e.finally((()=>clearTimeout(r))),new Promise((e=>s=e))])},t.asPromise=function(e){return new Promise(((t,i)=>{const s=e();c(s)?s.then(t,i):t(s)}))},t.promiseWithResolvers=u,t.timeout=g,t.disposableTimeout=function(e,t=0,i){const s=setTimeout((()=>{e(),i&&r.dispose()}),t),r=(0,o.toDisposable)((()=>{clearTimeout(s),i?.deleteAndLeak(r)}));return i?.add(r),r},t.sequence=function(e){const t=[];let i=0;const s=e.length;return Promise.resolve(null).then((function r(n){null!=n&&t.push(n);const o=i!!e,i=null){let s=0;const r=e.length,n=()=>{if(s>=r)return Promise.resolve(i);const o=e[s++];return Promise.resolve(o()).then((e=>t(e)?Promise.resolve(e):n()))};return n()},t.firstParallel=function(e,t=e=>!!e,i=null){if(0===e.length)return Promise.resolve(i);let s=e.length;const r=()=>{s=-1;for(const t of e)t.cancel?.()};return new Promise(((n,o)=>{for(const a of e)a.then((e=>{--s>=0&&t(e)?(r(),n(e)):0===s&&n(i)})).catch((e=>{--s>=0&&(r(),o(e))}))}))},t.retry=async function(e,t,i){let s;for(let r=0;r{const s=t.token.onCancellationRequested((()=>{s.dispose(),t.dispose(),e.reject(new r.CancellationError)}));try{for await(const s of i){if(t.token.isCancellationRequested)return;e.emitOne(s)}s.dispose(),t.dispose()}catch(i){s.dispose(),t.dispose(),e.reject(i)}}))};const s=i(8447),r=i(9807),n=i(802),o=i(7150),a=i(8163),l=i(5015),h=i(626);function c(e){return!!e&&\"function\"==typeof e.then}function d(e){const t=new s.CancellationTokenSource,i=e(t.token),n=new Promise(((e,s)=>{const n=t.token.onCancellationRequested((()=>{n.dispose(),s(new r.CancellationError)}));Promise.resolve(i).then((i=>{n.dispose(),t.dispose(),e(i)}),(e=>{n.dispose(),t.dispose(),s(e)}))}));return new class{cancel(){t.cancel(),t.dispose()}then(e,t){return n.then(e,t)}catch(e){return this.then(void 0,e)}finally(e){return n.finally(e)}}}function u(){let e,t;return{promise:new Promise(((i,s)=>{e=i,t=s})),resolve:e,reject:t}}class _{constructor(){this.isDisposed=!1,this.activePromise=null,this.queuedPromise=null,this.queuedPromiseFactory=null}queue(e){if(this.isDisposed)return Promise.reject(new Error(\"Throttler is disposed\"));if(this.activePromise){if(this.queuedPromiseFactory=e,!this.queuedPromise){const e=()=>{if(this.queuedPromise=null,this.isDisposed)return;const e=this.queue(this.queuedPromiseFactory);return this.queuedPromiseFactory=null,e};this.queuedPromise=new Promise((t=>{this.activePromise.then(e,e).then(t)}))}return new Promise(((e,t)=>{this.queuedPromise.then(e,t)}))}return this.activePromise=e(),new Promise(((e,t)=>{this.activePromise.then((t=>{this.activePromise=null,e(t)}),(e=>{this.activePromise=null,t(e)}))}))}dispose(){this.isDisposed=!0}}t.Throttler=_,t.Sequencer=class{constructor(){this.current=Promise.resolve(null)}queue(e){return this.current=this.current.then((()=>e()),(()=>e()))}},t.SequencerByKey=class{constructor(){this.promiseMap=new Map}queue(e,t){const i=(this.promiseMap.get(e)??Promise.resolve()).catch((()=>{})).then(t).finally((()=>{this.promiseMap.get(e)===i&&this.promiseMap.delete(e)}));return this.promiseMap.set(e,i),i}};class f{constructor(e){this.defaultDelay=e,this.deferred=null,this.completionPromise=null,this.doResolve=null,this.doReject=null,this.task=null}trigger(e,t=this.defaultDelay){this.task=e,this.cancelTimeout(),this.completionPromise||(this.completionPromise=new Promise(((e,t)=>{this.doResolve=e,this.doReject=t})).then((()=>{if(this.completionPromise=null,this.doResolve=null,this.task){const e=this.task;return this.task=null,e()}})));const i=()=>{this.deferred=null,this.doResolve?.(null)};return this.deferred=t===l.MicrotaskDelay?(e=>{let t=!0;return queueMicrotask((()=>{t&&(t=!1,e())})),{isTriggered:()=>t,dispose:()=>{t=!1}}})(i):((e,t)=>{let i=!0;const s=setTimeout((()=>{i=!1,t()}),e);return{isTriggered:()=>i,dispose:()=>{clearTimeout(s),i=!1}}})(t,i),this.completionPromise}isTriggered(){return!!this.deferred?.isTriggered()}cancel(){this.cancelTimeout(),this.completionPromise&&(this.doReject?.(new r.CancellationError),this.completionPromise=null)}cancelTimeout(){this.deferred?.dispose(),this.deferred=null}dispose(){this.cancel()}}t.Delayer=f,t.ThrottledDelayer=class{constructor(e){this.delayer=new f(e),this.throttler=new _}trigger(e,t){return this.delayer.trigger((()=>this.throttler.queue(e)),t)}isTriggered(){return this.delayer.isTriggered()}cancel(){this.delayer.cancel()}dispose(){this.delayer.dispose(),this.throttler.dispose()}};class p{constructor(){this._isOpen=!1,this._promise=new Promise(((e,t)=>{this._completePromise=e}))}isOpen(){return this._isOpen}open(){this._isOpen=!0,this._completePromise(!0)}wait(){return this._promise}}function g(e,t){return t?new Promise(((i,s)=>{const n=setTimeout((()=>{o.dispose(),i()}),e),o=t.onCancellationRequested((()=>{clearTimeout(n),o.dispose(),s(new r.CancellationError)}))})):d((t=>g(e,t)))}t.Barrier=p,t.AutoOpenBarrier=class extends p{constructor(e){super(),this._timeout=setTimeout((()=>this.open()),e)}open(){clearTimeout(this._timeout),super.open()}};class m{constructor(e){this._size=0,this._isDisposed=!1,this.maxDegreeOfParalellism=e,this.outstandingPromises=[],this.runningPromises=0,this._onDrained=new n.Emitter}whenIdle(){return this.size>0?n.Event.toPromise(this.onDrained):Promise.resolve()}get onDrained(){return this._onDrained.event}get size(){return this._size}queue(e){if(this._isDisposed)throw new Error(\"Object has been disposed\");return this._size++,new Promise(((t,i)=>{this.outstandingPromises.push({factory:e,c:t,e:i}),this.consume()}))}consume(){for(;this.outstandingPromises.length&&this.runningPromisesthis.consumed()),(()=>this.consumed()))}}consumed(){this._isDisposed||(this.runningPromises--,0==--this._size&&this._onDrained.fire(),this.outstandingPromises.length>0&&this.consume())}clear(){if(this._isDisposed)throw new Error(\"Object has been disposed\");this.outstandingPromises.length=0,this._size=this.runningPromises}dispose(){this._isDisposed=!0,this.outstandingPromises.length=0,this._size=0,this._onDrained.dispose()}}t.Limiter=m,t.Queue=class extends m{constructor(){super(1)}},t.LimitedQueue=class{constructor(){this.sequentializer=new C,this.tasks=0}queue(e){return this.sequentializer.isRunning()?this.sequentializer.queue((()=>this.sequentializer.run(this.tasks++,e()))):this.sequentializer.run(this.tasks++,e())}},t.TimeoutTimer=class{constructor(e,t){this._isDisposed=!1,this._token=-1,\"function\"==typeof e&&\"number\"==typeof t&&this.setIfNotSet(e,t)}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new r.BugIndicatingError(\"Calling 'cancelAndSet' on a disposed TimeoutTimer\");this.cancel(),this._token=setTimeout((()=>{this._token=-1,e()}),t)}setIfNotSet(e,t){if(this._isDisposed)throw new r.BugIndicatingError(\"Calling 'setIfNotSet' on a disposed TimeoutTimer\");-1===this._token&&(this._token=setTimeout((()=>{this._token=-1,e()}),t))}},t.IntervalTimer=class{constructor(){this.disposable=void 0,this.isDisposed=!1}cancel(){this.disposable?.dispose(),this.disposable=void 0}cancelAndSet(e,t,i=globalThis){if(this.isDisposed)throw new r.BugIndicatingError(\"Calling 'cancelAndSet' on a disposed IntervalTimer\");this.cancel();const s=i.setInterval((()=>{e()}),t);this.disposable=(0,o.toDisposable)((()=>{i.clearInterval(s),this.disposable=void 0}))}dispose(){this.cancel(),this.isDisposed=!0}};class v{constructor(e,t){this.timeoutToken=-1,this.runner=e,this.timeout=t,this.timeoutHandler=this.onTimeout.bind(this)}dispose(){this.cancel(),this.runner=null}cancel(){this.isScheduled()&&(clearTimeout(this.timeoutToken),this.timeoutToken=-1)}schedule(e=this.timeout){this.cancel(),this.timeoutToken=setTimeout(this.timeoutHandler,e)}get delay(){return this.timeout}set delay(e){this.timeout=e}isScheduled(){return-1!==this.timeoutToken}flush(){this.isScheduled()&&(this.cancel(),this.doRun())}onTimeout(){this.timeoutToken=-1,this.runner&&this.doRun()}doRun(){this.runner?.()}}t.RunOnceScheduler=v,t.ProcessTimeRunOnceScheduler=class{constructor(e,t){t%1e3!=0&&console.warn(`ProcessTimeRunOnceScheduler resolution is 1s, ${t}ms is not a multiple of 1000ms.`),this.runner=e,this.timeout=t,this.counter=0,this.intervalToken=-1,this.intervalHandler=this.onInterval.bind(this)}dispose(){this.cancel(),this.runner=null}cancel(){this.isScheduled()&&(clearInterval(this.intervalToken),this.intervalToken=-1)}schedule(e=this.timeout){e%1e3!=0&&console.warn(`ProcessTimeRunOnceScheduler resolution is 1s, ${e}ms is not a multiple of 1000ms.`),this.cancel(),this.counter=Math.ceil(e/1e3),this.intervalToken=setInterval(this.intervalHandler,1e3)}isScheduled(){return-1!==this.intervalToken}onInterval(){this.counter--,this.counter>0||(clearInterval(this.intervalToken),this.intervalToken=-1,this.runner?.())}},t.RunOnceWorker=class extends v{constructor(e,t){super(e,t),this.units=[]}work(e){this.units.push(e),this.isScheduled()||this.schedule()}doRun(){const e=this.units;this.units=[],this.runner?.(e)}dispose(){this.units=[],super.dispose()}};class S extends o.Disposable{constructor(e,t){super(),this.options=e,this.handler=t,this.pendingWork=[],this.throttler=this._register(new o.MutableDisposable),this.disposed=!1}get pending(){return this.pendingWork.length}work(e){if(this.disposed)return!1;if(\"number\"==typeof this.options.maxBufferedWork)if(this.throttler.value){if(this.pending+e.length>this.options.maxBufferedWork)return!1}else if(this.pending+e.length-this.options.maxWorkChunkSize>this.options.maxBufferedWork)return!1;for(const t of e)this.pendingWork.push(t);return this.throttler.value||this.doWork(),!0}doWork(){this.handler(this.pendingWork.splice(0,this.options.maxWorkChunkSize)),this.pendingWork.length>0&&(this.throttler.value=new v((()=>{this.throttler.clear(),this.doWork()}),this.options.throttleDelay),this.throttler.value.schedule())}dispose(){super.dispose(),this.disposed=!0}}t.ThrottledWorker=S,\"function\"!=typeof globalThis.requestIdleCallback||\"function\"!=typeof globalThis.cancelIdleCallback?t._runWhenIdle=(e,t)=>{(0,a.setTimeout0)((()=>{if(i)return;const e=Date.now()+15,s={didTimeout:!0,timeRemaining:()=>Math.max(0,e-Date.now())};t(Object.freeze(s))}));let i=!1;return{dispose(){i||(i=!0)}}}:t._runWhenIdle=(e,t,i)=>{const s=e.requestIdleCallback(t,\"number\"==typeof i?{timeout:i}:void 0);let r=!1;return{dispose(){r||(r=!0,e.cancelIdleCallback(s))}}},t.runWhenGlobalIdle=e=>(0,t._runWhenIdle)(globalThis,e);class b{constructor(e,i){this._didRun=!1,this._executor=()=>{try{this._value=i()}catch(e){this._error=e}finally{this._didRun=!0}},this._handle=(0,t._runWhenIdle)(e,(()=>this._executor()))}dispose(){this._handle.dispose()}get value(){if(this._didRun||(this._handle.dispose(),this._executor()),this._error)throw this._error;return this._value}get isInitialized(){return this._didRun}}t.AbstractIdleValue=b,t.GlobalIdleValue=class extends b{constructor(e){super(globalThis,e)}};class C{isRunning(e){return\"number\"==typeof e?this._running?.taskId===e:!!this._running}get running(){return this._running?.promise}cancelRunning(){this._running?.cancel()}run(e,t,i){return this._running={taskId:e,cancel:()=>i?.(),promise:t},t.then((()=>this.doneRunning(e)),(()=>this.doneRunning(e))),t}doneRunning(e){this._running&&e===this._running.taskId&&(this._running=void 0,this.runQueued())}runQueued(){if(this._queued){const e=this._queued;this._queued=void 0,e.run().then(e.promiseResolve,e.promiseReject)}}queue(e){if(this._queued)this._queued.run=e;else{const{promise:t,resolve:i,reject:s}=u();this._queued={run:e,promise:t,promiseResolve:i,promiseReject:s}}return this._queued.promise}hasQueued(){return!!this._queued}async join(){return this._queued?.promise??this._running?.promise}}var y,w,E;t.TaskSequentializer=C,t.IntervalCounter=class{constructor(e,t=()=>Date.now()){this.interval=e,this.nowFn=t,this.lastIncrementTime=0,this.value=0}increment(){const e=this.nowFn();return e-this.lastIncrementTime>this.interval&&(this.lastIncrementTime=e,this.value=0),this.value++,this.value}},function(e){e[e.Resolved=0]=\"Resolved\",e[e.Rejected=1]=\"Rejected\"}(y||(y={}));class D{get isRejected(){return this.outcome?.outcome===y.Rejected}get isResolved(){return this.outcome?.outcome===y.Resolved}get isSettled(){return!!this.outcome}get value(){return this.outcome?.outcome===y.Resolved?this.outcome?.value:void 0}constructor(){this.p=new Promise(((e,t)=>{this.completeCallback=e,this.errorCallback=t}))}complete(e){return new Promise((t=>{this.completeCallback(e),this.outcome={outcome:y.Resolved,value:e},t()}))}error(e){return new Promise((t=>{this.errorCallback(e),this.outcome={outcome:y.Rejected,value:e},t()}))}cancel(){return this.error(new r.CancellationError)}}t.DeferredPromise=D,function(e){e.settled=async function(e){let t;const i=await Promise.all(e.map((e=>e.then((e=>e),(e=>{t||(t=e)})))));if(void 0!==t)throw t;return i},e.withAsyncBody=function(e){return new Promise((async(t,i)=>{try{await e(t,i)}catch(e){i(e)}}))}}(w||(t.Promises=w={}));class L{get value(){return this._value}get error(){return this._error}get isResolved(){return this._isResolved}constructor(e){this._value=void 0,this._error=void 0,this._isResolved=!1,this.promise=e.then((e=>(this._value=e,this._isResolved=!0,e)),(e=>{throw this._error=e,this._isResolved=!0,e}))}requireValue(){if(!this._isResolved)throw new r.BugIndicatingError(\"Promise is not resolved yet\");if(this._error)throw this._error;return this._value}}t.StatefulPromise=L,t.LazyStatefulPromise=class{constructor(e){this._compute=e,this._promise=new h.Lazy((()=>new L(this._compute())))}requireValue(){return this._promise.value.requireValue()}getPromise(){return this._promise.value.promise}get currentValue(){return this._promise.rawValue?.value}},function(e){e[e.Initial=0]=\"Initial\",e[e.DoneOK=1]=\"DoneOK\",e[e.DoneError=2]=\"DoneError\"}(E||(E={}));class R{static fromArray(e){return new R((t=>{t.emitMany(e)}))}static fromPromise(e){return new R((async t=>{t.emitMany(await e)}))}static fromPromises(e){return new R((async t=>{await Promise.all(e.map((async e=>t.emitOne(await e))))}))}static merge(e){return new R((async t=>{await Promise.all(e.map((async e=>{for await(const i of e)t.emitOne(i)})))}))}static{this.EMPTY=R.fromArray([])}constructor(e,t){this._state=E.Initial,this._results=[],this._error=null,this._onReturn=t,this._onStateChanged=new n.Emitter,queueMicrotask((async()=>{const t={emitOne:e=>this.emitOne(e),emitMany:e=>this.emitMany(e),reject:e=>this.reject(e)};try{await Promise.resolve(e(t)),this.resolve()}catch(e){this.reject(e)}finally{t.emitOne=void 0,t.emitMany=void 0,t.reject=void 0}}))}[Symbol.asyncIterator](){let e=0;return{next:async()=>{for(;;){if(this._state===E.DoneError)throw this._error;if(e(this._onReturn?.(),{done:!0,value:void 0})}}static map(e,t){return new R((async i=>{for await(const s of e)i.emitOne(t(s))}))}map(e){return R.map(this,e)}static filter(e,t){return new R((async i=>{for await(const s of e)t(s)&&i.emitOne(s)}))}filter(e){return R.filter(this,e)}static coalesce(e){return R.filter(e,(e=>!!e))}coalesce(){return R.coalesce(this)}static async toPromise(e){const t=[];for await(const i of e)t.push(i);return t}toPromise(){return R.toPromise(this)}emitOne(e){this._state===E.Initial&&(this._results.push(e),this._onStateChanged.fire())}emitMany(e){this._state===E.Initial&&(this._results=this._results.concat(e),this._onStateChanged.fire())}resolve(){this._state===E.Initial&&(this._state=E.DoneOK,this._onStateChanged.fire())}reject(e){this._state===E.Initial&&(this._state=E.DoneError,this._error=e,this._onStateChanged.fire())}}t.AsyncIterableObject=R;class A extends R{constructor(e,t){super(t),this._source=e}cancel(){this._source.cancel()}}t.CancelableAsyncIterableObject=A,t.AsyncIterableSource=class{constructor(e){let t,i;this._deferred=new D,this._asyncIterable=new R((e=>{if(!t)return i&&e.emitMany(i),this._errorFn=t=>e.reject(t),this._emitFn=t=>e.emitOne(t),this._deferred.p;e.reject(t)}),e),this._emitFn=e=>{i||(i=[]),i.push(e)},this._errorFn=e=>{t||(t=e)}}get asyncIterable(){return this._asyncIterable}resolve(){this._deferred.complete()}reject(e){this._errorFn(e),this._deferred.complete()}emitOne(e){this._emitFn(e)}}},8447:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CancellationTokenSource=t.CancellationToken=void 0,t.cancelOnDispose=function(e){const t=new a;return e.add({dispose(){t.cancel()}}),t.token};const s=i(802),r=Object.freeze((function(e,t){const i=setTimeout(e.bind(t),0);return{dispose(){clearTimeout(i)}}}));var n;!function(e){e.isCancellationToken=function(t){return t===e.None||t===e.Cancelled||t instanceof o||!(!t||\"object\"!=typeof t)&&\"boolean\"==typeof t.isCancellationRequested&&\"function\"==typeof t.onCancellationRequested},e.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:s.Event.None}),e.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:r})}(n||(t.CancellationToken=n={}));class o{constructor(){this._isCancelled=!1,this._emitter=null}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?r:(this._emitter||(this._emitter=new s.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=null)}}class a{constructor(e){this._token=void 0,this._parentListener=void 0,this._parentListener=e&&e.onCancellationRequested(this.cancel,this)}get token(){return this._token||(this._token=new o),this._token}cancel(){this._token?this._token instanceof o&&this._token.cancel():this._token=n.Cancelled}dispose(e=!1){e&&this.cancel(),this._parentListener?.dispose(),this._token?this._token instanceof o&&this._token.dispose():this._token=n.None}}t.CancellationTokenSource=a},4869:(e,t)=>{var i;Object.defineProperty(t,\"__esModule\",{value:!0}),t.CharCode=void 0,function(e){e[e.Null=0]=\"Null\",e[e.Backspace=8]=\"Backspace\",e[e.Tab=9]=\"Tab\",e[e.LineFeed=10]=\"LineFeed\",e[e.CarriageReturn=13]=\"CarriageReturn\",e[e.Space=32]=\"Space\",e[e.ExclamationMark=33]=\"ExclamationMark\",e[e.DoubleQuote=34]=\"DoubleQuote\",e[e.Hash=35]=\"Hash\",e[e.DollarSign=36]=\"DollarSign\",e[e.PercentSign=37]=\"PercentSign\",e[e.Ampersand=38]=\"Ampersand\",e[e.SingleQuote=39]=\"SingleQuote\",e[e.OpenParen=40]=\"OpenParen\",e[e.CloseParen=41]=\"CloseParen\",e[e.Asterisk=42]=\"Asterisk\",e[e.Plus=43]=\"Plus\",e[e.Comma=44]=\"Comma\",e[e.Dash=45]=\"Dash\",e[e.Period=46]=\"Period\",e[e.Slash=47]=\"Slash\",e[e.Digit0=48]=\"Digit0\",e[e.Digit1=49]=\"Digit1\",e[e.Digit2=50]=\"Digit2\",e[e.Digit3=51]=\"Digit3\",e[e.Digit4=52]=\"Digit4\",e[e.Digit5=53]=\"Digit5\",e[e.Digit6=54]=\"Digit6\",e[e.Digit7=55]=\"Digit7\",e[e.Digit8=56]=\"Digit8\",e[e.Digit9=57]=\"Digit9\",e[e.Colon=58]=\"Colon\",e[e.Semicolon=59]=\"Semicolon\",e[e.LessThan=60]=\"LessThan\",e[e.Equals=61]=\"Equals\",e[e.GreaterThan=62]=\"GreaterThan\",e[e.QuestionMark=63]=\"QuestionMark\",e[e.AtSign=64]=\"AtSign\",e[e.A=65]=\"A\",e[e.B=66]=\"B\",e[e.C=67]=\"C\",e[e.D=68]=\"D\",e[e.E=69]=\"E\",e[e.F=70]=\"F\",e[e.G=71]=\"G\",e[e.H=72]=\"H\",e[e.I=73]=\"I\",e[e.J=74]=\"J\",e[e.K=75]=\"K\",e[e.L=76]=\"L\",e[e.M=77]=\"M\",e[e.N=78]=\"N\",e[e.O=79]=\"O\",e[e.P=80]=\"P\",e[e.Q=81]=\"Q\",e[e.R=82]=\"R\",e[e.S=83]=\"S\",e[e.T=84]=\"T\",e[e.U=85]=\"U\",e[e.V=86]=\"V\",e[e.W=87]=\"W\",e[e.X=88]=\"X\",e[e.Y=89]=\"Y\",e[e.Z=90]=\"Z\",e[e.OpenSquareBracket=91]=\"OpenSquareBracket\",e[e.Backslash=92]=\"Backslash\",e[e.CloseSquareBracket=93]=\"CloseSquareBracket\",e[e.Caret=94]=\"Caret\",e[e.Underline=95]=\"Underline\",e[e.BackTick=96]=\"BackTick\",e[e.a=97]=\"a\",e[e.b=98]=\"b\",e[e.c=99]=\"c\",e[e.d=100]=\"d\",e[e.e=101]=\"e\",e[e.f=102]=\"f\",e[e.g=103]=\"g\",e[e.h=104]=\"h\",e[e.i=105]=\"i\",e[e.j=106]=\"j\",e[e.k=107]=\"k\",e[e.l=108]=\"l\",e[e.m=109]=\"m\",e[e.n=110]=\"n\",e[e.o=111]=\"o\",e[e.p=112]=\"p\",e[e.q=113]=\"q\",e[e.r=114]=\"r\",e[e.s=115]=\"s\",e[e.t=116]=\"t\",e[e.u=117]=\"u\",e[e.v=118]=\"v\",e[e.w=119]=\"w\",e[e.x=120]=\"x\",e[e.y=121]=\"y\",e[e.z=122]=\"z\",e[e.OpenCurlyBrace=123]=\"OpenCurlyBrace\",e[e.Pipe=124]=\"Pipe\",e[e.CloseCurlyBrace=125]=\"CloseCurlyBrace\",e[e.Tilde=126]=\"Tilde\",e[e.NoBreakSpace=160]=\"NoBreakSpace\",e[e.U_Combining_Grave_Accent=768]=\"U_Combining_Grave_Accent\",e[e.U_Combining_Acute_Accent=769]=\"U_Combining_Acute_Accent\",e[e.U_Combining_Circumflex_Accent=770]=\"U_Combining_Circumflex_Accent\",e[e.U_Combining_Tilde=771]=\"U_Combining_Tilde\",e[e.U_Combining_Macron=772]=\"U_Combining_Macron\",e[e.U_Combining_Overline=773]=\"U_Combining_Overline\",e[e.U_Combining_Breve=774]=\"U_Combining_Breve\",e[e.U_Combining_Dot_Above=775]=\"U_Combining_Dot_Above\",e[e.U_Combining_Diaeresis=776]=\"U_Combining_Diaeresis\",e[e.U_Combining_Hook_Above=777]=\"U_Combining_Hook_Above\",e[e.U_Combining_Ring_Above=778]=\"U_Combining_Ring_Above\",e[e.U_Combining_Double_Acute_Accent=779]=\"U_Combining_Double_Acute_Accent\",e[e.U_Combining_Caron=780]=\"U_Combining_Caron\",e[e.U_Combining_Vertical_Line_Above=781]=\"U_Combining_Vertical_Line_Above\",e[e.U_Combining_Double_Vertical_Line_Above=782]=\"U_Combining_Double_Vertical_Line_Above\",e[e.U_Combining_Double_Grave_Accent=783]=\"U_Combining_Double_Grave_Accent\",e[e.U_Combining_Candrabindu=784]=\"U_Combining_Candrabindu\",e[e.U_Combining_Inverted_Breve=785]=\"U_Combining_Inverted_Breve\",e[e.U_Combining_Turned_Comma_Above=786]=\"U_Combining_Turned_Comma_Above\",e[e.U_Combining_Comma_Above=787]=\"U_Combining_Comma_Above\",e[e.U_Combining_Reversed_Comma_Above=788]=\"U_Combining_Reversed_Comma_Above\",e[e.U_Combining_Comma_Above_Right=789]=\"U_Combining_Comma_Above_Right\",e[e.U_Combining_Grave_Accent_Below=790]=\"U_Combining_Grave_Accent_Below\",e[e.U_Combining_Acute_Accent_Below=791]=\"U_Combining_Acute_Accent_Below\",e[e.U_Combining_Left_Tack_Below=792]=\"U_Combining_Left_Tack_Below\",e[e.U_Combining_Right_Tack_Below=793]=\"U_Combining_Right_Tack_Below\",e[e.U_Combining_Left_Angle_Above=794]=\"U_Combining_Left_Angle_Above\",e[e.U_Combining_Horn=795]=\"U_Combining_Horn\",e[e.U_Combining_Left_Half_Ring_Below=796]=\"U_Combining_Left_Half_Ring_Below\",e[e.U_Combining_Up_Tack_Below=797]=\"U_Combining_Up_Tack_Below\",e[e.U_Combining_Down_Tack_Below=798]=\"U_Combining_Down_Tack_Below\",e[e.U_Combining_Plus_Sign_Below=799]=\"U_Combining_Plus_Sign_Below\",e[e.U_Combining_Minus_Sign_Below=800]=\"U_Combining_Minus_Sign_Below\",e[e.U_Combining_Palatalized_Hook_Below=801]=\"U_Combining_Palatalized_Hook_Below\",e[e.U_Combining_Retroflex_Hook_Below=802]=\"U_Combining_Retroflex_Hook_Below\",e[e.U_Combining_Dot_Below=803]=\"U_Combining_Dot_Below\",e[e.U_Combining_Diaeresis_Below=804]=\"U_Combining_Diaeresis_Below\",e[e.U_Combining_Ring_Below=805]=\"U_Combining_Ring_Below\",e[e.U_Combining_Comma_Below=806]=\"U_Combining_Comma_Below\",e[e.U_Combining_Cedilla=807]=\"U_Combining_Cedilla\",e[e.U_Combining_Ogonek=808]=\"U_Combining_Ogonek\",e[e.U_Combining_Vertical_Line_Below=809]=\"U_Combining_Vertical_Line_Below\",e[e.U_Combining_Bridge_Below=810]=\"U_Combining_Bridge_Below\",e[e.U_Combining_Inverted_Double_Arch_Below=811]=\"U_Combining_Inverted_Double_Arch_Below\",e[e.U_Combining_Caron_Below=812]=\"U_Combining_Caron_Below\",e[e.U_Combining_Circumflex_Accent_Below=813]=\"U_Combining_Circumflex_Accent_Below\",e[e.U_Combining_Breve_Below=814]=\"U_Combining_Breve_Below\",e[e.U_Combining_Inverted_Breve_Below=815]=\"U_Combining_Inverted_Breve_Below\",e[e.U_Combining_Tilde_Below=816]=\"U_Combining_Tilde_Below\",e[e.U_Combining_Macron_Below=817]=\"U_Combining_Macron_Below\",e[e.U_Combining_Low_Line=818]=\"U_Combining_Low_Line\",e[e.U_Combining_Double_Low_Line=819]=\"U_Combining_Double_Low_Line\",e[e.U_Combining_Tilde_Overlay=820]=\"U_Combining_Tilde_Overlay\",e[e.U_Combining_Short_Stroke_Overlay=821]=\"U_Combining_Short_Stroke_Overlay\",e[e.U_Combining_Long_Stroke_Overlay=822]=\"U_Combining_Long_Stroke_Overlay\",e[e.U_Combining_Short_Solidus_Overlay=823]=\"U_Combining_Short_Solidus_Overlay\",e[e.U_Combining_Long_Solidus_Overlay=824]=\"U_Combining_Long_Solidus_Overlay\",e[e.U_Combining_Right_Half_Ring_Below=825]=\"U_Combining_Right_Half_Ring_Below\",e[e.U_Combining_Inverted_Bridge_Below=826]=\"U_Combining_Inverted_Bridge_Below\",e[e.U_Combining_Square_Below=827]=\"U_Combining_Square_Below\",e[e.U_Combining_Seagull_Below=828]=\"U_Combining_Seagull_Below\",e[e.U_Combining_X_Above=829]=\"U_Combining_X_Above\",e[e.U_Combining_Vertical_Tilde=830]=\"U_Combining_Vertical_Tilde\",e[e.U_Combining_Double_Overline=831]=\"U_Combining_Double_Overline\",e[e.U_Combining_Grave_Tone_Mark=832]=\"U_Combining_Grave_Tone_Mark\",e[e.U_Combining_Acute_Tone_Mark=833]=\"U_Combining_Acute_Tone_Mark\",e[e.U_Combining_Greek_Perispomeni=834]=\"U_Combining_Greek_Perispomeni\",e[e.U_Combining_Greek_Koronis=835]=\"U_Combining_Greek_Koronis\",e[e.U_Combining_Greek_Dialytika_Tonos=836]=\"U_Combining_Greek_Dialytika_Tonos\",e[e.U_Combining_Greek_Ypogegrammeni=837]=\"U_Combining_Greek_Ypogegrammeni\",e[e.U_Combining_Bridge_Above=838]=\"U_Combining_Bridge_Above\",e[e.U_Combining_Equals_Sign_Below=839]=\"U_Combining_Equals_Sign_Below\",e[e.U_Combining_Double_Vertical_Line_Below=840]=\"U_Combining_Double_Vertical_Line_Below\",e[e.U_Combining_Left_Angle_Below=841]=\"U_Combining_Left_Angle_Below\",e[e.U_Combining_Not_Tilde_Above=842]=\"U_Combining_Not_Tilde_Above\",e[e.U_Combining_Homothetic_Above=843]=\"U_Combining_Homothetic_Above\",e[e.U_Combining_Almost_Equal_To_Above=844]=\"U_Combining_Almost_Equal_To_Above\",e[e.U_Combining_Left_Right_Arrow_Below=845]=\"U_Combining_Left_Right_Arrow_Below\",e[e.U_Combining_Upwards_Arrow_Below=846]=\"U_Combining_Upwards_Arrow_Below\",e[e.U_Combining_Grapheme_Joiner=847]=\"U_Combining_Grapheme_Joiner\",e[e.U_Combining_Right_Arrowhead_Above=848]=\"U_Combining_Right_Arrowhead_Above\",e[e.U_Combining_Left_Half_Ring_Above=849]=\"U_Combining_Left_Half_Ring_Above\",e[e.U_Combining_Fermata=850]=\"U_Combining_Fermata\",e[e.U_Combining_X_Below=851]=\"U_Combining_X_Below\",e[e.U_Combining_Left_Arrowhead_Below=852]=\"U_Combining_Left_Arrowhead_Below\",e[e.U_Combining_Right_Arrowhead_Below=853]=\"U_Combining_Right_Arrowhead_Below\",e[e.U_Combining_Right_Arrowhead_And_Up_Arrowhead_Below=854]=\"U_Combining_Right_Arrowhead_And_Up_Arrowhead_Below\",e[e.U_Combining_Right_Half_Ring_Above=855]=\"U_Combining_Right_Half_Ring_Above\",e[e.U_Combining_Dot_Above_Right=856]=\"U_Combining_Dot_Above_Right\",e[e.U_Combining_Asterisk_Below=857]=\"U_Combining_Asterisk_Below\",e[e.U_Combining_Double_Ring_Below=858]=\"U_Combining_Double_Ring_Below\",e[e.U_Combining_Zigzag_Above=859]=\"U_Combining_Zigzag_Above\",e[e.U_Combining_Double_Breve_Below=860]=\"U_Combining_Double_Breve_Below\",e[e.U_Combining_Double_Breve=861]=\"U_Combining_Double_Breve\",e[e.U_Combining_Double_Macron=862]=\"U_Combining_Double_Macron\",e[e.U_Combining_Double_Macron_Below=863]=\"U_Combining_Double_Macron_Below\",e[e.U_Combining_Double_Tilde=864]=\"U_Combining_Double_Tilde\",e[e.U_Combining_Double_Inverted_Breve=865]=\"U_Combining_Double_Inverted_Breve\",e[e.U_Combining_Double_Rightwards_Arrow_Below=866]=\"U_Combining_Double_Rightwards_Arrow_Below\",e[e.U_Combining_Latin_Small_Letter_A=867]=\"U_Combining_Latin_Small_Letter_A\",e[e.U_Combining_Latin_Small_Letter_E=868]=\"U_Combining_Latin_Small_Letter_E\",e[e.U_Combining_Latin_Small_Letter_I=869]=\"U_Combining_Latin_Small_Letter_I\",e[e.U_Combining_Latin_Small_Letter_O=870]=\"U_Combining_Latin_Small_Letter_O\",e[e.U_Combining_Latin_Small_Letter_U=871]=\"U_Combining_Latin_Small_Letter_U\",e[e.U_Combining_Latin_Small_Letter_C=872]=\"U_Combining_Latin_Small_Letter_C\",e[e.U_Combining_Latin_Small_Letter_D=873]=\"U_Combining_Latin_Small_Letter_D\",e[e.U_Combining_Latin_Small_Letter_H=874]=\"U_Combining_Latin_Small_Letter_H\",e[e.U_Combining_Latin_Small_Letter_M=875]=\"U_Combining_Latin_Small_Letter_M\",e[e.U_Combining_Latin_Small_Letter_R=876]=\"U_Combining_Latin_Small_Letter_R\",e[e.U_Combining_Latin_Small_Letter_T=877]=\"U_Combining_Latin_Small_Letter_T\",e[e.U_Combining_Latin_Small_Letter_V=878]=\"U_Combining_Latin_Small_Letter_V\",e[e.U_Combining_Latin_Small_Letter_X=879]=\"U_Combining_Latin_Small_Letter_X\",e[e.LINE_SEPARATOR=8232]=\"LINE_SEPARATOR\",e[e.PARAGRAPH_SEPARATOR=8233]=\"PARAGRAPH_SEPARATOR\",e[e.NEXT_LINE=133]=\"NEXT_LINE\",e[e.U_CIRCUMFLEX=94]=\"U_CIRCUMFLEX\",e[e.U_GRAVE_ACCENT=96]=\"U_GRAVE_ACCENT\",e[e.U_DIAERESIS=168]=\"U_DIAERESIS\",e[e.U_MACRON=175]=\"U_MACRON\",e[e.U_ACUTE_ACCENT=180]=\"U_ACUTE_ACCENT\",e[e.U_CEDILLA=184]=\"U_CEDILLA\",e[e.U_MODIFIER_LETTER_LEFT_ARROWHEAD=706]=\"U_MODIFIER_LETTER_LEFT_ARROWHEAD\",e[e.U_MODIFIER_LETTER_RIGHT_ARROWHEAD=707]=\"U_MODIFIER_LETTER_RIGHT_ARROWHEAD\",e[e.U_MODIFIER_LETTER_UP_ARROWHEAD=708]=\"U_MODIFIER_LETTER_UP_ARROWHEAD\",e[e.U_MODIFIER_LETTER_DOWN_ARROWHEAD=709]=\"U_MODIFIER_LETTER_DOWN_ARROWHEAD\",e[e.U_MODIFIER_LETTER_CENTRED_RIGHT_HALF_RING=722]=\"U_MODIFIER_LETTER_CENTRED_RIGHT_HALF_RING\",e[e.U_MODIFIER_LETTER_CENTRED_LEFT_HALF_RING=723]=\"U_MODIFIER_LETTER_CENTRED_LEFT_HALF_RING\",e[e.U_MODIFIER_LETTER_UP_TACK=724]=\"U_MODIFIER_LETTER_UP_TACK\",e[e.U_MODIFIER_LETTER_DOWN_TACK=725]=\"U_MODIFIER_LETTER_DOWN_TACK\",e[e.U_MODIFIER_LETTER_PLUS_SIGN=726]=\"U_MODIFIER_LETTER_PLUS_SIGN\",e[e.U_MODIFIER_LETTER_MINUS_SIGN=727]=\"U_MODIFIER_LETTER_MINUS_SIGN\",e[e.U_BREVE=728]=\"U_BREVE\",e[e.U_DOT_ABOVE=729]=\"U_DOT_ABOVE\",e[e.U_RING_ABOVE=730]=\"U_RING_ABOVE\",e[e.U_OGONEK=731]=\"U_OGONEK\",e[e.U_SMALL_TILDE=732]=\"U_SMALL_TILDE\",e[e.U_DOUBLE_ACUTE_ACCENT=733]=\"U_DOUBLE_ACUTE_ACCENT\",e[e.U_MODIFIER_LETTER_RHOTIC_HOOK=734]=\"U_MODIFIER_LETTER_RHOTIC_HOOK\",e[e.U_MODIFIER_LETTER_CROSS_ACCENT=735]=\"U_MODIFIER_LETTER_CROSS_ACCENT\",e[e.U_MODIFIER_LETTER_EXTRA_HIGH_TONE_BAR=741]=\"U_MODIFIER_LETTER_EXTRA_HIGH_TONE_BAR\",e[e.U_MODIFIER_LETTER_HIGH_TONE_BAR=742]=\"U_MODIFIER_LETTER_HIGH_TONE_BAR\",e[e.U_MODIFIER_LETTER_MID_TONE_BAR=743]=\"U_MODIFIER_LETTER_MID_TONE_BAR\",e[e.U_MODIFIER_LETTER_LOW_TONE_BAR=744]=\"U_MODIFIER_LETTER_LOW_TONE_BAR\",e[e.U_MODIFIER_LETTER_EXTRA_LOW_TONE_BAR=745]=\"U_MODIFIER_LETTER_EXTRA_LOW_TONE_BAR\",e[e.U_MODIFIER_LETTER_YIN_DEPARTING_TONE_MARK=746]=\"U_MODIFIER_LETTER_YIN_DEPARTING_TONE_MARK\",e[e.U_MODIFIER_LETTER_YANG_DEPARTING_TONE_MARK=747]=\"U_MODIFIER_LETTER_YANG_DEPARTING_TONE_MARK\",e[e.U_MODIFIER_LETTER_UNASPIRATED=749]=\"U_MODIFIER_LETTER_UNASPIRATED\",e[e.U_MODIFIER_LETTER_LOW_DOWN_ARROWHEAD=751]=\"U_MODIFIER_LETTER_LOW_DOWN_ARROWHEAD\",e[e.U_MODIFIER_LETTER_LOW_UP_ARROWHEAD=752]=\"U_MODIFIER_LETTER_LOW_UP_ARROWHEAD\",e[e.U_MODIFIER_LETTER_LOW_LEFT_ARROWHEAD=753]=\"U_MODIFIER_LETTER_LOW_LEFT_ARROWHEAD\",e[e.U_MODIFIER_LETTER_LOW_RIGHT_ARROWHEAD=754]=\"U_MODIFIER_LETTER_LOW_RIGHT_ARROWHEAD\",e[e.U_MODIFIER_LETTER_LOW_RING=755]=\"U_MODIFIER_LETTER_LOW_RING\",e[e.U_MODIFIER_LETTER_MIDDLE_GRAVE_ACCENT=756]=\"U_MODIFIER_LETTER_MIDDLE_GRAVE_ACCENT\",e[e.U_MODIFIER_LETTER_MIDDLE_DOUBLE_GRAVE_ACCENT=757]=\"U_MODIFIER_LETTER_MIDDLE_DOUBLE_GRAVE_ACCENT\",e[e.U_MODIFIER_LETTER_MIDDLE_DOUBLE_ACUTE_ACCENT=758]=\"U_MODIFIER_LETTER_MIDDLE_DOUBLE_ACUTE_ACCENT\",e[e.U_MODIFIER_LETTER_LOW_TILDE=759]=\"U_MODIFIER_LETTER_LOW_TILDE\",e[e.U_MODIFIER_LETTER_RAISED_COLON=760]=\"U_MODIFIER_LETTER_RAISED_COLON\",e[e.U_MODIFIER_LETTER_BEGIN_HIGH_TONE=761]=\"U_MODIFIER_LETTER_BEGIN_HIGH_TONE\",e[e.U_MODIFIER_LETTER_END_HIGH_TONE=762]=\"U_MODIFIER_LETTER_END_HIGH_TONE\",e[e.U_MODIFIER_LETTER_BEGIN_LOW_TONE=763]=\"U_MODIFIER_LETTER_BEGIN_LOW_TONE\",e[e.U_MODIFIER_LETTER_END_LOW_TONE=764]=\"U_MODIFIER_LETTER_END_LOW_TONE\",e[e.U_MODIFIER_LETTER_SHELF=765]=\"U_MODIFIER_LETTER_SHELF\",e[e.U_MODIFIER_LETTER_OPEN_SHELF=766]=\"U_MODIFIER_LETTER_OPEN_SHELF\",e[e.U_MODIFIER_LETTER_LOW_LEFT_ARROW=767]=\"U_MODIFIER_LETTER_LOW_LEFT_ARROW\",e[e.U_GREEK_LOWER_NUMERAL_SIGN=885]=\"U_GREEK_LOWER_NUMERAL_SIGN\",e[e.U_GREEK_TONOS=900]=\"U_GREEK_TONOS\",e[e.U_GREEK_DIALYTIKA_TONOS=901]=\"U_GREEK_DIALYTIKA_TONOS\",e[e.U_GREEK_KORONIS=8125]=\"U_GREEK_KORONIS\",e[e.U_GREEK_PSILI=8127]=\"U_GREEK_PSILI\",e[e.U_GREEK_PERISPOMENI=8128]=\"U_GREEK_PERISPOMENI\",e[e.U_GREEK_DIALYTIKA_AND_PERISPOMENI=8129]=\"U_GREEK_DIALYTIKA_AND_PERISPOMENI\",e[e.U_GREEK_PSILI_AND_VARIA=8141]=\"U_GREEK_PSILI_AND_VARIA\",e[e.U_GREEK_PSILI_AND_OXIA=8142]=\"U_GREEK_PSILI_AND_OXIA\",e[e.U_GREEK_PSILI_AND_PERISPOMENI=8143]=\"U_GREEK_PSILI_AND_PERISPOMENI\",e[e.U_GREEK_DASIA_AND_VARIA=8157]=\"U_GREEK_DASIA_AND_VARIA\",e[e.U_GREEK_DASIA_AND_OXIA=8158]=\"U_GREEK_DASIA_AND_OXIA\",e[e.U_GREEK_DASIA_AND_PERISPOMENI=8159]=\"U_GREEK_DASIA_AND_PERISPOMENI\",e[e.U_GREEK_DIALYTIKA_AND_VARIA=8173]=\"U_GREEK_DIALYTIKA_AND_VARIA\",e[e.U_GREEK_DIALYTIKA_AND_OXIA=8174]=\"U_GREEK_DIALYTIKA_AND_OXIA\",e[e.U_GREEK_VARIA=8175]=\"U_GREEK_VARIA\",e[e.U_GREEK_OXIA=8189]=\"U_GREEK_OXIA\",e[e.U_GREEK_DASIA=8190]=\"U_GREEK_DASIA\",e[e.U_IDEOGRAPHIC_FULL_STOP=12290]=\"U_IDEOGRAPHIC_FULL_STOP\",e[e.U_LEFT_CORNER_BRACKET=12300]=\"U_LEFT_CORNER_BRACKET\",e[e.U_RIGHT_CORNER_BRACKET=12301]=\"U_RIGHT_CORNER_BRACKET\",e[e.U_LEFT_BLACK_LENTICULAR_BRACKET=12304]=\"U_LEFT_BLACK_LENTICULAR_BRACKET\",e[e.U_RIGHT_BLACK_LENTICULAR_BRACKET=12305]=\"U_RIGHT_BLACK_LENTICULAR_BRACKET\",e[e.U_OVERLINE=8254]=\"U_OVERLINE\",e[e.UTF8_BOM=65279]=\"UTF8_BOM\",e[e.U_FULLWIDTH_SEMICOLON=65307]=\"U_FULLWIDTH_SEMICOLON\",e[e.U_FULLWIDTH_COMMA=65292]=\"U_FULLWIDTH_COMMA\"}(i||(t.CharCode=i={}))},9087:(e,t)=>{var i;Object.defineProperty(t,\"__esModule\",{value:!0}),t.SetWithKey=void 0,t.groupBy=function(e,t){const i=Object.create(null);for(const s of e){const e=t(s);let r=i[e];r||(r=i[e]=[]),r.push(s)}return i},t.diffSets=function(e,t){const i=[],s=[];for(const s of e)t.has(s)||i.push(s);for(const i of t)e.has(i)||s.push(i);return{removed:i,added:s}},t.diffMaps=function(e,t){const i=[],s=[];for(const[s,r]of e)t.has(s)||i.push(r);for(const[i,r]of t)e.has(i)||s.push(r);return{removed:i,added:s}},t.intersection=function(e,t){const i=new Set;for(const s of t)e.has(s)&&i.add(s);return i};class s{static{i=Symbol.toStringTag}constructor(e,t){this.toKey=t,this._map=new Map,this[i]=\"SetWithKey\";for(const t of e)this.add(t)}get size(){return this._map.size}add(e){const t=this.toKey(e);return this._map.set(t,e),this}delete(e){return this._map.delete(this.toKey(e))}has(e){return this._map.has(this.toKey(e))}*entries(){for(const e of this._map.values())yield[e,e]}keys(){return this.values()}*values(){for(const e of this._map.values())yield e}clear(){this._map.clear()}forEach(e,t){this._map.forEach((i=>e.call(t,i,i,this)))}[Symbol.iterator](){return this.values()}}t.SetWithKey=s},4838:(e,t)=>{function i(e){return(t,i,s)=>{let r=null,n=null;if(\"function\"==typeof s.value?(r=\"value\",n=s.value):\"function\"==typeof s.get&&(r=\"get\",n=s.get),!n)throw new Error(\"not supported\");s[r]=e(n,i)}}Object.defineProperty(t,\"__esModule\",{value:!0}),t.memoize=function(e,t,i){let s=null,r=null;if(\"function\"==typeof i.value?(s=\"value\",r=i.value,0!==r.length&&console.warn(\"Memoize should only be used in functions with zero parameters\")):\"function\"==typeof i.get&&(s=\"get\",r=i.get),!r)throw new Error(\"not supported\");const n=`$memoize$${t}`;i[s]=function(...e){return this.hasOwnProperty(n)||Object.defineProperty(this,n,{configurable:!1,enumerable:!1,writable:!1,value:r.apply(this,e)}),this[n]}},t.debounce=function(e,t,s){return i(((i,r)=>{const n=`$debounce$${r}`,o=`$debounce$result$${r}`;return function(...r){this[o]||(this[o]=s?s():void 0),clearTimeout(this[n]),t&&(this[o]=t(this[o],...r),r=[this[o]]),this[n]=setTimeout((()=>{i.apply(this,r),this[o]=s?s():void 0}),e)}}))},t.throttle=function(e,t,s){return i(((i,r)=>{const n=`$throttle$timer$${r}`,o=`$throttle$result$${r}`,a=`$throttle$lastRun$${r}`,l=`$throttle$pending$${r}`;return function(...r){if(this[o]||(this[o]=s?s():void 0),null!==this[a]&&void 0!==this[a]||(this[a]=-Number.MAX_VALUE),t&&(this[o]=t(this[o],...r)),this[l])return;const h=this[a]+e;h<=Date.now()?(this[a]=Date.now(),i.apply(this,[this[o]]),this[o]=s?s():void 0):(this[l]=!0,this[n]=setTimeout((()=>{this[l]=!1,this[a]=Date.now(),i.apply(this,[this[o]]),this[o]=s?s():void 0}),h-Date.now()))}}))}},9807:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BugIndicatingError=t.ErrorNoTelemetry=t.ExpectedError=t.NotSupportedError=t.NotImplementedError=t.ReadonlyError=t.CancellationError=t.errorHandler=t.ErrorHandler=void 0,t.setUnexpectedErrorHandler=function(e){t.errorHandler.setUnexpectedErrorHandler(e)},t.isSigPipeError=function(e){if(!e||\"object\"!=typeof e)return!1;const t=e;return\"EPIPE\"===t.code&&\"WRITE\"===t.syscall?.toUpperCase()},t.onUnexpectedError=function(e){r(e)||t.errorHandler.onUnexpectedError(e)},t.onUnexpectedExternalError=function(e){r(e)||t.errorHandler.onUnexpectedExternalError(e)},t.transformErrorForSerialization=function(e){if(e instanceof Error){const{name:t,message:i}=e;return{$isError:!0,name:t,message:i,stack:e.stacktrace||e.stack,noTelemetry:c.isErrorNoTelemetry(e)}}return e},t.transformErrorFromSerialization=function(e){let t;return e.noTelemetry?t=new c:(t=new Error,t.name=e.name),t.message=e.message,t.stack=e.stack,t},t.isCancellationError=r,t.canceled=function(){const e=new Error(s);return e.name=e.message,e},t.illegalArgument=function(e){return e?new Error(`Illegal argument: ${e}`):new Error(\"Illegal argument\")},t.illegalState=function(e){return e?new Error(`Illegal state: ${e}`):new Error(\"Illegal state\")},t.getErrorMessage=function(e){return e?e.message?e.message:e.stack?e.stack.split(\"\\n\")[0]:String(e):\"Error\"};class i{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout((()=>{if(e.stack){if(c.isErrorNoTelemetry(e))throw new c(e.message+\"\\n\\n\"+e.stack);throw new Error(e.message+\"\\n\\n\"+e.stack)}throw e}),0)}}addListener(e){return this.listeners.push(e),()=>{this._removeListener(e)}}emit(e){this.listeners.forEach((t=>{t(e)}))}_removeListener(e){this.listeners.splice(this.listeners.indexOf(e),1)}setUnexpectedErrorHandler(e){this.unexpectedErrorHandler=e}getUnexpectedErrorHandler(){return this.unexpectedErrorHandler}onUnexpectedError(e){this.unexpectedErrorHandler(e),this.emit(e)}onUnexpectedExternalError(e){this.unexpectedErrorHandler(e)}}t.ErrorHandler=i,t.errorHandler=new i;const s=\"Canceled\";function r(e){return e instanceof n||e instanceof Error&&e.name===s&&e.message===s}class n extends Error{constructor(){super(s),this.name=this.message}}t.CancellationError=n;class o extends TypeError{constructor(e){super(e?`${e} is read-only and cannot be changed`:\"Cannot change read-only property\")}}t.ReadonlyError=o;class a extends Error{constructor(e){super(\"NotImplemented\"),e&&(this.message=e)}}t.NotImplementedError=a;class l extends Error{constructor(e){super(\"NotSupported\"),e&&(this.message=e)}}t.NotSupportedError=l;class h extends Error{constructor(){super(...arguments),this.isExpected=!0}}t.ExpectedError=h;class c extends Error{constructor(e){super(e),this.name=\"CodeExpectedError\"}static fromError(e){if(e instanceof c)return e;const t=new c;return t.message=e.message,t.stack=e.stack,t}static isErrorNoTelemetry(e){return\"CodeExpectedError\"===e.name}}t.ErrorNoTelemetry=c;class d extends Error{constructor(e){super(e||\"An unexpected bug occurred.\"),Object.setPrototypeOf(this,d.prototype)}}t.BugIndicatingError=d},802:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ValueWithChangeEvent=t.Relay=t.EventBufferer=t.DynamicListEventMultiplexer=t.EventMultiplexer=t.MicrotaskEmitter=t.DebounceEmitter=t.PauseableEmitter=t.AsyncEmitter=t.createEventDeliveryQueue=t.Emitter=t.ListenerRefusalError=t.ListenerLeakError=t.EventProfiling=t.Event=void 0,t.setGlobalLeakWarningThreshold=function(e){const t=c;return c=e,{dispose(){c=t}}};const s=i(9807),r=i(8841),n=i(7150),o=i(6317),a=i(9725);var l;!function(e){function t(e){return(t,i=null,s)=>{let r,n=!1;return r=e((e=>{if(!n)return r?r.dispose():n=!0,t.call(i,e)}),null,s),n&&r.dispose(),r}}function i(e,t,i){return r(((i,s=null,r)=>e((e=>i.call(s,t(e))),null,r)),i)}function s(e,t,i){return r(((i,s=null,r)=>e((e=>t(e)&&i.call(s,e)),null,r)),i)}function r(e,t){let i;const s=new m({onWillAddFirstListener(){i=e(s.fire,s)},onDidRemoveLastListener(){i?.dispose()}});return t?.add(s),s.event}function o(e,t,i=100,s=!1,r=!1,n,o){let a,l,h,c,d=0;const u=new m({leakWarningThreshold:n,onWillAddFirstListener(){a=e((e=>{d++,l=t(l,e),s&&!h&&(u.fire(l),l=void 0),c=()=>{const e=l;l=void 0,h=void 0,(!s||d>1)&&u.fire(e),d=0},\"number\"==typeof i?(clearTimeout(h),h=setTimeout(c,i)):void 0===h&&(h=0,queueMicrotask(c))}))},onWillRemoveListener(){r&&d>0&&c?.()},onDidRemoveLastListener(){c=void 0,a.dispose()}});return o?.add(u),u.event}e.None=()=>n.Disposable.None,e.defer=function(e,t){return o(e,(()=>{}),0,void 0,!0,void 0,t)},e.once=t,e.map=i,e.forEach=function(e,t,i){return r(((i,s=null,r)=>e((e=>{t(e),i.call(s,e)}),null,r)),i)},e.filter=s,e.signal=function(e){return e},e.any=function(...e){return(t,i=null,s)=>{return r=(0,n.combinedDisposable)(...e.map((e=>e((e=>t.call(i,e)))))),(o=s)instanceof Array?o.push(r):o&&o.add(r),r;var r,o}},e.reduce=function(e,t,s,r){let n=s;return i(e,(e=>(n=t(n,e),n)),r)},e.debounce=o,e.accumulate=function(t,i=0,s){return e.debounce(t,((e,t)=>e?(e.push(t),e):[t]),i,void 0,!0,void 0,s)},e.latch=function(e,t=(e,t)=>e===t,i){let r,n=!0;return s(e,(e=>{const i=n||!t(e,r);return n=!1,r=e,i}),i)},e.split=function(t,i,s){return[e.filter(t,i,s),e.filter(t,(e=>!i(e)),s)]},e.buffer=function(e,t=!1,i=[],s){let r=i.slice(),n=e((e=>{r?r.push(e):a.fire(e)}));s&&s.add(n);const o=()=>{r?.forEach((e=>a.fire(e))),r=null},a=new m({onWillAddFirstListener(){n||(n=e((e=>a.fire(e))),s&&s.add(n))},onDidAddFirstListener(){r&&(t?setTimeout(o):o())},onDidRemoveLastListener(){n&&n.dispose(),n=null}});return s&&s.add(a),a.event},e.chain=function(e,t){return(i,s,r)=>{const n=t(new l);return e((function(e){const t=n.evaluate(e);t!==a&&i.call(s,t)}),void 0,r)}};const a=Symbol(\"HaltChainable\");class l{constructor(){this.steps=[]}map(e){return this.steps.push(e),this}forEach(e){return this.steps.push((t=>(e(t),t))),this}filter(e){return this.steps.push((t=>e(t)?t:a)),this}reduce(e,t){let i=t;return this.steps.push((t=>(i=e(i,t),i))),this}latch(e=(e,t)=>e===t){let t,i=!0;return this.steps.push((s=>{const r=i||!e(s,t);return i=!1,t=s,r?s:a})),this}evaluate(e){for(const t of this.steps)if((e=t(e))===a)break;return e}}e.fromNodeEventEmitter=function(e,t,i=e=>e){const s=(...e)=>r.fire(i(...e)),r=new m({onWillAddFirstListener:()=>e.on(t,s),onDidRemoveLastListener:()=>e.removeListener(t,s)});return r.event},e.fromDOMEventEmitter=function(e,t,i=e=>e){const s=(...e)=>r.fire(i(...e)),r=new m({onWillAddFirstListener:()=>e.addEventListener(t,s),onDidRemoveLastListener:()=>e.removeEventListener(t,s)});return r.event},e.toPromise=function(e){return new Promise((i=>t(e)(i)))},e.fromPromise=function(e){const t=new m;return e.then((e=>{t.fire(e)}),(()=>{t.fire(void 0)})).finally((()=>{t.dispose()})),t.event},e.forward=function(e,t){return e((e=>t.fire(e)))},e.runAndSubscribe=function(e,t,i){return t(i),e((e=>t(e)))};class h{constructor(e,t){this._observable=e,this._counter=0,this._hasChanged=!1;const i={onWillAddFirstListener:()=>{e.addObserver(this)},onDidRemoveLastListener:()=>{e.removeObserver(this)}};this.emitter=new m(i),t&&t.add(this.emitter)}beginUpdate(e){this._counter++}handlePossibleChange(e){}handleChange(e,t){this._hasChanged=!0}endUpdate(e){this._counter--,0===this._counter&&(this._observable.reportChanges(),this._hasChanged&&(this._hasChanged=!1,this.emitter.fire(this._observable.get())))}}e.fromObservable=function(e,t){return new h(e,t).emitter.event},e.fromObservableLight=function(e){return(t,i,s)=>{let r=0,o=!1;const a={beginUpdate(){r++},endUpdate(){r--,0===r&&(e.reportChanges(),o&&(o=!1,t.call(i)))},handlePossibleChange(){},handleChange(){o=!0}};e.addObserver(a),e.reportChanges();const l={dispose(){e.removeObserver(a)}};return s instanceof n.DisposableStore?s.add(l):Array.isArray(s)&&s.push(l),l}}}(l||(t.Event=l={}));class h{static{this.all=new Set}static{this._idPool=0}constructor(e){this.listenerCount=0,this.invocationCount=0,this.elapsedOverall=0,this.durations=[],this.name=`${e}_${h._idPool++}`,h.all.add(this)}start(e){this._stopWatch=new a.StopWatch,this.listenerCount=e}stop(){if(this._stopWatch){const e=this._stopWatch.elapsed();this.durations.push(e),this.elapsedOverall+=e,this.invocationCount+=1,this._stopWatch=void 0}}}t.EventProfiling=h;let c=-1;class d{static{this._idPool=1}constructor(e,t,i=(d._idPool++).toString(16).padStart(3,\"0\")){this._errorHandler=e,this.threshold=t,this.name=i,this._warnCountdown=0}dispose(){this._stacks?.clear()}check(e,t){const i=this.threshold;if(i<=0||t{const t=this._stacks.get(e.value)||0;this._stacks.set(e.value,t-1)}}getMostFrequentStack(){if(!this._stacks)return;let e,t=0;for(const[i,s]of this._stacks)(!e||t0||this._options?.leakWarningThreshold?new d(e?.onListenerError??s.onUnexpectedError,this._options?.leakWarningThreshold??c):void 0,this._perfMon=this._options?._profName?new h(this._options._profName):void 0,this._deliveryQueue=this._options?.deliveryQueue}dispose(){this._disposed||(this._disposed=!0,this._deliveryQueue?.current===this&&this._deliveryQueue.reset(),this._listeners&&(this._listeners=void 0,this._size=0),this._options?.onDidRemoveLastListener?.(),this._leakageMon?.dispose())}get event(){return this._event??=(e,t,i)=>{if(this._leakageMon&&this._size>this._leakageMon.threshold**2){const e=`[${this._leakageMon.name}] REFUSES to accept new listeners because it exceeded its threshold by far (${this._size} vs ${this._leakageMon.threshold})`;console.warn(e);const t=this._leakageMon.getMostFrequentStack()??[\"UNKNOWN stack\",-1],i=new f(`${e}. HINT: Stack shows most frequent listener (${t[1]}-times)`,t[0]);return(this._options?.onListenerError||s.onUnexpectedError)(i),n.Disposable.None}if(this._disposed)return n.Disposable.None;t&&(e=e.bind(t));const r=new g(e);let o;this._leakageMon&&this._size>=Math.ceil(.2*this._leakageMon.threshold)&&(r.stack=u.create(),o=this._leakageMon.check(r.stack,this._size+1)),this._listeners?this._listeners instanceof g?(this._deliveryQueue??=new v,this._listeners=[this._listeners,r]):this._listeners.push(r):(this._options?.onWillAddFirstListener?.(this),this._listeners=r,this._options?.onDidAddFirstListener?.(this)),this._size++;const a=(0,n.toDisposable)((()=>{o?.(),this._removeListener(r)}));return i instanceof n.DisposableStore?i.add(a):Array.isArray(i)&&i.push(a),a},this._event}_removeListener(e){if(this._options?.onWillRemoveListener?.(this),!this._listeners)return;if(1===this._size)return this._listeners=void 0,this._options?.onDidRemoveLastListener?.(this),void(this._size=0);const t=this._listeners,i=t.indexOf(e);if(-1===i)throw console.log(\"disposed?\",this._disposed),console.log(\"size?\",this._size),console.log(\"arr?\",JSON.stringify(this._listeners)),new Error(\"Attempted to dispose unknown listener\");this._size--,t[i]=void 0;const s=this._deliveryQueue.current===this;if(2*this._size<=t.length){let e=0;for(let i=0;i0}}t.Emitter=m,t.createEventDeliveryQueue=()=>new v;class v{constructor(){this.i=-1,this.end=0}enqueue(e,t,i){this.i=0,this.end=i,this.current=e,this.value=t}reset(){this.i=this.end,this.current=void 0,this.value=void 0}}t.AsyncEmitter=class extends m{async fireAsync(e,t,i){if(this._listeners)for(this._asyncDeliveryQueue||(this._asyncDeliveryQueue=new o.LinkedList),((e,t)=>{if(e instanceof g)t(e);else for(let i=0;ithis._asyncDeliveryQueue.push([t.value,e])));this._asyncDeliveryQueue.size>0&&!t.isCancellationRequested;){const[e,r]=this._asyncDeliveryQueue.shift(),n=[],o={...r,token:t,waitUntil:t=>{if(Object.isFrozen(n))throw new Error(\"waitUntil can NOT be called asynchronous\");i&&(t=i(t,e)),n.push(t)}};try{e(o)}catch(e){(0,s.onUnexpectedError)(e);continue}Object.freeze(n),await Promise.allSettled(n).then((e=>{for(const t of e)\"rejected\"===t.status&&(0,s.onUnexpectedError)(t.reason)}))}}};class S extends m{get isPaused(){return 0!==this._isPaused}constructor(e){super(e),this._isPaused=0,this._eventQueue=new o.LinkedList,this._mergeFn=e?.merge}pause(){this._isPaused++}resume(){if(0!==this._isPaused&&0==--this._isPaused)if(this._mergeFn){if(this._eventQueue.size>0){const e=Array.from(this._eventQueue);this._eventQueue.clear(),super.fire(this._mergeFn(e))}}else for(;!this._isPaused&&0!==this._eventQueue.size;)super.fire(this._eventQueue.shift())}fire(e){this._size&&(0!==this._isPaused?this._eventQueue.push(e):super.fire(e))}}t.PauseableEmitter=S,t.DebounceEmitter=class extends S{constructor(e){super(e),this._delay=e.delay??100}fire(e){this._handle||(this.pause(),this._handle=setTimeout((()=>{this._handle=void 0,this.resume()}),this._delay)),super.fire(e)}},t.MicrotaskEmitter=class extends m{constructor(e){super(e),this._queuedEvents=[],this._mergeFn=e?.merge}fire(e){this.hasListeners()&&(this._queuedEvents.push(e),1===this._queuedEvents.length&&queueMicrotask((()=>{this._mergeFn?super.fire(this._mergeFn(this._queuedEvents)):this._queuedEvents.forEach((e=>super.fire(e))),this._queuedEvents=[]})))}};class b{constructor(){this.hasListeners=!1,this.events=[],this.emitter=new m({onWillAddFirstListener:()=>this.onFirstListenerAdd(),onDidRemoveLastListener:()=>this.onLastListenerRemove()})}get event(){return this.emitter.event}add(e){const t={event:e,listener:null};return this.events.push(t),this.hasListeners&&this.hook(t),(0,n.toDisposable)((0,r.createSingleCallFunction)((()=>{this.hasListeners&&this.unhook(t);const e=this.events.indexOf(t);this.events.splice(e,1)})))}onFirstListenerAdd(){this.hasListeners=!0,this.events.forEach((e=>this.hook(e)))}onLastListenerRemove(){this.hasListeners=!1,this.events.forEach((e=>this.unhook(e)))}hook(e){e.listener=e.event((e=>this.emitter.fire(e)))}unhook(e){e.listener?.dispose(),e.listener=null}dispose(){this.emitter.dispose();for(const e of this.events)e.listener?.dispose();this.events=[]}}t.EventMultiplexer=b,t.DynamicListEventMultiplexer=class{constructor(e,t,i,s){this._store=new n.DisposableStore;const r=this._store.add(new b),o=this._store.add(new n.DisposableMap);function a(e){o.set(e,r.add(s(e)))}for(const t of e)a(t);this._store.add(t((e=>{a(e)}))),this._store.add(i((e=>{o.deleteAndDispose(e)}))),this.event=r.event}dispose(){this._store.dispose()}},t.EventBufferer=class{constructor(){this.data=[]}wrapEvent(e,t,i){return(s,r,n)=>e((e=>{const n=this.data[this.data.length-1];if(!t)return void(n?n.buffers.push((()=>s.call(r,e))):s.call(r,e));const o=n;o?(o.items??=[],o.items.push(e),0===o.buffers.length&&n.buffers.push((()=>{o.reducedResult??=i?o.items.reduce(t,i):o.items.reduce(t),s.call(r,o.reducedResult)}))):s.call(r,t(i,e))}),void 0,n)}bufferEvents(e){const t={buffers:new Array};this.data.push(t);const i=e();return this.data.pop(),t.buffers.forEach((e=>e())),i}},t.Relay=class{constructor(){this.listening=!1,this.inputEvent=l.None,this.inputEventListener=n.Disposable.None,this.emitter=new m({onDidAddFirstListener:()=>{this.listening=!0,this.inputEventListener=this.inputEvent(this.emitter.fire,this.emitter)},onDidRemoveLastListener:()=>{this.listening=!1,this.inputEventListener.dispose()}}),this.event=this.emitter.event}set input(e){this.inputEvent=e,this.listening&&(this.inputEventListener.dispose(),this.inputEventListener=e(this.emitter.fire,this.emitter))}dispose(){this.inputEventListener.dispose(),this.emitter.dispose()}},t.ValueWithChangeEvent=class{static const(e){return new C(e)}constructor(e){this._value=e,this._onDidChange=new m,this.onDidChange=this._onDidChange.event}get value(){return this._value}set value(e){e!==this._value&&(this._value=e,this._onDidChange.fire(void 0))}};class C{constructor(e){this.value=e,this.onDidChange=l.None}}},8841:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.createSingleCallFunction=function(e,t){const i=this;let s,r=!1;return function(){if(r)return s;if(r=!0,t)try{s=e.apply(i,arguments)}finally{t()}else s=e.apply(i,arguments);return s}}},6304:function(e,t,i){var s=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!(\"get\"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)\"default\"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&s(t,e,i);return r(t,e),t};Object.defineProperty(t,\"__esModule\",{value:!0}),t.StringSHA1=t.Hasher=void 0,t.hash=function(e){return a(e,0)},t.doHash=a,t.numberHash=l,t.stringHash=h,t.toHexString=_;const o=n(i(1316));function a(e,t){switch(typeof e){case\"object\":return null===e?l(349,t):Array.isArray(e)?(i=e,s=l(104579,s=t),i.reduce(((e,t)=>a(t,e)),s)):function(e,t){return t=l(181387,t),Object.keys(e).sort().reduce(((t,i)=>(t=h(i,t),a(e[i],t))),t)}(e,t);case\"string\":return h(e,t);case\"boolean\":return function(e,t){return l(e?433:863,t)}(e,t);case\"number\":return l(e,t);case\"undefined\":return l(937,t);default:return l(617,t)}var i,s}function l(e,t){return(t<<5)-t+e|0}function h(e,t){t=l(149417,t);for(let i=0,s=e.length;i>>s)>>>0}function u(e,t=0,i=e.byteLength,s=0){for(let r=0;re.toString(16).padStart(2,\"0\"))).join(\"\"):function(e,t,i=\"0\"){for(;e.length>>0).toString(16),t/4)}t.Hasher=class{constructor(){this._value=0}get value(){return this._value}hash(e){return this._value=a(e,this._value),this._value}},function(e){e[e.BLOCK_SIZE=64]=\"BLOCK_SIZE\",e[e.UNICODE_REPLACEMENT=65533]=\"UNICODE_REPLACEMENT\"}(c||(c={}));class f{static{this._bigBlock32=new DataView(new ArrayBuffer(320))}constructor(){this._h0=1732584193,this._h1=4023233417,this._h2=2562383102,this._h3=271733878,this._h4=3285377520,this._buff=new Uint8Array(c.BLOCK_SIZE+3),this._buffDV=new DataView(this._buff.buffer),this._buffLen=0,this._totalLen=0,this._leftoverHighSurrogate=0,this._finished=!1}update(e){const t=e.length;if(0===t)return;const i=this._buff;let s,r,n=this._buffLen,a=this._leftoverHighSurrogate;for(0!==a?(s=a,r=-1,a=0):(s=e.charCodeAt(0),r=0);;){let l=s;if(o.isHighSurrogate(s)){if(!(r+1>>6,e[t++]=128|(63&i)>>>0):i<65536?(e[t++]=224|(61440&i)>>>12,e[t++]=128|(4032&i)>>>6,e[t++]=128|(63&i)>>>0):(e[t++]=240|(1835008&i)>>>18,e[t++]=128|(258048&i)>>>12,e[t++]=128|(4032&i)>>>6,e[t++]=128|(63&i)>>>0),t>=c.BLOCK_SIZE&&(this._step(),t-=c.BLOCK_SIZE,this._totalLen+=c.BLOCK_SIZE,e[0]=e[c.BLOCK_SIZE+0],e[1]=e[c.BLOCK_SIZE+1],e[2]=e[c.BLOCK_SIZE+2]),t}digest(){return this._finished||(this._finished=!0,this._leftoverHighSurrogate&&(this._leftoverHighSurrogate=0,this._buffLen=this._push(this._buff,this._buffLen,c.UNICODE_REPLACEMENT)),this._totalLen+=this._buffLen,this._wrapUp()),_(this._h0)+_(this._h1)+_(this._h2)+_(this._h3)+_(this._h4)}_wrapUp(){this._buff[this._buffLen++]=128,u(this._buff,this._buffLen),this._buffLen>56&&(this._step(),u(this._buff));const e=8*this._totalLen;this._buffDV.setUint32(56,Math.floor(e/4294967296),!1),this._buffDV.setUint32(60,e%4294967296,!1),this._step()}_step(){const e=f._bigBlock32,t=this._buffDV;for(let i=0;i<64;i+=4)e.setUint32(i,t.getUint32(i,!1),!1);for(let t=64;t<320;t+=4)e.setUint32(t,d(e.getUint32(t-12,!1)^e.getUint32(t-32,!1)^e.getUint32(t-56,!1)^e.getUint32(t-64,!1),1),!1);let i,s,r,n=this._h0,o=this._h1,a=this._h2,l=this._h3,h=this._h4;for(let t=0;t<80;t++)t<20?(i=o&a|~o&l,s=1518500249):t<40?(i=o^a^l,s=1859775393):t<60?(i=o&a|o&l|a&l,s=2400959708):(i=o^a^l,s=3395469782),r=d(n,5)+i+h+s+e.getUint32(4*t,!1)&4294967295,h=l,l=a,a=d(o,30),o=n,n=r;this._h0=this._h0+n&4294967295,this._h1=this._h1+o&4294967295,this._h2=this._h2+a&4294967295,this._h3=this._h3+l&4294967295,this._h4=this._h4+h&4294967295}}t.StringSHA1=f},4218:(e,t)=>{var i;Object.defineProperty(t,\"__esModule\",{value:!0}),t.Iterable=void 0,function(e){function t(e){return e&&\"object\"==typeof e&&\"function\"==typeof e[Symbol.iterator]}e.is=t;const i=Object.freeze([]);function*s(e){yield e}e.empty=function(){return i},e.single=s,e.wrap=function(e){return t(e)?e:s(e)},e.from=function(e){return e||i},e.reverse=function*(e){for(let t=e.length-1;t>=0;t--)yield e[t]},e.isEmpty=function(e){return!e||!0===e[Symbol.iterator]().next().done},e.first=function(e){return e[Symbol.iterator]().next().value},e.some=function(e,t){let i=0;for(const s of e)if(t(s,i++))return!0;return!1},e.find=function(e,t){for(const i of e)if(t(i))return i},e.filter=function*(e,t){for(const i of e)t(i)&&(yield i)},e.map=function*(e,t){let i=0;for(const s of e)yield t(s,i++)},e.flatMap=function*(e,t){let i=0;for(const s of e)yield*t(s,i++)},e.concat=function*(...e){for(const t of e)yield*t},e.reduce=function(e,t,i){let s=i;for(const i of e)s=t(s,i);return s},e.slice=function*(e,t,i=e.length){for(t<0&&(t+=e.length),i<0?i+=e.length:i>e.length&&(i=e.length);tr}]},e.asyncToArray=async function(e){const t=[];for await(const i of e)t.push(i);return Promise.resolve(t)}}(i||(t.Iterable=i={}))},7883:(e,t)=>{var i,s;Object.defineProperty(t,\"__esModule\",{value:!0}),t.KeyMod=t.KeyCodeUtils=t.ScanCodeUtils=t.NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE=t.EVENT_KEY_CODE_MAP=t.ScanCode=t.KeyCode=void 0,t.KeyChord=function(e,t){return(e|(65535&t)<<16>>>0)>>>0},function(e){e[e.DependsOnKbLayout=-1]=\"DependsOnKbLayout\",e[e.Unknown=0]=\"Unknown\",e[e.Backspace=1]=\"Backspace\",e[e.Tab=2]=\"Tab\",e[e.Enter=3]=\"Enter\",e[e.Shift=4]=\"Shift\",e[e.Ctrl=5]=\"Ctrl\",e[e.Alt=6]=\"Alt\",e[e.PauseBreak=7]=\"PauseBreak\",e[e.CapsLock=8]=\"CapsLock\",e[e.Escape=9]=\"Escape\",e[e.Space=10]=\"Space\",e[e.PageUp=11]=\"PageUp\",e[e.PageDown=12]=\"PageDown\",e[e.End=13]=\"End\",e[e.Home=14]=\"Home\",e[e.LeftArrow=15]=\"LeftArrow\",e[e.UpArrow=16]=\"UpArrow\",e[e.RightArrow=17]=\"RightArrow\",e[e.DownArrow=18]=\"DownArrow\",e[e.Insert=19]=\"Insert\",e[e.Delete=20]=\"Delete\",e[e.Digit0=21]=\"Digit0\",e[e.Digit1=22]=\"Digit1\",e[e.Digit2=23]=\"Digit2\",e[e.Digit3=24]=\"Digit3\",e[e.Digit4=25]=\"Digit4\",e[e.Digit5=26]=\"Digit5\",e[e.Digit6=27]=\"Digit6\",e[e.Digit7=28]=\"Digit7\",e[e.Digit8=29]=\"Digit8\",e[e.Digit9=30]=\"Digit9\",e[e.KeyA=31]=\"KeyA\",e[e.KeyB=32]=\"KeyB\",e[e.KeyC=33]=\"KeyC\",e[e.KeyD=34]=\"KeyD\",e[e.KeyE=35]=\"KeyE\",e[e.KeyF=36]=\"KeyF\",e[e.KeyG=37]=\"KeyG\",e[e.KeyH=38]=\"KeyH\",e[e.KeyI=39]=\"KeyI\",e[e.KeyJ=40]=\"KeyJ\",e[e.KeyK=41]=\"KeyK\",e[e.KeyL=42]=\"KeyL\",e[e.KeyM=43]=\"KeyM\",e[e.KeyN=44]=\"KeyN\",e[e.KeyO=45]=\"KeyO\",e[e.KeyP=46]=\"KeyP\",e[e.KeyQ=47]=\"KeyQ\",e[e.KeyR=48]=\"KeyR\",e[e.KeyS=49]=\"KeyS\",e[e.KeyT=50]=\"KeyT\",e[e.KeyU=51]=\"KeyU\",e[e.KeyV=52]=\"KeyV\",e[e.KeyW=53]=\"KeyW\",e[e.KeyX=54]=\"KeyX\",e[e.KeyY=55]=\"KeyY\",e[e.KeyZ=56]=\"KeyZ\",e[e.Meta=57]=\"Meta\",e[e.ContextMenu=58]=\"ContextMenu\",e[e.F1=59]=\"F1\",e[e.F2=60]=\"F2\",e[e.F3=61]=\"F3\",e[e.F4=62]=\"F4\",e[e.F5=63]=\"F5\",e[e.F6=64]=\"F6\",e[e.F7=65]=\"F7\",e[e.F8=66]=\"F8\",e[e.F9=67]=\"F9\",e[e.F10=68]=\"F10\",e[e.F11=69]=\"F11\",e[e.F12=70]=\"F12\",e[e.F13=71]=\"F13\",e[e.F14=72]=\"F14\",e[e.F15=73]=\"F15\",e[e.F16=74]=\"F16\",e[e.F17=75]=\"F17\",e[e.F18=76]=\"F18\",e[e.F19=77]=\"F19\",e[e.F20=78]=\"F20\",e[e.F21=79]=\"F21\",e[e.F22=80]=\"F22\",e[e.F23=81]=\"F23\",e[e.F24=82]=\"F24\",e[e.NumLock=83]=\"NumLock\",e[e.ScrollLock=84]=\"ScrollLock\",e[e.Semicolon=85]=\"Semicolon\",e[e.Equal=86]=\"Equal\",e[e.Comma=87]=\"Comma\",e[e.Minus=88]=\"Minus\",e[e.Period=89]=\"Period\",e[e.Slash=90]=\"Slash\",e[e.Backquote=91]=\"Backquote\",e[e.BracketLeft=92]=\"BracketLeft\",e[e.Backslash=93]=\"Backslash\",e[e.BracketRight=94]=\"BracketRight\",e[e.Quote=95]=\"Quote\",e[e.OEM_8=96]=\"OEM_8\",e[e.IntlBackslash=97]=\"IntlBackslash\",e[e.Numpad0=98]=\"Numpad0\",e[e.Numpad1=99]=\"Numpad1\",e[e.Numpad2=100]=\"Numpad2\",e[e.Numpad3=101]=\"Numpad3\",e[e.Numpad4=102]=\"Numpad4\",e[e.Numpad5=103]=\"Numpad5\",e[e.Numpad6=104]=\"Numpad6\",e[e.Numpad7=105]=\"Numpad7\",e[e.Numpad8=106]=\"Numpad8\",e[e.Numpad9=107]=\"Numpad9\",e[e.NumpadMultiply=108]=\"NumpadMultiply\",e[e.NumpadAdd=109]=\"NumpadAdd\",e[e.NUMPAD_SEPARATOR=110]=\"NUMPAD_SEPARATOR\",e[e.NumpadSubtract=111]=\"NumpadSubtract\",e[e.NumpadDecimal=112]=\"NumpadDecimal\",e[e.NumpadDivide=113]=\"NumpadDivide\",e[e.KEY_IN_COMPOSITION=114]=\"KEY_IN_COMPOSITION\",e[e.ABNT_C1=115]=\"ABNT_C1\",e[e.ABNT_C2=116]=\"ABNT_C2\",e[e.AudioVolumeMute=117]=\"AudioVolumeMute\",e[e.AudioVolumeUp=118]=\"AudioVolumeUp\",e[e.AudioVolumeDown=119]=\"AudioVolumeDown\",e[e.BrowserSearch=120]=\"BrowserSearch\",e[e.BrowserHome=121]=\"BrowserHome\",e[e.BrowserBack=122]=\"BrowserBack\",e[e.BrowserForward=123]=\"BrowserForward\",e[e.MediaTrackNext=124]=\"MediaTrackNext\",e[e.MediaTrackPrevious=125]=\"MediaTrackPrevious\",e[e.MediaStop=126]=\"MediaStop\",e[e.MediaPlayPause=127]=\"MediaPlayPause\",e[e.LaunchMediaPlayer=128]=\"LaunchMediaPlayer\",e[e.LaunchMail=129]=\"LaunchMail\",e[e.LaunchApp2=130]=\"LaunchApp2\",e[e.Clear=131]=\"Clear\",e[e.MAX_VALUE=132]=\"MAX_VALUE\"}(i||(t.KeyCode=i={})),function(e){e[e.DependsOnKbLayout=-1]=\"DependsOnKbLayout\",e[e.None=0]=\"None\",e[e.Hyper=1]=\"Hyper\",e[e.Super=2]=\"Super\",e[e.Fn=3]=\"Fn\",e[e.FnLock=4]=\"FnLock\",e[e.Suspend=5]=\"Suspend\",e[e.Resume=6]=\"Resume\",e[e.Turbo=7]=\"Turbo\",e[e.Sleep=8]=\"Sleep\",e[e.WakeUp=9]=\"WakeUp\",e[e.KeyA=10]=\"KeyA\",e[e.KeyB=11]=\"KeyB\",e[e.KeyC=12]=\"KeyC\",e[e.KeyD=13]=\"KeyD\",e[e.KeyE=14]=\"KeyE\",e[e.KeyF=15]=\"KeyF\",e[e.KeyG=16]=\"KeyG\",e[e.KeyH=17]=\"KeyH\",e[e.KeyI=18]=\"KeyI\",e[e.KeyJ=19]=\"KeyJ\",e[e.KeyK=20]=\"KeyK\",e[e.KeyL=21]=\"KeyL\",e[e.KeyM=22]=\"KeyM\",e[e.KeyN=23]=\"KeyN\",e[e.KeyO=24]=\"KeyO\",e[e.KeyP=25]=\"KeyP\",e[e.KeyQ=26]=\"KeyQ\",e[e.KeyR=27]=\"KeyR\",e[e.KeyS=28]=\"KeyS\",e[e.KeyT=29]=\"KeyT\",e[e.KeyU=30]=\"KeyU\",e[e.KeyV=31]=\"KeyV\",e[e.KeyW=32]=\"KeyW\",e[e.KeyX=33]=\"KeyX\",e[e.KeyY=34]=\"KeyY\",e[e.KeyZ=35]=\"KeyZ\",e[e.Digit1=36]=\"Digit1\",e[e.Digit2=37]=\"Digit2\",e[e.Digit3=38]=\"Digit3\",e[e.Digit4=39]=\"Digit4\",e[e.Digit5=40]=\"Digit5\",e[e.Digit6=41]=\"Digit6\",e[e.Digit7=42]=\"Digit7\",e[e.Digit8=43]=\"Digit8\",e[e.Digit9=44]=\"Digit9\",e[e.Digit0=45]=\"Digit0\",e[e.Enter=46]=\"Enter\",e[e.Escape=47]=\"Escape\",e[e.Backspace=48]=\"Backspace\",e[e.Tab=49]=\"Tab\",e[e.Space=50]=\"Space\",e[e.Minus=51]=\"Minus\",e[e.Equal=52]=\"Equal\",e[e.BracketLeft=53]=\"BracketLeft\",e[e.BracketRight=54]=\"BracketRight\",e[e.Backslash=55]=\"Backslash\",e[e.IntlHash=56]=\"IntlHash\",e[e.Semicolon=57]=\"Semicolon\",e[e.Quote=58]=\"Quote\",e[e.Backquote=59]=\"Backquote\",e[e.Comma=60]=\"Comma\",e[e.Period=61]=\"Period\",e[e.Slash=62]=\"Slash\",e[e.CapsLock=63]=\"CapsLock\",e[e.F1=64]=\"F1\",e[e.F2=65]=\"F2\",e[e.F3=66]=\"F3\",e[e.F4=67]=\"F4\",e[e.F5=68]=\"F5\",e[e.F6=69]=\"F6\",e[e.F7=70]=\"F7\",e[e.F8=71]=\"F8\",e[e.F9=72]=\"F9\",e[e.F10=73]=\"F10\",e[e.F11=74]=\"F11\",e[e.F12=75]=\"F12\",e[e.PrintScreen=76]=\"PrintScreen\",e[e.ScrollLock=77]=\"ScrollLock\",e[e.Pause=78]=\"Pause\",e[e.Insert=79]=\"Insert\",e[e.Home=80]=\"Home\",e[e.PageUp=81]=\"PageUp\",e[e.Delete=82]=\"Delete\",e[e.End=83]=\"End\",e[e.PageDown=84]=\"PageDown\",e[e.ArrowRight=85]=\"ArrowRight\",e[e.ArrowLeft=86]=\"ArrowLeft\",e[e.ArrowDown=87]=\"ArrowDown\",e[e.ArrowUp=88]=\"ArrowUp\",e[e.NumLock=89]=\"NumLock\",e[e.NumpadDivide=90]=\"NumpadDivide\",e[e.NumpadMultiply=91]=\"NumpadMultiply\",e[e.NumpadSubtract=92]=\"NumpadSubtract\",e[e.NumpadAdd=93]=\"NumpadAdd\",e[e.NumpadEnter=94]=\"NumpadEnter\",e[e.Numpad1=95]=\"Numpad1\",e[e.Numpad2=96]=\"Numpad2\",e[e.Numpad3=97]=\"Numpad3\",e[e.Numpad4=98]=\"Numpad4\",e[e.Numpad5=99]=\"Numpad5\",e[e.Numpad6=100]=\"Numpad6\",e[e.Numpad7=101]=\"Numpad7\",e[e.Numpad8=102]=\"Numpad8\",e[e.Numpad9=103]=\"Numpad9\",e[e.Numpad0=104]=\"Numpad0\",e[e.NumpadDecimal=105]=\"NumpadDecimal\",e[e.IntlBackslash=106]=\"IntlBackslash\",e[e.ContextMenu=107]=\"ContextMenu\",e[e.Power=108]=\"Power\",e[e.NumpadEqual=109]=\"NumpadEqual\",e[e.F13=110]=\"F13\",e[e.F14=111]=\"F14\",e[e.F15=112]=\"F15\",e[e.F16=113]=\"F16\",e[e.F17=114]=\"F17\",e[e.F18=115]=\"F18\",e[e.F19=116]=\"F19\",e[e.F20=117]=\"F20\",e[e.F21=118]=\"F21\",e[e.F22=119]=\"F22\",e[e.F23=120]=\"F23\",e[e.F24=121]=\"F24\",e[e.Open=122]=\"Open\",e[e.Help=123]=\"Help\",e[e.Select=124]=\"Select\",e[e.Again=125]=\"Again\",e[e.Undo=126]=\"Undo\",e[e.Cut=127]=\"Cut\",e[e.Copy=128]=\"Copy\",e[e.Paste=129]=\"Paste\",e[e.Find=130]=\"Find\",e[e.AudioVolumeMute=131]=\"AudioVolumeMute\",e[e.AudioVolumeUp=132]=\"AudioVolumeUp\",e[e.AudioVolumeDown=133]=\"AudioVolumeDown\",e[e.NumpadComma=134]=\"NumpadComma\",e[e.IntlRo=135]=\"IntlRo\",e[e.KanaMode=136]=\"KanaMode\",e[e.IntlYen=137]=\"IntlYen\",e[e.Convert=138]=\"Convert\",e[e.NonConvert=139]=\"NonConvert\",e[e.Lang1=140]=\"Lang1\",e[e.Lang2=141]=\"Lang2\",e[e.Lang3=142]=\"Lang3\",e[e.Lang4=143]=\"Lang4\",e[e.Lang5=144]=\"Lang5\",e[e.Abort=145]=\"Abort\",e[e.Props=146]=\"Props\",e[e.NumpadParenLeft=147]=\"NumpadParenLeft\",e[e.NumpadParenRight=148]=\"NumpadParenRight\",e[e.NumpadBackspace=149]=\"NumpadBackspace\",e[e.NumpadMemoryStore=150]=\"NumpadMemoryStore\",e[e.NumpadMemoryRecall=151]=\"NumpadMemoryRecall\",e[e.NumpadMemoryClear=152]=\"NumpadMemoryClear\",e[e.NumpadMemoryAdd=153]=\"NumpadMemoryAdd\",e[e.NumpadMemorySubtract=154]=\"NumpadMemorySubtract\",e[e.NumpadClear=155]=\"NumpadClear\",e[e.NumpadClearEntry=156]=\"NumpadClearEntry\",e[e.ControlLeft=157]=\"ControlLeft\",e[e.ShiftLeft=158]=\"ShiftLeft\",e[e.AltLeft=159]=\"AltLeft\",e[e.MetaLeft=160]=\"MetaLeft\",e[e.ControlRight=161]=\"ControlRight\",e[e.ShiftRight=162]=\"ShiftRight\",e[e.AltRight=163]=\"AltRight\",e[e.MetaRight=164]=\"MetaRight\",e[e.BrightnessUp=165]=\"BrightnessUp\",e[e.BrightnessDown=166]=\"BrightnessDown\",e[e.MediaPlay=167]=\"MediaPlay\",e[e.MediaRecord=168]=\"MediaRecord\",e[e.MediaFastForward=169]=\"MediaFastForward\",e[e.MediaRewind=170]=\"MediaRewind\",e[e.MediaTrackNext=171]=\"MediaTrackNext\",e[e.MediaTrackPrevious=172]=\"MediaTrackPrevious\",e[e.MediaStop=173]=\"MediaStop\",e[e.Eject=174]=\"Eject\",e[e.MediaPlayPause=175]=\"MediaPlayPause\",e[e.MediaSelect=176]=\"MediaSelect\",e[e.LaunchMail=177]=\"LaunchMail\",e[e.LaunchApp2=178]=\"LaunchApp2\",e[e.LaunchApp1=179]=\"LaunchApp1\",e[e.SelectTask=180]=\"SelectTask\",e[e.LaunchScreenSaver=181]=\"LaunchScreenSaver\",e[e.BrowserSearch=182]=\"BrowserSearch\",e[e.BrowserHome=183]=\"BrowserHome\",e[e.BrowserBack=184]=\"BrowserBack\",e[e.BrowserForward=185]=\"BrowserForward\",e[e.BrowserStop=186]=\"BrowserStop\",e[e.BrowserRefresh=187]=\"BrowserRefresh\",e[e.BrowserFavorites=188]=\"BrowserFavorites\",e[e.ZoomToggle=189]=\"ZoomToggle\",e[e.MailReply=190]=\"MailReply\",e[e.MailForward=191]=\"MailForward\",e[e.MailSend=192]=\"MailSend\",e[e.MAX_VALUE=193]=\"MAX_VALUE\"}(s||(t.ScanCode=s={}));class r{constructor(){this._keyCodeToStr=[],this._strToKeyCode=Object.create(null)}define(e,t){this._keyCodeToStr[e]=t,this._strToKeyCode[t.toLowerCase()]=e}keyCodeToStr(e){return this._keyCodeToStr[e]}strToKeyCode(e){return this._strToKeyCode[e.toLowerCase()]||i.Unknown}}const n=new r,o=new r,a=new r;t.EVENT_KEY_CODE_MAP=new Array(230),t.NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE={};const l=[],h=Object.create(null),c=Object.create(null);var d,u;t.ScanCodeUtils={lowerCaseToEnum:e=>c[e]||s.None,toEnum:e=>h[e]||s.None,toString:e=>l[e]||\"None\"},function(e){e.toString=function(e){return n.keyCodeToStr(e)},e.fromString=function(e){return n.strToKeyCode(e)},e.toUserSettingsUS=function(e){return o.keyCodeToStr(e)},e.toUserSettingsGeneral=function(e){return a.keyCodeToStr(e)},e.fromUserSettings=function(e){return o.strToKeyCode(e)||a.strToKeyCode(e)},e.toElectronAccelerator=function(e){if(e>=i.Numpad0&&e<=i.NumpadDivide)return null;switch(e){case i.UpArrow:return\"Up\";case i.DownArrow:return\"Down\";case i.LeftArrow:return\"Left\";case i.RightArrow:return\"Right\"}return n.keyCodeToStr(e)}}(d||(t.KeyCodeUtils=d={})),function(e){e[e.CtrlCmd=2048]=\"CtrlCmd\",e[e.Shift=1024]=\"Shift\",e[e.Alt=512]=\"Alt\",e[e.WinCtrl=256]=\"WinCtrl\"}(u||(t.KeyMod=u={}))},2811:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ResolvedKeybinding=t.ResolvedChord=t.Keybinding=t.ScanCodeChord=t.KeyCodeChord=void 0,t.decodeKeybinding=function(e,t){if(\"number\"==typeof e){if(0===e)return null;const i=(65535&e)>>>0,s=(4294901760&e)>>>16;return new c(0!==s?[a(i,t),a(s,t)]:[a(i,t)])}{const i=[];for(let s=0;s{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Lazy=void 0,t.Lazy=class{constructor(e){this.executor=e,this._didRun=!1}get hasValue(){return this._didRun}get value(){if(!this._didRun)try{this._value=this.executor()}catch(e){this._error=e}finally{this._didRun=!0}if(this._error)throw this._error;return this._value}get rawValue(){return this._value}}},7150:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.DisposableMap=t.ImmortalReference=t.AsyncReferenceCollection=t.ReferenceCollection=t.SafeDisposable=t.RefCountedDisposable=t.MandatoryMutableDisposable=t.MutableDisposable=t.Disposable=t.DisposableStore=t.DisposableTracker=void 0,t.setDisposableTracker=function(e){l=e},t.trackDisposable=c,t.markAsDisposed=d,t.markAsSingleton=function(e){return l?.markAsSingleton(e),e},t.isDisposable=_,t.dispose=f,t.disposeIfDisposable=function(e){for(const t of e)_(t)&&t.dispose();return[]},t.combinedDisposable=function(...e){const t=p((()=>f(e)));return function(e,t){if(l)for(const i of e)l.setParent(i,t)}(e,t),t},t.toDisposable=p,t.disposeOnReturn=function(e){const t=new g;try{e(t)}finally{t.dispose()}};const s=i(3058),r=i(9087),n=i(2608),o=i(8841),a=i(4218);let l=null;class h{constructor(){this.livingDisposables=new Map}static{this.idx=0}getDisposableData(e){let t=this.livingDisposables.get(e);return t||(t={parent:null,source:null,isSingleton:!1,value:e,idx:h.idx++},this.livingDisposables.set(e,t)),t}trackDisposable(e){const t=this.getDisposableData(e);t.source||(t.source=(new Error).stack)}setParent(e,t){this.getDisposableData(e).parent=t}markAsDisposed(e){this.livingDisposables.delete(e)}markAsSingleton(e){this.getDisposableData(e).isSingleton=!0}getRootParent(e,t){const i=t.get(e);if(i)return i;const s=e.parent?this.getRootParent(this.getDisposableData(e.parent),t):e;return t.set(e,s),s}getTrackedDisposables(){const e=new Map;return[...this.livingDisposables.entries()].filter((([,t])=>null!==t.source&&!this.getRootParent(t,e).isSingleton)).flatMap((([e])=>e))}computeLeakingDisposables(e=10,t){let i;if(t)i=t;else{const e=new Map,t=[...this.livingDisposables.values()].filter((t=>null!==t.source&&!this.getRootParent(t,e).isSingleton));if(0===t.length)return;const s=new Set(t.map((e=>e.value)));if(i=t.filter((e=>!(e.parent&&s.has(e.parent)))),0===i.length)throw new Error(\"There are cyclic diposable chains!\")}if(!i)return;function o(e){const t=e.source.split(\"\\n\").map((e=>e.trim().replace(\"at \",\"\"))).filter((e=>\"\"!==e));return function(e,t){for(;e.length>0&&t.some((t=>\"string\"==typeof t?t===e[0]:e[0].match(t)));)e.shift()}(t,[\"Error\",/^trackDisposable \\(.*\\)$/,/^DisposableTracker.trackDisposable \\(.*\\)$/]),t.reverse()}const a=new n.SetMap;for(const e of i){const t=o(e);for(let i=0;i<=t.length;i++)a.add(t.slice(0,i).join(\"\\n\"),e)}i.sort((0,s.compareBy)((e=>e.idx),s.numberComparator));let l=\"\",h=0;for(const t of i.slice(0,e)){h++;const e=o(t),s=[];for(let t=0;to(e)[t])),(e=>e));delete h[e[t]];for(const[e,t]of Object.entries(h))s.unshift(` - stacktraces of ${t.length} other leaks continue with ${e}`);s.unshift(n)}l+=`\\n\\n\\n==================== Leaking disposable ${h}/${i.length}: ${t.value.constructor.name} ====================\\n${s.join(\"\\n\")}\\n============================================================\\n\\n`}return i.length>e&&(l+=`\\n\\n\\n... and ${i.length-e} more leaking disposables\\n\\n`),{leaks:i,details:l}}}function c(e){return l?.trackDisposable(e),e}function d(e){l?.markAsDisposed(e)}function u(e,t){l?.setParent(e,t)}function _(e){return\"object\"==typeof e&&null!==e&&\"function\"==typeof e.dispose&&0===e.dispose.length}function f(e){if(a.Iterable.is(e)){const t=[];for(const i of e)if(i)try{i.dispose()}catch(e){t.push(e)}if(1===t.length)throw t[0];if(t.length>1)throw new AggregateError(t,\"Encountered errors while disposing of store\");return Array.isArray(e)?[]:e}if(e)return e.dispose(),e}function p(e){const t=c({dispose:(0,o.createSingleCallFunction)((()=>{d(t),e()}))});return t}t.DisposableTracker=h;class g{static{this.DISABLE_DISPOSED_WARNING=!1}constructor(){this._toDispose=new Set,this._isDisposed=!1,c(this)}dispose(){this._isDisposed||(d(this),this._isDisposed=!0,this.clear())}get isDisposed(){return this._isDisposed}clear(){if(0!==this._toDispose.size)try{f(this._toDispose)}finally{this._toDispose.clear()}}add(e){if(!e)return e;if(e===this)throw new Error(\"Cannot register a disposable on itself!\");return u(e,this),this._isDisposed?g.DISABLE_DISPOSED_WARNING||console.warn(new Error(\"Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!\").stack):this._toDispose.add(e),e}delete(e){if(e){if(e===this)throw new Error(\"Cannot dispose a disposable on itself!\");this._toDispose.delete(e),e.dispose()}}deleteAndLeak(e){e&&this._toDispose.has(e)&&(this._toDispose.delete(e),u(e,null))}}t.DisposableStore=g;class m{static{this.None=Object.freeze({dispose(){}})}constructor(){this._store=new g,c(this),u(this._store,this)}dispose(){d(this),this._store.dispose()}_register(e){if(e===this)throw new Error(\"Cannot register a disposable on itself!\");return this._store.add(e)}}t.Disposable=m;class v{constructor(){this._isDisposed=!1,c(this)}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),e&&u(e,this),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,d(this),this._value?.dispose(),this._value=void 0}clearAndLeak(){const e=this._value;return this._value=void 0,e&&u(e,null),e}}t.MutableDisposable=v,t.MandatoryMutableDisposable=class{constructor(e){this._disposable=new v,this._isDisposed=!1,this._disposable.value=e}get value(){return this._disposable.value}set value(e){this._isDisposed||e===this._disposable.value||(this._disposable.value=e)}dispose(){this._isDisposed=!0,this._disposable.dispose()}},t.RefCountedDisposable=class{constructor(e){this._disposable=e,this._counter=1}acquire(){return this._counter++,this}release(){return 0==--this._counter&&this._disposable.dispose(),this}},t.SafeDisposable=class{constructor(){this.dispose=()=>{},this.unset=()=>{},this.isset=()=>!1,c(this)}set(e){let t=e;return this.unset=()=>t=void 0,this.isset=()=>void 0!==t,this.dispose=()=>{t&&(t(),t=void 0,d(this))},this}},t.ReferenceCollection=class{constructor(){this.references=new Map}acquire(e,...t){let i=this.references.get(e);i||(i={counter:0,object:this.createReferencedObject(e,...t)},this.references.set(e,i));const{object:s}=i,r=(0,o.createSingleCallFunction)((()=>{0==--i.counter&&(this.destroyReferencedObject(e,i.object),this.references.delete(e))}));return i.counter++,{object:s,dispose:r}}},t.AsyncReferenceCollection=class{constructor(e){this.referenceCollection=e}async acquire(e,...t){const i=this.referenceCollection.acquire(e,...t);try{return{object:await i.object,dispose:()=>i.dispose()}}catch(e){throw i.dispose(),e}}},t.ImmortalReference=class{constructor(e){this.object=e}dispose(){}};class S{constructor(){this._store=new Map,this._isDisposed=!1,c(this)}dispose(){d(this),this._isDisposed=!0,this.clearAndDisposeAll()}clearAndDisposeAll(){if(this._store.size)try{f(this._store.values())}finally{this._store.clear()}}has(e){return this._store.has(e)}get size(){return this._store.size}get(e){return this._store.get(e)}set(e,t,i=!1){this._isDisposed&&console.warn(new Error(\"Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!\").stack),i||this._store.get(e)?.dispose(),this._store.set(e,t)}deleteAndDispose(e){this._store.get(e)?.dispose(),this._store.delete(e)}deleteAndLeak(e){const t=this._store.get(e);return this._store.delete(e),t}keys(){return this._store.keys()}values(){return this._store.values()}[Symbol.iterator](){return this._store[Symbol.iterator]()}}t.DisposableMap=S},6317:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LinkedList=void 0;class i{static{this.Undefined=new i(void 0)}constructor(e){this.element=e,this.next=i.Undefined,this.prev=i.Undefined}}class s{constructor(){this._first=i.Undefined,this._last=i.Undefined,this._size=0}get size(){return this._size}isEmpty(){return this._first===i.Undefined}clear(){let e=this._first;for(;e!==i.Undefined;){const t=e.next;e.prev=i.Undefined,e.next=i.Undefined,e=t}this._first=i.Undefined,this._last=i.Undefined,this._size=0}unshift(e){return this._insert(e,!1)}push(e){return this._insert(e,!0)}_insert(e,t){const s=new i(e);if(this._first===i.Undefined)this._first=s,this._last=s;else if(t){const e=this._last;this._last=s,s.prev=e,e.next=s}else{const e=this._first;this._first=s,s.next=e,e.prev=s}this._size+=1;let r=!1;return()=>{r||(r=!0,this._remove(s))}}shift(){if(this._first!==i.Undefined){const e=this._first.element;return this._remove(this._first),e}}pop(){if(this._last!==i.Undefined){const e=this._last.element;return this._remove(this._last),e}}_remove(e){if(e.prev!==i.Undefined&&e.next!==i.Undefined){const t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===i.Undefined&&e.next===i.Undefined?(this._first=i.Undefined,this._last=i.Undefined):e.next===i.Undefined?(this._last=this._last.prev,this._last.next=i.Undefined):e.prev===i.Undefined&&(this._first=this._first.next,this._first.prev=i.Undefined);this._size-=1}*[Symbol.iterator](){let e=this._first;for(;e!==i.Undefined;)yield e.element,e=e.next}}t.LinkedList=s},2608:(e,t)=>{var i;Object.defineProperty(t,\"__esModule\",{value:!0}),t.SetMap=t.BidirectionalMap=t.CounterSet=t.Touch=void 0,t.getOrSet=function(e,t,i){let s=e.get(t);return void 0===s&&(s=i,e.set(t,s)),s},t.mapToString=function(e){const t=[];return e.forEach(((e,i)=>{t.push(`${i} => ${e}`)})),`Map(${e.size}) {${t.join(\", \")}}`},t.setToString=function(e){const t=[];return e.forEach((e=>{t.push(e)})),`Set(${e.size}) {${t.join(\", \")}}`},t.mapsStrictEqualIgnoreOrder=function(e,t){if(e===t)return!0;if(e.size!==t.size)return!1;for(const[i,s]of e)if(!t.has(i)||t.get(i)!==s)return!1;for(const[i]of t)if(!e.has(i))return!1;return!0},function(e){e[e.None=0]=\"None\",e[e.AsOld=1]=\"AsOld\",e[e.AsNew=2]=\"AsNew\"}(i||(t.Touch=i={})),t.CounterSet=class{constructor(){this.map=new Map}add(e){return this.map.set(e,(this.map.get(e)||0)+1),this}delete(e){let t=this.map.get(e)||0;return 0!==t&&(t--,0===t?this.map.delete(e):this.map.set(e,t),!0)}has(e){return this.map.has(e)}},t.BidirectionalMap=class{constructor(e){if(this._m1=new Map,this._m2=new Map,e)for(const[t,i]of e)this.set(t,i)}clear(){this._m1.clear(),this._m2.clear()}set(e,t){this._m1.set(e,t),this._m2.set(t,e)}get(e){return this._m1.get(e)}getKey(e){return this._m2.get(e)}delete(e){const t=this._m1.get(e);return void 0!==t&&(this._m1.delete(e),this._m2.delete(t),!0)}forEach(e,t){this._m1.forEach(((i,s)=>{e.call(t,i,s,this)}))}keys(){return this._m1.keys()}values(){return this._m1.values()}},t.SetMap=class{constructor(){this.map=new Map}add(e,t){let i=this.map.get(e);i||(i=new Set,this.map.set(e,i)),i.add(t)}delete(e,t){const i=this.map.get(e);i&&(i.delete(t),0===i.size&&this.map.delete(e))}forEach(e,t){const i=this.map.get(e);i&&i.forEach(t)}get(e){return this.map.get(e)||new Set}}},7704:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.SlidingWindowAverage=t.MovingAverage=t.Counter=void 0,t.clamp=function(e,t,i){return Math.min(Math.max(e,t),i)},t.rot=function(e,t){return(t+e%t)%t},t.isPointWithinTriangle=function(e,t,i,s,r,n,o,a){const l=o-i,h=a-s,c=r-i,d=n-s,u=e-i,_=t-s,f=l*l+h*h,p=l*c+h*d,g=l*u+h*_,m=c*c+d*d,v=c*u+d*_,S=1/(f*m-p*p),b=(m*g-p*v)*S,C=(f*v-p*g)*S;return b>=0&&C>=0&&b+C<1},t.Counter=class{constructor(){this._next=0}getNext(){return this._next++}},t.MovingAverage=class{constructor(){this._n=1,this._val=0}update(e){return this._val=this._val+(e-this._val)/this._n,this._n+=1,this._val}get value(){return this._val}},t.SlidingWindowAverage=class{constructor(e){this._n=0,this._val=0,this._values=[],this._index=0,this._sum=0,this._values=new Array(e),this._values.fill(0,0,e)}update(e){const t=this._values[this._index];return this._values[this._index]=e,this._index=(this._index+1)%this._values.length,this._sum-=t,this._sum+=e,this._n{Object.defineProperty(t,\"__esModule\",{value:!0}),t.isAndroid=t.isEdge=t.isSafari=t.isFirefox=t.isChrome=t.OS=t.OperatingSystem=t.setTimeout0=t.setTimeout0IsFaster=t.translationsConfigFile=t.platformLocale=t.locale=t.Language=t.language=t.userAgent=t.platform=t.isCI=t.isMobile=t.isIOS=t.webWorkerOrigin=t.isWebWorker=t.isWeb=t.isElectron=t.isNative=t.isLinuxSnap=t.isLinux=t.isMacintosh=t.isWindows=t.Platform=t.LANGUAGE_DEFAULT=void 0,t.PlatformToString=function(e){switch(e){case C.Web:return\"Web\";case C.Mac:return\"Mac\";case C.Linux:return\"Linux\";case C.Windows:return\"Windows\"}},t.isLittleEndian=function(){if(!L){L=!0;const e=new Uint8Array(2);e[0]=1,e[1]=2;const t=new Uint16Array(e.buffer);D=513===t[0]}return D},t.isBigSurOrNewer=function(e){return parseFloat(e)>=20},t.LANGUAGE_DEFAULT=\"en\";let i,s,r,n=!1,o=!1,a=!1,l=!1,h=!1,c=!1,d=!1,u=!1,_=!1,f=!1,p=t.LANGUAGE_DEFAULT,g=t.LANGUAGE_DEFAULT;const m=globalThis;let v;void 0!==m.vscode&&void 0!==m.vscode.process?v=m.vscode.process:\"undefined\"!=typeof process&&\"string\"==typeof process?.versions?.node&&(v=process);const S=\"string\"==typeof v?.versions?.electron,b=S&&\"renderer\"===v?.type;if(\"object\"==typeof v){n=\"win32\"===v.platform,o=\"darwin\"===v.platform,a=\"linux\"===v.platform,l=a&&!!v.env.SNAP&&!!v.env.SNAP_REVISION,d=S,_=!!v.env.CI||!!v.env.BUILD_ARTIFACTSTAGINGDIRECTORY,i=t.LANGUAGE_DEFAULT,p=t.LANGUAGE_DEFAULT;const e=v.env.VSCODE_NLS_CONFIG;if(e)try{const r=JSON.parse(e);i=r.userLocale,g=r.osLocale,p=r.resolvedLanguage||t.LANGUAGE_DEFAULT,s=r.languagePack?.translationsConfigFile}catch(e){}h=!0}else\"object\"!=typeof navigator||b?console.error(\"Unable to resolve platform.\"):(r=navigator.userAgent,n=r.indexOf(\"Windows\")>=0,o=r.indexOf(\"Macintosh\")>=0,u=(r.indexOf(\"Macintosh\")>=0||r.indexOf(\"iPad\")>=0||r.indexOf(\"iPhone\")>=0)&&!!navigator.maxTouchPoints&&navigator.maxTouchPoints>0,a=r.indexOf(\"Linux\")>=0,f=r?.indexOf(\"Mobi\")>=0,c=!0,p=globalThis._VSCODE_NLS_LANGUAGE||t.LANGUAGE_DEFAULT,i=navigator.language.toLowerCase(),g=i);var C;!function(e){e[e.Web=0]=\"Web\",e[e.Mac=1]=\"Mac\",e[e.Linux=2]=\"Linux\",e[e.Windows=3]=\"Windows\"}(C||(t.Platform=C={}));let y=C.Web;var w,E;o?y=C.Mac:n?y=C.Windows:a&&(y=C.Linux),t.isWindows=n,t.isMacintosh=o,t.isLinux=a,t.isLinuxSnap=l,t.isNative=h,t.isElectron=d,t.isWeb=c,t.isWebWorker=c&&\"function\"==typeof m.importScripts,t.webWorkerOrigin=t.isWebWorker?m.origin:void 0,t.isIOS=u,t.isMobile=f,t.isCI=_,t.platform=y,t.userAgent=r,t.language=p,function(e){e.value=function(){return t.language},e.isDefaultVariant=function(){return 2===t.language.length?\"en\"===t.language:t.language.length>=3&&\"e\"===t.language[0]&&\"n\"===t.language[1]&&\"-\"===t.language[2]},e.isDefault=function(){return\"en\"===t.language}}(w||(t.Language=w={})),t.locale=i,t.platformLocale=g,t.translationsConfigFile=s,t.setTimeout0IsFaster=\"function\"==typeof m.postMessage&&!m.importScripts,t.setTimeout0=(()=>{if(t.setTimeout0IsFaster){const e=[];m.addEventListener(\"message\",(t=>{if(t.data&&t.data.vscodeScheduleAsyncWork)for(let i=0,s=e.length;i{const s=++t;e.push({id:s,callback:i}),m.postMessage({vscodeScheduleAsyncWork:s},\"*\")}}return e=>setTimeout(e)})(),function(e){e[e.Windows=1]=\"Windows\",e[e.Macintosh=2]=\"Macintosh\",e[e.Linux=3]=\"Linux\"}(E||(t.OperatingSystem=E={})),t.OS=o||u?E.Macintosh:n?E.Windows:E.Linux;let D=!0,L=!1;t.isChrome=!!(t.userAgent&&t.userAgent.indexOf(\"Chrome\")>=0),t.isFirefox=!!(t.userAgent&&t.userAgent.indexOf(\"Firefox\")>=0),t.isSafari=!!(!t.isChrome&&t.userAgent&&t.userAgent.indexOf(\"Safari\")>=0),t.isEdge=!!(t.userAgent&&t.userAgent.indexOf(\"Edg/\")>=0),t.isAndroid=!!(t.userAgent&&t.userAgent.indexOf(\"Android\")>=0)},9881:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.SmoothScrollingOperation=t.SmoothScrollingUpdate=t.Scrollable=t.ScrollState=t.ScrollbarVisibility=void 0;const s=i(802),r=i(7150);var n;!function(e){e[e.Auto=1]=\"Auto\",e[e.Hidden=2]=\"Hidden\",e[e.Visible=3]=\"Visible\"}(n||(t.ScrollbarVisibility=n={}));class o{constructor(e,t,i,s,r,n,o){this._forceIntegerValues=e,this._scrollStateBrand=void 0,this._forceIntegerValues&&(t|=0,i|=0,s|=0,r|=0,n|=0,o|=0),this.rawScrollLeft=s,this.rawScrollTop=o,t<0&&(t=0),s+t>i&&(s=i-t),s<0&&(s=0),r<0&&(r=0),o+r>n&&(o=n-r),o<0&&(o=0),this.width=t,this.scrollWidth=i,this.scrollLeft=s,this.height=r,this.scrollHeight=n,this.scrollTop=o}equals(e){return this.rawScrollLeft===e.rawScrollLeft&&this.rawScrollTop===e.rawScrollTop&&this.width===e.width&&this.scrollWidth===e.scrollWidth&&this.scrollLeft===e.scrollLeft&&this.height===e.height&&this.scrollHeight===e.scrollHeight&&this.scrollTop===e.scrollTop}withScrollDimensions(e,t){return new o(this._forceIntegerValues,void 0!==e.width?e.width:this.width,void 0!==e.scrollWidth?e.scrollWidth:this.scrollWidth,t?this.rawScrollLeft:this.scrollLeft,void 0!==e.height?e.height:this.height,void 0!==e.scrollHeight?e.scrollHeight:this.scrollHeight,t?this.rawScrollTop:this.scrollTop)}withScrollPosition(e){return new o(this._forceIntegerValues,this.width,this.scrollWidth,void 0!==e.scrollLeft?e.scrollLeft:this.rawScrollLeft,this.height,this.scrollHeight,void 0!==e.scrollTop?e.scrollTop:this.rawScrollTop)}createScrollEvent(e,t){const i=this.width!==e.width,s=this.scrollWidth!==e.scrollWidth,r=this.scrollLeft!==e.scrollLeft,n=this.height!==e.height,o=this.scrollHeight!==e.scrollHeight,a=this.scrollTop!==e.scrollTop;return{inSmoothScrolling:t,oldWidth:e.width,oldScrollWidth:e.scrollWidth,oldScrollLeft:e.scrollLeft,width:this.width,scrollWidth:this.scrollWidth,scrollLeft:this.scrollLeft,oldHeight:e.height,oldScrollHeight:e.scrollHeight,oldScrollTop:e.scrollTop,height:this.height,scrollHeight:this.scrollHeight,scrollTop:this.scrollTop,widthChanged:i,scrollWidthChanged:s,scrollLeftChanged:r,heightChanged:n,scrollHeightChanged:o,scrollTopChanged:a}}}t.ScrollState=o;class a extends r.Disposable{constructor(e){super(),this._scrollableBrand=void 0,this._onScroll=this._register(new s.Emitter),this.onScroll=this._onScroll.event,this._smoothScrollDuration=e.smoothScrollDuration,this._scheduleAtNextAnimationFrame=e.scheduleAtNextAnimationFrame,this._state=new o(e.forceIntegerValues,0,0,0,0,0,0),this._smoothScrolling=null}dispose(){this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),super.dispose()}setSmoothScrollDuration(e){this._smoothScrollDuration=e}validateScrollPosition(e){return this._state.withScrollPosition(e)}getScrollDimensions(){return this._state}setScrollDimensions(e,t){const i=this._state.withScrollDimensions(e,t);this._setState(i,Boolean(this._smoothScrolling)),this._smoothScrolling?.acceptScrollDimensions(this._state)}getFutureScrollPosition(){return this._smoothScrolling?this._smoothScrolling.to:this._state}getCurrentScrollPosition(){return this._state}setScrollPositionNow(e){const t=this._state.withScrollPosition(e);this._smoothScrolling&&(this._smoothScrolling.dispose(),this._smoothScrolling=null),this._setState(t,!1)}setScrollPositionSmooth(e,t){if(0===this._smoothScrollDuration)return this.setScrollPositionNow(e);if(this._smoothScrolling){e={scrollLeft:void 0===e.scrollLeft?this._smoothScrolling.to.scrollLeft:e.scrollLeft,scrollTop:void 0===e.scrollTop?this._smoothScrolling.to.scrollTop:e.scrollTop};const i=this._state.withScrollPosition(e);if(this._smoothScrolling.to.scrollLeft===i.scrollLeft&&this._smoothScrolling.to.scrollTop===i.scrollTop)return;let s;s=t?new c(this._smoothScrolling.from,i,this._smoothScrolling.startTime,this._smoothScrolling.duration):this._smoothScrolling.combine(this._state,i,this._smoothScrollDuration),this._smoothScrolling.dispose(),this._smoothScrolling=s}else{const t=this._state.withScrollPosition(e);this._smoothScrolling=c.start(this._state,t,this._smoothScrollDuration)}this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame((()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())}))}hasPendingScrollAnimation(){return Boolean(this._smoothScrolling)}_performSmoothScrolling(){if(!this._smoothScrolling)return;const e=this._smoothScrolling.tick(),t=this._state.withScrollPosition(e);return this._setState(t,!0),this._smoothScrolling?e.isDone?(this._smoothScrolling.dispose(),void(this._smoothScrolling=null)):void(this._smoothScrolling.animationFrameDisposable=this._scheduleAtNextAnimationFrame((()=>{this._smoothScrolling&&(this._smoothScrolling.animationFrameDisposable=null,this._performSmoothScrolling())}))):void 0}_setState(e,t){const i=this._state;i.equals(e)||(this._state=e,this._onScroll.fire(this._state.createScrollEvent(i,t)))}}t.Scrollable=a;class l{constructor(e,t,i){this.scrollLeft=e,this.scrollTop=t,this.isDone=i}}function h(e,t){const i=t-e;return function(t){return e+i*(1-(s=1-t,Math.pow(s,3)));var s}}t.SmoothScrollingUpdate=l;class c{constructor(e,t,i,s){this.from=e,this.to=t,this.duration=s,this.startTime=i,this.animationFrameDisposable=null,this._initAnimations()}_initAnimations(){this.scrollLeft=this._initAnimation(this.from.scrollLeft,this.to.scrollLeft,this.to.width),this.scrollTop=this._initAnimation(this.from.scrollTop,this.to.scrollTop,this.to.height)}_initAnimation(e,t,i){if(Math.abs(e-t)>2.5*i){let o,a;return e{Object.defineProperty(t,\"__esModule\",{value:!0}),t.StopWatch=void 0;const i=globalThis.performance&&\"function\"==typeof globalThis.performance.now;class s{static create(e){return new s(e)}constructor(e){this._now=i&&!1===e?Date.now:globalThis.performance.now.bind(globalThis.performance),this._startTime=this._now(),this._stopTime=-1}stop(){this._stopTime=this._now()}reset(){this._startTime=this._now(),this._stopTime=-1}elapsed(){return-1!==this._stopTime?this._stopTime-this._startTime:this._now()-this._startTime}}t.StopWatch=s},1316:(e,t,i)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.noBreakWhitespace=t.CodePointIterator=void 0,t.isFalsyOrWhitespace=function(e){return!e||\"string\"!=typeof e||0===e.trim().length},t.format=function(e,...t){return 0===t.length?e:e.replace(n,(function(e,i){const s=parseInt(i,10);return isNaN(s)||s<0||s>=t.length?e:t[s]}))},t.format2=function(e,t){return 0===Object.keys(t).length?e:e.replace(o,((e,i)=>t[i]??e))},t.htmlAttributeEncodeValue=function(e){return e.replace(/[<>\"'&]/g,(e=>{switch(e){case\"<\":return\"<\";case\">\":return\">\";case'\"':return\""\";case\"'\":return\"'\";case\"&\":return\"&\"}return e}))},t.escape=function(e){return e.replace(/[<>&]/g,(function(e){switch(e){case\"<\":return\"<\";case\">\":return\">\";case\"&\":return\"&\";default:return e}}))},t.escapeRegExpCharacters=a,t.count=function(e,t){let i=0,s=e.indexOf(t);for(;-1!==s;)i++,s=e.indexOf(t,s+t.length);return i},t.truncate=function(e,t,i=\"…\"){return e.length<=t?e:`${e.substr(0,t)}${i}`},t.truncateMiddle=function(e,t,i=\"…\"){if(e.length<=t)return e;const s=Math.ceil(t/2)-i.length/2,r=Math.floor(t/2)-i.length/2;return`${e.substr(0,s)}${i}${e.substr(e.length-r)}`},t.trim=function(e,t=\" \"){return h(l(e,t),t)},t.ltrim=l,t.rtrim=h,t.convertSimple2RegExpPattern=function(e){return e.replace(/[\\-\\\\\\{\\}\\+\\?\\|\\^\\$\\.\\,\\[\\]\\(\\)\\#\\s]/g,\"\\\\$&\").replace(/[\\*]/g,\".*\")},t.stripWildcards=function(e){return e.replace(/\\*/g,\"\")},t.createRegExp=function(e,t,i={}){if(!e)throw new Error(\"Cannot create regex from empty string\");t||(e=a(e)),i.wholeWord&&(/\\B/.test(e.charAt(0))||(e=\"\\\\b\"+e),/\\B/.test(e.charAt(e.length-1))||(e+=\"\\\\b\"));let s=\"\";return i.global&&(s+=\"g\"),i.matchCase||(s+=\"i\"),i.multiline&&(s+=\"m\"),i.unicode&&(s+=\"u\"),new RegExp(e,s)},t.regExpLeadsToEndlessLoop=function(e){return\"^\"!==e.source&&\"^$\"!==e.source&&\"$\"!==e.source&&\"^\\\\s*$\"!==e.source&&!(!e.exec(\"\")||0!==e.lastIndex)},t.splitLines=function(e){return e.split(/\\r\\n|\\r|\\n/)},t.splitLinesIncludeSeparators=function(e){const t=[],i=e.split(/(\\r\\n|\\r|\\n)/);for(let e=0;e=0;i--){const t=e.charCodeAt(i);if(t!==s.CharCode.Space&&t!==s.CharCode.Tab)return i}return-1},t.replaceAsync=function(e,t,i){const s=[];let r=0;for(const n of e.matchAll(t)){if(s.push(e.slice(r,n.index)),void 0===n.index)throw new Error(\"match.index should be defined\");r=n.index+n[0].length,s.push(i(n[0],...n.slice(1),n.index,e,n.groups))}return s.push(e.slice(r)),Promise.all(s).then((e=>e.join(\"\")))},t.compare=function(e,t){return et?1:0},t.compareSubstring=c,t.compareIgnoreCase=function(e,t){return d(e,t,0,e.length,0,t.length)},t.compareSubstringIgnoreCase=d,t.isAsciiDigit=function(e){return e>=s.CharCode.Digit0&&e<=s.CharCode.Digit9},t.isLowerAsciiLetter=u,t.isUpperAsciiLetter=function(e){return e>=s.CharCode.A&&e<=s.CharCode.Z},t.equalsIgnoreCase=function(e,t){return e.length===t.length&&0===d(e,t)},t.startsWithIgnoreCase=function(e,t){const i=t.length;return!(t.length>e.length)&&0===d(e,t,0,i)},t.commonPrefixLength=function(e,t){const i=Math.min(e.length,t.length);let s;for(s=0;sn)return 1}const o=s-i,a=n-r;return oa?1:0}function d(e,t,i=0,s=e.length,r=0,n=t.length){for(;i=128||a>=128)return c(e.toLowerCase(),t.toLowerCase(),i,s,r,n);u(o)&&(o-=32),u(a)&&(a-=32);const l=o-a;if(0!==l)return l}const o=s-i,a=n-r;return oa?1:0}function u(e){return e>=s.CharCode.a&&e<=s.CharCode.z}function _(e){return 55296<=e&&e<=56319}function f(e){return 56320<=e&&e<=57343}function p(e,t){return t-56320+(e-55296<<10)+65536}function g(e,t,i){const s=e.charCodeAt(i);if(_(s)&&i+11){const s=e.charCodeAt(t-2);if(_(s))return p(s,i)}return i}(this._str,this._offset);return this._offset-=e>=r.Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN?2:1,e}nextCodePoint(){const e=g(this._str,this._len,this._offset);return this._offset+=e>=r.Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN?2:1,e}eol(){return this._offset>=this._len}},t.noBreakWhitespace=\" \"},5015:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.MicrotaskDelay=void 0,t.MicrotaskDelay=Symbol(\"MicrotaskDelay\")},8960:(e,t)=>{var i;Object.defineProperty(t,\"__esModule\",{value:!0}),t.Constants=void 0,t.toUint8=function(e){return e<0?0:e>i.MAX_UINT_8?i.MAX_UINT_8:0|e},t.toUint32=function(e){return e<0?0:e>i.MAX_UINT_32?i.MAX_UINT_32:0|e},function(e){e[e.MAX_SAFE_SMALL_INTEGER=1073741824]=\"MAX_SAFE_SMALL_INTEGER\",e[e.MIN_SAFE_SMALL_INTEGER=-1073741824]=\"MIN_SAFE_SMALL_INTEGER\",e[e.MAX_UINT_8=255]=\"MAX_UINT_8\",e[e.MAX_UINT_16=65535]=\"MAX_UINT_16\",e[e.MAX_UINT_32=4294967295]=\"MAX_UINT_32\",e[e.UNICODE_SUPPLEMENTARY_PLANE_BEGIN=65536]=\"UNICODE_SUPPLEMENTARY_PLANE_BEGIN\"}(i||(t.Constants=i={}))}},t={};function i(s){var r=t[s];if(void 0!==r)return r.exports;var n=t[s]={exports:{}};return e[s].call(n.exports,n,n.exports,i),n.exports}var s={};return(()=>{var e=s;Object.defineProperty(e,\"__esModule\",{value:!0}),e.Terminal=void 0;const t=i(7721),r=i(1718),n=i(7150),o=i(3027),a=i(5101),l=i(6097),h=i(4335),c=[\"cols\",\"rows\"];let d=0;class u extends n.Disposable{constructor(e){super(),this._core=this._register(new r.CoreBrowserTerminal(e)),this._addonManager=this._register(new o.AddonManager),this._publicOptions={...this._core.options};const t=e=>this._core.options[e],i=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(const e in this._core.options){const s={get:t.bind(this,e),set:i.bind(this,e)};Object.defineProperty(this._publicOptions,e,s)}}_checkReadonlyOptions(e){if(c.includes(e))throw new Error(`Option \"${e}\" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw new Error(\"You must set the allowProposedApi option to true to use proposed API\")}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get element(){return this._core.element}get parser(){return this._parser||(this._parser=new l.ParserApi(this._core)),this._parser}get unicode(){return this._checkProposedApi(),new h.UnicodeApi(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer||(this._buffer=this._register(new a.BufferNamespaceApi(this._core))),this._buffer}get markers(){return this._checkProposedApi(),this._core.markers}get modes(){const e=this._core.coreService.decPrivateModes;let t=\"none\";switch(this._core.coreMouseService.activeProtocol){case\"X10\":t=\"x10\";break;case\"VT200\":t=\"vt200\";break;case\"DRAG\":t=\"drag\";break;case\"ANY\":t=\"any\"}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,synchronizedOutputMode:e.synchronizedOutput,wraparoundMode:e.wraparound}}get options(){return this._publicOptions}set options(e){for(const t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}input(e,t=!0){this._core.input(e,t)}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}attachCustomWheelEventHandler(e){this._core.attachCustomWheelEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._checkProposedApi(),this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._checkProposedApi(),this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){return this._checkProposedApi(),this._verifyPositiveIntegers(e.x??0,e.width??0,e.height??0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,i){this._verifyIntegers(e,t,i),this._core.select(e,t,i)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write(\"\\r\\n\",t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return{get promptLabel(){return t.promptLabel.get()},set promptLabel(e){t.promptLabel.set(e)},get tooMuchOutput(){return t.tooMuchOutput.get()},set tooMuchOutput(e){t.tooMuchOutput.set(e)}}}_verifyIntegers(...e){for(d of e)if(d===1/0||isNaN(d)||d%1!=0)throw new Error(\"This API only accepts integers\")}_verifyPositiveIntegers(...e){for(d of e)if(d&&(d===1/0||isNaN(d)||d%1!=0||d<0))throw new Error(\"This API only accepts positive integers\")}}e.Terminal=u})(),s})()));\n//# sourceMappingURL=xterm.js.map"; +export const XTERM_CSS = "/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n * @license MIT\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n */\n\n/**\n * Default styles for xterm.js\n */\n\n.xterm {\n cursor: text;\n position: relative;\n user-select: none;\n -ms-user-select: none;\n -webkit-user-select: none;\n}\n\n.xterm.focus,\n.xterm:focus {\n outline: none;\n}\n\n.xterm .xterm-helpers {\n position: absolute;\n top: 0;\n /**\n * The z-index of the helpers must be higher than the canvases in order for\n * IMEs to appear on top.\n */\n z-index: 5;\n}\n\n.xterm .xterm-helper-textarea {\n padding: 0;\n border: 0;\n margin: 0;\n /* Move textarea out of the screen to the far left, so that the cursor is not visible */\n position: absolute;\n opacity: 0;\n left: -9999em;\n top: 0;\n width: 0;\n height: 0;\n z-index: -5;\n /** Prevent wrapping so the IME appears against the textarea at the correct position */\n white-space: nowrap;\n overflow: hidden;\n resize: none;\n}\n\n.xterm .composition-view {\n /* TODO: Composition position got messed up somewhere */\n background: #000;\n color: #FFF;\n display: none;\n position: absolute;\n white-space: nowrap;\n z-index: 1;\n}\n\n.xterm .composition-view.active {\n display: block;\n}\n\n.xterm .xterm-viewport {\n /* On OS X this is required in order for the scroll bar to appear fully opaque */\n background-color: #000;\n overflow-y: scroll;\n cursor: default;\n position: absolute;\n right: 0;\n left: 0;\n top: 0;\n bottom: 0;\n}\n\n.xterm .xterm-screen {\n position: relative;\n}\n\n.xterm .xterm-screen canvas {\n position: absolute;\n left: 0;\n top: 0;\n}\n\n.xterm-char-measure-element {\n display: inline-block;\n visibility: hidden;\n position: absolute;\n top: 0;\n left: -9999em;\n line-height: normal;\n}\n\n.xterm.enable-mouse-events {\n /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */\n cursor: default;\n}\n\n.xterm.xterm-cursor-pointer,\n.xterm .xterm-cursor-pointer {\n cursor: pointer;\n}\n\n.xterm.column-select.focus {\n /* Column selection mode */\n cursor: crosshair;\n}\n\n.xterm .xterm-accessibility:not(.debug),\n.xterm .xterm-message {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n z-index: 10;\n color: transparent;\n pointer-events: none;\n}\n\n.xterm .xterm-accessibility-tree:not(.debug) *::selection {\n color: transparent;\n}\n\n.xterm .xterm-accessibility-tree {\n font-family: monospace;\n user-select: text;\n white-space: pre;\n}\n\n.xterm .xterm-accessibility-tree > div {\n transform-origin: left;\n width: fit-content;\n}\n\n.xterm .live-region {\n position: absolute;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n}\n\n.xterm-dim {\n /* Dim should not apply to background, so the opacity of the foreground color is applied\n * explicitly in the generated class and reset to 1 here */\n opacity: 1 !important;\n}\n\n.xterm-underline-1 { text-decoration: underline; }\n.xterm-underline-2 { text-decoration: double underline; }\n.xterm-underline-3 { text-decoration: wavy underline; }\n.xterm-underline-4 { text-decoration: dotted underline; }\n.xterm-underline-5 { text-decoration: dashed underline; }\n\n.xterm-overline {\n text-decoration: overline;\n}\n\n.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }\n.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }\n.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }\n.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }\n.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }\n\n.xterm-strikethrough {\n text-decoration: line-through;\n}\n\n.xterm-screen .xterm-decoration-container .xterm-decoration {\n\tz-index: 6;\n\tposition: absolute;\n}\n\n.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {\n\tz-index: 7;\n}\n\n.xterm-decoration-overview-ruler {\n z-index: 8;\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n}\n\n.xterm-decoration-top {\n z-index: 2;\n position: relative;\n}\n\n\n\n/* Derived from vs/base/browser/ui/scrollbar/media/scrollbar.css */\n\n/* xterm.js customization: Override xterm's cursor style */\n.xterm .xterm-scrollable-element > .scrollbar {\n cursor: default;\n}\n\n/* Arrows */\n.xterm .xterm-scrollable-element > .scrollbar > .scra {\n\tcursor: pointer;\n\tfont-size: 11px !important;\n}\n\n.xterm .xterm-scrollable-element > .visible {\n\topacity: 1;\n\n\t/* Background rule added for IE9 - to allow clicks on dom node */\n\tbackground:rgba(0,0,0,0);\n\n\ttransition: opacity 100ms linear;\n\t/* In front of peek view */\n\tz-index: 11;\n}\n.xterm .xterm-scrollable-element > .invisible {\n\topacity: 0;\n\tpointer-events: none;\n}\n.xterm .xterm-scrollable-element > .invisible.fade {\n\ttransition: opacity 800ms linear;\n}\n\n/* Scrollable Content Inset Shadow */\n.xterm .xterm-scrollable-element > .shadow {\n\tposition: absolute;\n\tdisplay: none;\n}\n.xterm .xterm-scrollable-element > .shadow.top {\n\tdisplay: block;\n\ttop: 0;\n\tleft: 3px;\n\theight: 3px;\n\twidth: 100%;\n\tbox-shadow: var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset;\n}\n.xterm .xterm-scrollable-element > .shadow.left {\n\tdisplay: block;\n\ttop: 3px;\n\tleft: 0;\n\theight: 100%;\n\twidth: 3px;\n\tbox-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;\n}\n.xterm .xterm-scrollable-element > .shadow.top-left-corner {\n\tdisplay: block;\n\ttop: 0;\n\tleft: 0;\n\theight: 3px;\n\twidth: 3px;\n}\n.xterm .xterm-scrollable-element > .shadow.top.left {\n\tbox-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;\n}\n"; +export const FIT_ADDON_JS = "!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(globalThis,(()=>(()=>{\"use strict\";var e={};return(()=>{var t=e;Object.defineProperty(t,\"__esModule\",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;const t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(r.getPropertyValue(\"height\")),o=Math.max(0,parseInt(r.getPropertyValue(\"width\"))),s=window.getComputedStyle(this._terminal.element),n=i-(parseInt(s.getPropertyValue(\"padding-top\"))+parseInt(s.getPropertyValue(\"padding-bottom\"))),l=o-(parseInt(s.getPropertyValue(\"padding-right\"))+parseInt(s.getPropertyValue(\"padding-left\")))-t;return{cols:Math.max(2,Math.floor(l/e.css.cell.width)),rows:Math.max(1,Math.floor(n/e.css.cell.height))}}}})(),e})()));\n//# sourceMappingURL=addon-fit.js.map"; From 29ee803f2f22e342bbb66d810df5137bd6dac842 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 16:47:01 +0200 Subject: [PATCH 25/83] fix(mobile): repaint the TUI on terminal reattach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reopening a task's terminal replayed the scrollback but left a running full-screen TUI (Claude Code) missing its live input box + footer: a same-size reattach fires no SIGWINCH, so the TUI never repaints its alt-screen UI and you see only the serialized snapshot. After applying the snapshot, jiggle the PTY size (rows-1 → rows) to force SIGWINCH; the TUI then repaints everything from scratch — authoritative, and better than trusting the snapshot for alt-screen content. Harmless on a fresh shell (no TUI to redraw). --- apps/mobile/src/TerminalScreen.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/mobile/src/TerminalScreen.tsx b/apps/mobile/src/TerminalScreen.tsx index 294ce57..ee40190 100644 --- a/apps/mobile/src/TerminalScreen.tsx +++ b/apps/mobile/src/TerminalScreen.tsx @@ -150,7 +150,9 @@ export function TerminalScreen({ } else if (msg.type === "ready") { // xterm is mounted: size the PTY, paint its current screen, then flush // any chunks that streamed in while we were setting up. - if (msg.cols && msg.rows) api.pty.resize(id, msg.cols, msg.rows); + const cols = msg.cols ?? 80; + const rows = msg.rows ?? 24; + api.pty.resize(id, cols, rows); try { const snap = await api.pty.snapshot(id); if (snap.data) inject(snap.data); @@ -165,6 +167,14 @@ export function TerminalScreen({ buffered.current = []; applied.current = true; } + // Force a full repaint. A same-size reattach fires no SIGWINCH, so a + // running full-screen TUI (Claude Code) never redraws its live UI — you + // see only the replayed scrollback, missing the input box/footer. Jiggle + // the size (rows-1 → rows) to trigger SIGWINCH; the TUI then repaints + // everything from scratch (authoritative — better than trusting the + // serialized snapshot for alt-screen content). + setTimeout(() => api.pty.resize(id, cols, Math.max(1, rows - 1)), 80); + setTimeout(() => api.pty.resize(id, cols, rows), 200); } }, [api, terminalId, inject], From 656e5fb0e1935c95043f854e6091d1df1bd5aa58 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 17:01:29 +0200 Subject: [PATCH 26/83] feat(mobile,agents): board composer, agent-mode launch, project switcher, persisted connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile board is now a control surface, not just a viewer: - Composer (src/Composer.tsx) at the board bottom: prompt + agent picker + auto-mode (yolo) + agents-mode toggles + send. Submitting creates a task and launches the agent, then opens its terminal — mirrors the desktop's create→spawnAgent sequence. - Agent mode: engine gains `agentsCommand` ("claude agents") + agentCommand({ agentMode}); protocol spawnAgent + dispatcher pass `agentMode` through (additive optional, no PROTOCOL_VERSION bump). Launches the tool's multi-agent board in the task's worktree (the PTY already cwd's there, so no --cwd). - Board header redesigned: connection status dot (left, tap → connection page) + centered project dropdown; dropped the IP/app-icon/name chrome. - Connection page: back-to-board + Disconnect when connected; host/port persisted via AsyncStorage (src/storage.ts) so a restart/reinstall keeps the box IP. - Terminal reattach: widen the SIGWINCH redraw jiggle (350/900ms, cancel on unmount) so a running TUI fully repaints instead of coming back partial. Verified headless: agents/protocol/server tc + 81 server tests green, mobile tc clean, Metro bundle 569 modules. Box redeployed via login shell so the agents list populates (system:hello → agents:["claude"]). --- apps/mobile/App.tsx | 391 +++++++++++++++++++++-------- apps/mobile/package-lock.json | 31 +++ apps/mobile/package.json | 1 + apps/mobile/src/Composer.tsx | 179 +++++++++++++ apps/mobile/src/TerminalScreen.tsx | 15 +- apps/mobile/src/storage.ts | 28 +++ packages/agents/src/registry.ts | 25 +- packages/protocol/src/index.ts | 2 + packages/server/src/dispatcher.ts | 8 +- 9 files changed, 568 insertions(+), 112 deletions(-) create mode 100644 apps/mobile/src/Composer.tsx create mode 100644 apps/mobile/src/storage.ts diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 3c7704a..7a3b039 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -1,19 +1,20 @@ // Ateam mobile — a thin remote for a box running the Ateam engine. The phone // opens a WebSocket to the box's opt-in `ateam` WS listener (over Tailscale), // handshakes, and drives the SAME engine the desktop does via the shared -// @ateam/protocol contract (see src/connection.ts). The board below is LIVE: -// projects/tasks come from the engine and taskUpdated pushes keep it fresh. +// @ateam/protocol contract (see src/connection.ts). The board is LIVE and the +// composer creates + launches tasks on the box; tapping a task opens its terminal. // // Theme = Ateam's real tokens (apps/desktop/src/renderer/src/index.css): near-black -// #0c0c0e canvas, purple accent #7c5cff, ink/white primary action (a hue is never -// the CTA), amber/blue/green status. Logo = the "mission-control tiling" mark from -// apps/desktop/build/icon.svg, redrawn with Views. Connection = ALWAYS a WebSocket -// to a Tailscale address (RN can't spawn ssh; WireGuard is the auth boundary). - -import type { ProjectDTO, TaskDTO } from "@ateam/protocol"; +// #0c0c0e canvas, purple accent #7c5cff, ink/white primary action, amber/blue/green +// status. Connection = ALWAYS a WebSocket to a Tailscale address (RN can't spawn +// ssh; WireGuard is the auth boundary). +import type { AgentDTO, ProjectDTO, TaskDTO } from "@ateam/protocol"; import { useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, + KeyboardAvoidingView, + Modal, + Platform, Pressable, ScrollView, StatusBar, @@ -23,18 +24,20 @@ import { useColorScheme, View, } from "react-native"; +import { Composer, type ComposerSubmit } from "./src/Composer"; import { type Connection, connect } from "./src/connection"; +import { loadConnection, saveConnection } from "./src/storage"; import { TerminalScreen } from "./src/TerminalScreen"; const C = { bg: "#0c0c0e", - surface: "#141418", // --bg-elev - sunken: "#1c1c22", // --bg-elev-2 - line: "#2a2a33", // --border - ink: "#e6e6ea", // --text - muted: "#9a9aa6", // --text-dim + surface: "#141418", + sunken: "#1c1c22", + line: "#2a2a33", + ink: "#e6e6ea", + muted: "#9a9aa6", faint: "#6a6a75", - accent: "#7c5cff", // --accent (Ateam purple) + accent: "#7c5cff", green: "#4ade80", amber: "#fbbf24", red: "#f87171", @@ -50,8 +53,6 @@ const TINT: Record = { [C.red]: "rgba(248,113,113,0.14)", }; -// Column keys match @ateam/protocol's KanbanColumn exactly, so a live TaskDTO's -// `column` drops straight into the right zone. const COLUMNS: { key: TaskDTO["column"]; label: string; tint: string }[] = [ { key: "needs_attention", label: "Needs You", tint: C.amber }, { key: "running", label: "In Progress", tint: C.accent }, @@ -60,8 +61,6 @@ const COLUMNS: { key: TaskDTO["column"]; label: string; tint: string }[] = [ { key: "merged", label: "Done", tint: C.green }, ]; -// A short status line for a card, derived from the live task (mirrors the desktop's -// signal priority: a pending question first, then agent state, then git/PR facts). function taskNote(t: TaskDTO): string { if (t.column === "needs_attention") return "awaiting your input"; if (t.agentStatus === "running") return "running"; @@ -72,8 +71,11 @@ function taskNote(t: TaskDTO): string { return t.agentStatus ?? "idle"; } -// The Ateam logo mark: a wide top pane + two dimming squares (icon.svg), on a dark -// tile. Redrawn with Views so it scales + themes with no native SVG dependency. +/** Readable task name from the prompt's first words (mirrors the desktop). */ +function titleFromPrompt(p: string): string { + return p.trim().split(/\s+/).slice(0, 6).join(" ").slice(0, 60); +} + function LogoMark() { return ( @@ -131,7 +133,62 @@ function TaskCard({ task, tint, onOpen }: { task: TaskDTO; tint: string; onOpen: ); } -// ── Connection screen — one WebSocket target (host = the box's Tailscale IP) ── +// ── Project dropdown — centered in the board header ── + +function ProjectDropdown({ + projects, + selectedId, + onSelect, +}: { + projects: ProjectDTO[]; + selectedId: string | null; + onSelect: (id: string) => void; +}) { + const [open, setOpen] = useState(false); + const selected = projects.find((p) => p.id === selectedId); + return ( + <> + setOpen(true)} hitSlop={6}> + + {selected?.name ?? "No project"} + + + + setOpen(false)}> + setOpen(false)}> + + {projects.length === 0 ? ( + No projects on this box + ) : ( + projects.map((p) => ( + { + onSelect(p.id); + setOpen(false); + }} + > + + + {p.name} + + + )) + )} + + + + + ); +} + +// ── Connection screen — the box's WebSocket target; back/Disconnect when live ── function Field({ label, @@ -171,7 +228,10 @@ function ConnectionScreen({ setHost, setPort, onConnect, + onBack, + onDisconnect, connecting, + connected, error, }: { host: string; @@ -179,15 +239,24 @@ function ConnectionScreen({ setHost: (t: string) => void; setPort: (t: string) => void; onConnect: () => void; + onBack: () => void; + onDisconnect: () => void; connecting: boolean; + connected: boolean; error: string | null; }) { return ( - - New connection + {connected ? ( + + ‹ Board + + ) : ( + + )} + {connected ? "Connection" : "New connection"} ) : ( - Connect + {connected ? "Reconnect" : "Connect"} )} @@ -231,74 +300,88 @@ function ConnectionScreen({ ) : null} + {connected ? ( + + Disconnect + + ) : null} + The phone opens a WebSocket to your box's `ateam` listener over Tailscale — WireGuard is the encryption and the auth boundary. Enable it on the box with{" "} - ATEAM_WS_ADDR=<tailscale-ip>:<port> (never a - wildcard bind). + ATEAM_WS_ADDR=<tailscale-ip>:<port>. ); } -// ── Board screen — LIVE tasks from the connected engine ── +// ── Board screen — status dot (left) · project dropdown (center) · composer ── function BoardScreen({ - host, + connColor, + projects, + selectedProjectId, + onSelectProject, agents, tasks, loading, + creating, onOpenConnection, - onRefresh, onOpenTask, + onCreate, }: { - host: string; - agents: string[]; + connColor: string; + projects: ProjectDTO[]; + selectedProjectId: string | null; + onSelectProject: (id: string) => void; + agents: AgentDTO[]; tasks: TaskDTO[]; loading: boolean; + creating: boolean; onOpenConnection: () => void; - onRefresh: () => void; onOpenTask: (task: TaskDTO) => void; + onCreate: (input: ComposerSubmit) => void; }) { + const shown = tasks.filter((t) => t.projectId === selectedProjectId); return ( - + - - - - Ateam - - - - - {host} - - + + + + + + - - WS · {host} ·{" "} - {agents.length ? agents.join(", ") : "no agents"} - + - {loading && tasks.length === 0 ? ( + {loading && shown.length === 0 ? ( loading board… - ) : tasks.length === 0 ? ( + ) : shown.length === 0 ? ( - no tasks on this box yet + no tasks yet — start one below ) : ( COLUMNS.map((col) => { - const inCol = tasks.filter((t) => t.column === col.key); + const inCol = shown.filter((t) => t.column === col.key); if (inCol.length === 0) return null; return ( @@ -314,11 +397,10 @@ function BoardScreen({ ); }) )} - - tap to refresh - - + + + ); } @@ -328,22 +410,36 @@ export default function App() { const [host, setHost] = useState(""); const [port, setPort] = useState("8787"); const [connecting, setConnecting] = useState(false); + const [connected, setConnected] = useState(false); const [error, setError] = useState(null); const [tasks, setTasks] = useState([]); - const [agents, setAgents] = useState([]); + const [projects, setProjects] = useState([]); + const [selectedProjectId, setSelectedProjectId] = useState(null); + const [agents, setAgents] = useState([]); const [loading, setLoading] = useState(false); + const [creating, setCreating] = useState(false); const [openTask, setOpenTask] = useState(null); const conn = useRef(null); - // Pull the whole board: every project's tasks, flattened. Sorted newest-active - // first so the freshest work leads each column. + // Prefill the last box on launch, so a restart/reinstall doesn't lose the IP. + useEffect(() => { + void loadConnection().then((saved) => { + if (saved) { + setHost(saved.host); + setPort(saved.port); + } + }); + }, []); + const refresh = useCallback(async () => { const api = conn.current?.api; if (!api) return; setLoading(true); try { - const projects: ProjectDTO[] = await api.projects.list(); - const perProject = await Promise.all(projects.map((p) => api.tasks.list(p.id))); + const projs: ProjectDTO[] = await api.projects.list(); + setProjects(projs); + setSelectedProjectId((cur) => cur ?? projs[0]?.id ?? null); + const perProject = await Promise.all(projs.map((p) => api.tasks.list(p.id))); const all = perProject.flat().sort((a, b) => (b.lastEventAt ?? 0) - (a.lastEventAt ?? 0)); setTasks(all); } finally { @@ -378,44 +474,95 @@ export default function App() { conn.current?.close(); const c = await connect(`ws://${host.trim()}:${port.trim() || "8787"}`); conn.current = c; - setAgents(c.info.agents); + await saveConnection({ host: host.trim(), port: port.trim() || "8787" }); + setConnected(true); + void c.api.agents.list().then(setAgents); setView("board"); await refresh(); } catch (err) { conn.current = null; + setConnected(false); setError(err instanceof Error ? err.message : String(err)); } finally { setConnecting(false); } }, [host, port, refresh]); - // A tapped task opens its live terminal; the engine api comes from the live - // connection. Overlays the board (which stays mounted behind it). + const onDisconnect = useCallback(() => { + conn.current?.close(); + conn.current = null; + setConnected(false); + setTasks([]); + setProjects([]); + setSelectedProjectId(null); + setView("connect"); + }, []); + + // Composer submit: create a task in the selected project, launch the agent, + // and open its terminal (which attaches to the just-spawned session). + const onCreate = useCallback( + async (input: ComposerSubmit) => { + const api = conn.current?.api; + if (!api || !selectedProjectId) return; + setCreating(true); + try { + const name = titleFromPrompt(input.prompt) || (input.agentMode ? "agent session" : "task"); + const task = await api.tasks.create({ projectId: selectedProjectId, name }); + await api.pty.spawnAgent({ + taskId: task.id, + agentId: input.agentId, + yolo: input.yolo, + agentMode: input.agentMode, + prompt: input.prompt || undefined, + }); + setTasks((prev) => [task, ...prev.filter((t) => t.id !== task.id)]); + setOpenTask(task); + } catch (err) { + setError(err instanceof Error ? err.message : String(err)); + } finally { + setCreating(false); + } + }, + [selectedProjectId], + ); + + // A tapped task opens its live terminal (api comes from the live connection). if (openTask && conn.current) { return ( setOpenTask(null)} /> ); } - return view === "connect" ? ( - - ) : ( + if (view === "connect") { + return ( + setView("board")} + onDisconnect={onDisconnect} + connecting={connecting} + connected={connected} + error={error} + /> + ); + } + + return ( setView("connect")} - onRefresh={refresh} onOpenTask={setOpenTask} + onCreate={onCreate} /> ); } @@ -423,7 +570,7 @@ export default function App() { const styles = StyleSheet.create({ root: { flex: 1, backgroundColor: C.bg, paddingTop: 60 }, - // logo mark (icon.svg redrawn) + // logo mark (icon.svg redrawn) — connection screen only logo: { width: 32, height: 32, @@ -440,13 +587,60 @@ const styles = StyleSheet.create({ logoBottom: { flexDirection: "row", gap: 2.5 }, logoSq: { flex: 1, height: 8, borderRadius: 1.5, backgroundColor: "#ffffff" }, - // header / nav - header: { - paddingHorizontal: 18, - paddingBottom: 14, + // board header: [status dot] [project dropdown centered] [spacer] + boardHeader: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 14, + paddingBottom: 12, borderBottomWidth: 1, borderBottomColor: C.line, }, + statusHit: { width: 44, alignItems: "flex-start", justifyContent: "center" }, + statusDot: { width: 12, height: 12, borderRadius: 6 }, + headerCenter: { flex: 1, alignItems: "center" }, + projPill: { + flexDirection: "row", + alignItems: "center", + gap: 6, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + paddingHorizontal: 14, + paddingVertical: 7, + borderRadius: 999, + maxWidth: 240, + }, + projName: { color: C.ink, fontSize: 14, fontWeight: "700", letterSpacing: -0.2 }, + projCaret: { color: C.muted, fontSize: 11 }, + + // project dropdown modal + modalBackdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.5)", + paddingTop: 100, + alignItems: "center", + }, + modalCard: { + width: 280, + backgroundColor: C.surface, + borderWidth: 1, + borderColor: C.line, + borderRadius: 12, + paddingVertical: 6, + }, + modalEmpty: { color: C.muted, fontSize: 13, textAlign: "center", paddingVertical: 16 }, + modalRow: { + flexDirection: "row", + alignItems: "center", + gap: 10, + paddingHorizontal: 14, + paddingVertical: 12, + }, + modalDot: { width: 7, height: 7, borderRadius: 4 }, + modalRowText: { color: C.ink, fontSize: 15, flex: 1 }, + + // connection nav navBar: { flexDirection: "row", alignItems: "center", @@ -457,36 +651,18 @@ const styles = StyleSheet.create({ borderBottomColor: C.line, }, navTitle: { color: C.ink, fontSize: 17, fontWeight: "700", letterSpacing: -0.2 }, - brandRow: { flexDirection: "row", alignItems: "center", gap: 10 }, - brand: { color: C.ink, fontSize: 20, fontWeight: "700", letterSpacing: -0.3 }, + backText: { color: C.accent, fontSize: 15, fontWeight: "600" }, spacer: { flex: 1 }, - // Primary action = ink/white (a hue is never the CTA — Ateam + clawnify). connectBtn: { backgroundColor: C.ink, paddingHorizontal: 16, paddingVertical: 8, borderRadius: 8, - minWidth: 74, + minWidth: 84, alignItems: "center", }, connectBtnBusy: { opacity: 0.7 }, connectBtnText: { color: "#15151a", fontSize: 13, fontWeight: "800" }, - connPill: { - flexDirection: "row", - alignItems: "center", - gap: 6, - backgroundColor: C.sunken, - borderWidth: 1, - borderColor: C.line, - paddingHorizontal: 10, - paddingVertical: 5, - borderRadius: 999, - maxWidth: 180, - }, - connDot: { width: 7, height: 7, borderRadius: 4, backgroundColor: C.green }, - connText: { color: C.muted, fontSize: 12, fontWeight: "600" }, - connMeta: { color: C.muted, fontSize: 12, marginTop: 12 }, - connHost: { color: C.ink, fontVariant: ["tabular-nums"] }, // eyebrow eyebrowRow: { @@ -536,12 +712,21 @@ const styles = StyleSheet.create({ marginTop: 16, }, errorText: { color: C.red, fontSize: 13, lineHeight: 18 }, + disconnectBtn: { + marginTop: 20, + borderWidth: 1, + borderColor: "rgba(248,113,113,0.4)", + borderRadius: 10, + paddingVertical: 12, + alignItems: "center", + }, + disconnectText: { color: C.red, fontSize: 14, fontWeight: "700" }, formNote: { color: C.faint, fontSize: 12, lineHeight: 18, marginTop: 18, paddingHorizontal: 2 }, mono: { color: C.muted, fontVariant: ["tabular-nums"] }, // board board: { flex: 1 }, - boardContent: { padding: 16, paddingBottom: 40 }, + boardContent: { padding: 16, paddingBottom: 24 }, centerPad: { alignItems: "center", paddingVertical: 48, gap: 12 }, zone: { marginBottom: 22 }, card: { diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index 3387d9c..612d41c 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -8,6 +8,7 @@ "name": "mobile", "version": "1.0.0", "dependencies": { + "@react-native-async-storage/async-storage": "^1.23.1", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", "expo": "^52.0.49", @@ -2429,6 +2430,17 @@ "node": ">=14" } }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.23.1.tgz", + "integrity": "sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, "node_modules/@react-native/assets-registry": { "version": "0.76.9", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.9.tgz", @@ -5388,6 +5400,14 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -6228,6 +6248,17 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 32d57a7..d923a6c 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "main": "index.ts", "dependencies": { + "@react-native-async-storage/async-storage": "^1.23.1", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", "expo": "^52.0.49", diff --git a/apps/mobile/src/Composer.tsx b/apps/mobile/src/Composer.tsx new file mode 100644 index 0000000..c21d316 --- /dev/null +++ b/apps/mobile/src/Composer.tsx @@ -0,0 +1,179 @@ +// Bottom composer on the board — mobile counterpart to the desktop +// NewTaskComposer. Type a prompt, pick the agent + launch mode, send: it creates +// a task (worktree on the box) and launches the agent, then opens its terminal. +// Auto mode = permission-free (yolo); Agent mode = the tool's own multi-agent +// board (`claude agents`) in that worktree. Attachments are a fast-follow +// (cross-machine: the phone has no files the remote agent can read). + +import type { AgentDTO } from "@ateam/protocol"; +import { useState } from "react"; +import { Pressable, StyleSheet, Text, TextInput, View } from "react-native"; + +const C = { + surface: "#141418", + sunken: "#1c1c22", + line: "#2a2a33", + ink: "#e6e6ea", + muted: "#9a9aa6", + faint: "#6a6a75", + accent: "#7c5cff", + amber: "#fbbf24", +}; + +export interface ComposerSubmit { + prompt: string; + agentId: string; + yolo: boolean; + agentMode: boolean; +} + +export function Composer({ + agents, + busy, + onSubmit, +}: { + agents: AgentDTO[]; + busy: boolean; + onSubmit: (input: ComposerSubmit) => void; +}) { + // Prefer an installed agent; fall back to claude so the picker is never empty + // even when the box's availability probe came back empty (non-login daemon). + const pickable = agents.length + ? agents + : [{ id: "claude", label: "Claude Code", available: true } as AgentDTO]; + const [prompt, setPrompt] = useState(""); + const [agentId, setAgentId] = useState( + pickable.find((a) => a.available)?.id ?? pickable[0]?.id ?? "claude", + ); + const [yolo, setYolo] = useState(false); + const [agentMode, setAgentMode] = useState(false); + + // Agent mode takes the task interactively on its own board, so a prompt is + // optional there; otherwise a prompt (or at least something) is required. + const canSubmit = !busy && (agentMode || prompt.trim().length > 0); + + const submit = () => { + if (!canSubmit) return; + onSubmit({ prompt: prompt.trim(), agentId, yolo, agentMode }); + setPrompt(""); + }; + + return ( + + + + {/* Agent picker — tappable chips (few agents, no dropdown needed). */} + {pickable.map((a) => ( + setAgentId(a.id)} + hitSlop={4} + > + + {a.label.replace(/ Code$/, "")} + + + ))} + + {/* Auto mode (yolo) */} + setYolo((v) => !v)} + hitSlop={4} + > + auto + + {/* Agent mode (claude agents) */} + setAgentMode((v) => !v)} + hitSlop={4} + > + agents + + {/* Send */} + + + + + + ); +} + +const styles = StyleSheet.create({ + wrap: { + borderTopWidth: 1, + borderTopColor: C.line, + backgroundColor: C.surface, + paddingHorizontal: 12, + paddingTop: 10, + paddingBottom: 12, + gap: 8, + }, + input: { + color: C.ink, + fontSize: 15, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + borderRadius: 10, + paddingHorizontal: 12, + paddingVertical: 10, + minHeight: 40, + maxHeight: 120, + }, + row: { flexDirection: "row", alignItems: "center", gap: 6 }, + spacer: { flex: 1 }, + chip: { + paddingHorizontal: 10, + height: 30, + borderRadius: 8, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + chipOn: { borderColor: C.accent, backgroundColor: "rgba(124,92,255,0.16)" }, + chipText: { color: C.muted, fontSize: 12, fontWeight: "600" }, + chipTextOn: { color: C.ink }, + mode: { + paddingHorizontal: 10, + height: 30, + borderRadius: 8, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + modeAuto: { borderColor: C.amber, backgroundColor: "rgba(251,191,36,0.13)" }, + modeAgents: { borderColor: C.accent, backgroundColor: "rgba(124,92,255,0.16)" }, + modeText: { color: C.muted, fontSize: 12, fontWeight: "600" }, + send: { + width: 34, + height: 34, + borderRadius: 8, + backgroundColor: C.ink, + alignItems: "center", + justifyContent: "center", + }, + sendOff: { opacity: 0.35 }, + sendText: { color: "#15151a", fontSize: 18, fontWeight: "800" }, +}); diff --git a/apps/mobile/src/TerminalScreen.tsx b/apps/mobile/src/TerminalScreen.tsx index ee40190..89602b0 100644 --- a/apps/mobile/src/TerminalScreen.tsx +++ b/apps/mobile/src/TerminalScreen.tsx @@ -69,6 +69,8 @@ export function TerminalScreen({ const buffered = useRef([]); const applied = useRef(false); const lastSeq = useRef(-1); + // Pending redraw timers, cleared on unmount so we never resize a dead PTY. + const redrawTimers = useRef[]>([]); const inject = useCallback((data: string) => { // injectJavaScript evals a JS string; JSON.stringify makes `data` a safe @@ -128,6 +130,7 @@ export function TerminalScreen({ cancelled = true; offData(); offExit(); + for (const t of redrawTimers.current) clearTimeout(t); // Detach only — the session (and the running agent) lives on. }; }, [api, task.id, inject]); @@ -173,8 +176,16 @@ export function TerminalScreen({ // the size (rows-1 → rows) to trigger SIGWINCH; the TUI then repaints // everything from scratch (authoritative — better than trusting the // serialized snapshot for alt-screen content). - setTimeout(() => api.pty.resize(id, cols, Math.max(1, rows - 1)), 80); - setTimeout(() => api.pty.resize(id, cols, rows), 200); + // + // The gaps are deliberately generous: a heavy TUI needs time to process + // each SIGWINCH and finish its redraw before the next size lands, or the + // second resize interrupts a mid-flight repaint and the input box comes + // back partial. Let it settle, shrink, let THAT redraw finish, then grow. + for (const t of redrawTimers.current) clearTimeout(t); + redrawTimers.current = [ + setTimeout(() => api.pty.resize(id, cols, Math.max(1, rows - 1)), 350), + setTimeout(() => api.pty.resize(id, cols, rows), 900), + ]; } }, [api, terminalId, inject], diff --git a/apps/mobile/src/storage.ts b/apps/mobile/src/storage.ts new file mode 100644 index 0000000..aad16a2 --- /dev/null +++ b/apps/mobile/src/storage.ts @@ -0,0 +1,28 @@ +// Persist the last connection so the host/port survive app restarts and +// reinstalls — otherwise every launch (and every rebuild) starts blank and you +// retype the box's Tailscale IP. AsyncStorage is RN's simple key-value store. +import AsyncStorage from "@react-native-async-storage/async-storage"; + +const KEY = "ateam.connection"; + +export interface SavedConnection { + host: string; + port: string; +} + +export async function loadConnection(): Promise { + try { + const raw = await AsyncStorage.getItem(KEY); + return raw ? (JSON.parse(raw) as SavedConnection) : null; + } catch { + return null; + } +} + +export async function saveConnection(conn: SavedConnection): Promise { + try { + await AsyncStorage.setItem(KEY, JSON.stringify(conn)); + } catch { + /* best-effort — a failed persist just means a blank field next launch */ + } +} diff --git a/packages/agents/src/registry.ts b/packages/agents/src/registry.ts index 71cb7c1..dd5759b 100644 --- a/packages/agents/src/registry.ts +++ b/packages/agents/src/registry.ts @@ -26,6 +26,12 @@ export interface AgentDefinition { * pick a session back up after the agent process ended (e.g. app restart). */ resumeCommand?: string; + /** + * "Agent mode" command — the tool's autonomous multi-agent surface (e.g. + * Claude Code's `claude agents` board), launched in the task's worktree. + * Omitted for agents without one. + */ + agentsCommand?: string; /** How an initial task prompt is delivered (if supported). */ promptTransport?: PromptTransport; } @@ -43,12 +49,12 @@ export const AGENTS = [ command: "claude", yoloFlag: "--permission-mode auto", resumeCommand: "claude --continue", + agentsCommand: "claude agents", }, { id: "codex", label: "Codex", - description: - "OpenAI's coding agent for reading, modifying, and running code across tasks.", + description: "OpenAI's coding agent for reading, modifying, and running code across tasks.", bin: "codex", command: "codex", yoloFlag: "--dangerously-bypass-approvals-and-sandbox", @@ -64,13 +70,20 @@ export const AGENTS = [ }, ] as const satisfies readonly AgentDefinition[]; -/** Build the launch command line for an agent (YOLO and/or resume variants). */ +/** Build the launch command line for an agent (YOLO, resume, or agent-mode variants). */ export function agentCommand( agent: AgentDefinition, - opts: { yolo?: boolean; resume?: boolean; prompt?: string } = {}, + opts: { yolo?: boolean; resume?: boolean; agentMode?: boolean; prompt?: string } = {}, ): string { - const base = - opts.resume && agent.resumeCommand ? agent.resumeCommand : agent.command; + // Agent mode launches the tool's own multi-agent board (interactive — it takes + // the task description itself), so it ignores the prompt/resume variants. The + // PTY already spawns in the task's worktree, so no --cwd is needed. + if (opts.agentMode && agent.agentsCommand) { + return opts.yolo && agent.yoloFlag + ? `${agent.agentsCommand} ${agent.yoloFlag}` + : agent.agentsCommand; + } + const base = opts.resume && agent.resumeCommand ? agent.resumeCommand : agent.command; const cmd = opts.yolo && agent.yoloFlag ? `${base} ${agent.yoloFlag}` : base; if (!opts.prompt) return cmd; // Single-quoted for the login shell; claude/codex take the prompt as a diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index 05c4c33..d79cd3f 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -366,6 +366,8 @@ export interface AteamApi { agentId: string; yolo?: boolean; resume?: boolean; + /** Launch the agent's own multi-agent board (e.g. `claude agents`) in the worktree. */ + agentMode?: boolean; /** Initial instruction handed to the agent at launch. */ prompt?: string; /** Absolute paths to attach — appended to the prompt for the agent to read. */ diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts index 34e9f88..8e2201b 100644 --- a/packages/server/src/dispatcher.ts +++ b/packages/server/src/dispatcher.ts @@ -465,6 +465,7 @@ export function createDispatcher(engine: Engine): Dispatcher { agentId: string; yolo?: boolean; resume?: boolean; + agentMode?: boolean; prompt?: string; files?: string[]; }) => { @@ -503,7 +504,12 @@ export function createDispatcher(engine: Engine): Dispatcher { const list = input.files.map((f) => `- ${f}`).join("\n"); prompt = prompt ? `${prompt}\n\nAttached files:\n${list}` : `Attached files:\n${list}`; } - let agentCmd = agentCommand(agent, { yolo: input.yolo, resume: input.resume, prompt }); + let agentCmd = agentCommand(agent, { + yolo: input.yolo, + resume: input.resume, + agentMode: input.agentMode, + prompt, + }); if (agent.id === "codex") { // Codex has no hooks, but `notify` invokes a program with a JSON // payload on turn completion — our script maps it to Stop. Injected From 4d07abe19e6c24b069ce7e10d5411dd4539a0c7a Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 17:12:06 +0200 Subject: [PATCH 27/83] fix(mobile,agents): scope agent mode to the worktree, hide prompt in agent mode, terminal scroll + keyboard dismiss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Agent mode is now scoped: `claude agents` ignores the process cwd and shows the global board, so pass `--cwd ` explicitly (dispatcher hands agentCommand the task's worktreePath; single-quoted for spaces). Matches the `claude agents --cwd ~/repo` shape. - Composer: agent mode passes no prompt (its board is interactive), so hide the textarea and show a hint; agent-mode tasks get a unique time-stamped name so the worktree branch doesn't collide. - Terminal: touch-drag now scrolls the xterm scrollback (xterm only scrolls on wheel events, absent on touch → map drag to term.scrollLines; a tap re-focuses). Added a "Hide ⌨" button that blurs the hidden input so iOS dismisses the keyboard and you can see the full terminal. --- apps/mobile/App.tsx | 6 ++++- apps/mobile/src/Composer.tsx | 39 +++++++++++++++++++++--------- apps/mobile/src/TerminalScreen.tsx | 18 ++++++++++++++ apps/mobile/src/terminal-html.ts | 24 ++++++++++++++++++ packages/agents/src/registry.ts | 18 ++++++++++---- packages/server/src/dispatcher.ts | 1 + 6 files changed, 89 insertions(+), 17 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 7a3b039..46399f6 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -506,7 +506,11 @@ export default function App() { if (!api || !selectedProjectId) return; setCreating(true); try { - const name = titleFromPrompt(input.prompt) || (input.agentMode ? "agent session" : "task"); + // Agent mode has no prompt to name from — stamp a unique time so the + // worktree branch doesn't collide with a previous "agents" task. + const name = + titleFromPrompt(input.prompt) || + (input.agentMode ? `agents ${new Date().toTimeString().slice(0, 8)}` : "task"); const task = await api.tasks.create({ projectId: selectedProjectId, name }); await api.pty.spawnAgent({ taskId: task.id, diff --git a/apps/mobile/src/Composer.tsx b/apps/mobile/src/Composer.tsx index c21d316..42da740 100644 --- a/apps/mobile/src/Composer.tsx +++ b/apps/mobile/src/Composer.tsx @@ -60,17 +60,23 @@ export function Composer({ return ( - + {/* Agent mode drives its own interactive board — no prompt is passed, so + hide the textarea and show a hint instead. */} + {agentMode ? ( + + Agent mode — opens the tool's multi-agent board scoped to this project's worktree. + + ) : ( + + )} {/* Agent picker — tappable chips (few agents, no dropdown needed). */} {pickable.map((a) => ( @@ -138,6 +144,17 @@ const styles = StyleSheet.create({ minHeight: 40, maxHeight: 120, }, + agentHint: { + color: C.faint, + fontSize: 13, + lineHeight: 18, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + borderRadius: 10, + paddingHorizontal: 12, + paddingVertical: 10, + }, row: { flexDirection: "row", alignItems: "center", gap: 6 }, spacer: { flex: 1 }, chip: { diff --git a/apps/mobile/src/TerminalScreen.tsx b/apps/mobile/src/TerminalScreen.tsx index 89602b0..ed8202f 100644 --- a/apps/mobile/src/TerminalScreen.tsx +++ b/apps/mobile/src/TerminalScreen.tsx @@ -213,6 +213,13 @@ export function TerminalScreen({ {task.name} + webRef.current?.injectJavaScript("window.__termBlur();true;")} + hitSlop={8} + > + Hide ⌨ + @@ -285,6 +292,17 @@ const styles = StyleSheet.create({ closeBtn: { paddingVertical: 4, paddingRight: 4 }, closeText: { color: C.accent, fontSize: 15, fontWeight: "600" }, title: { color: C.ink, fontSize: 15, fontWeight: "700", flex: 1 }, + kbdBtn: { + paddingHorizontal: 10, + height: 28, + borderRadius: 7, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + kbdText: { color: C.muted, fontSize: 12, fontWeight: "600" }, dot: { width: 8, height: 8, borderRadius: 4 }, termWrap: { flex: 1, backgroundColor: "#000" }, web: { flex: 1, backgroundColor: "#000" }, diff --git a/apps/mobile/src/terminal-html.ts b/apps/mobile/src/terminal-html.ts index 2d51bf8..b106f5e 100644 --- a/apps/mobile/src/terminal-html.ts +++ b/apps/mobile/src/terminal-html.ts @@ -57,11 +57,35 @@ html, body { margin: 0; padding: 0; height: 100%; background: #000; overflow: hi window.__termWrite = function (s) { term.write(s); }; window.__termFit = function () { refit(); }; window.__termFocus = function () { term.focus(); }; + // Blur the hidden textarea → iOS dismisses the keyboard, revealing the full terminal. + window.__termBlur = function () { + if (document.activeElement && document.activeElement.blur) document.activeElement.blur(); + }; // webview → RN term.onData(function (d) { post({ type: "input", data: d }); }); window.addEventListener("resize", refit); + // Touch scrollback: xterm only scrolls on wheel events (none on touch), so map a + // vertical drag to term.scrollLines. A drag scrolls; a tap (no real movement) + // focuses to bring the keyboard back after it was dismissed. + var el = document.getElementById("term"); + var startY = 0, lastY = 0, moved = false; + var CELL = 17; // ~fontSize 12 line height; good enough for touch scroll feel + el.addEventListener("touchstart", function (e) { + startY = lastY = e.touches[0].clientY; moved = false; + }, { passive: true }); + el.addEventListener("touchmove", function (e) { + var y = e.touches[0].clientY; + var dy = lastY - y; + if (Math.abs(y - startY) > 6) moved = true; + var lines = (dy / CELL) | 0; + if (lines !== 0) { term.scrollLines(lines); lastY = y; } + }, { passive: true }); + el.addEventListener("touchend", function () { + if (!moved) term.focus(); // a tap (not a scroll) re-opens the keyboard + }); + // First paint: fit, then tell RN we're ready (it snapshots + streams from here). setTimeout(function () { refit(); diff --git a/packages/agents/src/registry.ts b/packages/agents/src/registry.ts index dd5759b..feb3c34 100644 --- a/packages/agents/src/registry.ts +++ b/packages/agents/src/registry.ts @@ -73,15 +73,23 @@ export const AGENTS = [ /** Build the launch command line for an agent (YOLO, resume, or agent-mode variants). */ export function agentCommand( agent: AgentDefinition, - opts: { yolo?: boolean; resume?: boolean; agentMode?: boolean; prompt?: string } = {}, + opts: { + yolo?: boolean; + resume?: boolean; + agentMode?: boolean; + /** Working dir to scope agent mode to (the task's worktree). */ + cwd?: string; + prompt?: string; + } = {}, ): string { // Agent mode launches the tool's own multi-agent board (interactive — it takes // the task description itself), so it ignores the prompt/resume variants. The - // PTY already spawns in the task's worktree, so no --cwd is needed. + // board is NOT scoped by the process cwd — it needs an explicit `--cwd` to + // filter to this worktree (e.g. `claude agents --cwd `). if (opts.agentMode && agent.agentsCommand) { - return opts.yolo && agent.yoloFlag - ? `${agent.agentsCommand} ${agent.yoloFlag}` - : agent.agentsCommand; + const cwd = opts.cwd ? ` --cwd '${opts.cwd.replace(/'/g, `'\\''`)}'` : ""; + const base = `${agent.agentsCommand}${cwd}`; + return opts.yolo && agent.yoloFlag ? `${base} ${agent.yoloFlag}` : base; } const base = opts.resume && agent.resumeCommand ? agent.resumeCommand : agent.command; const cmd = opts.yolo && agent.yoloFlag ? `${base} ${agent.yoloFlag}` : base; diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts index 8e2201b..ab6f4ca 100644 --- a/packages/server/src/dispatcher.ts +++ b/packages/server/src/dispatcher.ts @@ -508,6 +508,7 @@ export function createDispatcher(engine: Engine): Dispatcher { yolo: input.yolo, resume: input.resume, agentMode: input.agentMode, + cwd: task.worktreePath, prompt, }); if (agent.id === "codex") { From 1bb1e072e4aa279d214ee162f4fd592bb833ba52 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 7 Jul 2026 17:18:24 +0200 Subject: [PATCH 28/83] fix(mobile): agent-mode task-name field + terminal touch scroll + keyboard refit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Composer: agent mode still needs to name the worktree, so keep the field but relabel it "TASK NAME" (placeholder makes clear it's a name, not a prompt); its value is passed as the explicit task name (ComposerSubmit.name), while normal mode still derives the name from the prompt. - Terminal touch scroll: handle drags at the document level with capture + preventDefault so xterm's focused hidden textarea can't swallow the gesture (the previous #term-level passive handler didn't fire). A tap still re-focuses. - Terminal fit: refit on keyboard show/hide (RN Keyboard events → __termFit) so the TUI is always sized to the visible area and its input box isn't clipped under the keyboard — the real fix for "see the full terminal". --- apps/mobile/App.tsx | 7 +--- apps/mobile/src/Composer.tsx | 67 +++++++++++++++--------------- apps/mobile/src/TerminalScreen.tsx | 16 +++++++ apps/mobile/src/terminal-html.ts | 39 +++++++++-------- 4 files changed, 74 insertions(+), 55 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 46399f6..34f70c2 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -506,11 +506,8 @@ export default function App() { if (!api || !selectedProjectId) return; setCreating(true); try { - // Agent mode has no prompt to name from — stamp a unique time so the - // worktree branch doesn't collide with a previous "agents" task. - const name = - titleFromPrompt(input.prompt) || - (input.agentMode ? `agents ${new Date().toTimeString().slice(0, 8)}` : "task"); + // Agent mode supplies an explicit name; normal mode derives it from the prompt. + const name = input.name?.trim() || titleFromPrompt(input.prompt) || "task"; const task = await api.tasks.create({ projectId: selectedProjectId, name }); await api.pty.spawnAgent({ taskId: task.id, diff --git a/apps/mobile/src/Composer.tsx b/apps/mobile/src/Composer.tsx index 42da740..771a5e0 100644 --- a/apps/mobile/src/Composer.tsx +++ b/apps/mobile/src/Composer.tsx @@ -21,7 +21,10 @@ const C = { }; export interface ComposerSubmit { + /** The agent's first instruction (normal mode). Empty in agent mode. */ prompt: string; + /** Explicit task/worktree name — set in agent mode, where there's no prompt to derive one from. */ + name?: string; agentId: string; yolo: boolean; agentMode: boolean; @@ -41,42 +44,43 @@ export function Composer({ const pickable = agents.length ? agents : [{ id: "claude", label: "Claude Code", available: true } as AgentDTO]; - const [prompt, setPrompt] = useState(""); + // One field, two roles: the agent's first instruction (normal), or the task + // name (agent mode, which drives its own interactive board with no prompt). + const [text, setText] = useState(""); const [agentId, setAgentId] = useState( pickable.find((a) => a.available)?.id ?? pickable[0]?.id ?? "claude", ); const [yolo, setYolo] = useState(false); const [agentMode, setAgentMode] = useState(false); - // Agent mode takes the task interactively on its own board, so a prompt is - // optional there; otherwise a prompt (or at least something) is required. - const canSubmit = !busy && (agentMode || prompt.trim().length > 0); + // Always need something: a prompt (normal) or a task name (agent mode). + const canSubmit = !busy && text.trim().length > 0; const submit = () => { if (!canSubmit) return; - onSubmit({ prompt: prompt.trim(), agentId, yolo, agentMode }); - setPrompt(""); + const value = text.trim(); + onSubmit( + agentMode + ? { prompt: "", name: value, agentId, yolo, agentMode: true } + : { prompt: value, agentId, yolo, agentMode: false }, + ); + setText(""); }; return ( - {/* Agent mode drives its own interactive board — no prompt is passed, so - hide the textarea and show a hint instead. */} - {agentMode ? ( - - Agent mode — opens the tool's multi-agent board scoped to this project's worktree. - - ) : ( - - )} + {/* Agent mode passes no prompt — but we still need to name the worktree, so + the field becomes an explicit task-name input (clearly labelled). */} + {agentMode ? TASK NAME : null} + {/* Agent picker — tappable chips (few agents, no dropdown needed). */} {pickable.map((a) => ( @@ -144,16 +148,13 @@ const styles = StyleSheet.create({ minHeight: 40, maxHeight: 120, }, - agentHint: { - color: C.faint, - fontSize: 13, - lineHeight: 18, - backgroundColor: C.sunken, - borderWidth: 1, - borderColor: C.line, - borderRadius: 10, - paddingHorizontal: 12, - paddingVertical: 10, + fieldLabel: { + color: C.accent, + fontSize: 10, + fontWeight: "700", + letterSpacing: 1.1, + paddingLeft: 2, + marginBottom: -2, }, row: { flexDirection: "row", alignItems: "center", gap: 6 }, spacer: { flex: 1 }, diff --git a/apps/mobile/src/TerminalScreen.tsx b/apps/mobile/src/TerminalScreen.tsx index ed8202f..6d0b2ff 100644 --- a/apps/mobile/src/TerminalScreen.tsx +++ b/apps/mobile/src/TerminalScreen.tsx @@ -13,6 +13,7 @@ import type { AteamApi, PtyDataEvent, TaskDTO } from "@ateam/protocol"; import { useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, + Keyboard, KeyboardAvoidingView, Platform, Pressable, @@ -201,6 +202,21 @@ export function TerminalScreen({ [api, terminalId], ); + // The visible terminal area changes when the keyboard shows/hides — refit so + // the TUI is always sized to what's on screen (its input box stays visible and + // nothing is clipped under the keyboard). A short delay lets layout settle. + useEffect(() => { + const refit = () => { + setTimeout(() => webRef.current?.injectJavaScript("window.__termFit();true;"), 120); + }; + const show = Keyboard.addListener("keyboardDidShow", refit); + const hide = Keyboard.addListener("keyboardDidHide", refit); + return () => { + show.remove(); + hide.remove(); + }; + }, []); + return ( + ); +} diff --git a/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx b/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx index 1f1e170..64c1512 100644 --- a/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx +++ b/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx @@ -1,6 +1,7 @@ -import { Check, Download, Laptop, Plus, Server } from "lucide-react"; +import { Check, Cloud, Download, Laptop, Plus, Server } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; +import { CreateBoxDialog } from "./CreateBoxDialog"; // The task's "Run on" control — the pill + popover style the global connection // switcher used, moved into the New Task dialog. `null` alias = this Mac; a box alias @@ -46,6 +47,8 @@ export function EnvironmentPicker({ const [installing, setInstalling] = useState(false); const [log, setLog] = useState(""); const [installError, setInstallError] = useState(null); + // The "Create a new box" flow opens a modal (too much for the popover). + const [creating, setCreating] = useState(false); const btnRef = useRef(null); const popRef = useRef(null); const logRef = useRef(null); @@ -289,9 +292,39 @@ export function EnvironmentPicker({ ))} + {onInstall && ( + + )} , document.body, )} + {creating && + createPortal( + setCreating(false)} + onDone={(alias) => { + setCreating(false); + onChange(alias); + close(); + }} + />, + document.body, + )} ); } diff --git a/apps/desktop/src/renderer/src/components/HetznerLogo.tsx b/apps/desktop/src/renderer/src/components/HetznerLogo.tsx new file mode 100644 index 0000000..2cdebea --- /dev/null +++ b/apps/desktop/src/renderer/src/components/HetznerLogo.tsx @@ -0,0 +1,17 @@ +// Hetzner brand mark (their red "H"), inlined so it works under the app's CSP and +// offline — never hotlinked from a CDN. +export function HetznerLogo({ size = 16 }: { size?: number }) { + return ( + + + + ); +} diff --git a/apps/desktop/src/renderer/src/index.css b/apps/desktop/src/renderer/src/index.css index 1d61afb..e0b2a3b 100644 --- a/apps/desktop/src/renderer/src/index.css +++ b/apps/desktop/src/renderer/src/index.css @@ -1751,3 +1751,141 @@ input { .conn-install-go:hover { border-color: var(--text); } + +/* Create-a-box dialog */ +.dialog.createbox { + width: 420px; + max-width: calc(100vw - 80px); + display: flex; + flex-direction: column; + gap: 12px; +} +.cb-head { + display: flex; + align-items: center; + gap: 8px; + color: var(--text); +} +.cb-title { + font-size: 15px; + font-weight: 600; +} +.cb-sub { + font-size: 12px; + color: var(--text-dim); +} +.cb-x { + margin-left: auto; +} +.cb-form, +.cb-progress { + display: flex; + flex-direction: column; + gap: 10px; +} +.cb-row { + display: flex; + flex-direction: column; + gap: 4px; +} +.cb-row > span { + font-size: 12px; + color: var(--text-dim); +} +.cb-input { + width: 100%; + background: var(--bg-elev-2); + border: 1px solid var(--border); + border-radius: 7px; + padding: 7px 9px; + color: var(--text); + font: inherit; + font-size: 13px; +} +.cb-input:focus { + outline: none; + border-color: var(--text); +} +.cb-error { + font-size: 12px; + color: #e5645a; +} +.cb-create { + background: var(--text); + color: var(--bg); + border: none; + border-radius: 8px; + padding: 9px 14px; + font: inherit; + font-weight: 600; + font-size: 13px; + cursor: pointer; +} +.cb-create:hover { + opacity: 0.9; +} +.cb-hint { + font-size: 11px; + color: var(--text-dim); + line-height: 1.45; +} +.cb-stages { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 5px; +} +.cb-stages li { + font-size: 13px; + color: var(--text-dim); + padding-left: 18px; + position: relative; +} +.cb-stages li.done::before { + content: "✓"; + position: absolute; + left: 0; + color: var(--text); +} +.cb-stages li.active { + color: var(--text); +} +.cb-stages li.active::before { + content: "…"; + position: absolute; + left: 0; +} +.cb-log { + margin: 0; + max-height: 180px; + overflow-y: auto; + white-space: pre-wrap; + word-break: break-word; + font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-size: 11px; + line-height: 1.45; + color: var(--text-dim); + background: var(--bg-elev-2); + border-radius: 6px; + padding: 8px 10px; +} +.cb-actions { + display: flex; + gap: 8px; +} +.cb-back { + background: var(--bg-elev-2); + border: 1px solid var(--border); + border-radius: 8px; + padding: 9px 14px; + color: var(--text); + font: inherit; + font-size: 13px; + cursor: pointer; +} +.cb-create:disabled { + opacity: 0.5; + cursor: default; +} diff --git a/apps/desktop/src/shared/host.ts b/apps/desktop/src/shared/host.ts index a22847c..95f3c09 100644 --- a/apps/desktop/src/shared/host.ts +++ b/apps/desktop/src/shared/host.ts @@ -18,9 +18,18 @@ export const HOST_CH = { provision: "host:provision", /** Install the ateam engine on a reachable SSH box, then connect to it. */ install: "host:install", + /** Create a box from scratch at a cloud provider, provision it, and connect. */ + createBox: "host:createBox", + /** Read/write the encrypted provider credentials (token + Tailscale auth key). */ + secretsStatus: "host:secretsStatus", + saveSecrets: "host:saveSecrets", + /** The provider's live catalog (regions + sizes) for the given/saved token. */ + providerOptions: "host:providerOptions", evtConnectionsChanged: "evt:host:connections", /** Streamed installer output (stdout+stderr) during host:install. */ evtInstallLog: "evt:host:install-log", + /** Staged progress while creating a box (host:createBox). */ + evtCreateProgress: "evt:host:create-progress", } as const; /** One chunk of installer output, tagged with the destination it came from. */ @@ -30,6 +39,39 @@ export interface InstallLogEvent { chunk: string; } +/** What to create at the provider. Credentials fall back to the saved secrets. */ +export interface CreateBoxSpec { + /** Box name → ssh_config alias + Tailscale hostname (sanitized to a DNS label). */ + name: string; + /** Provider location slug (e.g. Hetzner `fsn1`). */ + region: string; + /** Provider server-type slug (e.g. Hetzner `cx22`). */ + size: string; + /** Overrides the saved Hetzner token for this run (and is then remembered). */ + hetznerToken?: string; + /** Overrides the saved Tailscale auth key for this run (and is then remembered). */ + tailscaleAuthKey?: string; +} + +/** A stage narration while a box is being created (no secrets, just the step). */ +export interface CreateProgressEvent { + alias: string; + stage: string; +} + +/** Whether each provisioning secret is already saved (never the value itself). */ +export interface SecretsStatus { + hetznerToken: boolean; + tailscaleAuthKey: boolean; +} + +/** The provider's live catalog, fetched with the token so it reflects real availability. */ +export interface ProviderOptions { + locations: { slug: string; label: string }[]; + /** `locations` = the slugs a size is available in (empty = unknown → offer anywhere). */ + serverTypes: { slug: string; label: string; locations: string[] }[]; +} + /** Which engine is driving the app right now. */ export interface HostStatus { mode: "local" | "remote"; @@ -62,8 +104,20 @@ export interface AteamHost { * phone's WebSocket listener too), then connect. `dest` is an ssh_config alias * or `user@host`. Progress streams via onInstallLog. */ install(dest: string, opts?: { wsAddr?: string }): Promise; + /** Create a box from scratch at a cloud provider (generates the SSH key, joins + * Tailscale, installs the engine), then connect. Progress via onCreateProgress + + * onInstallLog; credentials fall back to the saved secrets. */ + createBox(spec: CreateBoxSpec): Promise; + /** Which provisioning secrets are already saved (booleans, never the values). */ + secretsStatus(): Promise; + /** Persist provider credentials (encrypted at rest). Empty string clears one. */ + saveSecrets(patch: { hetznerToken?: string; tailscaleAuthKey?: string }): Promise; + /** The provider's real regions + sizes for the given token (or the saved one). */ + providerOptions(token?: string): Promise; /** Fires with the full connected set whenever an engine is added or removed. */ onConnectionsChanged(cb: (connected: HostStatus[]) => void): () => void; - /** Subscribe to installer output during install(); returns an unsubscribe. */ + /** Subscribe to installer output during install()/createBox(); returns an unsubscribe. */ onInstallLog(cb: (e: InstallLogEvent) => void): () => void; + /** Subscribe to box-creation stage narration; returns an unsubscribe. */ + onCreateProgress(cb: (e: CreateProgressEvent) => void): () => void; } diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index fdd935c..00b6a44 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -19,6 +19,13 @@ export { createDispatcher } from "./dispatcher"; export type { Engine, EngineOptions } from "./engine"; export { createEngine } from "./engine"; export type { ServerTransport } from "./rpc"; +export type { BoxProvider, CreatedServer, CreateServerInput, ProviderOptions } from "./provision"; +export { + buildCloudInit, + HETZNER_LOCATIONS, + HETZNER_SIZES, + hetznerProvider, +} from "./provision"; export { serveRpc } from "./rpc"; export type { Services } from "./services"; export { socketClientTransport, socketServerTransport } from "./transport/socket"; diff --git a/packages/server/src/provision.ts b/packages/server/src/provision.ts new file mode 100644 index 0000000..f9b931d --- /dev/null +++ b/packages/server/src/provision.ts @@ -0,0 +1,234 @@ +// Creating a box FROM SCRATCH at a cloud provider, so the user never has to open a +// provider console or hand-manage SSH keys. A BoxProvider turns a spec into a running +// Linux VM with a public IPv4; the caller (desktop main) then generates the SSH key, +// bakes a cloud-init that stands up the `ateam` user + Tailscale, and reuses the SSH +// installer to bring up the engine. This module is pure (fetch + strings) — the +// Electron-specific bits (key material, secret storage, ~/.ssh/config) live in the app. + +/** A cloud host Ateam can create a box on. */ +export interface BoxProvider { + readonly id: string; + readonly label: string; + /** Create + start a server and return it once it has a public IPv4. Throws on API + * error; `onProgress` narrates the stages for the UI. */ + createServer(input: CreateServerInput): Promise; + /** The REAL per-account catalog for the picker — so we only ever offer regions and + * sizes that actually exist and are in stock, never a hardcoded guess. */ + fetchOptions(token: string): Promise; +} + +/** What the picker shows once a token is entered — the provider's live catalog. */ +export interface ProviderOptions { + locations: { slug: string; label: string }[]; + /** `locations` = the location slugs this size is available in (empty = unknown/any). */ + serverTypes: { slug: string; label: string; locations: string[] }[]; +} + +export interface CreateServerInput { + /** The provider API token (the user's own — their account, their bill). */ + token: string; + /** Server + ssh_config alias; also the Tailscale hostname. Sanitized by the caller. */ + name: string; + /** Provider location slug (e.g. Hetzner `fsn1`). */ + region: string; + /** Provider server-type slug (e.g. Hetzner `cx22`). */ + size: string; + /** The OpenSSH public key to authorize on the box (`ssh-ed25519 AAAA…`). */ + sshPublicKey: string; + /** cloud-init `user_data` run on first boot. */ + cloudInit: string; + onProgress?: (stage: string) => void; +} + +export interface CreatedServer { + /** Provider's server id (opaque string), for later teardown. */ + providerId: string; + publicIp: string; +} + +/** A Tailscale auth key looks like `tskey-auth-…`; a box name is a DNS label. */ +const NAME_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/; +const AUTHKEY_RE = /^tskey-auth-[A-Za-z0-9-]+$/; + +/** + * Build the cloud-init that makes a fresh box reachable exactly the way the rest of + * Ateam expects: a non-root `ateam` user carrying our SSH key (the installer refuses + * to run as root), and Tailscale up with SSH so the tailnet — not a password — is the + * auth boundary for both the desktop (SSH) and the phone (the daemon's WebSocket). + * The engine itself is installed afterward over SSH (streamed), not here. + */ +export function buildCloudInit(opts: { + hostname: string; + sshPublicKey: string; + tailscaleAuthKey: string; +}): string { + const { hostname, sshPublicKey, tailscaleAuthKey } = opts; + if (!NAME_RE.test(hostname)) throw new Error(`invalid box name: ${hostname}`); + if (!AUTHKEY_RE.test(tailscaleAuthKey)) throw new Error("invalid Tailscale auth key"); + if (!/^ssh-(ed25519|rsa) /.test(sshPublicKey)) throw new Error("invalid SSH public key"); + // A YAML literal — the key and authkey are validated above so neither can break out + // of the document or the shell line below. + return [ + "#cloud-config", + "package_update: true", + "packages: [curl]", + "users:", + " - name: ateam", + " groups: [sudo]", + ' sudo: "ALL=(ALL) NOPASSWD:ALL"', + " shell: /bin/bash", + " ssh_authorized_keys:", + ` - ${sshPublicKey}`, + "runcmd:", + " - curl -fsSL https://tailscale.com/install.sh | sh", + // --operator=ateam lets the non-root user run `tailscale ip -4`, which the + // engine installer reads to bake ATEAM_WS_ADDR (the phone's WebSocket listener). + ` - tailscale up --ssh --authkey=${tailscaleAuthKey} --hostname=${hostname} --operator=ateam`, + ].join("\n"); +} + +const HETZNER_API = "https://api.hetzner.cloud/v1"; +const CREATE_POLL_TRIES = 60; +const CREATE_POLL_MS = 3000; + +/** A curated slice of Hetzner's catalog for the picker (the API accepts any valid slug). */ +export const HETZNER_LOCATIONS = [ + { slug: "fsn1", label: "Falkenstein 🇩🇪" }, + { slug: "nbg1", label: "Nuremberg 🇩🇪" }, + { slug: "hel1", label: "Helsinki 🇫🇮" }, + { slug: "ash", label: "Ashburn, VA 🇺🇸" }, + { slug: "hil", label: "Hillsboro, OR 🇺🇸" }, + { slug: "sin", label: "Singapore 🇸🇬" }, +]; +export const HETZNER_SIZES = [ + { slug: "cx22", label: "CX22 — 2 vCPU / 4 GB (x86)" }, + { slug: "cx32", label: "CX32 — 4 vCPU / 8 GB (x86)" }, + { slug: "cpx11", label: "CPX11 — 2 vCPU / 2 GB (AMD)" }, +]; + +/** One authenticated Hetzner API call, with their `{error:{message}}` shape unwrapped. */ +async function hetznerCall(token: string, path: string, init?: RequestInit) { + const res = await fetch(`${HETZNER_API}${path}`, { + ...init, + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + ...init?.headers, + }, + }); + const text = await res.text(); + const body = text ? JSON.parse(text) : {}; + if (!res.ok) throw new Error(`Hetzner ${path}: ${body?.error?.message ?? `HTTP ${res.status}`}`); + return body; +} + +// Availability per location moved onto server_types.locations — the datacenters +// `server_types.available` field is deprecated (removed 2026-10-01). Read defensively: +// the entry may be a slug string or an object keyed by `location`/`name`. +function locationSlugsOf(st: { locations?: unknown[] }): string[] { + return (st.locations ?? []) + .map((l) => (typeof l === "string" ? l : ((l as { location?: string; name?: string })?.location ?? (l as { name?: string })?.name))) + .filter((s): s is string => typeof s === "string"); +} + +export const hetznerProvider: BoxProvider = { + id: "hetzner", + label: "Hetzner Cloud", + + async fetchOptions(token) { + const [locs, types] = await Promise.all([ + hetznerCall(token, "/locations"), + hetznerCall(token, "/server_types?per_page=50"), + ]); + const locations = (locs.locations ?? []).map((l: Record) => ({ + slug: l.name, + label: `${l.city ?? l.description ?? l.name}${l.country ? ` (${l.country})` : ""}`, + })); + const serverTypes = (types.server_types ?? []) + // Skip globally-deprecated types (Hetzner marks them with a `deprecation` object). + .filter((t: Record) => !t.deprecation && !t.deprecated) + .map((t: Record) => ({ + slug: t.name as string, + label: `${String(t.name).toUpperCase()} — ${t.cores} vCPU / ${t.memory} GB${t.cpu_type === "dedicated" ? " (dedicated)" : ""}`, + locations: locationSlugsOf(t as { locations?: unknown[] }), + cores: Number(t.cores) || 0, + })) + .sort((a: { cores: number }, b: { cores: number }) => a.cores - b.cores) + .map(({ cores: _cores, ...rest }: { cores: number; slug: string; label: string; locations: string[] }) => rest); + return { locations, serverTypes }; + }, + + async createServer(input) { + const call = (path: string, init?: RequestInit) => hetznerCall(input.token, path, init); + + // Never spin up (and bill) a second server with the same name, or touch an + // existing one — refuse and let the user pick another name. + input.onProgress?.("Checking the name is free"); + const dup = await call(`/servers?name=${encodeURIComponent(input.name)}`); + if (dup.servers?.length) { + throw new Error( + `A box named "${input.name}" already exists on your Hetzner account. Pick another name, or connect to an existing box with "Set up a box over SSH".`, + ); + } + + input.onProgress?.("Uploading SSH key"); + // A fresh key per box; if a prior attempt already uploaded this name, reuse it. + const keyName = `ateam-${input.name}`; + let keyId: number; + try { + const k = await call("/ssh_keys", { + method: "POST", + body: JSON.stringify({ name: keyName, public_key: input.sshPublicKey }), + }); + keyId = k.ssh_key.id; + } catch { + const found = await call(`/ssh_keys?name=${encodeURIComponent(keyName)}`); + const existing = found.ssh_keys?.[0]; + if (!existing) throw new Error(`could not upload or find SSH key "${keyName}"`); + keyId = existing.id; + } + + input.onProgress?.("Creating server"); + // public_net.enable_ipv4 is REQUIRED now — Hetzner stopped auto-assigning a + // public IPv4, and without one there's no address to SSH into or curl from. + const created = await call("/servers", { + method: "POST", + body: JSON.stringify({ + name: input.name, + server_type: input.size, + image: "ubuntu-24.04", + location: input.region, + public_net: { enable_ipv4: true, enable_ipv6: true }, + ssh_keys: [keyId], + user_data: input.cloudInit, + // Tag it as ours so we can list/identify Ateam boxes and, later, safely make + // Create idempotent for boxes WE made (never a user's own same-named server). + labels: { "managed-by": "ateam" }, + start_after_create: true, + }), + }); + const serverId: number = created.server.id; + const actionId: number = created.action.id; + + input.onProgress?.("Provisioning"); + let ok = false; + for (let i = 0; i < CREATE_POLL_TRIES; i++) { + const a = await call(`/servers/${serverId}/actions/${actionId}`); + const status = a.action?.status; + if (status === "success") { + ok = true; + break; + } + if (status === "error") { + throw new Error(`Hetzner create failed: ${a.action?.error?.message ?? "unknown"}`); + } + await new Promise((r) => setTimeout(r, CREATE_POLL_MS)); + } + if (!ok) throw new Error("Hetzner create did not finish in time"); + + const srv = await call(`/servers/${serverId}`); + const ip = srv.server?.public_net?.ipv4?.ip; + if (!ip) throw new Error("server came up without a public IPv4"); + return { providerId: String(serverId), publicIp: ip }; + }, +}; diff --git a/packages/server/test/provision.test.ts b/packages/server/test/provision.test.ts new file mode 100644 index 0000000..8594b94 --- /dev/null +++ b/packages/server/test/provision.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, test } from "bun:test"; +import { buildCloudInit } from "../src/provision"; + +const KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAITESTKEYtestkeytestkeytestkeytestkey ateam"; +const AUTHKEY = "tskey-auth-abc123DEF-ghiJKL456"; + +describe("buildCloudInit", () => { + test("emits a cloud-config that creates the ateam user and joins Tailscale with SSH", () => { + const yaml = buildCloudInit({ + hostname: "my-box", + sshPublicKey: KEY, + tailscaleAuthKey: AUTHKEY, + }); + expect(yaml.startsWith("#cloud-config")).toBe(true); + expect(yaml).toContain("name: ateam"); + expect(yaml).toContain(`- ${KEY}`); + // Non-interactive Tailscale join, with SSH so the tailnet is the auth boundary. + expect(yaml).toContain( + `tailscale up --ssh --authkey=${AUTHKEY} --hostname=my-box --operator=ateam`, + ); + // The ateam engine is installed AFTERWARD over SSH — cloud-init must not fetch it + // (the clawnify installer). Note Tailscale's own installer is also `install.sh`. + expect(yaml).not.toContain("clawnify"); + }); + + test("rejects a bad box name (would break the DNS label / shell line)", () => { + expect(() => + buildCloudInit({ hostname: "bad name!", sshPublicKey: KEY, tailscaleAuthKey: AUTHKEY }), + ).toThrow(/invalid box name/); + }); + + test("rejects a non-Tailscale auth key", () => { + expect(() => + buildCloudInit({ hostname: "b", sshPublicKey: KEY, tailscaleAuthKey: "nope" }), + ).toThrow(/Tailscale auth key/); + }); + + test("rejects a value that isn't an SSH public key", () => { + expect(() => + buildCloudInit({ hostname: "b", sshPublicKey: "rm -rf /", tailscaleAuthKey: AUTHKEY }), + ).toThrow(/SSH public key/); + }); +}); From 34157c23c1d8399ff37ea226f3bf990729ccbed5 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Thu, 6 Aug 2026 14:27:24 +0200 Subject: [PATCH 80/83] desktop: install coding agents on a box The composer's agent dropdown is now a popover (like the environment picker): a coding agent that's missing on the selected box gets an Install action that runs its official installer over SSH (streamed), then surfaces the one-time OAuth login. Create-a-box gains 'preinstall agents' checkboxes. Agent registry carries each tool's install command + login command (claude/codex/opencode, verified). --- apps/desktop/src/main/host.ts | 45 ++++- apps/desktop/src/preload/index.ts | 1 + apps/desktop/src/renderer/src/App.tsx | 15 ++ .../renderer/src/components/AgentPicker.tsx | 177 ++++++++++++++++++ .../src/components/CreateBoxDialog.tsx | 46 ++++- .../src/components/EnvironmentPicker.tsx | 2 +- .../src/components/NewTaskComposer.tsx | 31 +-- apps/desktop/src/renderer/src/index.css | 68 +++++++ apps/desktop/src/shared/host.ts | 14 ++ packages/agents/src/registry.ts | 11 ++ 10 files changed, 392 insertions(+), 18 deletions(-) create mode 100644 apps/desktop/src/renderer/src/components/AgentPicker.tsx diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts index 0ad6684..a1e8814 100644 --- a/apps/desktop/src/main/host.ts +++ b/apps/desktop/src/main/host.ts @@ -17,6 +17,7 @@ import { type SystemInfo, wsClientTransport, } from "@ateam/protocol"; +import { getAgent } from "@ateam/agents"; import { buildCloudInit, type ConnectionDTO, @@ -38,6 +39,7 @@ import { type CreateProgressEvent, HOST_CH, type HostStatus, + type InstallAgentResult, type InstallLogEvent, type ProviderOptions, type SecretsStatus, @@ -108,6 +110,8 @@ export interface Host { install(dest: string, opts?: { wsAddr?: string }): Promise; /** Create a box from scratch at a provider, provision it, and connect. */ createBox(spec: CreateBoxSpec): Promise; + /** Install an agent's CLI on a connected box, streaming the log; returns the login step. */ + installAgent(alias: string, agentId: string): Promise; /** Which provisioning secrets are saved (booleans, never the values). */ secretsStatus(): SecretsStatus; /** Persist provider credentials (encrypted). Returns the new saved-status. */ @@ -400,7 +404,42 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { // Reuse the streamed installer (Gap A): it derives the box's tailnet IP into // ATEAM_WS_ADDR (so the phone can connect) and connects on success. progress("Installing the engine"); - return install(boxAlias); + const status = await install(boxAlias); + + // Preinstall any requested agent CLIs (best-effort — the box is usable without + // them, and the OAuth login is a separate step the user does after). + for (const agentId of spec.agents ?? []) { + progress(`Installing ${getAgent(agentId)?.label ?? agentId}`); + try { + await installAgent(boxAlias, agentId); + } catch (err) { + progress( + `Couldn't install ${agentId}: ${err instanceof Error ? err.message : String(err)}`, + ); + } + } + return status; + } + + async function installAgent(alias: string, agentId: string): Promise { + const agent = getAgent(agentId); + if (!agent?.install) throw new Error(`Don't know how to install "${agentId}".`); + if (!backends.has(alias)) throw new Error(`Not connected to "${alias}".`); + // Run the official installer in a login shell (PATH/profile set up), then confirm + // the binary is on the login PATH the daemon will actually spawn it from. + const remote = `bash -lc '${agent.install} && command -v ${agent.bin}'`; + const result = await sshExec(alias, remote, { + onData: (chunk) => + broadcast(HOST_CH.evtInstallLog, { dest: alias, chunk } satisfies InstallLogEvent), + }); + if (result.code !== 0) { + throw new Error( + `Installing ${agent.label} on "${alias}" failed (exit ${result.code ?? "on a signal"}) — it may have installed but not landed on the login PATH.`, + ); + } + // The box's agent list now includes it — refresh so the composer's env-agents update. + broadcastConnections(); + return { agentId, loginCommand: agent.loginCommand }; } async function provision(alias: string, input: { cloneUrl: string }): Promise { @@ -427,6 +466,7 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { provision, install, createBox, + installAgent, secretsStatus, saveSecrets, providerOptions, @@ -447,6 +487,9 @@ export function registerHostIpc(host: Host): void { host.install(dest, opts), ); ipcMain.handle(HOST_CH.createBox, (_e, spec: CreateBoxSpec) => host.createBox(spec)); + ipcMain.handle(HOST_CH.installAgent, (_e, alias: string, agentId: string) => + host.installAgent(alias, agentId), + ); ipcMain.handle(HOST_CH.secretsStatus, () => host.secretsStatus()); ipcMain.handle( HOST_CH.saveSecrets, diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index 76c875f..6f567d5 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -125,6 +125,7 @@ const host: AteamHost = { provision: (alias, input) => ipcRenderer.invoke(HOST_CH.provision, alias, input), install: (dest, opts) => ipcRenderer.invoke(HOST_CH.install, dest, opts), createBox: (spec) => ipcRenderer.invoke(HOST_CH.createBox, spec), + installAgent: (alias, agentId) => ipcRenderer.invoke(HOST_CH.installAgent, alias, agentId), secretsStatus: () => ipcRenderer.invoke(HOST_CH.secretsStatus), saveSecrets: (patch) => ipcRenderer.invoke(HOST_CH.saveSecrets, patch), providerOptions: (token) => ipcRenderer.invoke(HOST_CH.providerOptions, token), diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index 7f4b52c..71fc15e 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -391,6 +391,20 @@ export function App() { off(); } }, []); + // Install a coding agent's CLI on a connected box (streamed via the same install log). + const installAgentOnBox = useCallback( + async (alias: string, agentId: string, onLog: (chunk: string) => void) => { + const off = window.ateamHost.onInstallLog((e) => { + if (e.dest === alias) onLog(e.chunk); + }); + try { + return await window.ateamHost.installAgent(alias, agentId); + } finally { + off(); + } + }, + [], + ); const canRemote = activeRepoRemote !== null; const hasLocalMember = activeMembers.some((m) => m.alias === null); const composerEnvs = useMemo(() => { @@ -1083,6 +1097,7 @@ export function App() { envAgents={envAgents} onAdd={addTailscaleBox} onInstall={installBox} + onInstallAgent={installAgentOnBox} onClose={() => setComposerOpen(false)} onCreate={composeTask} /> diff --git a/apps/desktop/src/renderer/src/components/AgentPicker.tsx b/apps/desktop/src/renderer/src/components/AgentPicker.tsx new file mode 100644 index 0000000..a1583fe --- /dev/null +++ b/apps/desktop/src/renderer/src/components/AgentPicker.tsx @@ -0,0 +1,177 @@ +import { Check, Download } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; +import type { AgentDTO } from "@ateam/protocol"; + +// The composer's coding-agent control — the pill + popover the environment picker +// uses, so a *missing* agent on the selected box can be installed right here instead +// of being a dead "(not installed)" option. Installing runs the agent's official +// installer on the box over SSH (streamed); the one-time OAuth login is a follow-up +// the user runs in the box's terminal. + +const POP_W = 260; + +export function AgentPicker({ + agents, + value, + onChange, + isAvailable, + alias, + onInstallAgent, +}: { + agents: AgentDTO[]; + value: string; + onChange: (agentId: string) => void; + isAvailable: (agentId: string) => boolean; + /** The selected environment — install targets this box; null (local) can't install. */ + alias: string | null; + /** Install an agent on the box, streaming log lines; resolves with the login step. */ + onInstallAgent?: ( + alias: string, + agentId: string, + onLog: (chunk: string) => void, + ) => Promise<{ loginCommand?: string }>; +}) { + const [pos, setPos] = useState<{ bottom: number; left: number } | null>(null); + const [installing, setInstalling] = useState(null); + const [log, setLog] = useState(""); + const [error, setError] = useState(null); + const [loginFor, setLoginFor] = useState<{ agentId: string; command?: string } | null>(null); + const btnRef = useRef(null); + const popRef = useRef(null); + const logRef = useRef(null); + + const current = agents.find((a) => a.id === value); + const label = current?.label ?? value; + + const close = () => setPos(null); + const open = () => { + const r = btnRef.current?.getBoundingClientRect(); + if (!r) return; + const left = Math.max(8, Math.min(r.left, window.innerWidth - POP_W - 8)); + setPos({ bottom: window.innerHeight - r.top + 6, left }); + }; + + useEffect(() => { + if (!pos) return; + const onDoc = (e: MouseEvent) => { + const t = e.target as Node; + if (btnRef.current?.contains(t) || popRef.current?.contains(t)) return; + close(); + }; + document.addEventListener("mousedown", onDoc); + return () => document.removeEventListener("mousedown", onDoc); + }, [pos]); + useEffect(() => { + if (logRef.current) logRef.current.scrollTop = logRef.current.scrollHeight; + }, [log]); + + const install = async (agentId: string) => { + if (!alias || !onInstallAgent || installing) return; + setInstalling(agentId); + setError(null); + setLog(""); + setLoginFor(null); + try { + const res = await onInstallAgent(alias, agentId, (chunk) => setLog((l) => l + chunk)); + // The box's agent list refreshes via onConnectionsChanged; select it now. + onChange(agentId); + setLoginFor({ agentId, command: res.loginCommand }); + } catch (err) { + setError(err instanceof Error ? err.message : String(err)); + } finally { + setInstalling(null); + } + }; + + return ( + <> + + {pos && + createPortal( +
    +
    + Coding agent +
    + {agents.map((a) => { + const avail = isAvailable(a.id); + const canInstall = !avail && alias !== null && !!onInstallAgent; + return ( +
    + + {canInstall ? ( + + ) : null} + {installing === a.id && log ? ( +
    +											{log}
    +										
    + ) : null} + {loginFor?.agentId === a.id ? ( +
    + Installed ✓ — sign in on the box:{" "} + {loginFor.command ?? `${a.id} login`} +
    + ) : null} +
    + ); + })} + {error ?
    {error}
    : null} +
    , + document.body, + )} + + ); +} diff --git a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx index b4cf493..5bccd67 100644 --- a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx +++ b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx @@ -1,5 +1,6 @@ import { X } from "lucide-react"; import { useEffect, useRef, useState } from "react"; +import type { AgentDTO } from "@ateam/protocol"; import type { ProviderOptions } from "../../../shared/host"; import { HetznerLogo } from "./HetznerLogo"; @@ -29,6 +30,8 @@ export function CreateBoxDialog({ const [stages, setStages] = useState([]); const [log, setLog] = useState(""); const [error, setError] = useState(null); + const [agents, setAgents] = useState([]); + const [preinstall, setPreinstall] = useState([]); const logRef = useRef(null); const loadOptions = async () => { @@ -51,6 +54,7 @@ export function CreateBoxDialog({ // A saved token means we can show real availability immediately. if (s.hetznerToken) void loadOptions(); }); + void window.ateam.agents.list().then(setAgents); // biome-ignore lint/correctness/useExhaustiveDependencies: run once on open }, []); useEffect(() => { @@ -92,6 +96,7 @@ export function CreateBoxDialog({ size, hetznerToken: token.trim() || undefined, tailscaleAuthKey: tsKey.trim() || undefined, + agents: preinstall.length ? preinstall : undefined, }); // A created box is always a remote engine (never the local null alias). if (status.alias) onDone(status.alias); @@ -120,7 +125,10 @@ export function CreateBoxDialog({
      {stages.map((s, i) => ( -
    • +
    • {s}
    • ))} @@ -168,7 +176,9 @@ export function CreateBoxDialog({ className="cb-input" type="password" value={token} - placeholder={saved.hetznerToken ? "saved ✓ — leave blank to reuse" : "paste your token"} + placeholder={ + saved.hetznerToken ? "saved ✓ — leave blank to reuse" : "paste your token" + } // A new token means a possibly different account — reload availability. onChange={(e) => { setToken(e.target.value); @@ -182,7 +192,9 @@ export function CreateBoxDialog({ className="cb-input" type="password" value={tsKey} - placeholder={saved.tailscaleAuthKey ? "saved ✓ — leave blank to reuse" : "tskey-auth-…"} + placeholder={ + saved.tailscaleAuthKey ? "saved ✓ — leave blank to reuse" : "tskey-auth-…" + } onChange={(e) => setTsKey(e.target.value)} /> @@ -205,7 +217,11 @@ export function CreateBoxDialog({ + {agents.length > 0 && ( +
      + Preinstall agents (optional) +
      + {agents.map((a) => ( + + ))} +
      + You sign in (OAuth) on the box afterward. +
      + )} {error &&
      {error}
      } - + onChange={setAgentId} + isAvailable={isAvail} + alias={alias} + onInstallAgent={onInstallAgent} + /> ; + /** Install an agent's CLI on a connected box (streamed via onInstallLog), then + * return the one-time OAuth login to run on the box. */ + installAgent(alias: string, agentId: string): Promise; /** Which provisioning secrets are already saved (booleans, never the values). */ secretsStatus(): Promise; /** Persist provider credentials (encrypted at rest). Empty string clears one. */ diff --git a/packages/agents/src/registry.ts b/packages/agents/src/registry.ts index feb3c34..07733d7 100644 --- a/packages/agents/src/registry.ts +++ b/packages/agents/src/registry.ts @@ -34,6 +34,11 @@ export interface AgentDefinition { agentsCommand?: string; /** How an initial task prompt is delivered (if supported). */ promptTransport?: PromptTransport; + /** Non-interactive command that installs this agent's CLI on a box (run in a + * login shell over SSH). Omitted if we don't know how to install it. */ + install?: string; + /** The one-time OAuth login the user runs on the box after install (browser flow). */ + loginCommand?: string; } // Registry of the supported agent CLIs. Command lines and the YOLO bypass @@ -50,6 +55,8 @@ export const AGENTS = [ yoloFlag: "--permission-mode auto", resumeCommand: "claude --continue", agentsCommand: "claude agents", + install: "curl -fsSL https://claude.ai/install.sh | bash", + loginCommand: "claude login", }, { id: "codex", @@ -59,6 +66,8 @@ export const AGENTS = [ command: "codex", yoloFlag: "--dangerously-bypass-approvals-and-sandbox", resumeCommand: "codex resume --last", + install: "curl -fsSL https://chatgpt.com/codex/install.sh | sh", + loginCommand: "codex login", }, { id: "opencode", @@ -67,6 +76,8 @@ export const AGENTS = [ bin: "opencode", command: "opencode", resumeCommand: "opencode --continue", + install: "curl -fsSL https://opencode.ai/install | bash", + loginCommand: "opencode auth login", }, ] as const satisfies readonly AgentDefinition[]; From 092be2d7db88d3f53207c485a524f8485abceb56 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Thu, 6 Aug 2026 14:46:26 +0200 Subject: [PATCH 81/83] =?UTF-8?q?install.sh:=20make=20a=20box=20task-ready?= =?UTF-8?q?=20=E2=80=94=20install=20gh=20+=20derive=20git=20identity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fresh box ran the engine but couldn't clone private repos (no gh, no GitHub auth, no git identity) — the first task failed. install.sh now installs gh (sudo-free user-local binary) and, because gh auth does NOT set the commit identity, derives it from the authenticated GitHub account (gh api user → name + noreply email) on any re-run after sign-in. Validated live on a box. --- packages/server/scripts/install.sh | 45 ++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/packages/server/scripts/install.sh b/packages/server/scripts/install.sh index 00fbf7a..af82c2a 100644 --- a/packages/server/scripts/install.sh +++ b/packages/server/scripts/install.sh @@ -185,6 +185,30 @@ case "$HELLO" in *) die "handshake failed: ${HELLO:-}" ;; esac +# ------------------------------------------------------------------ gh ------ + +# The GitHub CLI, so the box can clone/push your repos AND we can derive your git +# identity from your account (below). Installed as a user-local binary — NO sudo: +# some boxes have no passwordless sudo, and the rest of this script is sudo-free. +# Non-fatal: a box with no gh can still run non-GitHub work. +if ! bash -lc 'command -v gh' >/dev/null 2>&1; then + step "install the GitHub CLI (gh)" + GH_ARCH="$(uname -m)" + case "$GH_ARCH" in x86_64) GH_ARCH=amd64 ;; aarch64 | arm64) GH_ARCH=arm64 ;; esac + GH_TAG="$(curl -fsSL https://api.github.com/repos/cli/cli/releases/latest | grep -m1 '"tag_name"' | cut -d'"' -f4)" + if [ -n "$GH_TAG" ]; then + GH_TMP="$(mktemp -d)" + if curl -fsSL "https://github.com/cli/cli/releases/download/${GH_TAG}/gh_${GH_TAG#v}_linux_${GH_ARCH}.tar.gz" | + tar -xz -C "$GH_TMP" 2>/dev/null; then + cp "$GH_TMP"/gh_*/bin/gh "$BIN_DIR/gh" && chmod +x "$BIN_DIR/gh" + info "gh installed ($("$BIN_DIR/gh" --version | head -1))" + else + info "could not download gh — clone/push will need it installed later" + fi + rm -rf "$GH_TMP" + fi +fi + # -------------------------------------------------------------- service ---- # Opt-in (`install.sh --service`). Without it the daemon is started on demand by @@ -264,17 +288,28 @@ step "readiness" have() { bash -lc "command -v $1" >/dev/null 2>&1; } mark() { [ "$1" = ok ] && printf ' [ok] %s\n' "$2" || printf ' [--] %s\n' "$2"; } -if [ -n "$(git config --global user.email || true)" ] && [ -n "$(git config --global user.name || true)" ]; then +# gh auth does NOT set your commit identity, so derive it from the authenticated +# GitHub account — one `gh auth login` then covers BOTH clone/push access and the +# commit author. Runs on any re-run after you've signed in. +GH_BIN="$(bash -lc 'command -v gh' 2>/dev/null || true)" +if { [ -z "$(git config --global user.name || true)" ] || [ -z "$(git config --global user.email || true)" ]; } && + [ -n "$GH_BIN" ] && "$GH_BIN" auth status >/dev/null 2>&1; then + GH_NAME="$("$GH_BIN" api user -q '.name // .login' 2>/dev/null || true)" + GH_EMAIL="$("$GH_BIN" api user -q '"\(.id)+\(.login)@users.noreply.github.com"' 2>/dev/null || true)" + [ -n "$GH_NAME" ] && git config --global user.name "$GH_NAME" + [ -n "$GH_EMAIL" ] && git config --global user.email "$GH_EMAIL" +fi +if [ -n "$(git config --global user.name || true)" ] && [ -n "$(git config --global user.email || true)" ]; then mark ok "git identity ($(git config --global user.name) <$(git config --global user.email)>)" else - mark no 'git identity — REQUIRED, agent commits fail without it:' + mark no 'git identity — set automatically once you `gh auth login`, or by hand:' info ' git config --global user.name "you"; git config --global user.email "you@example.com"' fi -if have gh && [ -n "$(gh auth token 2>/dev/null)" ]; then - mark ok "gh authenticated" +if [ -n "$GH_BIN" ] && "$GH_BIN" auth status >/dev/null 2>&1; then + mark ok "GitHub signed in ($("$GH_BIN" api user -q .login 2>/dev/null))" else - mark no 'gh — needed for PRs and the merge queue: gh auth login' + mark no 'GitHub — sign in so the box can clone your repos: gh auth login' fi AGENTS="" From fbd87c6eb7bc5d0040e4238cb9cfaaba5b529ec1 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Thu, 6 Aug 2026 15:11:27 +0200 Subject: [PATCH 82/83] desktop: box-readiness checklist + inline agent Install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After Create-a-box connects, show a readiness checklist instead of closing blind: engine + Tailscale done, and the two interactive steps that remain — GitHub sign-in (gh auth login) and agent login — with a Recheck that re-probes and auto-derives the git identity from the GitHub account once signed in. New host.boxReadiness(alias) probes the box over SSH. Also: the agent picker's Install button now sits inline with the agent name. --- apps/desktop/src/main/host.ts | 51 +++++++++++ apps/desktop/src/preload/index.ts | 1 + .../renderer/src/components/AgentPicker.tsx | 60 ++++++------- .../src/components/CreateBoxDialog.tsx | 86 +++++++++++++++++-- apps/desktop/src/renderer/src/index.css | 61 ++++++++++++- apps/desktop/src/shared/host.ts | 14 +++ 6 files changed, 237 insertions(+), 36 deletions(-) diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts index a1e8814..d1d0d5d 100644 --- a/apps/desktop/src/main/host.ts +++ b/apps/desktop/src/main/host.ts @@ -35,6 +35,7 @@ import { app, ipcMain } from "electron"; import WebSocket from "ws"; import { join } from "node:path"; import { + type BoxReadiness, type CreateBoxSpec, type CreateProgressEvent, HOST_CH, @@ -71,6 +72,28 @@ const INSTALL_URL = // Default WebSocket port baked into a provisioned box's Tailscale listener (matches // the picker's placeholder). The listener only exists if the box is on Tailscale. const WS_DEFAULT_PORT = 8787; + +// Probe a box's task-readiness (base64'd over SSH to dodge quoting) and self-heal the +// git identity: once the box is signed into GitHub, derive name+email from the account +// — `gh auth login` authenticates but does NOT set the commit identity. `\\(` becomes +// `\(` in the string so jq gets its interpolation syntax. +const READINESS_PROBE = `GH=$(command -v gh || true) +SIGNED=0; LOGIN="" +if [ -n "$GH" ] && "$GH" auth status >/dev/null 2>&1; then + SIGNED=1 + LOGIN=$("$GH" api user -q .login 2>/dev/null || true) + if [ -z "$(git config --global user.name || true)" ] || [ -z "$(git config --global user.email || true)" ]; then + N=$("$GH" api user -q '.name // .login' 2>/dev/null || true) + E=$("$GH" api user -q '"\\(.id)+\\(.login)@users.noreply.github.com"' 2>/dev/null || true) + [ -n "$N" ] && git config --global user.name "$N" + [ -n "$E" ] && git config --global user.email "$E" + fi +fi +echo "gh_installed=$([ -n "$GH" ] && echo 1 || echo 0)" +echo "gh_signed_in=$SIGNED" +echo "gh_login=$LOGIN" +echo "git_name=$(git config --global user.name || true)" +echo "git_email=$(git config --global user.email || true)"`; // Cap a connect: ssh can hang on an auth prompt or an unreachable host with no // error, and the UI must not wait forever. A live daemon replies in well under this. const CONNECT_TIMEOUT_MS = 20_000; @@ -112,6 +135,8 @@ export interface Host { createBox(spec: CreateBoxSpec): Promise; /** Install an agent's CLI on a connected box, streaming the log; returns the login step. */ installAgent(alias: string, agentId: string): Promise; + /** Probe a connected box's task-readiness (and self-heal git identity once signed in). */ + boxReadiness(alias: string): Promise; /** Which provisioning secrets are saved (booleans, never the values). */ secretsStatus(): SecretsStatus; /** Persist provider credentials (encrypted). Returns the new saved-status. */ @@ -442,6 +467,30 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { return { agentId, loginCommand: agent.loginCommand }; } + async function boxReadiness(alias: string): Promise { + if (!backends.has(alias)) throw new Error(`Not connected to "${alias}".`); + const b64 = Buffer.from(READINESS_PROBE).toString("base64"); + let out = ""; + const r = await sshExec(alias, `echo ${b64} | base64 -d | bash -ls`, { + onData: (chunk) => { + out += chunk; + }, + }); + if (r.code !== 0) { + throw new Error(`Couldn't read "${alias}" readiness (ssh exited ${r.code ?? "on a signal"}).`); + } + const val = (k: string) => out.match(new RegExp(`^${k}=(.*)$`, "m"))?.[1]?.trim() ?? ""; + return { + gh: { + installed: val("gh_installed") === "1", + signedIn: val("gh_signed_in") === "1", + login: val("gh_login") || undefined, + }, + gitName: val("git_name") || undefined, + gitEmail: val("git_email") || undefined, + }; + } + async function provision(alias: string, input: { cloneUrl: string }): Promise { // Provisioning targets a SPECIFIC engine — the aggregate routes by learned id, // but there's no id on the box yet, so call that backend's clone directly. @@ -467,6 +516,7 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { install, createBox, installAgent, + boxReadiness, secretsStatus, saveSecrets, providerOptions, @@ -490,6 +540,7 @@ export function registerHostIpc(host: Host): void { ipcMain.handle(HOST_CH.installAgent, (_e, alias: string, agentId: string) => host.installAgent(alias, agentId), ); + ipcMain.handle(HOST_CH.boxReadiness, (_e, alias: string) => host.boxReadiness(alias)); ipcMain.handle(HOST_CH.secretsStatus, () => host.secretsStatus()); ipcMain.handle( HOST_CH.saveSecrets, diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index 6f567d5..bdc8072 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -126,6 +126,7 @@ const host: AteamHost = { install: (dest, opts) => ipcRenderer.invoke(HOST_CH.install, dest, opts), createBox: (spec) => ipcRenderer.invoke(HOST_CH.createBox, spec), installAgent: (alias, agentId) => ipcRenderer.invoke(HOST_CH.installAgent, alias, agentId), + boxReadiness: (alias) => ipcRenderer.invoke(HOST_CH.boxReadiness, alias), secretsStatus: () => ipcRenderer.invoke(HOST_CH.secretsStatus), saveSecrets: (patch) => ipcRenderer.invoke(HOST_CH.saveSecrets, patch), providerOptions: (token) => ipcRenderer.invoke(HOST_CH.providerOptions, token), diff --git a/apps/desktop/src/renderer/src/components/AgentPicker.tsx b/apps/desktop/src/renderer/src/components/AgentPicker.tsx index a1583fe..86bca69 100644 --- a/apps/desktop/src/renderer/src/components/AgentPicker.tsx +++ b/apps/desktop/src/renderer/src/components/AgentPicker.tsx @@ -121,39 +121,41 @@ export function AgentPicker({ const canInstall = !avail && alias !== null && !!onInstallAgent; return (
      - - {canInstall ? ( +
      - ) : null} + {canInstall ? ( + + ) : null} +
      {installing === a.id && log ? (
       											{log}
      diff --git a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx
      index 5bccd67..06ae142 100644
      --- a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx
      +++ b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx
      @@ -1,7 +1,14 @@
       import { X } from "lucide-react";
       import { useEffect, useRef, useState } from "react";
       import type { AgentDTO } from "@ateam/protocol";
      -import type { ProviderOptions } from "../../../shared/host";
      +import type { BoxReadiness, ProviderOptions } from "../../../shared/host";
      +
      +// The one-time OAuth login per agent (mirrors the registry; the renderer can't import it).
      +const AGENT_LOGIN: Record = {
      +	claude: "claude login",
      +	codex: "codex login",
      +	opencode: "opencode auth login",
      +};
       import { HetznerLogo } from "./HetznerLogo";
       
       // "Create a box" — Ateam stands up a fresh VPS at a provider, generates the SSH key,
      @@ -32,8 +39,24 @@ export function CreateBoxDialog({
       	const [error, setError] = useState(null);
       	const [agents, setAgents] = useState([]);
       	const [preinstall, setPreinstall] = useState([]);
      +	// After a box is created + connected: its readiness (gh/identity) + installed agents.
      +	const [readyAlias, setReadyAlias] = useState(null);
      +	const [readyBox, setReadyBox] = useState(null);
      +	const [readyAgents, setReadyAgents] = useState([]);
      +	const [checking, setChecking] = useState(false);
       	const logRef = useRef(null);
       
      +	const checkReadiness = async (alias: string) => {
      +		setChecking(true);
      +		try {
      +			setReadyBox(await window.ateamHost.boxReadiness(alias));
      +		} catch {
      +			// A probe failure just leaves the checklist partial — not worth blocking on.
      +		} finally {
      +			setChecking(false);
      +		}
      +	};
      +
       	const loadOptions = async () => {
       		setLoadingOpts(true);
       		setOptsError(null);
      @@ -98,8 +121,13 @@ export function CreateBoxDialog({
       				tailscaleAuthKey: tsKey.trim() || undefined,
       				agents: preinstall.length ? preinstall : undefined,
       			});
      -			// A created box is always a remote engine (never the local null alias).
      -			if (status.alias) onDone(status.alias);
      +			// Created + connected (always a remote engine). Show what's left to make it
      +			// task-ready (GitHub sign-in, agent logins) instead of closing blind.
      +			if (status.alias) {
      +				setReadyAlias(status.alias);
      +				setReadyAgents(status.info.agents);
      +				void checkReadiness(status.alias);
      +			}
       		} catch (e) {
       			setError(e instanceof Error ? e.message : String(e));
       		} finally {
      @@ -139,7 +167,55 @@ export function CreateBoxDialog({
       							
      )} {error &&
      {error}
      } - {!busy && ( + {!busy && readyAlias ? ( +
      +
      + Box created — finish these in the box’s terminal: +
      +
        +
      • Engine + Tailscale
      • +
      • + {readyBox?.gh.signedIn + ? `GitHub signed in${readyBox.gh.login ? ` as ${readyBox.gh.login}` : ""}` + : "GitHub — sign in: "} + {!readyBox?.gh.signedIn ? gh auth login : null} +
      • +
      • + {readyBox?.gitName + ? `git identity (${readyBox.gitName})` + : "git identity — sets automatically after GitHub sign-in"} +
      • + {readyAgents.length === 0 ? ( +
      • + no coding agent yet — install one from the agent picker +
      • + ) : ( + readyAgents.map((a) => ( +
      • + {a} — sign in: {AGENT_LOGIN[a] ?? `${a} login`} +
      • + )) + )} +
      +
      + + +
      +
      + ) : !busy ? (
      - )} + ) : null}
      ) : (
      diff --git a/apps/desktop/src/renderer/src/index.css b/apps/desktop/src/renderer/src/index.css index 6fa700b..85817a3 100644 --- a/apps/desktop/src/renderer/src/index.css +++ b/apps/desktop/src/renderer/src/index.css @@ -1903,12 +1903,22 @@ input { display: flex; flex-direction: column; } +.agent-row { + display: flex; + align-items: center; + gap: 6px; + padding-right: 8px; +} +.agent-row > .conn-row { + flex: 1; + min-width: 0; +} .agent-install-btn { display: inline-flex; align-items: center; gap: 5px; - align-self: flex-start; - margin: 0 10px 6px 34px; + flex: none; + margin: 0; background: var(--bg-elev-2); border: 1px solid var(--border); border-radius: 6px; @@ -1957,3 +1967,50 @@ input { color: var(--text); cursor: pointer; } + +.cb-ready { + display: flex; + flex-direction: column; + gap: 10px; +} +.cb-ready-title { + font-size: 13px; + color: var(--text); +} +.cb-ready-list { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 6px; +} +.cb-ready-list li { + font-size: 13px; + color: var(--text-dim); + padding-left: 18px; + position: relative; +} +.cb-ready-list li.done { + color: var(--text); +} +.cb-ready-list li.done::before { + content: "\2713"; + position: absolute; + left: 0; + color: var(--text); +} +.cb-ready-list li.todo::before { + content: "\2192"; + position: absolute; + left: 0; + color: var(--text-dim); +} +.cb-ready-list code { + font-family: ui-monospace, Menlo, monospace; + font-size: 12px; + color: var(--text); + background: var(--bg-elev-2); + padding: 1px 5px; + border-radius: 4px; +} diff --git a/apps/desktop/src/shared/host.ts b/apps/desktop/src/shared/host.ts index 9d3a618..0220d04 100644 --- a/apps/desktop/src/shared/host.ts +++ b/apps/desktop/src/shared/host.ts @@ -22,6 +22,8 @@ export const HOST_CH = { createBox: "host:createBox", /** Install an agent's CLI on a connected box (streamed via evtInstallLog). */ installAgent: "host:installAgent", + /** Probe a connected box's task-readiness (gh installed/signed-in, git identity). */ + boxReadiness: "host:boxReadiness", /** Read/write the encrypted provider credentials (token + Tailscale auth key). */ secretsStatus: "host:secretsStatus", saveSecrets: "host:saveSecrets", @@ -57,6 +59,15 @@ export interface CreateBoxSpec { agents?: string[]; } +/** A connected box's task-readiness — what a task needs beyond the engine. */ +export interface BoxReadiness { + /** GitHub CLI: installed on the box, and signed in (so it can clone private repos). */ + gh: { installed: boolean; signedIn: boolean; login?: string }; + /** The git commit identity (derived from the GitHub login once signed in). */ + gitName?: string; + gitEmail?: string; +} + /** Result of installing an agent's CLI on a box — the login the user runs next. */ export interface InstallAgentResult { agentId: string; @@ -122,6 +133,9 @@ export interface AteamHost { /** Install an agent's CLI on a connected box (streamed via onInstallLog), then * return the one-time OAuth login to run on the box. */ installAgent(alias: string, agentId: string): Promise; + /** Probe a connected box's task-readiness (also derives the git identity once the + * box is signed into GitHub). */ + boxReadiness(alias: string): Promise; /** Which provisioning secrets are already saved (booleans, never the values). */ secretsStatus(): Promise; /** Persist provider credentials (encrypted at rest). Empty string clears one. */ From 979b995d06dba99234b63bdacac1dac8773a619c Mon Sep 17 00:00:00 2001 From: pallaoro Date: Thu, 6 Aug 2026 15:17:36 +0200 Subject: [PATCH 83/83] desktop: agent login isn't a box-setup pre-step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The coding agent signs in interactively on its first run inside the task terminal, unlike gh (whose auth the clone needs up front). So the readiness checklist lists an installed agent as done — not a 'run `claude login`' step — and the agent picker says it signs in on first use rather than printing a login command. --- .../src/renderer/src/components/AgentPicker.tsx | 5 +---- .../src/renderer/src/components/CreateBoxDialog.tsx | 10 ++-------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/AgentPicker.tsx b/apps/desktop/src/renderer/src/components/AgentPicker.tsx index 86bca69..91d345d 100644 --- a/apps/desktop/src/renderer/src/components/AgentPicker.tsx +++ b/apps/desktop/src/renderer/src/components/AgentPicker.tsx @@ -162,10 +162,7 @@ export function AgentPicker({ ) : null} {loginFor?.agentId === a.id ? ( -
      - Installed ✓ — sign in on the box:{" "} - {loginFor.command ?? `${a.id} login`} -
      +
      Installed ✓ — it signs in on first use.
      ) : null}
      ); diff --git a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx index 06ae142..54254a5 100644 --- a/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx +++ b/apps/desktop/src/renderer/src/components/CreateBoxDialog.tsx @@ -3,12 +3,6 @@ import { useEffect, useRef, useState } from "react"; import type { AgentDTO } from "@ateam/protocol"; import type { BoxReadiness, ProviderOptions } from "../../../shared/host"; -// The one-time OAuth login per agent (mirrors the registry; the renderer can't import it). -const AGENT_LOGIN: Record = { - claude: "claude login", - codex: "codex login", - opencode: "opencode auth login", -}; import { HetznerLogo } from "./HetznerLogo"; // "Create a box" — Ateam stands up a fresh VPS at a provider, generates the SSH key, @@ -191,8 +185,8 @@ export function CreateBoxDialog({ ) : ( readyAgents.map((a) => ( -
    • - {a} — sign in: {AGENT_LOGIN[a] ?? `${a} login`} +
    • + {a} installed
    • )) )}
    diff --git a/apps/desktop/src/renderer/src/components/ConnectionSwitcher.tsx b/apps/desktop/src/renderer/src/components/ConnectionSwitcher.tsx new file mode 100644 index 0000000..a8e7f49 --- /dev/null +++ b/apps/desktop/src/renderer/src/components/ConnectionSwitcher.tsx @@ -0,0 +1,216 @@ +import type { ConnectionDTO, SystemInfo } from "@ateam/protocol"; +import { AlertCircle, Check, Laptop, Loader2, RefreshCw, Server } from "lucide-react"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; + +// Which engine drives the app: this Mac (local, in-process) or a remote box over +// SSH — over Tailscale, that's the "online ateam" connection. The whole backend +// seam (window.ateamHost) is already wired in main; this is its faucet in the UI. +// Lists ~/.ssh/config hosts so onboarding is just "add a Host entry, then pick it". + +const POP_W = 280; + +type HostStatus = { mode: "local" | "remote"; alias: string | null; info: SystemInfo }; + +// "local" is the sentinel for the in-process engine (connect(null)). +type Target = string | "local"; + +function ago(ms: number | null): string | null { + if (!ms) return null; + const s = Math.max(0, Math.round((Date.now() - ms) / 1000)); + if (s < 60) return "just now"; + const m = Math.round(s / 60); + if (m < 60) return `${m}m ago`; + const h = Math.round(m / 60); + if (h < 24) return `${h}h ago`; + return `${Math.round(h / 24)}d ago`; +} + +export function ConnectionSwitcher({ onChanged }: { onChanged?: (status: HostStatus) => void }) { + const [current, setCurrent] = useState(null); + const [conns, setConns] = useState([]); + const [connecting, setConnecting] = useState(null); + const [error, setError] = useState(null); + const [pos, setPos] = useState<{ top: number; left: number } | null>(null); + const btnRef = useRef(null); + const popRef = useRef(null); + + const refresh = useCallback(async () => { + const [cur, list] = await Promise.all([ + window.ateamHost.current(), + window.ateamHost.list(), + ]); + setCurrent(cur); + setConns(list); + }, []); + + // Keep the button label live even when another window switches the engine. + useEffect(() => { + void refresh(); + return window.ateamHost.onChanged((status) => { + setCurrent(status); + void window.ateamHost.list().then(setConns); + }); + }, [refresh]); + + const close = () => setPos(null); + const open = () => { + const r = btnRef.current?.getBoundingClientRect(); + if (!r) return; + let left = Math.min(r.left, window.innerWidth - POP_W - 8); + left = Math.max(8, left); + setPos({ top: r.bottom + 6, left }); + setError(null); + void refresh(); + }; + + useEffect(() => { + if (!pos) return; + const onDoc = (e: MouseEvent) => { + const t = e.target as Node; + if (btnRef.current?.contains(t) || popRef.current?.contains(t)) return; + close(); + }; + document.addEventListener("mousedown", onDoc); + return () => document.removeEventListener("mousedown", onDoc); + }, [pos]); + + const pick = async (target: Target) => { + // Already there — just close. + const isActive = + target === "local" ? current?.mode === "local" : current?.alias === target; + if (isActive) { + close(); + return; + } + setConnecting(target); + setError(null); + try { + const status = await window.ateamHost.connect(target === "local" ? null : target); + setCurrent(status); + onChanged?.(status); + close(); + } catch (e) { + // Surface the real reason (box unreachable, daemon not running, protocol + // mismatch) — the main-process connect() throws a descriptive message. + setError(e instanceof Error ? e.message : String(e)); + } finally { + setConnecting(null); + } + }; + + const remote = current?.mode === "remote"; + const label = remote ? (current?.alias ?? "remote") : "Local"; + + return ( + <> + + {pos && + createPortal( +
    +
    + Run agents on + +
    + + {/* Local engine */} + } + title="This Mac" + subtitle="Runs locally, no connection" + active={current?.mode === "local"} + busy={connecting === "local"} + onClick={() => void pick("local")} + /> + +
    + + {conns.length === 0 ? ( +
    + No servers in ~/.ssh/config. +
    + Add a Host entry for your box to connect. +
    + ) : ( + conns.map((c) => { + const seen = ago(c.lastSeen); + const sub = c.hostName + ? c.known && seen + ? `${c.hostName} · seen ${seen}` + : c.hostName + : c.known + ? "saved host (not in ssh config)" + : "unknown host"; + return ( + } + title={c.alias} + subtitle={sub} + active={current?.mode === "remote" && current.alias === c.alias} + busy={connecting === c.alias} + onClick={() => void pick(c.alias)} + /> + ); + }) + )} + + {error && ( +
    + + {error} +
    + )} +
    , + document.body, + )} + + ); +} + +function ConnRow({ + icon, + title, + subtitle, + active, + busy, + onClick, +}: { + icon: React.ReactNode; + title: string; + subtitle: string; + active: boolean; + busy: boolean; + onClick: () => void; +}) { + return ( + + ); +} diff --git a/apps/desktop/src/renderer/src/index.css b/apps/desktop/src/renderer/src/index.css index 0659107..4b32863 100644 --- a/apps/desktop/src/renderer/src/index.css +++ b/apps/desktop/src/renderer/src/index.css @@ -1153,6 +1153,141 @@ input { background: rgba(248, 113, 113, 0.14); } +/* ---- connection switcher (which engine drives the app) ---- */ +.conn-btn { + max-width: 200px; +} +.conn-btn > span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.conn-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--text-dim); + flex: none; +} +.conn-dot.on { + background: var(--green); + box-shadow: 0 0 6px rgba(74, 222, 128, 0.7); +} +.conn-pop { + padding: 6px; +} +.conn-head { + display: flex; + align-items: center; + justify-content: space-between; + padding: 4px 8px 6px; + font-size: 11px; + letter-spacing: 0.4px; + text-transform: uppercase; + color: var(--text-dim); +} +.conn-refresh { + display: inline-flex; + background: transparent; + border: none; + color: var(--text-dim); + cursor: pointer; + padding: 2px; + border-radius: 4px; +} +.conn-refresh:hover { + color: var(--text); + background: var(--bg-elev-2); +} +.conn-sep { + height: 1px; + background: var(--border); + margin: 4px 6px; +} +.conn-row { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + background: transparent; + border: none; + border-radius: 7px; + padding: 8px 10px; + color: var(--text); + cursor: pointer; + text-align: left; +} +.conn-row:hover { + background: var(--bg-elev-2); +} +.conn-row.active { + background: rgba(124, 92, 255, 0.12); +} +.conn-row:disabled { + cursor: default; +} +.conn-ico { + display: inline-flex; + color: var(--text-dim); + flex: none; +} +.conn-row.active .conn-ico { + color: var(--text); +} +.conn-txt { + display: flex; + flex-direction: column; + gap: 1px; + min-width: 0; + flex: 1; +} +.conn-title { + font-size: 13px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.conn-sub { + font-size: 11px; + color: var(--text-dim); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.conn-spin { + animation: spin 0.7s linear infinite; + color: var(--text-dim); + flex: none; +} +.conn-empty { + padding: 8px 10px 10px; + font-size: 12px; + color: var(--text-dim); + line-height: 1.5; +} +.conn-empty code { + font-size: 11px; + background: var(--bg-elev-2); + padding: 1px 4px; + border-radius: 4px; +} +.conn-error { + display: flex; + align-items: flex-start; + gap: 6px; + margin: 6px 6px 2px; + padding: 7px 9px; + font-size: 12px; + line-height: 1.4; + color: var(--red); + background: rgba(248, 113, 113, 0.1); + border-radius: 6px; +} +.conn-error svg { + flex: none; + margin-top: 1px; +} + /* ---- collapsible sidebar section header ---- */ .section-head { display: flex; From d1b2127b80c17cf9566eaa5fa733ab689d3d6c05 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 11:46:01 +0200 Subject: [PATCH 45/83] docs: guide for running Ateam online (agents on a remote box over SSH/Tailscale) --- docs/online-ateam.md | 135 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 docs/online-ateam.md diff --git a/docs/online-ateam.md b/docs/online-ateam.md new file mode 100644 index 0000000..482f964 --- /dev/null +++ b/docs/online-ateam.md @@ -0,0 +1,135 @@ +# Running Ateam online (agents on a remote box) + +Ateam is local-first: by default it runs your agents, worktrees, and git on **this +Mac**. "Online Ateam" points the same desktop app at a **remote box** instead — a +Linux server that runs the agents while your Mac stays a thin UI. Useful when you +want agents working around the clock, on a beefier machine, or reachable from your +phone. + +The connection rides **SSH over [Tailscale](https://tailscale.com)**, so the box +exposes **no public ports** — it's only reachable on your private tailnet. + +## How it works + +``` + your Mac your box (on the tailnet) +┌───────────────┐ SSH over ┌──────────────────────────────┐ +│ Ateam desktop │───Tailscale────▶│ ateam daemon │ +│ (the UI) │ │ ├─ agents (claude, …) │ +│ │◀── JSON-RPC ────│ ├─ git worktrees │ +└───────────────┘ │ └─ PTY sessions │ + └──────────────────────────────┘ +``` + +When you pick a box in the desktop's connection switcher, Ateam runs +`ssh ateam attach --stdio`, which relays JSON-RPC to the box's daemon. If no +daemon is running yet, `attach` **starts one automatically** and waits for it — you +never have to start it by hand. The daemon (and its running agents) **outlives your +connection**: close the app or drop off Wi-Fi and the agents keep working; reconnect +and you re-attach to the same live sessions. + +## Prerequisites + +- A Linux box you can SSH into (Hetzner, EC2, a home server, …). +- **Node ≥ 22** on the box (`node --version`). +- **Tailscale** installed on both the Mac and the box, joined to the **same tailnet**. +- The **Ateam desktop app** on your Mac. + +## 1. Install the `ateam` server on the box + +The server ships as a small standalone bundle. Build it on your Mac from the repo, +copy it over, and install the two native modules on the box (they're prebuilt — the +box needs no compiler). + +**On your Mac** (in the repo): + +```bash +cd packages/server +bun run build # → dist/{cli.js, daemon.js, package.json} +scp -r dist ":~/ateam-app" # = your ssh host (see step 3) +``` + +**On the box:** + +```bash +cd ~/ateam-app +npm install # fetches better-sqlite3 + prebuilt node-pty + +# put `ateam` on your login-shell PATH +mkdir -p ~/.local/bin +printf '#!/usr/bin/env bash\nexec node "$HOME/ateam-app/cli.js" "$@"\n' > ~/.local/bin/ateam +chmod +x ~/.local/bin/ateam +``` + +Make sure `~/.local/bin` is on the PATH of a **login** shell (most distros add it in +`~/.profile`). The desktop invokes the box as `bash -lc 'ateam …'`, so this is what +matters. Verify from your Mac: + +```bash +ssh "bash -lc 'ateam'" +# → usage: ateam +``` + +> Also install the agent CLIs you want to run on the box (e.g. `claude`) — the daemon +> only exposes agents that are installed and on its PATH. + +## 2. Put the box on your tailnet + +Install Tailscale on the box and bring it up: + +```bash +curl -fsSL https://tailscale.com/install.sh | sh +sudo tailscale up +``` + +Note the box's **tailnet IP** (`100.x.y.z`) or its MagicDNS name (`tailscale ip -4`). + +## 3. Add the box to `~/.ssh/config` (on your Mac) + +The desktop lists whatever it finds in your SSH config. Add a `Host` entry pointing +at the box's **tailnet** address: + +```sshconfig +Host my-ateam-box + HostName 100.x.y.z # the box's Tailscale IP (or MagicDNS name) + User you + # IdentityFile ~/.ssh/id_ed25519 # if you use a specific key +``` + +Test it: + +```bash +ssh my-ateam-box "bash -lc 'ateam'" +``` + +## 4. Connect from the desktop app + +1. Open Ateam. Top-right of the toolbar is the **connection button** — it shows + **Local** with a laptop icon. +2. Click it. The menu lists **This Mac** plus every `Host` in your SSH config. +3. Pick **my-ateam-box**. Ateam handshakes with the box (starting its daemon if + needed) and the board reloads with the **box's** projects and tasks. The button + turns green and shows the host name. +4. Work as usual — new tasks, agents, terminals, and git all run **on the box**. +5. Switch back to your Mac anytime via **This Mac**. + +## Troubleshooting + +The connection menu surfaces the real error inline. Common ones: + +| Symptom | Fix | +| --- | --- | +| **"No servers in ~/.ssh/config"** in the menu | Add a `Host` entry (step 3). | +| Connect hangs or fails | Check `ssh ` works, Tailscale is up on **both** ends (`tailscale status`), and `ateam` is on the box's login PATH: `ssh "bash -lc 'command -v ateam'"`. | +| **"Protocol mismatch"** | The Mac app and box server are different versions — rebuild & redeploy the box dist (step 1), or update the desktop app, so both speak the same protocol. | +| Board is empty after connecting | The box has no registered projects yet — add one from the box's filesystem via **Add project** (or register a repo path on the box). | + +## Notes + +- **Nothing is exposed publicly.** The box is reachable only over your tailnet; there + are no open ports and no inbound firewall rules to manage. +- **The same box also backs the iOS app** — the phone connects to the daemon over a + WebSocket (`ATEAM_WS_ADDR`) instead of SSH, but it's the same daemon, agents, and + worktrees. Both transports ride Tailscale. +- **Sessions persist.** The daemon keeps agents and PTYs alive across disconnects; + reconnecting re-attaches to the exact running sessions. From 46f453dd281c53b7c9cdb0903c30c77acaf5965f Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 13:02:47 +0200 Subject: [PATCH 46/83] chore: release 0.1.29 --- apps/desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 4aeaf9d..e6b9bdc 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@ateam/desktop", - "version": "0.1.28", + "version": "0.1.29", "private": true, "main": "./out/main/index.js", "scripts": { From 1ed613eed75119cdac8d14232df1406ba13cce0b Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 14:01:58 +0200 Subject: [PATCH 47/83] =?UTF-8?q?chore(mobile):=20prep=20for=20TestFlight?= =?UTF-8?q?=20=E2=80=94=20app=20name,=20iOS=20build=20number,=20export-com?= =?UTF-8?q?pliance=20+=20publishing=20guide?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app.json is the source of truth (ios/ is prebuild-generated + gitignored): name mobile→Ateam, slug→ateam, add ios.buildNumber (bump per upload), and ITSAppUsesNonExemptEncryption=false (standard TLS/SSH/WS only) to skip the export-compliance prompt on every upload. - docs/publishing-ios.md: internal-TestFlight-first pipeline, signing/App Store Connect setup, local-archive + EAS routes, and the review demo-box path for going wider (keeps local-first). --- apps/mobile/app.json | 10 ++-- docs/publishing-ios.md | 114 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 docs/publishing-ios.md diff --git a/apps/mobile/app.json b/apps/mobile/app.json index f4f5398..3d8250f 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -1,14 +1,18 @@ { "expo": { - "name": "mobile", - "slug": "mobile", + "name": "Ateam", + "slug": "ateam", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", "ios": { "supportsTablet": true, - "bundleIdentifier": "com.ricalla.mobile" + "bundleIdentifier": "com.ricalla.mobile", + "buildNumber": "1", + "infoPlist": { + "ITSAppUsesNonExemptEncryption": false + } }, "android": { "adaptiveIcon": { diff --git a/docs/publishing-ios.md b/docs/publishing-ios.md new file mode 100644 index 0000000..462b0e7 --- /dev/null +++ b/docs/publishing-ios.md @@ -0,0 +1,114 @@ +# Publishing the Ateam iOS app (TestFlight → App Store) + +The mobile app (`apps/mobile`) is an Expo SDK 52 **bare** app: `app.json` is the +source of truth and the native `ios/` project is **generated by `expo prebuild`** +(it's git-ignored — never hand-edit `ios/` and expect it to stick). The vendored +SwiftTerm terminal lives in the tracked `modules/expo-swiftterm` Expo module and +**re-autolinks on every prebuild**, so regenerating `ios/` is safe. + +## Distribution strategy + +Ship on **internal TestFlight first**, then widen only once onboarding is solved. +Why (the full reasoning is in the `/scalable` ruling in chat, condensed here): + +- **Internal TestFlight** — up to 100 team testers, **no App Review**, installs + immediately. This is OTA to your phone with zero gatekeeping. Start here. +- **External TestFlight** (up to 10k) and a **public App Store listing** both trigger + **Beta/App Review**, which requires a reviewer to reach a *working* backend. Ateam + needs a proprietary `ateam daemon` a reviewer can't stand up, so both need a + **review-only demo box** (see below). Same uploaded build, more rings flipped on — + no rebuild, no rework. +- **TestFlight builds expire after 90 days.** Your release cadence already beats that; + automate the upload (EAS or CI) rather than hand-cranking Xcode each quarter. + +## One-time setup + +1. **Apple Developer Program** — team **`X2VZX44YM2`** (the same Clawnify publishing + team used for the macOS releases; your macOS Developer ID proves it's enrolled). +2. **App Store Connect** → **My Apps → +** → new app: + - Platform: iOS · Bundle ID: **`com.ricalla.mobile`** · SKU: `ateam-mobile`. + - (The bundle ID is a personal `ricalla` namespace. If this should ship under + Clawnify, change `ios.bundleIdentifier` in `app.json` **before** creating the + App Store Connect record — renaming after is painful.) +3. **Signing** — easiest is Xcode's *Automatically manage signing* with team + `X2VZX44YM2`; it provisions the Apple Distribution cert + App Store profile. + +## Per-release checklist + +`app.json` already carries the release identity: + +| Field | Value | Becomes (native) | +| --- | --- | --- | +| `expo.name` | `Ateam` | `CFBundleDisplayName` (name under the icon) | +| `expo.version` | `1.0.0` | `CFBundleShortVersionString` (marketing version) | +| `expo.ios.buildNumber` | `1` | `CFBundleVersion` (**must increase every upload**) | +| `expo.ios.infoPlist.ITSAppUsesNonExemptEncryption` | `false` | skips the export-compliance prompt on every upload¹ | + +**Bump `ios.buildNumber` on every TestFlight upload** (App Store Connect rejects a +duplicate `version`+`buildNumber` pair). Keep `version` until you cut a user-visible +release. + +¹ Declares the app uses only standard/exempt encryption (OS-provided TLS/SSH/WebSocket — +no custom crypto). Correct for Ateam; revisit if you ever add proprietary encryption. + +## Build & upload — Route A: local Xcode archive (recommended first) + +Reuses the exact toolchain that already produces working device builds (SwiftTerm +module, SDK-52 / Xcode-16.2 pinning): + +```bash +cd apps/mobile +npx expo prebuild -p ios # regenerate ios/ from app.json (SwiftTerm re-autolinks) + +open ios/mobile.xcworkspace +# in Xcode: +# 1. select scheme "mobile", destination "Any iOS Device (arm64)" +# 2. Signing & Capabilities → team X2VZX44YM2, automatic signing +# 3. Product ▸ Archive (Release) +# 4. Organizer opens → Distribute App ▸ App Store Connect ▸ Upload +``` + +Headless equivalent (for later CI): + +```bash +xcodebuild -workspace ios/mobile.xcworkspace -scheme mobile \ + -configuration Release -destination 'generic/platform=iOS' \ + -archivePath build/Ateam.xcarchive archive +xcodebuild -exportArchive -archivePath build/Ateam.xcarchive \ + -exportOptionsPlist ios/ExportOptions.plist -exportPath build/export +xcrun altool --upload-app -f build/export/mobile.ipa -t ios \ + --apiKey "$ASC_KEY_ID" --apiIssuer "$ASC_ISSUER_ID" # App Store Connect API key +``` + +## Build & upload — Route B: EAS (scalable follow-up) + +Cloud-reproducible and CI-friendly, but needs an `eas.json` + credentials setup that +must account for the bun workspace + vendored native module. Do this **after** a first +successful manual submission, not as the way in: + +```bash +bunx eas-cli build -p ios --profile production +bunx eas-cli submit -p ios --latest +``` + +## After upload + +1. App Store Connect processes the build (~5–15 min). +2. **TestFlight** tab → add yourself under **Internal Testing** (no review) → install + the TestFlight app on your phone. Every later upload is OTA to all testers. +3. Each build is usable for **90 days**; ship a fresh one before it lapses. + +## Going wider (external testers / public listing) + +Both need a reviewer to exercise a live backend. Provide it via **App Review +Information → Demo account**: + +- Run a **review-only `ateam daemon`** on a box you control, with a demo project and + baked-in demo connection details. Keep it live during review (*"backend services + must be enabled and live"* — Apple guideline 2.1). +- This stays review-only, so it doesn't compromise Ateam's **local-first** model — + real users still self-host their own box (see [online-ateam.md](./online-ateam.md)). + +A public listing additionally needs: a real app name that isn't taken, a privacy +policy URL, an age rating, and screenshots. The app icon (`assets/icon.png`) is +already 1024×1024 with no alpha — App Store compliant. From e5f0eecc09ea7f71b4361f26bd287822411c6b42 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 14:06:41 +0200 Subject: [PATCH 48/83] =?UTF-8?q?chore(mobile):=20bundle=20id=20=E2=86=92?= =?UTF-8?q?=20com.clawnify.ateam=20(Clawnify=20namespace)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mobile/app.json | 2 +- docs/publishing-ios.md | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 3d8250f..fd76b85 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -8,7 +8,7 @@ "userInterfaceStyle": "light", "ios": { "supportsTablet": true, - "bundleIdentifier": "com.ricalla.mobile", + "bundleIdentifier": "com.clawnify.ateam", "buildNumber": "1", "infoPlist": { "ITSAppUsesNonExemptEncryption": false diff --git a/docs/publishing-ios.md b/docs/publishing-ios.md index 462b0e7..14c5be2 100644 --- a/docs/publishing-ios.md +++ b/docs/publishing-ios.md @@ -26,10 +26,11 @@ Why (the full reasoning is in the `/scalable` ruling in chat, condensed here): 1. **Apple Developer Program** — team **`X2VZX44YM2`** (the same Clawnify publishing team used for the macOS releases; your macOS Developer ID proves it's enrolled). 2. **App Store Connect** → **My Apps → +** → new app: - - Platform: iOS · Bundle ID: **`com.ricalla.mobile`** · SKU: `ateam-mobile`. - - (The bundle ID is a personal `ricalla` namespace. If this should ship under - Clawnify, change `ios.bundleIdentifier` in `app.json` **before** creating the - App Store Connect record — renaming after is painful.) + - Platform: iOS · Bundle ID: **`com.clawnify.ateam`** · SKU: `ateam-mobile`. + - The bundle ID must first be registered as an App ID in **Certificates, + Identifiers & Profiles → Identifiers** (Explicit, no capabilities) under team + `X2VZX44YM2`, then it appears in the New App dialog's dropdown. It's permanent + once the app record exists. 3. **Signing** — easiest is Xcode's *Automatically manage signing* with team `X2VZX44YM2`; it provisions the Apple Distribution cert + App Store profile. From 802b8983834157d8bf1ada2d26fea4edab880504 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 14:09:17 +0200 Subject: [PATCH 49/83] =?UTF-8?q?chore(mobile):=20app=20name=20=E2=86=92?= =?UTF-8?q?=20Ateam=20Go=20(match=20App=20Store=20listing=20+=20icon)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mobile/app.json | 2 +- docs/publishing-ios.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mobile/app.json b/apps/mobile/app.json index fd76b85..0333f71 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -1,6 +1,6 @@ { "expo": { - "name": "Ateam", + "name": "Ateam Go", "slug": "ateam", "version": "1.0.0", "orientation": "portrait", diff --git a/docs/publishing-ios.md b/docs/publishing-ios.md index 14c5be2..91e1dd4 100644 --- a/docs/publishing-ios.md +++ b/docs/publishing-ios.md @@ -40,7 +40,7 @@ Why (the full reasoning is in the `/scalable` ruling in chat, condensed here): | Field | Value | Becomes (native) | | --- | --- | --- | -| `expo.name` | `Ateam` | `CFBundleDisplayName` (name under the icon) | +| `expo.name` | `Ateam Go` | `CFBundleDisplayName` (name under the icon; matches the App Store name) | | `expo.version` | `1.0.0` | `CFBundleShortVersionString` (marketing version) | | `expo.ios.buildNumber` | `1` | `CFBundleVersion` (**must increase every upload**) | | `expo.ios.infoPlist.ITSAppUsesNonExemptEncryption` | `false` | skips the export-compliance prompt on every upload¹ | From a2a66a07578cbc74596b0309813cde6b8fa77049 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 12 Jul 2026 14:17:46 +0200 Subject: [PATCH 50/83] feat(mobile): app icon from the Ateam brand (full-bleed, iOS-safe, no alpha) Adapt the desktop mission-control mark for iOS: full-bleed dark gradient + board tiles, no macOS squircle/shadow (iOS applies its own mask), flattened opaque so it passes App Store icon rules. Source kept as assets/icon.svg for future edits. --- apps/mobile/assets/icon.png | Bin 393493 -> 7064 bytes apps/mobile/assets/icon.svg | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 apps/mobile/assets/icon.svg diff --git a/apps/mobile/assets/icon.png b/apps/mobile/assets/icon.png index 7165a53c7475d846df195bc570482459d61bad67..76440a92d949c344ee6bd9d4f8634001512c2833 100644 GIT binary patch literal 7064 zcmc&(c~nzZ8oxvo5CNBh3P=>IIO+%}0%{~wvFcHX)6OWCElPmF1>zbsYh8*CQm{Ir zvP8$JoEC+ELqQ=BMFZ3T)mVtEh9w9B2?W9#GB*hpjL`(locZVSPTqar^85CW^EG$xUP1l3x0=Z-xKsSJQv{-537 zxo{4?(~6RYiz_i)Z=wkREImgk)_W8=1tBy&Fuy=9=!d1%z(bu{k3UYa2t_hp0s!tR zT{07*aeA-(t!7hE4B@q<+u@jNTI~+Njy+n4rb_;U?xwgHd*VW79Mr-3GX-SVl8X(sRqI-X zKZvX|ajC|4HTJ~$9e-JAtVc_fLCmp_xr);BuU>+@~(g2oK2qJR9(d5+w#w_Z+7~nY}BM0&=iXX zVcD8MJVJhysdE6WH(DwQNq(DI|RoSV4-~lm#Z7eCOLHhkRKf}WyD3buAm?HM%4h} zjEPD?DC`-OrB`e*|DC{5_{qP$bad3b-JJ|4mO0V*%7b4jch}1n+}%OKiiCC%7*jr-3Ovp z65qHNE#U?Rf z)MoRZ>{&}0>N}WKBf0Iu{L2);O6z@OY>(=1q>{z)btpnd0(0*gg;7XTppxU9nBG=4 zyt^WE;cVnIVzp`Xi*h9h*T&j`a;xxsDcR1;m(cQKTq@JTl~YPb%eeI6ZlAh=3L&Yv zj=hu04+;+#zW6CCac$2pDX9Z@Z*6AoW1WH*sRP}Zyk4ddE#|CpzTVWvX%B~{@*#09@~^)+Bfl6zEX^^vlJP5TOCkTPCj2kKD$_@<_~fIOzTUK;OBfb3)rTRs!u!)U+z9eQFOk0LFj+XCl9 zFN5M6Wwy~QgB%Z4BGJ#9?y zlqMFb);HClGlaaf?_ozfp7)|qF0-;jr!BfrlEil*xiZYdHjbk)QG|qmZy*4sw;cTk zeBSU`JF`u8Yu~VsFWo3Kzm^<&hdBjUWE8K;-DSX=+~F}^fz>fp)^-LBYEjk5XSG(J zAKP+&66DIJ55J_JFge94zUF+#UR?>T-lFndL*zy3F2(~#=LfTDo-m9js0@eupNIBO zCNXl@!DS*VH*4P1tOdHAaMVW7DA>vp>&^bIOyoZwdn|0@M@I6Mm`iDT2-nMUS^ei> zXJ^lPscFpBqRQ$Z_C}Oo&9Rpr?80M@b$E+ zm2N->a;l}M+#0ZEzK80yNQS=a1$IPB_+6#wMk+gu|Bw92sm}HCP|m5}qf0tG2##$C zg6&6~cBL6|MTp+8-@{fm@3q&_*##@`b{RTbx@hfTBRFqxCVkh7&`UXDm7%&5(txL8 zU4owz-TAz3v6;cnW-pv(gG6OVbe>8)d(1CeR3B_cm|gHI+{I-}X1XT86502%j1mSb zZr}yFjC89?RDJ(QflF+`&!tK0-{b>Dt<9;E64n_n8{nJC#MSp@HH}lt(6XTzN_T^z zDknwM8!5|eL?55(N*&HEIh#r9j50ewxtK<3N~!WT7VS$w%jzrghfRozGVe+r=w9DD z6pcZ!mfBGIg!$5T;Q>lwq0L}S8o8Y=Zw&riWE&mttEPCO50J#;-H;54JDvR(ND7@u6h-K^R!z8UrPughY>JFm0SIvbGa!6tiI z!zGMcXq@*sfIXyGau&adnU_=TUvQYxlM=9guj3i=)=V=+~jtnC^(^m>GiAR=V&Os9r%HPhQ+uB^NyvcSPB8te|&mR zuY2j#sxdMpyt*;IW#Y*4LMID&btPYI^;BHcLg105-;GD|55_qU7{X6<*1)L|7y|bt hWTAt9B{&=#LRxb%Z&G(}+yNmb412^vTU?i$?PJ!pX7u1RnS?(TymxO;GS`H-A*@45HC zw_dNsVo!Hf@2cwRs_LrVVM+>8C`kB70000*Mp|4M0DyUVgaIHxJ^efKY5MW>59pvQ zB?>4VA^i391JPDm-2nhV#(Mq(0#ed&pTOPC->NyP$;VlS_qJ<$t#hH+1MMCax#ON!Q_HS zq@<+$_C_YW%HooLp+Ef+AUAV#wB==CadB~Bc423>u{UL5<>BFB0kg5Nu`xYCFgdtc zJL8M~VQFKEvrf6#vO_2+f`&y(@0D;qo5SUNqECCJ6b|N9O9(fM!s z{viAt{++eCqu}2t|JD89SZefrMf8qRp1OJUF@kFPpvHfrIz-(-Pzw4jf|BWJMV`Xb&{UitnF&k?Wb5ke# zKN9&j+|yeAR#O#YyML_hUn~5qXO`yAT>bU*A9#PGK0!RK;{O4`{(nL|$>D#R<4^B@ zlJ_qu|6knk|6UDAOMM5krv?6(@L0ir3;n-`{>|VY)Zc2M{=cimKZgE7{X_3RcIzKg z@SC?MTOf$U&+;$3B8b!pd$a+7z2lG(7kTSCyLWFMN7?_G5`j$!;~n3;0RKTBRoazosXkB*|<2pI>@!9j(I;Hl4OpAT*K_}iDK z29xy!oU_Uk3_y8AQ+R}}V=#3=>^koM+NrnV_`OuB_<0!9_v3ThdPzvk_)`c0MHkn6 zlN<#cr+%0NTR~j?JoXwu|J*V(Lw|I^z3mbve|rH{NgB`zBdehP2Urh%5g&%kGX(@pZ^-26{gF5Xi*V4=z#mWam-k%~L}Z{v(K}4j}Up zluYb0Dvv0bcJQ{RI12Fgxj`vCgB|mWO+1=wB2(7mNy7wO?uHV6UM4Dn`|=NVULr7B zwhbve^MKTJwDIyw=|km?=iIrKe$_o z`k9;XG^(e4cW@O|0EQM%J^oYfx=JIIn`DoPGw_){n`vSQGh$O>rNXB}d#X0TXOaA& z?=AllApl?$C@)HiBp<1PP4$)VR!(Sao&@SKRPSQ;6 zKySSI`U!LBA}E8fKN*8x#z8ygZsV)BPZkAP?pA0@%Z^^TYn`P}4HedPv~hDZCzf!1 z`K8NS$3q%8(akU59Q7z2HP8toYG5yGEhA^(z4JYLC+%4&|7hivG)Uk?o=PiaPBpgr zsJO?Tu1r2vhz@F9?dwOr2p}%<@rN?W%BSbIiR~;tEhNc~^o+CyU)QDx z((;iUbjPwgWk3YUcZ_Fcdh>?4l_YK59s8LuW}I+$6Q>qB4L{|xXvNGPoBHdiIbE#s z64rSpGzF`dcZxrI`CxB?zkqzIzRt+ds&XD**ex84sW>0gSUzar!{Y}pF(f2G3#^Hy zde2-T#&Z?ChI=N)w*mUu9<%<8;FI5sJ|MOzYD=S^i7ea1p+c{jz3eOy9y`HKen^_+ zv&Pr5)IM~a@6`?(>u%knko$Hyep`EN%>D5T9F&&w7%30sr@-VZko##P{razk{aNJ5 zGI$jlAKAuMHXA!E>5l;=_rcZbQ{##qA8dGtbV5%M9$m$2_t;_N`@4MOFPL?|Qk*05OJ6_l zG_#*6z(o+pDkjT8CqiM|t4t>vzN>Nu4(wtT_ywnjs3^D$$iLKqsPsDQ-lGYm~d6dC=)P%P{?n)aRJeLtTrBYt#X99`k`6c7M5{=Db5 z<5QhYs#7T9& zI}0>zSzZ|Ovr5bqX|1}Ca(?WeE?sJJ8_49n!VPiHbjHM7usV$~_Xsg|ImjA;e)bZU z-=%jz&t45yQn5c$&8yM*hooGNc1L-B3f|73KC0{01+2gzwSQvjNX-?f7a!3vSh>gk zHq)}XGW<}_H3iYu!LI-S9H6YSd~rnL<9Nv33p%KJy!7!hT**bjI4%~5*}oM0xjKi} z39)QdEaS1ebVY47In5~Oti^L(N3kZwRK984C zCm$v~#%~w;+o2eI6Yp0_d4$qak^dEIl((;%2^ivZ+Ih>7`sU=s%Ow-(eHGZuO!E9e z7)H|SH5u6)?`OT2Ix9!DhW&z`Z*<<{paY;<<{&gpSL=LwYVeMD)YU-0qX<9Q>9*JN zT#L7u2-CDJ{V4^&nw^JZh`z2K1+FOZV^!0JOb3TLl)TNm*#6uXx#SI$2zlzX{NKPa z$K0CPG$x(M8Qw!UQn-Q?QxX$7&%Wian6hR^jAU-O+pz`a!QN~=F~xr8rf@GWS-#;y z*^z!wHb^67B;Ps6EL7}WGgW|{A6(|^yW?;+&Qw^JGekOy+p|I%$js;bJ!Z1T!u0{_ z!ojLWMLxK*q0+-CGCn+B3mD`R>A{(*!H9M_dl^c~OvvmnUvv;zjEOjwUVJhva=V!% zGC0TFfYd)b3;`$~hzEr+060@H!KHN#wv(0S_!i24Tju~}$9NeOrX~N=Yo@TR?VZ|% z)xevPjFP(S*VT3bdXyZ01x~+X(~5dx`@Y6mPg#2V`|!oHx$*e%B$Bj;!AziF(yy4ll`SI~MUyPSkgJ{|K4a&PO>e_GGJk21k0~jZxq2ytPD{(0@G@{NROC z`Ei3AbI> z!~@7kF|ydhm6KtVjtAuAL3>TR+WYeL1$xiEKHF2#_@A9ia^B=VR?)y{a0kxtd7*F;3PjD^`m!j!o+QG`N2Dg~fpCj{vZlCPor^VkUA<#QO*2xljf*idfi}kdU=52r z1Vc5L1IU$jp))O@=G;cGxGfMEWLCo(o-z$r&x^l7J!ogdMTyz^1WXD}@Fo+hF-GFx zy|lek)S)d6xeGW(vCavRl7U=RkAHTFwhhSB`XY%nBOYF`VKB+bX_IFy&S?9%i5YZRX95kHe{D+@EswnreOL;JsG90EAA}tz<9z)n{xUk|G^z)n0;b~kI zGmpc_fuQQO7-mx9M_2nkY;luFPF_RR$)xGs096UGBwW&f2^DZ4dJ1l?I+hs7qz9KV z2@fw~j4|m`s9%NL3n_4$FQ7}go(td$!{K^~AauV!rvCbqcl|L-v-9cA&+Kjm67knO zD9VH{2|JhD#Xa~L8XG+ZGPGwt%~vsO%x|SBkIXonP?CvpEX`TeUO zc4XaOjoPglc6u}H>;?$$InIYDzYZ%d-0^5MIdFM?RHRb25~n{4Pvn>H`K+?*PBC%$ z<^YNuS-ay`z3T4S`g*mZhLici)*i0xbWCx7rSdlgo6izQx=%sx$Lo`xcQ9bM*wFSA zTz`F=iqLk0YHAIvF-Z=LcCZa6R<#POwj7U@CxM?BEx7gvXXj&hHueE^%%T{R_c=hw z?eYyt#14-4#Y>BfXP>6mAnRQ7m^6OkCXd3S>_r>B5`;=vor!;&u zU-6?0tIsR{Ey$*}FiU3toUoeDh~4r>Dl)V5)CuKe#?E_Tioqx2dL=TwT5araf#-8SMy|;I_=h>`r zN!KX>j`!hpJS+UF^+Ho_cDk?7o;J6F2c8~3wT(KkChSywPW<4zCHY)|xn@tOU6Qi_ z>dWNO5tlPiY_*Esc)EaJjOIrkO217J;liJmg1YJL1b2mpLf)}SqI$NF-ZJe)pWE}! zpcq8_q*F#1SEUez&DJin`NFyOYcF~} zkZm%08XR1RzM2XgZBg#m;t+Fte{=yZKU=gP28$zGRU4iyTEX2Q4`gv@c7JprmLpk0l41hP82g6#JD)2*=B)lwZ%{0vDK){% znRqie48bOD3~=GQ-!9`h>CwFfPo5S8@Fi_Vs1MeX>0fV8-!Ss z1ea zP`GVqf%l_)ipo&73)Et$a33PfeskkhzYR&5RR#!Apk&GPA$*ss#T6OPwH>K`3T zbkYtJVH(8qaTOmBbh;mLxK}PdJ{=RgnDxp01q|`L|v{1nc+%H>h<3ggRvTJe3 zC=Z8?7G`8mH|KO4E6uWrQP>6GlZ07Hr8~DS%rOD{FZ{Gbu{_TR$U{EIae#0{REUI}wJ7$>HVHKP>-+)H3t`iv1CaNRl# ziQ?T!Qgjj9X;m8c)B#ngUu0+ub*bq0&nerm^{2q%83A;;~I~od3uZjsA>d*a3lLje^spJ%fJr|5Gn}EwCEtZ(j zS>_w6<#~)!X{Y+r?hMA%l$%$ZD6?#G#)EBwEm=wvlKqN-rL%zZ6T*g`Woo%uD)ou2 zkDyIOn&Bd8u)fYD*i0Hsz3>648A(j}Gc_ki-Kb|UzO|j%bgG#>dAMVjeKG&))aCJ- z?$Ytaa`EM;IFty|BA15O`FX0%qIe$|;wRWQ29JUKs-E2I8y`S%EQ3wITq0yBI1EWF zqX$zmhg(h?nUZbPG|h=y({N#Joj<+o_Fd*A-Fd&cUmhRSTzqBUXcr}9zyyFT2UmE5 zU=y&8zJ!icwj0BVp($cbZ>T(j zMgZbisrR<`MJad84l9WKJ*?8-X~N91qJC8=2if)}I+vag1rhL|$m<0&Re=CiY<(^n zjZAE4rZ%E+a83&0q(Qpfkj&-s5xI-5HWjm0DIMEuKR4iu(92>%6wr_1-=}+Lxyt7@Q-Ltdn~7i!-y( zML_lL=>&a2hM#GPi`BwG#A=6&%sfFtA3*C5n+HOqTRS7%+WO`BomVq|?QDjUm9Pc{uD?}%UFA{FSdG(_QF_-wNF%#q zQ~uS|*%oCI13nKy0M1+L^rFvi{v|ywBrr~{#CR_9nI3zICRO9>&&2_|B zgkXZpR}Nzen6$LD?K}@hPv^zkU%VymMv`hOd3SyFSNn1k@RE3+8=VNOSZyv6PMbG8 zE0*p3+yZ(q>hSuRP&_Esll>#f^f^OS;iMk3XV=uG#mQ1oTtrumo{d#lIMWO3#p6;6EA9nMv)o2!S8u!Pysvk`=`ZYBR`M z@BDxVuT^l_h|%pgD*Yk2xeOV`0^gQotzZyG7=*r8*#(u3n zt@u$h&P!BeCPU>jVdo_IGFDLvXbFxI5 zwY|qkxo7dAui~RygQ17~0HmzkC{c6KlR|EXD`A_3W|lR5i?0rJ8(J=xAI9DYYINOQ zywqu~h&c6Kr<3wWXt~boNa)-sv|X#8z9m5fgw#i!ByN=8(k)ewBgTK#igdF|)q}mp zU6CW$;^zLf3C%u66X=T`!;Wxa_N(!f9E3~WABQS?nez8p zRYi>dY@xQDtkRt!7} zw7Kn;{lmqyr(&VZ8)?HGqslIc48cl!0gPELp|)ZyY0lh&on!qw zmJ34sycmNy8?8~9z0Ks` zf)A|fSn3o^a@JgpnyR;;h>OLADPV4Z3q`~z z5AcpiT3zgWBsWV`ALnYzszo``lZ-i{NHK6vT>DwwElAvDJd|mA# z4S`7VkxaVc){tY>UH=Gfoq4-#C!O&me_mOt7|^OkIFBG1Qx&SMMF?lZGGP&$*#&iUb^c4JE~4y96sy~Y_-1+dz%HIej{kshhl&};_Gv_IEJW+mh$Ut z$>;V)3pxN%`KaB&L|TTRiQAYqmEQR3x+*^g!tXt&tC(gLI}#1s?A+hA**SiN7RFC+ z~*_Q-M>#u~Let8k> zkK21c6=KK7FHDlSltd{zxa%7c?dj{4yOuA7>NKO=-q0iMlJN`Y*&qPwG|vq~Q#zdY zT`O=sB*V%UT3f-}cXT8^U|=2>b~k_5oIgMgr`utLq~-FeYm?_nuGi=CqQv+>Dh>|- z66~T!rj=>isH$e$zMH`W2;QIixYRcutId9&UWy6aAI1g9Wkt{N*37&~YMH&Gd+`FY ze)6_wQufY4JkhqHV~mcND3d6&^oFvw&Uv6X?|q#o;q3^Jhn8v1c0FvqgL;e<|Vk}DkdB6Cs{z%gWjO@FM8|?ZSFLYc3{waZVg9O`WRPZ zilxJUFI2l~3mbKRl0F+hq3HcB@TbDt4pUnm63e*20t9auqrohdtRdWyK%c9JdzGOV z+^2D^KDU!>E@MD&oDN*#t0p>@Udxn^aDr>N8V0FMRwUQM6$>{IIuCq&-K~RGd}nXY z5E`=-lC}ineNMO2v4(-c*?a_llXkgS)BHUg!|SOHw|uaRh^TX#ldEU7`_=kgzk2OR z0v=upra35gorgx*syylDUftnZ@9-plbDS6lgSxB(c7I*}!@COfpQym;6+mFk zs%;5}tBc3On%38v!Pyf0vns1)oMx4RH%7|CQ@J(-J=jvpim*dLRU|n4= zx5CsrS`pjgpb>6(YvLdVj$uwrqm)1_1V zK*>9rr?MW;+K_me+6+tH`_>PHU=j)(_>;){ZLHix?Tj&ofLxTzSA;Ia=TA{YMrj;7 zHw9x|3>ENGc@vU!q&`n{h{x%(+t@Q)gmQ~F0~otchnjUmFNU`u_%;ri0qJB39QtK` z2ytIVyA$hgLEh{Q%L}<0R+g5$tvZQdV!h_1YO6we?JZt-S5>+oXG@Mpn@WYgEr#O| z!y`)K`uc9-@}Pu+rlSM$cv)M<#10p(7@*>Y?-FB4^Uc`;Yn{D`;+G*IWPia=d&*Oe zeQ~xx=cP$it$F?OMJl2HApZu0gla zjknPX3h%WO=s0F(wSs?AG3-!KomO*&zh_~x)>7A6>}&#kFWSqm_?H@kj~3~G+mtw$BRer7Zigf znBG_{uUg;h33~OG9x7ou!MX$6yFbuSTjXH4DA~I{?cCF{UZ+mD9*{q7C zDSsmvS%E*-^maB9V|nDmio|9EUSdMcNT%t@^L?G)mwp7%V1yM&hDUjR3U}5mQ;V84 z9P%Z-3S7iDnpn^-)#DIzcHxnRqxdxL-Y5HdQH^oH2#H+8!4S$lfIxwdpZ8pMsbz}C zL2?A{Rrf-da6_uH_y?v#metPz-9HCU@2OVJimQxEc}8Xqs%J7w*RDOnx3s$lV1+UZ zEeO0F!yYW5%C+5mBw--+>`jb&;&$>_u(|bL=WlTh4yHNCs9{pj2kVb-;mygZ8ueR5Z$960u1>vPq zUsO``z#S+dQM*ow^G#b=>*(t6RU1Q}nT2f&i-L~!I69I(5hY8GRv{zwC@D{5<**lHv9}YB`q}N1I=<*_V{fCHbcdwM%3G{94!=n416`ogHm zKy(FxyH2!&32&l0zYx8F77=-9<|jxv)|$l)o-8rJ1^R5P{cVR7&xe3MrvzBIfWUZ|%FtT~CNbf!kIUc$hEMU2Jr&<5nZbk9e6sDdP0y_!8Z>&;>yK9U={Qo56$79jT~b zdpMRH;(0y3Sdt$Uk%tXM(fRf0@!=r-v`#Vn)bsAJ)ypf{p${m|#xr<;9`y_!234vv z)7l`cQWHkW^-|AJXI3@NM>!)xP*iM84YBQz+o!}8ULTZ<9uufjcWUd^v_q0!tT0s{ zSO3Zy1NGGML@%%q(CS(4dOh3z*=z4R!p0g&?TJ?3Ou!3|oa|TN73h<@6-O(rb$YgJ>H4CS-<_WOW3Rs50_%oMzHoSd2qF{`EuJK3W|R+x zw9RkC?y*m(>2Z6^JQ1A;BSIpb#23IxDNu{?Y+ZFMO80VENfjG>6sqEB74CJO2qy<@ zj7}%GZQuY$lV*!zXLmu(6a?O9Rk^ply&q0=EFKRC%3k5Ik{4PMH~2oDdbo^qvQ4Bs zYzy7(4~C}=Lj$;2PRhj}2GN#;cp~gUeA3u1RDzoIh@B4rDYEzX zo8v=z~%)A7K3FUIeClwIqjlmek2{-Rs@>fdEFwU_@-tfRLnKlv>#>{C>N81cWa`=T& z_&cC~jOx~V{~EV%HurXT^0w}julp{nnQt&Tv2{<4C;LiHrYoXdA0X~ zGT74flG*zv^_JMMV>nuFB6sV)dL<5&8Pod&P{x5f z#>r=0R(n}cRO^}KN=CMl`}*wBb0q$>LsvJPcvh@<2n$4((8Wb zfN6)oOu4dxcp${n>f>lXX;BhW@(K1O0<7y%OTMlK$9tB2Z2?QvM6)1nq}Fcb_X)1~ zOfHFUNc{ElzT=>i$N(gz6r#lS@Szf9^eF+x9{Gjo(2pl;G>WR?ps2Meo4v=4!CQ7R zI9JRnOOw{R-NSjem^?1s=Ifpp98^5&U?XAC?Y_r{A{rNk@#MLt$oGa1b7i_2d^w)Q zAgM=M<;Lz+6K*x!UcQ~JTRsIntCtfh=~gBO^peE~Ib$F%Nu;L(aI@6)!&+|DdQmYk zFq_WQIxt6h?Y?s5yX@^0Gn2J8Y%^`Ouy1he2Y&Cs^`2eC*>!p?+MAFIp-d)}Z~vi3 zIfkf`Tb`ElKGcP;MXBN6G7@Pb3WJee~pb%-LT;H~G zAy1)Q>NIe+R>K?ju_Eh*0LHc%>B+ID#PujNxxk~#0ruM8eXq0$v&8N2I4)*GhyckP z`OCb?{ohx((2lB>_=l2=by>C+YFkdmOYjUNm805Y<}vKW(axf9M|nHc!cy4$L;;I@ z?a@nKXJ*5koboO=?`;-5*LX$!Q8MXkw3UM*@Ao8JvR(tcX}r*I#~DtxzcCU3P!NYltFVIGa{_`(sCp4t+lY zLwmZqLaT2gjcuO2m?G!n~K~T3rtm@+W zbkpd!)2}51%v1#li*|;VB!-eJ)?1lk@|$)GgE8k-47o74x!|(aUJ7ucixof-KC`s_=x>Zl(bWz6(O!k_ zkTK4*i|5$KYfAyu;~+`>VSpiVv95j8aE!DNL<%>^gKV7eA~)SK8J<|sCwo@>p;U2- zlY-AUR5bOg7l!2@o;~lPdYBH1>D|yxR8{-i1TOc1KD4Sy9SyB6C|=UJ2nfb=}88* zOZN>{gE@v+5~9k4O@FY{-!d7tD{la%UDYR{R@X2A5mC32>w>T3H47y8vS=P|AqR`P z5L}ZQ_mfG6#MZL`OGz8Qv;`&{DD?OMEu(^Kvm0{R_|ymqM}_AL$eBLn?vE>OA)LaA zDF^#yx&jEHs1)`Ctmv4Lbfy|@&WzJ0@L8C?OAZePTw(6FX?Q$s;8HQNzQQJ6t58lh zm>xN!EUb*Qm5YFbkxm+<;ctq}UDFz&eRw<)o3f|2y94c!gLY%2_Geq4@eN1tlo3oM zT@vRDma9)v2=lUW9{#$!eW#h;I*<^3wXj zl6;|tHQ2sHQ(r$KQwe^u8dUvGX%|5^xOV-@5?Rk-Q4jyi3>64w#TOb(DaGPx+v;K8 z;BMc*d$`W&ApW@?`jDdemC(F}ZhgJaKDs;rQ?!HMUtA%E9~a}~JqTQS0NkX-iU@95DVE+^{CQ!Lb@u5qZ z$Xd?%ZDr<0eVA2djPNUN2hT%Y52rTS?XOZG7ylHB?`BcCvW; ziDU#NzkEo9-1<X4sX*I4rOe*3ZWeHjx4)F=$CYzCA_N+M|y-Ayf~Z?puU zS{5KZR->Fy*r8)Me{yhlPF>*=&J^!3F4D(Hz}wr;L(Ko{P>`30ci)2}f{C$?FCKcK zDOF;=$@%)b=J018PZZ;)%PgeuR22CfM$j=}_lg&*Rie^Q#_Er?DuyiOAhY`WThxh# zOZ#J4<5J`t9kF`ft_099P;=5n8^en$R%PK_=UarZ=w^~I!Y>I^_>&bHVdDmqD}qUJ zV?tD05NL>KktpNlmQ`BaKE2docg8e&lMmCHd&9!yG)E4=N9EKWvJT~UxVy;kzHV~AlU=@<%H3J^)kXobnqjQi^g;#QSNtBnTv;(&MiBe zXJt*Eze?Vl*j8gKGK_w5h-fFurDOWO0w6Ib)n&Ew4d3cf?Z9U_$Y90l22OH{%>jl) zSSIeX!A>ESZN=M!y^qaZAJZ3n?A^zWgX-Ch#v)Ybo0}RdmKGb_ZSRp%xnVvAeVP`@ zuLmE9V+)|~V*C6RU_MfB+0xw*#SVdj87WDzh;0|wIz6sC8_`A@7iTwSG|J)L8ip2x zI)bC0q7B{VF>x{kY8Ww)Et%;nl=&+0(O^UfV_$%N$_e&RZLE0jSQnEIgy}P6U8(B> z*#j$L+ZQxEL}55_Ha5TT09U65qlpD{^qEiMQz8WcUy7+_C zMSP))P^Ai84=(~HoOaTZ$-*m1@%e{;k}%I{PBH7Y`l}05LIEI3oG~1+n9JbUptteu zx<>8#RCCAyuwR0+$R}U}I*@~k%h%u=hJp0JEA3q=$B&!(w9VTF%#*@V)EI?`j~nnL zrB;iqY-KISv+apGDYXJ7;@5;5#L)TcZ%LByUfoE+k@krwMrgv2B1@N|6F{ZgO5R;q zKm7DS^Bv97<-EGkZQ|e>LZHTr^`lZZIKsyNFtz$t9l0x71W-PhRNJ~dk~S1mTM-6I zmHtj3%jkeNMMnf|H|`es=vW7LfB;@+`-WBiy6zTGdnm-CalXY-h=Jtm_907hF{S0C zJMr?R8V48{r3da4z^jd0sylC~slDVDgmafcXFH$;1`P*7*J>g-rI!Es#BHn8H!c;q zd%knXstzURhaUc*7lW50JR3U#^s?B9#R_WkR)N+0f{L|R7GEWMu!GSnD@=CV4BJ~` z!6pyK8fQ}k)&{nCLnVcx>*9JRojv1Hxuwpc;YNcBq?A~2jSIe7t2m>{&(W9~3fRrA+zQ zBlg_?-ZQC&OWrhu2O6_qPP*iOoBM(!9Ma(0-gAJMC}4PUl%bC07I)H;RzDS{j~VE__-N!!;Ip$O8^O5%$_ z+hQw1qlUBx(|^0N=_52-ts-e^bU$nl+b+{udfc=aoV*>6%CAGT&8?KhVPk|& zuJfwBom%p)`*4xQUw&6oHs4esEUkB7YNfTc&QU1ulrIz5WDVeF373Bj(r$ZJLy~zf z*UF2CNem)TdraK5`^;+3%F}UUV`Y(&=chr zyQhWJkIL6|S+B*qSt zx+mk1wtZoyL9N#Sw2U+%9-d!SMnDcghKeD=>-T6lWlIg7_W+c(2w@loW&O`NORs}1 zr~sLoQ05BiL;BOe^7RA&sf3#6R_WvFy@wRtaAH;d^_*_2n_lRE(lH9Yi9KBdKMZ@P zUB}}kJPF}eUmMT+M~F?U;3>cA<2t%H1M;4VL4>yY`(R4Xt=`(hk~FfwgEN*z_xiFW~dFO`3 z)F_}`3DfTv9lGD-2>(l)KZ@XRFV$;VF7BR{&Vs z4$x)OI`)o|#B(o*V2F>hq5RNWqMJs)4q$9UABASnNAWxY-`_0of#B(|V(_v-REE|8 zIxTh^-!-2$rv@5gi?kO)f(Xgot(uXLSad1QhfFCb01d4qO^_wCiFz<@ll;hS;nfPu z;-LKA%}=f+_xp{aY$q5uypqL>6|zs-93^ItSLtYt<&N|hPvzO#GRQ*sygxxuqOSoZ zM38~QE*%}e$)ommBLrDAH0OnQivwn;)528fD*c>oQ+#rbqR(!vaS=&AG`-&ksH0vI?~h~GA46J6DvH2NNJ>kMJ7h zaYgqaUH_nfYUJ@ivvyN`j@JS8fq4e1nK25z0R|rPc=7(hb3t39E3tG)gIu&=XqAgS z!ruWOmZWIlc0&U(2zTxxjQn3#EJ=)qYm-~07XoSZk!5im(&VD*isk2s&JX8bPYW5^ZN?c>}V za2=#`Nrr$Ntd9WC@>v{dc6iJf6e)%#9~Y;sF`2?7Y!AF_b@ZR9g$(e6Q@XQ_mC*nW zaa^p%`2~l9Pevm%jP?;nY2O}s;f}7U0Hl7)fMr#}x8iM;^#ogLrj$?}{=)vBzhVLj zZ;B=0ev8t!|9Scq?pe>^+Du|&M-9B^vMJGB%3=Ax#0TaLaO6To;x|E`7zZg4YMB4Bm zsqsFcwp6FV&B@!`Pq>Sf0E!u<9oD4VX=vTCum{_SfHRuIS!^gBPxwgbIeq?|`h<`G zr_D&WCFY{_aofOAFxV^Sqf8X=UV_m6R4aL%<{c29+pD@k8H{Whuizg^5@#iuUMm{} zTsGC+`F!a1qyfSp+eBG;LsI2nelDDkbBoT0t(d+LI$+zVFc(T3*_sbMcWk4_ zB<<#^VHjgd%az?f6V7CrEYKDYtz@N>$X)o&IKaa zbP1kma`A5$9rE%oY<6?l(7OoIJe6o;%K^p^owT7x3CmFU;#<0l0GNvPsLY$C!?>?nDl=Cv_I!8#x3+hZ9>Pl?P7$_Ls_YabjN?U~1M zh7ulWTqy@{f(vZvx|i>d^hwC!Xx+Z{6)Xw?T*~OPAPk;+zf`J~=Tr4E#0_F9s1_xo7tHAib)WW?}3X zZ`G&o>QLB81ZP~#Oghcpw&wtLX!ZdEkl5=pY9^x-iRqM=bQHAsQ;N+TPj?lblDx-h z={l(Al-$_YKrp(3QJ5sMuPhxb7{6+7z8@#7?h>Z;`e=JaW{QHGqu*gdO$o`(3*5;t z#j@1IKWBkK=sbq%DeGQg#m+GsSk>@>pDSjoC9ECxB}NWkd^6EUHW!CNLJoBdS#Ef~ zub2%mysu~-#6R*wKm2Np9x2DRDqVZJk+9P-@nwO_il^fL(exHvadb`F=-?jQgABnT zxVw9R06~KV5ALpmy9Rf6cXuBwKyY_=hcox{e&-MLS~Fd{chzMT*{+g)2QytCf-!{n zJJc_NLkSt!2h~FXXo)Yt;?TJAs%T>UX>|;-TjsI4Fcn2|^Td8;S@p@;@NxTKTp}_& zYbY8mwf&O!EPwO(JUPzIY$OF662HvDMH0+o_)ys(0YXEW(H&SYhn$4}I|}Gf7z>oB znBi&wU@sg2K`i^KpcFf~nQ;z!i)-YA4cUe;pLo5KW!o+#wBz*iSe^UX{#KMYhaWEy z^q@{?de;R(7f0i5dEB~VyH^g|Ah1U^m?u^)Bnno22bVQ#Y<%_VUAvt&Vi z+-8QDX^vT))A&AcYaFaA@uRAeaN+qbQ^n>PNF}%blmajjOqxr%N!=SdqBzAnBW$)( z0Qf;Gs@spZgO4+cQyfGuu<#WmWI{dd52Pf{S(TF;k2U~QCs-D=$=0vCj zzA9fSRsugW_K7Xhh}8G^Io%oDFHeHfLqeh1mI2VZi#l}3!|TF@XKhh)XYH>V*6+e* zumC6--YwfRQWi^%-5Ih zR;~x1iZdSbx(F$2*RSY-u<^Tg{-{N4J!1RolNGPT#A!p&%74G$PGLe36vwk@KcLFn zr{K_dbI(hNg^oo3AhHtoee0dssqd23bY2om;ha&Go(dUXvTSD36&|RA!Xg5)^m`Jk zNx=s@K-Jsxkmtku|G#4Yyspg7COb>1GAKd}`z*w5P5bWAx%G~@-tBpN*q}pa3jayU zU01x@zUARK3RM1r7!4l^3*poQ@Vts8R8xCCpM(2wE;&{gip|sn$YA}bji=joRyKLAmGt*{_*>q>j2>!~?SRaa5_tL-Nm@gSLshm}G1~oX#oHdxmsRfuA2+8i zIlJJWSr^`x?$vwc+z@PI5>LWTLadaV{gd~{WPoF`^+E7|BBcMFYzzQ3J_tAeHW&8- znt=E=8hmw$)7|O#dRTEnz*qcbK%}TX_#{0fV$tSjR~;%l$ON_rz}rCpd8z$5q;kJc zH9y&$|DzaW%?=A#rH68>LIlu~V-h;>1Ob9)-AS;EBETX4c);f}ehoiraiK5QUd%L6 zv2vPiCj^t9NsWO~(?cmH^zaDpntTnEJpzv*Sn$k!Ts?^S@Sn*2e?Z>~RPqobnb
      H|zz{j8vX-lqku;-NW2E3;BMf3f>Jhxt3 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
      %-(a@!i`89VK;?-qg=ZiR0A&pVk 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

      wrV@M0ad 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 diff --git a/apps/mobile/assets/icon.svg b/apps/mobile/assets/icon.svg new file mode 100644 index 0000000..f51b107 --- /dev/null +++ b/apps/mobile/assets/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + From d2f0e708de3ff4917fc89019a58601bb1b0e1433 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 19 Jul 2026 21:13:43 +0200 Subject: [PATCH 51/83] feat(mobile): upgrade to Expo SDK 54 (RN 0.81) for Xcode 26 / iOS 26 SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple now requires builds made with the iOS 26 SDK (Xcode 26); SDK 52 can't produce those. Upgrade to SDK 54 — the last SDK supporting the legacy architecture, so the vendored SwiftTerm native view needs no Fabric migration (newArchEnabled pinned false). - expo ^54, react-native 0.81.5, react 19.1.0 (expo install --fix) - .npmrc legacy-peer-deps=true (npm can't resolve the react 18→19 transition otherwise) - plugins/withFmtConstevalFix.js: build the fmt pod as C++17 — RN 0.81 vendors fmt 11.0.2, whose consteval format-string checks fail under Xcode 26's Clang (fixed in fmt 12 upstream, not backported to 0.81). Durable config plugin (ios/ is regenerated). - metro.config: drop disableHierarchicalLookup — SDK 54's expo pulls in nested transitive deps (whatwg-url-without-unicode → webidl-conversions) that the walk-up must resolve; bun-root shadowing is already prevented by the workspace exclusion. - gitignore build/ (archive/export artifacts) Verified: archive + export signed Apple Distribution (X2VZX44YM2), uploaded to TestFlight (UUID 5f44c209). Xcode 26 also needs one-time: -downloadPlatform iOS + -downloadComponent MetalToolchain. --- apps/mobile/.gitignore | 3 + apps/mobile/.npmrc | 1 + apps/mobile/app.json | 2 + apps/mobile/metro.config.js | 9 +- apps/mobile/package-lock.json | 4886 +++++++------------- apps/mobile/package.json | 18 +- apps/mobile/plugins/withFmtConstevalFix.js | 44 + 7 files changed, 1795 insertions(+), 3168 deletions(-) create mode 100644 apps/mobile/.npmrc create mode 100644 apps/mobile/plugins/withFmtConstevalFix.js diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore index d914c32..f75a8bd 100644 --- a/apps/mobile/.gitignore +++ b/apps/mobile/.gitignore @@ -39,3 +39,6 @@ yarn-error.* # generated native folders /ios /android + +# native archive/export artifacts +/build diff --git a/apps/mobile/.npmrc b/apps/mobile/.npmrc new file mode 100644 index 0000000..521a9f7 --- /dev/null +++ b/apps/mobile/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 0333f71..874a1c9 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -6,6 +6,8 @@ "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", + "newArchEnabled": false, + "plugins": ["./plugins/withFmtConstevalFix"], "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", diff --git a/apps/mobile/metro.config.js b/apps/mobile/metro.config.js index a5ec37a..641f8a1 100644 --- a/apps/mobile/metro.config.js +++ b/apps/mobile/metro.config.js @@ -8,8 +8,15 @@ const path = require("node:path"); const projectRoot = __dirname; const config = getDefaultConfig(projectRoot); +// Resolve this app's own node_modules first. We deliberately KEEP Metro's +// hierarchical (walk-up) lookup on: SDK 54's `expo` pulls in transitive deps that +// npm nests (e.g. whatwg-url-without-unicode → its own webidl-conversions), and +// disabling the walk-up makes those nested modules unresolvable. The original +// bun-root-shadowing concern is now handled structurally — apps/mobile is excluded +// from the bun workspace ("!apps/mobile") with its own lockfile + isolated +// node_modules, and closest-wins resolution means the app's own react/react-native +// always win for app code. config.resolver.nodeModulesPaths = [path.resolve(projectRoot, "node_modules")]; -config.resolver.disableHierarchicalLookup = true; // Surgically link the one workspace package the app consumes — @ateam/protocol, // the pure-TS wire contract (no deps of its own). We watch its folder so Metro diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index 46eb17e..9bb89d2 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -8,25 +8,26 @@ "name": "mobile", "version": "1.0.0", "dependencies": { - "@react-native-async-storage/async-storage": "^1.23.1", + "@react-native-async-storage/async-storage": "2.2.0", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", - "expo": "^52.0.49", - "expo-status-bar": "~2.0.1", - "react": "18.3.1", - "react-native": "0.76.9", - "react-native-svg": "^15.8.0", - "react-native-webview": "13.12.5" + "expo": "^54.0.36", + "expo-status-bar": "~3.0.9", + "react": "19.1.0", + "react-native": "0.81.5", + "react-native-svg": "15.12.1", + "react-native-webview": "13.15.0" }, "devDependencies": { - "@types/react": "~19.2.2", - "typescript": "~6.0.3" + "@types/react": "~19.1.10", + "typescript": "~5.9.2" } }, "node_modules/@0no-co/graphql.web": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.3.2.tgz", "integrity": "sha512-Q1+pRlLhE31GOY/2c9BAEnFTNxO7Awtc6fhhEDlxyCBQ2N0IhD32cPVvPChrK9mwBNSgRdW/sF1kd2e0ojHj1Q==", + "license": "MIT", "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" }, @@ -40,6 +41,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } @@ -382,6 +384,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "chalk": "^2.4.2", @@ -396,6 +399,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -407,6 +411,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -420,6 +425,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -427,12 +433,14 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -441,6 +449,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } @@ -449,6 +458,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -470,26 +480,11 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-decorators": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz", "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", @@ -516,39 +511,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -600,6 +562,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, @@ -882,6 +845,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, "node_modules/@babel/plugin-transform-classes": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", @@ -935,6 +914,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, @@ -1205,6 +1185,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", + "license": "MIT", "dependencies": { "@babel/plugin-transform-react-jsx": "^7.29.7" }, @@ -1247,6 +1228,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" @@ -1375,26 +1357,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-flow": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.29.7.tgz", - "integrity": "sha512-KYIRV0BuaN68CDdsqFkAD7MU7yipUqQNuNElwATdxaIdpTjhvtY82QvkBJs7zV3Evxj2jFAAZ1iO8nyy0nhjqA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7", - "@babel/helper-validator-option": "^7.29.7", - "@babel/plugin-transform-flow-strip-types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/preset-react": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.29.7.tgz", "integrity": "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", @@ -1428,24 +1395,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/register": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.29.7.tgz", - "integrity": "sha512-AMGJoWuES861riy6pcB0fphE1YXybtQnBYQMuIyPv6mKLiosfa79BKTnAOyx215c/3RJPJpdQwoHZ3earVH7AA==", - "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.6", - "source-map-support": "^0.5.16" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/runtime": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", @@ -1553,70 +1502,54 @@ "node": ">=6.9.0" } }, - "node_modules/@expo/bunyan": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.1.tgz", - "integrity": "sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==", - "dependencies": { - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@expo/cli": { - "version": "0.22.28", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.28.tgz", - "integrity": "sha512-lvt72KNitGuixYD2l3SZmRKVu2G4zJpmg5V7WfUBNpmUU5oODBw/6qmiJ6kSLAlfDozscUk+BBGknBBzxUrwrA==", + "version": "54.0.26", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.26.tgz", + "integrity": "sha512-BjsAoKINLEo3LRE+sDC6FCgjxuOWsyfOFOKz0txrbEcxSatzIjJDVuX8XaTdmeicZdcoN524yl1sfwCWfxhYMw==", + "license": "MIT", "dependencies": { "@0no-co/graphql.web": "^1.0.8", - "@babel/runtime": "^7.20.0", "@expo/code-signing-certificates": "^0.0.6", - "@expo/config": "~10.0.11", - "@expo/config-plugins": "~9.0.17", - "@expo/devcert": "^1.1.2", - "@expo/env": "~0.4.2", - "@expo/image-utils": "^0.6.5", - "@expo/json-file": "^9.0.2", - "@expo/metro-config": "~0.19.12", - "@expo/osascript": "^2.1.6", - "@expo/package-manager": "^1.7.2", - "@expo/plist": "^0.2.2", - "@expo/prebuild-config": "~8.2.0", - "@expo/rudder-sdk-node": "^1.1.1", + "@expo/config": "~12.0.14", + "@expo/config-plugins": "~54.0.5", + "@expo/devcert": "^1.2.1", + "@expo/env": "~2.0.12", + "@expo/image-utils": "^0.8.8", + "@expo/json-file": "^10.0.16", + "@expo/metro": "~54.2.0", + "@expo/metro-config": "~54.0.17", + "@expo/osascript": "^2.3.8", + "@expo/package-manager": "^1.9.10", + "@expo/plist": "^0.4.9", + "@expo/prebuild-config": "^54.0.9", + "@expo/schema-utils": "^0.1.9", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.3.0", - "@react-native/dev-middleware": "0.76.9", + "@react-native/dev-middleware": "0.81.5", "@urql/core": "^5.0.6", "@urql/exchange-retry": "^1.3.0", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", - "bplist-creator": "0.0.7", + "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", - "cacache": "^18.0.2", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "env-editor": "^0.4.1", - "fast-glob": "^3.3.2", - "form-data": "^3.0.1", + "expo-server": "^1.0.7", "freeport-async": "^2.0.0", - "fs-extra": "~8.1.0", - "getenv": "^1.0.0", - "glob": "^10.4.2", - "internal-ip": "^4.3.0", - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1", - "lodash.debounce": "^4.0.8", - "minimatch": "^3.0.4", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "lan-network": "^0.2.1", + "minimatch": "^9.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", - "picomatch": "^3.0.1", + "picomatch": "^4.0.3", "pretty-bytes": "^5.6.0", "pretty-format": "^29.7.0", "progress": "^2.0.3", @@ -1633,60 +1566,97 @@ "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", - "tar": "^6.2.1", - "temp-dir": "^2.0.0", - "tempy": "^0.7.1", + "tar": "^7.5.2", "terminal-link": "^2.1.1", "undici": "^6.18.2", - "unique-string": "~2.0.0", "wrap-ansi": "^7.0.0", "ws": "^8.12.1" }, "bin": { "expo-internal": "build/bin/cli" + }, + "peerDependencies": { + "expo": "*", + "expo-router": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo-router": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@expo/cli/node_modules/brace-expansion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@expo/cli/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@expo/code-signing-certificates": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", + "license": "MIT", "dependencies": { "node-forge": "^1.3.3" } }, "node_modules/@expo/config": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.11.tgz", - "integrity": "sha512-nociJ4zr/NmbVfMNe9j/+zRlt7wz/siISu7PjdWE4WE+elEGxWWxsGzltdJG0llzrM+khx8qUiFK5aiVcdMBww==", + "version": "12.0.14", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.14.tgz", + "integrity": "sha512-3dfbBd9LnPDgyylhCgkOsaG8Adg52uOVOTQYH5lf23a/t8M5eQpXKCvzUarrf62B78057n2NnkiofK9TfPgvzw==", + "license": "MIT", "dependencies": { "@babel/code-frame": "~7.10.4", - "@expo/config-plugins": "~9.0.17", - "@expo/config-types": "^52.0.5", - "@expo/json-file": "^9.0.2", + "@expo/config-plugins": "~54.0.5", + "@expo/config-types": "^54.0.10", + "@expo/json-file": "^10.0.16", "deepmerge": "^4.3.1", - "getenv": "^1.0.0", - "glob": "^10.4.2", + "getenv": "^2.0.0", + "glob": "^13.0.0", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4", - "sucrase": "3.35.0" + "sucrase": "~3.35.1" } }, "node_modules/@expo/config-plugins": { - "version": "9.0.17", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.17.tgz", - "integrity": "sha512-m24F1COquwOm7PBl5wRbkT9P9DviCXe0D7S7nQsolfbhdCWuvMkfXeoWmgjtdhy7sDlOyIgBrAdnB6MfsWKqIg==", - "dependencies": { - "@expo/config-types": "^52.0.5", - "@expo/json-file": "~9.0.2", - "@expo/plist": "^0.2.2", + "version": "54.0.5", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.5.tgz", + "integrity": "sha512-aWQ3sViNRoQWw6So4A2qhWCt24CuGBK6MrRHI1AG+V6/NQAjIZCHaSvcXK2gXKpmisRhTSUWaKPIgLJQFB+AeQ==", + "license": "MIT", + "dependencies": { + "@expo/config-types": "^54.0.10", + "@expo/json-file": "~10.0.16", + "@expo/plist": "^0.4.9", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", - "getenv": "^1.0.0", - "glob": "^10.4.2", + "getenv": "^2.0.0", + "glob": "^13.0.0", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", @@ -1696,24 +1666,26 @@ } }, "node_modules/@expo/config-plugins/node_modules/@expo/json-file": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.2.tgz", - "integrity": "sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==", + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.16.tgz", + "integrity": "sha512-fcVkWEj+hLuP2yt5W0aw6LmDRqSPWDLUSxOMcmFeV+algmIF59sQVKCwB9btjQLd4V6x9N0pISkQEkBubUHrCw==", + "license": "MIT", "dependencies": { "@babel/code-frame": "~7.10.4", - "json5": "^2.2.3", - "write-file-atomic": "^2.3.0" + "json5": "^2.2.3" } }, "node_modules/@expo/config-types": { - "version": "52.0.5", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-52.0.5.tgz", - "integrity": "sha512-AMDeuDLHXXqd8W+0zSjIt7f37vUd/BP8p43k68NHpyAvQO+z8mbQZm3cNQVAMySeayK2XoPigAFB1JF2NFajaA==" + "version": "54.0.10", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.10.tgz", + "integrity": "sha512-/J16SC2an1LdtCZ67xhSkGXpALYUVUNyZws7v+PVsFZxClYehDSoKLqyRaGkpHlYrCc08bS0RF5E0JV6g50psA==", + "license": "MIT" }, "node_modules/@expo/devcert": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz", "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==", + "license": "MIT", "dependencies": { "@expo/sudo-prompt": "^9.3.1", "debug": "^3.1.0" @@ -1723,34 +1695,59 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, + "node_modules/@expo/devtools": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.8.tgz", + "integrity": "sha512-SVLxbuanDjJPgc0sy3EfXUMLb/tXzp6XIHkhtPVmTWJAp+FOr6+5SeiCfJrCzZFet0Ifyke2vX3sFcKwEvCXwQ==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@expo/env": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-0.4.2.tgz", - "integrity": "sha512-TgbCgvSk0Kq0e2fLoqHwEBL4M0ztFjnBEz0YCDm5boc1nvkV1VMuIMteVdeBwnTh8Z0oPJTwHCD49vhMEt1I6A==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.12.tgz", + "integrity": "sha512-wVfzeBGlUohZG5kS8QCqXurpuWZFJEkBB1wXCifai3EZ/Llcg/VMTiUCpAgHImD3lI7GIU3V1uI64c04XIo98Q==", + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", - "getenv": "^1.0.0" + "getenv": "^2.0.0" } }, "node_modules/@expo/fingerprint": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.11.tgz", - "integrity": "sha512-gNyn1KnAOpEa8gSNsYqXMTcq0fSwqU/vit6fP5863vLSKxHm/dNt/gm/uZJxrRZxKq71KUJWF6I7d3z8qIfq5g==", + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.5.tgz", + "integrity": "sha512-mdVoAMcux1WlM6kd1RoWiHRNqKqS+J6mKmWQ/BKgeh937S/fcW58EE68O6nc4KDXtWi3PBeNHskOFcgyIuD4hw==", + "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", - "find-up": "^5.0.0", - "getenv": "^1.0.0", - "minimatch": "^3.0.4", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "ignore": "^5.3.1", + "minimatch": "^10.2.2", "p-limit": "^3.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" @@ -1759,169 +1756,178 @@ "fingerprint": "bin/cli.js" } }, - "node_modules/@expo/image-utils": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.6.5.tgz", - "integrity": "sha512-RsS/1CwJYzccvlprYktD42KjyfWZECH6PPIEowvoSmXfGLfdViwcUEI4RvBfKX5Jli6P67H+6YmHvPTbGOboew==", - "dependencies": { - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "fs-extra": "9.0.0", - "getenv": "^1.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "resolve-from": "^5.0.0", - "semver": "^7.6.0", - "temp-dir": "~2.0.0", - "unique-string": "~2.0.0" + "node_modules/@expo/fingerprint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/image-utils/node_modules/fs-extra": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", - "integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==", + "node_modules/@expo/fingerprint/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/image-utils/node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "node_modules/@expo/fingerprint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "universalify": "^2.0.0" + "brace-expansion": "^5.0.5" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@expo/image-utils/node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { - "node": ">= 10.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/image-utils/node_modules/universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", - "engines": { - "node": ">= 10.0.0" + "node_modules/@expo/image-utils": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.15.tgz", + "integrity": "sha512-3f5CgKJnJ8m4mp8VTcAFQqLrxof99RDr77Aa+7hgzDPg3ZotjLnofl77hf+COQRYi/kuqRYdYFgPIqOIOIdWJA==", + "license": "MIT", + "dependencies": { + "@expo/require-utils": "^55.0.6", + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "getenv": "^2.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "semver": "^7.6.0" } }, "node_modules/@expo/json-file": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.1.5.tgz", - "integrity": "sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz", + "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "~7.10.4", + "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, + "node_modules/@expo/json-file/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/metro": { + "version": "54.2.0", + "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz", + "integrity": "sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w==", + "license": "MIT", + "dependencies": { + "metro": "0.83.3", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-config": "0.83.3", + "metro-core": "0.83.3", + "metro-file-map": "0.83.3", + "metro-minify-terser": "0.83.3", + "metro-resolver": "0.83.3", + "metro-runtime": "0.83.3", + "metro-source-map": "0.83.3", + "metro-symbolicate": "0.83.3", + "metro-transform-plugins": "0.83.3", + "metro-transform-worker": "0.83.3" + } + }, "node_modules/@expo/metro-config": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.12.tgz", - "integrity": "sha512-fhT3x1ikQWHpZgw7VrEghBdscFPz1laRYa8WcVRB18nTTqorF6S8qPYslkJu1faEziHZS7c2uyDzTYnrg/CKbg==", + "version": "54.0.17", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.17.tgz", + "integrity": "sha512-PQFgQCZGY0DffZUvBzJttDPreZfHrQakaBlKjnvOUMNXbDna+TYmg1IFZuIDUYJezLcdp+TvVFTLjNi1+mqaVw==", + "license": "MIT", "dependencies": { + "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", - "@babel/parser": "^7.20.0", - "@babel/types": "^7.20.0", - "@expo/config": "~10.0.11", - "@expo/env": "~0.4.2", - "@expo/json-file": "~9.0.2", + "@expo/config": "~12.0.14", + "@expo/env": "~2.0.12", + "@expo/json-file": "~10.0.16", + "@expo/metro": "~54.2.0", "@expo/spawn-async": "^1.7.2", + "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", - "fs-extra": "^9.1.0", - "getenv": "^1.0.0", - "glob": "^10.4.2", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "hermes-parser": "^0.29.1", "jsc-safe-url": "^0.2.4", - "lightningcss": "~1.27.0", - "minimatch": "^3.0.4", + "lightningcss": "^1.30.1", + "picomatch": "^4.0.3", "postcss": "~8.4.32", "resolve-from": "^5.0.0" - } - }, - "node_modules/@expo/metro-config/node_modules/@expo/json-file": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.2.tgz", - "integrity": "sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "json5": "^2.2.3", - "write-file-atomic": "^2.3.0" - } - }, - "node_modules/@expo/metro-config/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } } }, - "node_modules/@expo/metro-config/node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "node_modules/@expo/metro-config/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@expo/metro-config/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" } }, - "node_modules/@expo/osascript": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.7.0.tgz", - "integrity": "sha512-wKIXL8UtbuX4KwavPasIW3CUcgTbYfjzLcgUhjyKUAYDEqMaf6gmU1bqz3ffBPTokmX+G8/vFG1ZuI9etQWukA==", + "node_modules/@expo/metro-config/node_modules/@expo/json-file": { + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.16.tgz", + "integrity": "sha512-fcVkWEj+hLuP2yt5W0aw6LmDRqSPWDLUSxOMcmFeV+algmIF59sQVKCwB9btjQLd4V6x9N0pISkQEkBubUHrCw==", + "license": "MIT", "dependencies": { - "@expo/spawn-async": "^1.8.0" - }, - "engines": { - "node": ">=12" + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3" } }, - "node_modules/@expo/package-manager": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.13.0.tgz", - "integrity": "sha512-s3W3eZafJDEyVL7W/jxj2Nz3eONKxSCU604S5xj8ijrVaRz83x0DnZznLf/UXQEI1w+FyibH68nHeQyk767b1A==", + "node_modules/@expo/metro-config/node_modules/@expo/json-file/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "license": "MIT", "dependencies": { - "@expo/json-file": "^11.0.0", - "@expo/spawn-async": "^1.8.0", - "chalk": "^4.0.0", - "npm-package-arg": "^11.0.0", - "ora": "^3.4.0", - "resolve-workspace-root": "^2.0.0" + "@babel/highlight": "^7.10.4" } }, - "node_modules/@expo/package-manager/node_modules/@babel/code-frame": { + "node_modules/@expo/metro/node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", @@ -1931,102 +1937,461 @@ "node": ">=6.9.0" } }, - "node_modules/@expo/package-manager/node_modules/@expo/json-file": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-11.0.0.tgz", - "integrity": "sha512-pHJCETqFL5x5BzNV6cEPwjwuECgGmnl0bNmfHIJ6LM1tlh2eVXi5HEdit3zby/JO/B8Otk5cgcqtJXgvvUat3A==", - "dependencies": { - "@babel/code-frame": "^7.20.0", - "json5": "^2.2.3" - } + "node_modules/@expo/metro/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT" }, - "node_modules/@expo/plist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.2.2.tgz", - "integrity": "sha512-ZZGvTO6vEWq02UAPs3LIdja+HRO18+LRI5QuDl6Hs3Ps7KX7xU6Y6kjahWKY37Rx2YjNpX07dGpBFzzC+vKa2g==", - "dependencies": { - "@xmldom/xmldom": "~0.7.7", - "base64-js": "^1.2.3", - "xmlbuilder": "^14.0.0" - } + "node_modules/@expo/metro/node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "license": "MIT" }, - "node_modules/@expo/prebuild-config": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.2.0.tgz", - "integrity": "sha512-CxiPpd980s0jyxi7eyN3i/7YKu3XL+8qPjBZUCYtc0+axpGweqIkq2CslyLSKHyqVyH/zlPkbVgWdyiYavFS5Q==", - "dependencies": { - "@expo/config": "~10.0.11", - "@expo/config-plugins": "~9.0.17", - "@expo/config-types": "^52.0.5", - "@expo/image-utils": "^0.6.5", - "@expo/json-file": "^9.0.2", - "@react-native/normalize-colors": "0.76.9", - "debug": "^4.3.1", - "fs-extra": "^9.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.6.0", - "xml2js": "0.6.0" + "node_modules/@expo/metro/node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.32.0" } }, - "node_modules/@expo/prebuild-config/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/@expo/metro/node_modules/metro": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.3.tgz", + "integrity": "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==", + "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@babel/code-frame": "^7.24.7", + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "@babel/types": "^7.25.2", + "accepts": "^1.3.7", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "error-stack-parser": "^2.0.6", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.32.0", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-config": "0.83.3", + "metro-core": "0.83.3", + "metro-file-map": "0.83.3", + "metro-resolver": "0.83.3", + "metro-runtime": "0.83.3", + "metro-source-map": "0.83.3", + "metro-symbolicate": "0.83.3", + "metro-transform-plugins": "0.83.3", + "metro-transform-worker": "0.83.3", + "mime-types": "^2.1.27", + "nullthrows": "^1.1.1", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "throat": "^5.0.0", + "ws": "^7.5.10", + "yargs": "^17.6.2" + }, + "bin": { + "metro": "src/cli.js" }, "engines": { - "node": ">=10" + "node": ">=20.19.4" } }, - "node_modules/@expo/prebuild-config/node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "node_modules/@expo/metro/node_modules/metro-babel-transformer": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz", + "integrity": "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==", + "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "@babel/core": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "hermes-parser": "0.32.0", + "nullthrows": "^1.1.1" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=20.19.4" } }, - "node_modules/@expo/prebuild-config/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/@expo/metro/node_modules/metro-cache": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.3.tgz", + "integrity": "sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q==", + "license": "MIT", + "dependencies": { + "exponential-backoff": "^3.1.1", + "flow-enums-runtime": "^0.0.6", + "https-proxy-agent": "^7.0.5", + "metro-core": "0.83.3" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=20.19.4" } }, - "node_modules/@expo/rudder-sdk-node": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@expo/rudder-sdk-node/-/rudder-sdk-node-1.1.1.tgz", - "integrity": "sha512-uy/hS/awclDJ1S88w9UGpc6Nm9XnNUjzOAAib1A3PVAnGQIwebg8DpFqOthFBTlZxeuV/BKbZ5jmTbtNZkp1WQ==", + "node_modules/@expo/metro/node_modules/metro-cache-key": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.3.tgz", + "integrity": "sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-config": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.3.tgz", + "integrity": "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==", + "license": "MIT", + "dependencies": { + "connect": "^3.6.5", + "flow-enums-runtime": "^0.0.6", + "jest-validate": "^29.7.0", + "metro": "0.83.3", + "metro-cache": "0.83.3", + "metro-core": "0.83.3", + "metro-runtime": "0.83.3", + "yaml": "^2.6.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-core": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.3.tgz", + "integrity": "sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.83.3" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-file-map": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.3.tgz", + "integrity": "sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fb-watchman": "^2.0.0", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-minify-terser": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz", + "integrity": "sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "terser": "^5.15.0" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-resolver": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.3.tgz", + "integrity": "sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-runtime": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.3.tgz", + "integrity": "sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-source-map": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.3.tgz", + "integrity": "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-symbolicate": "0.83.3", + "nullthrows": "^1.1.1", + "ob1": "0.83.3", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-symbolicate": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz", + "integrity": "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-source-map": "0.83.3", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-transform-plugins": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz", + "integrity": "sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "flow-enums-runtime": "^0.0.6", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/metro-transform-worker": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz", + "integrity": "sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "metro": "0.83.3", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-minify-terser": "0.83.3", + "metro-source-map": "0.83.3", + "metro-transform-plugins": "0.83.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/ob1": { + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.3.tgz", + "integrity": "sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/@expo/metro/node_modules/ws": { + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@expo/osascript": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.7.1.tgz", + "integrity": "sha512-Zn03EX6In7ts2lPUW2ESUSkEhEWQN1qqsiXjadtZMJOuZRkMiAg1ZQHuvz9DjByDWNJ2pBwAGyrts9lj9k389g==", + "license": "MIT", "dependencies": { - "@expo/bunyan": "^4.0.0", - "@segment/loosely-validate-event": "^2.0.0", - "fetch-retry": "^4.1.1", - "md5": "^2.2.1", - "node-fetch": "^2.6.1", - "remove-trailing-slash": "^0.1.0", - "uuid": "^8.3.2" + "@expo/spawn-async": "^1.8.0" }, "engines": { "node": ">=12" } }, + "node_modules/@expo/package-manager": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.13.1.tgz", + "integrity": "sha512-y/K+CaYYpZpNGZhSX4HyLT/vyIunFjNfyoxNysPBCefeLKI/VCx6f9LNPzrxayr3rCYO5bl9O8H+HRQK265Nkg==", + "license": "MIT", + "dependencies": { + "@expo/json-file": "^11.0.1", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.0.0", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "resolve-workspace-root": "^2.0.0" + } + }, + "node_modules/@expo/package-manager/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/package-manager/node_modules/@expo/json-file": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-11.0.1.tgz", + "integrity": "sha512-zxHWj4MKKMAL29ZQSY/Fssx4Thluk40JmuGNaeS078wy/NhlFhnVi+rHHunulE3xJAJ0CM73m8VK2+GkF9eRwQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, + "node_modules/@expo/plist": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.9.tgz", + "integrity": "sha512-MPVpmKGfnQEnrCzgxuXcmPP/y/t6AVm+DcSb2Myp21LKWv1N3l8uFxMggesfF4ixAxkRlGmMMx9GyDC9M+XklQ==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.2.3", + "xmlbuilder": "^15.1.1" + } + }, + "node_modules/@expo/prebuild-config": { + "version": "54.0.9", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.9.tgz", + "integrity": "sha512-3/Rmyzt8vduPjnSVHbnc0wYFrlhwLWn2g596rDyKcLGeqN2WTLJbzVeznsrUwyzhBNXgnTomZWO5HDzbZ/4E7g==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.14", + "@expo/config-plugins": "~54.0.5", + "@expo/config-types": "^54.0.10", + "@expo/image-utils": "^0.8.8", + "@expo/json-file": "^10.0.16", + "@react-native/normalize-colors": "0.81.5", + "debug": "^4.3.1", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/@expo/require-utils": { + "version": "55.0.6", + "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.6.tgz", + "integrity": "sha512-IqsRGPdGbF0lAIrg3XQ+GzcITYcsskvIRmFAjw2kBnr8RgSrRhFAJY1bKksukEUsuZy0knhTCVIIUce7hocqeA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8" + }, + "peerDependencies": { + "typescript": "^5.0.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@expo/require-utils/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/schema-utils": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.9.tgz", + "integrity": "sha512-t9bYwG4Z0yCVzHYJoDMci1OFq2FkBkhStlfUGSkspKYTwB/84+x6sY+CXCgdhkQNQtvWaugW5KUs9YZfAXq9Sg==", + "license": "MIT" + }, "node_modules/@expo/sdk-runtime-versions": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", - "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==" + "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==", + "license": "MIT" }, "node_modules/@expo/spawn-async": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz", "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.6" }, @@ -2037,25 +2402,31 @@ "node_modules/@expo/sudo-prompt": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz", - "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==" + "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==", + "license": "MIT" }, "node_modules/@expo/vector-icons": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.4.tgz", - "integrity": "sha512-+yKshcbpDfbV4zoXOgHxCwh7lkE9VVTT5T03OUlBsqfze1PLy6Hi4jp1vSb1GVbY6eskvMIivGVc9SKzIv0oEQ==", - "dependencies": { - "prop-types": "^15.8.1" + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz", + "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==", + "license": "MIT", + "peerDependencies": { + "expo-font": ">=14.0.4", + "react": "*", + "react-native": "*" } }, "node_modules/@expo/ws-tunnel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz", - "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==" + "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==", + "license": "MIT" }, "node_modules/@expo/xcpretty": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz", "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==", + "license": "BSD-3-Clause", "dependencies": { "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", @@ -2069,6 +2440,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", @@ -2078,47 +2450,16 @@ "node": ">=6.9.0" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "minipass": "^7.0.4" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=18.0.0" } }, "node_modules/@isaacs/ttlcache": { @@ -2297,11 +2638,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "node_modules/@jest/transform/node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", @@ -2379,165 +2715,46 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", - "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.23.1", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.23.1.tgz", - "integrity": "sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz", + "integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==", + "license": "MIT", "dependencies": { "merge-options": "^3.0.4" }, "peerDependencies": { - "react-native": "^0.0.0-0 || >=0.60 <1.0" + "react-native": "^0.0.0-0 || >=0.65 <1.0" } }, "node_modules/@react-native/assets-registry": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.9.tgz", - "integrity": "sha512-pN0Ws5xsjWOZ8P37efh0jqHHQmq+oNGKT4AyAoKRpxBDDDmlAmpaYjer9Qz7PpDKF+IUyRjF/+rBsM50a8JcUg==", - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/babel-plugin-codegen": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.9.tgz", - "integrity": "sha512-vxL/vtDEIYHfWKm5oTaEmwcnNGsua/i9OjIxBDBFiJDu5i5RU3bpmDiXQm/bJxrJNPRp5lW0I0kpGihVhnMAIQ==", - "dependencies": { - "@react-native/codegen": "0.76.9" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/babel-preset": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.9.tgz", - "integrity": "sha512-TbSeCplCM6WhL3hR2MjC/E1a9cRnMLz7i767T7mP90oWkklEjyPxWl+0GGoVGnJ8FC/jLUupg/HvREKjjif6lw==", - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-proposal-export-default-from": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-default-from": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.4", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.25.4", - "@babel/plugin-transform-classes": "^7.25.4", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.8", - "@babel/plugin-transform-flow-strip-types": "^7.25.2", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.25.1", - "@babel/plugin-transform-literals": "^7.25.2", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.8", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-runtime": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.25.2", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/template": "^7.25.0", - "@react-native/babel-plugin-codegen": "0.76.9", - "babel-plugin-syntax-hermes-parser": "^0.25.1", - "babel-plugin-transform-flow-enums": "^0.0.2", - "react-refresh": "^0.14.0" - }, + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz", + "integrity": "sha512-705B6x/5Kxm1RKRvSv0ADYWm5JOnoiQ1ufW7h8uu2E6G9Of/eE6hP/Ivw3U5jI16ERqZxiKQwk34VJbB0niX9w==", + "license": "MIT", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@babel/core": "*" + "node": ">= 20.19.4" } }, "node_modules/@react-native/codegen": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.9.tgz", - "integrity": "sha512-AzlCHMTKrAVC2709V4ZGtBXmGVtWTpWm3Ruv5vXcd3/anH4mGucfJ4rjbWKdaYQJMpXa3ytGomQrsIsT/s8kgA==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", + "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", + "license": "MIT", "dependencies": { + "@babel/core": "^7.25.2", "@babel/parser": "^7.25.3", "glob": "^7.1.1", - "hermes-parser": "0.23.1", + "hermes-parser": "0.29.1", "invariant": "^2.2.4", - "jscodeshift": "^0.14.0", - "mkdirp": "^0.5.1", "nullthrows": "^1.1.1", "yargs": "^17.6.2" }, "engines": { - "node": ">=18" + "node": ">= 20.19.4" }, "peerDependencies": { - "@babel/preset-env": "^7.1.6" + "@babel/core": "*" } }, "node_modules/@react-native/codegen/node_modules/glob": { @@ -2545,6 +2762,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2561,218 +2779,113 @@ } }, "node_modules/@react-native/community-cli-plugin": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.9.tgz", - "integrity": "sha512-08jx8ixCjjd4jNQwNpP8yqrjrDctN2qvPPlf6ebz1OJQk8e1sbUl3wVn1zhhMvWrYcaraDnatPb5uCPq+dn3NQ==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.5.tgz", + "integrity": "sha512-yWRlmEOtcyvSZ4+OvqPabt+NS36vg0K/WADTQLhrYrm9qdZSuXmq8PmdJWz/68wAqKQ+4KTILiq2kjRQwnyhQw==", + "license": "MIT", "dependencies": { - "@react-native/dev-middleware": "0.76.9", - "@react-native/metro-babel-transformer": "0.76.9", - "chalk": "^4.0.0", - "execa": "^5.1.1", + "@react-native/dev-middleware": "0.81.5", + "debug": "^4.4.0", "invariant": "^2.2.4", - "metro": "^0.81.0", - "metro-config": "^0.81.0", - "metro-core": "^0.81.0", - "node-fetch": "^2.2.0", - "readline": "^1.3.0", + "metro": "^0.83.1", + "metro-config": "^0.83.1", + "metro-core": "^0.83.1", "semver": "^7.1.3" }, "engines": { - "node": ">=18" + "node": ">= 20.19.4" }, "peerDependencies": { - "@react-native-community/cli": "*" + "@react-native-community/cli": "*", + "@react-native/metro-config": "*" }, "peerDependenciesMeta": { "@react-native-community/cli": { "optional": true + }, + "@react-native/metro-config": { + "optional": true } } }, - "node_modules/@react-native/community-cli-plugin/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-native/community-cli-plugin/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "node_modules/@react-native/debugger-frontend": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.9.tgz", - "integrity": "sha512-0Ru72Bm066xmxFuOXhhvrryxvb57uI79yDSFf+hxRpktkC98NMuRenlJhslMrbJ6WjCu1vOe/9UjWNYyxXTRTA==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.5.tgz", + "integrity": "sha512-bnd9FSdWKx2ncklOetCgrlwqSGhMHP2zOxObJbOWXoj7GHEmih4MKarBo5/a8gX8EfA1EwRATdfNBQ81DY+h+w==", + "license": "BSD-3-Clause", "engines": { - "node": ">=18" + "node": ">= 20.19.4" } }, "node_modules/@react-native/dev-middleware": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.9.tgz", - "integrity": "sha512-xkd3C3dRcmZLjFTEAOvC14q3apMLouIvJViCZY/p1EfCMrNND31dgE1dYrLTiI045WAWMt5bD15i6f7dE2/QWA==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.81.5.tgz", + "integrity": "sha512-WfPfZzboYgo/TUtysuD5xyANzzfka8Ebni6RIb2wDxhb56ERi7qDrE4xGhtPsjCL4pQBXSVxyIlCy0d8I6EgGA==", + "license": "MIT", "dependencies": { "@isaacs/ttlcache": "^1.4.1", - "@react-native/debugger-frontend": "0.76.9", + "@react-native/debugger-frontend": "0.81.5", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", - "debug": "^2.2.0", + "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", - "selfsigned": "^2.4.1", - "serve-static": "^1.13.1", + "serve-static": "^1.16.2", "ws": "^6.2.3" }, "engines": { - "node": ">=18" + "node": ">= 20.19.4" } }, - "node_modules/@react-native/dev-middleware/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@react-native/dev-middleware/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/@react-native/dev-middleware/node_modules/ws": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.4.tgz", - "integrity": "sha512-PNIUUyLI5YpkJZj60YBzX1o0ByQ4ovvfmq9N/Kig/PAYbVlGyz4R6G0SEWrD0O9acc0sT2+IdMBVLFv8FSi0Nw==", + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.6.tgz", + "integrity": "sha512-XTrf1gv7kXoVf1hbC3PAyAiPgR8Wz1blcrYIjEsUmr08BLksT41R8KbjmS9408C2ERx7v1JDLD/BkpLEttjfKA==", + "license": "MIT", "dependencies": { "async-limiter": "~1.0.0" } }, "node_modules/@react-native/gradle-plugin": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.9.tgz", - "integrity": "sha512-uGzp3dL4GfNDz+jOb8Nik1Vrfq1LHm0zESizrGhHACFiFlUSflVAnWuUAjlZlz5XfLhzGVvunG4Vdrpw8CD2ng==", - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/js-polyfills": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.9.tgz", - "integrity": "sha512-s6z6m8cK4SMjIX1hm8LT187aQ6//ujLrjzDBogqDCYXRbfjbAYovw5as/v2a2rhUIyJbS3UjokZm3W0H+Oh/RQ==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.81.5.tgz", + "integrity": "sha512-hORRlNBj+ReNMLo9jme3yQ6JQf4GZpVEBLxmTXGGlIL78MAezDZr5/uq9dwElSbcGmLEgeiax6e174Fie6qPLg==", + "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 20.19.4" } - }, - "node_modules/@react-native/metro-babel-transformer": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.9.tgz", - "integrity": "sha512-HGq11347UHNiO/NvVbAO35hQCmH8YZRs7in7nVq7SL99pnpZK4WXwLdAXmSuwz5uYqOuwnKYDlpadz8fkE94Mg==", - "dependencies": { - "@babel/core": "^7.25.2", - "@react-native/babel-preset": "0.76.9", - "hermes-parser": "0.23.1", - "nullthrows": "^1.1.1" - }, + }, + "node_modules/@react-native/js-polyfills": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.5.tgz", + "integrity": "sha512-fB7M1CMOCIUudTRuj7kzxIBTVw2KXnsgbQ6+4cbqSxo8NmRRhA0Ul4ZUzZj3rFd3VznTL4Brmocv1oiN0bWZ8w==", + "license": "MIT", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@babel/core": "*" + "node": ">= 20.19.4" } }, "node_modules/@react-native/normalize-colors": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.9.tgz", - "integrity": "sha512-TUdMG2JGk72M9d8DYbubdOlrzTYjw+YMe/xOnLU4viDgWRHsCbtRS9x0IAxRjs3amj/7zmK3Atm8jUPvdAc8qw==" + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.5.tgz", + "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==", + "license": "MIT" }, "node_modules/@react-native/virtualized-lists": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.9.tgz", - "integrity": "sha512-2neUfZKuqMK2LzfS8NyOWOyWUJOWgDym5fUph6fN9qF+LNPjAvnc4Zr9+o+59qjNu/yXwQgVMWNU4+8WJuPVWw==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", + "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==", + "license": "MIT", "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "engines": { - "node": ">=18" + "node": ">= 20.19.4" }, "peerDependencies": { - "@types/react": "^18.2.6", + "@types/react": "^19.1.0", "react": "*", "react-native": "*" }, @@ -2782,15 +2895,6 @@ } } }, - "node_modules/@segment/loosely-validate-event": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", - "integrity": "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==", - "dependencies": { - "component-type": "^1.2.1", - "join-component": "^1.1.0" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.10", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", @@ -2886,21 +2990,14 @@ "undici-types": "~8.3.0" } }, - "node_modules/@types/node-forge": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "version": "19.1.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz", + "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==", "dev": true, + "license": "MIT", "dependencies": { - "csstype": "^3.2.2" + "csstype": "^3.0.2" } }, "node_modules/@types/stack-utils": { @@ -2921,10 +3018,17 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "license": "ISC" + }, "node_modules/@urql/core": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz", "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==", + "license": "MIT", "dependencies": { "@0no-co/graphql.web": "^1.0.13", "wonka": "^6.3.2" @@ -2934,6 +3038,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz", "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==", + "license": "MIT", "dependencies": { "@urql/core": "^5.1.2", "wonka": "^6.3.2" @@ -2943,10 +3048,10 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", - "deprecated": "this version has critical issues, please update to the latest version", + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -2998,16 +3103,13 @@ "node": ">=0.4.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 14" } }, "node_modules/anser": { @@ -3019,6 +3121,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3033,6 +3136,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3065,7 +3169,8 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", @@ -3093,63 +3198,25 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, - "node_modules/ast-types": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", - "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/babel-core": { - "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -3243,30 +3310,28 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/babel-plugin-react-native-web": { - "version": "0.19.13", - "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.13.tgz", - "integrity": "sha512-4hHoto6xaN23LCyZgL9LJZc3olmAxd7b6jDzlZnKXAh4rRAbZRKNBJoOOdp46OBqgy+K0t0guTj5/mhA8inymQ==" - }, - "node_modules/babel-plugin-syntax-hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz", - "integrity": "sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==", + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "license": "MIT", "dependencies": { - "hermes-parser": "0.25.1" + "@babel/types": "^7.26.0" } }, - "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + "node_modules/babel-plugin-react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz", + "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==", + "license": "MIT" }, - "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.29.1.tgz", + "integrity": "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA==", + "license": "MIT", "dependencies": { - "hermes-estree": "0.25.1" + "hermes-parser": "0.29.1" } }, "node_modules/babel-plugin-transform-flow-enums": { @@ -3303,33 +3368,120 @@ } }, "node_modules/babel-preset-expo": { - "version": "12.0.12", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.12.tgz", - "integrity": "sha512-qAuaGGZIN//DyQVackP7Czr1SMq5dYb5tpu/uQqL/f1bRARb74r+kBWQRLJGxQ3QujsEw13SyAodCZIOUoD6KQ==", + "version": "54.0.12", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.12.tgz", + "integrity": "sha512-6xeSkdaixmQhWSYL7tfLu0pOS0BY+8ftwmdNSHtpEFSizrXYZkCjk/B6Dxr+6nwNRihixMcS0aBlWS1wlDl3pw==", + "license": "MIT", "dependencies": { + "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", - "@babel/plugin-transform-export-namespace-from": "^7.22.11", - "@babel/plugin-transform-object-rest-spread": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", "@babel/preset-react": "^7.22.15", "@babel/preset-typescript": "^7.23.0", - "@react-native/babel-preset": "0.76.9", - "babel-plugin-react-native-web": "~0.19.13", - "react-refresh": "^0.14.2" + "@react-native/babel-preset": "0.81.5", + "babel-plugin-react-compiler": "^1.0.0", + "babel-plugin-react-native-web": "~0.21.0", + "babel-plugin-syntax-hermes-parser": "^0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "debug": "^4.3.4", + "resolve-from": "^5.0.0" }, "peerDependencies": { - "babel-plugin-react-compiler": "^19.0.0-beta-9ee70a1-20241017", - "react-compiler-runtime": "^19.0.0-beta-8a03594-20241020" + "@babel/runtime": "^7.20.0", + "expo": "*", + "react-refresh": ">=0.14.0 <1.0.0" }, "peerDependenciesMeta": { - "babel-plugin-react-compiler": { + "@babel/runtime": { "optional": true }, - "react-compiler-runtime": { + "expo": { "optional": true } } }, + "node_modules/babel-preset-expo/node_modules/@react-native/babel-plugin-codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.81.5.tgz", + "integrity": "sha512-oF71cIH6je3fSLi6VPjjC3Sgyyn57JLHXs+mHWc9MoCiJJcM4nqsS5J38zv1XQ8d3zOW2JtHro+LF0tagj2bfQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@react-native/codegen": "0.81.5" + }, + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/babel-preset-expo/node_modules/@react-native/babel-preset": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.81.5.tgz", + "integrity": "sha512-UoI/x/5tCmi+pZ3c1+Ypr1DaRMDLI3y+Q70pVLLVgrnC3DHsHRIbHcCHIeG/IJvoeFqFM2sTdhSOLJrf8lOPrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.25.2", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/template": "^7.25.0", + "@react-native/babel-plugin-codegen": "0.81.5", + "babel-plugin-syntax-hermes-parser": "0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, "node_modules/babel-preset-jest": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", @@ -3384,6 +3536,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "license": "MIT", "dependencies": { "open": "^8.0.4" }, @@ -3395,6 +3548,7 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -3411,6 +3565,7 @@ "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", "engines": { "node": ">=0.6" } @@ -3421,17 +3576,19 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/bplist-creator": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", - "integrity": "sha512-xp/tcaV3T5PCiaY04mXga7o/TE+t95gqeLmADeBI1CvZtdWTbgBt3uLpvh4UWtenKeBhCV6oVxGk38yZr2uYEA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "license": "MIT", "dependencies": { - "stream-buffers": "~2.2.0" + "stream-buffers": "2.2.x" } }, "node_modules/bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "license": "MIT", "dependencies": { "big-integer": "1.6.x" }, @@ -3522,25 +3679,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3550,79 +3688,11 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "18.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", - "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "engines": { - "node": ">=4" - } - }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -3665,20 +3735,13 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "engines": { - "node": "*" - } - }, "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/chrome-launcher": { @@ -3736,18 +3799,11 @@ "node": ">=8" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, "node_modules/cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "license": "MIT", "dependencies": { "restore-cursor": "^2.0.0" }, @@ -3759,6 +3815,7 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -3812,23 +3869,11 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", "engines": { "node": ">=0.8" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3845,42 +3890,20 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/component-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.2.tgz", - "integrity": "sha512-99VUHREHiN5cLeHm3YLq312p6v+HUEcwtLCAtelvUDI6+SH5g5Cr85oNR2S1o6ywzL0ykMbuwLzM2ANocjEOIA==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -3892,6 +3915,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", @@ -3909,6 +3933,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -3916,12 +3941,14 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/compression/node_modules/negotiator": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3954,67 +3981,25 @@ } }, "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/core-js-compat": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", - "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", - "dependencies": { - "browserslist": "^4.28.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", - "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/cross-fetch": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", - "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "dependencies": { - "node-fetch": "^2.7.0" + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/cross-spawn": { @@ -4030,22 +4015,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "engines": { - "node": ">=8" - } - }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -4118,6 +4087,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -4126,26 +4096,16 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dependencies": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -4157,39 +4117,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4208,23 +4140,10 @@ } }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -4284,6 +4203,7 @@ "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -4295,6 +4215,7 @@ "version": "11.0.7", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "license": "BSD-2-Clause", "dependencies": { "dotenv": "^16.4.5" }, @@ -4305,24 +4226,6 @@ "url": "https://dotenvx.com" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4333,11 +4236,6 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.387.tgz", "integrity": "sha512-TaxwufTFDufvPEoXdhwVrA3UdFWBeWGkYoJ1K8ldF1xe6gKfth6iRNS5lTQ5JPNOHdGQm8PT1QYKUqFLCiUefQ==" }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -4346,14 +4244,6 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -4369,18 +4259,11 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz", "integrity": "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==", + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", @@ -4389,14 +4272,6 @@ "stackframe": "^1.3.4" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -4405,31 +4280,6 @@ "node": ">= 0.4" } }, - "node_modules/es-object-atoms": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", - "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -4482,111 +4332,32 @@ "node": ">=6" } }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/expo": { - "version": "52.0.49", - "resolved": "https://registry.npmjs.org/expo/-/expo-52.0.49.tgz", - "integrity": "sha512-ge3gUnuyGEePWWKzPY7TQ7FsvtFTdmsdYDHeBVUjMr9KIoQig/gf8A03oH26p3UtTL6sUJcyOIg9vwIHGNPSUw==", + "version": "54.0.36", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.36.tgz", + "integrity": "sha512-HMHp1H+actmnX85NJE6lILKzSJV6pTDNkwghq9EMOP3zTynjvBYVqJGSLlm6sEVzJCC5Z2ZiKgLvtsHrqlY0dg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.22.28", - "@expo/config": "~10.0.11", - "@expo/config-plugins": "~9.0.17", - "@expo/fingerprint": "0.11.11", - "@expo/metro-config": "0.19.12", - "@expo/vector-icons": "~14.0.4", - "babel-preset-expo": "~12.0.12", - "expo-asset": "~11.0.5", - "expo-constants": "~17.0.8", - "expo-file-system": "~18.0.12", - "expo-font": "~13.0.4", - "expo-keep-awake": "~14.0.3", - "expo-modules-autolinking": "2.0.8", - "expo-modules-core": "2.2.3", - "fbemitter": "^3.0.0", - "web-streams-polyfill": "^3.3.2", + "@expo/cli": "54.0.26", + "@expo/config": "~12.0.14", + "@expo/config-plugins": "~54.0.5", + "@expo/devtools": "0.1.8", + "@expo/fingerprint": "0.15.5", + "@expo/metro": "~54.2.0", + "@expo/metro-config": "54.0.17", + "@expo/vector-icons": "^15.0.3", + "@ungap/structured-clone": "^1.3.0", + "babel-preset-expo": "~54.0.12", + "expo-asset": "~12.0.13", + "expo-constants": "~18.0.13", + "expo-file-system": "~19.0.23", + "expo-font": "~14.0.12", + "expo-keep-awake": "~15.0.8", + "expo-modules-autolinking": "3.0.26", + "expo-modules-core": "3.0.30", + "pretty-format": "^29.7.0", + "react-refresh": "^0.14.2", "whatwg-url-without-unicode": "8.0.0-3" }, "bin": { @@ -4614,14 +4385,13 @@ } }, "node_modules/expo-asset": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.0.5.tgz", - "integrity": "sha512-TL60LmMBGVzs3NQcO8ylWqBumMh4sx0lmeJsn7+9C88fylGDhyyVnKZ1PyTXo9CVDBkndutZx2JUEQWM9BaiXw==", + "version": "12.0.13", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.13.tgz", + "integrity": "sha512-x/p7WvQUnkn6K43b9eL6SPeq5Vnf1E8BDe9bDrWrvMqzyUvJnUFvl+ctg3034s/+UHe7Ne2pAmc0+yzbl8CrDQ==", + "license": "MIT", "dependencies": { - "@expo/image-utils": "^0.6.5", - "expo-constants": "~17.0.8", - "invariant": "^2.2.4", - "md5-file": "^3.2.3" + "@expo/image-utils": "^0.8.8", + "expo-constants": "~18.0.13" }, "peerDependencies": { "expo": "*", @@ -4630,12 +4400,13 @@ } }, "node_modules/expo-constants": { - "version": "17.0.8", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.8.tgz", - "integrity": "sha512-XfWRyQAf1yUNgWZ1TnE8pFBMqGmFP5Gb+SFSgszxDdOoheB/NI5D4p7q86kI2fvGyfTrxAe+D+74nZkfsGvUlg==", + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", + "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", + "license": "MIT", "dependencies": { - "@expo/config": "~10.0.11", - "@expo/env": "~0.4.2" + "@expo/config": "~12.0.13", + "@expo/env": "~2.0.8" }, "peerDependencies": { "expo": "*", @@ -4643,49 +4414,48 @@ } }, "node_modules/expo-file-system": { - "version": "18.0.12", - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.12.tgz", - "integrity": "sha512-HAkrd/mb8r+G3lJ9MzmGeuW2B+BxQR1joKfeCyY4deLl1zoZ48FrAWjgZjHK9aHUVhJ0ehzInu/NQtikKytaeg==", - "dependencies": { - "web-streams-polyfill": "^3.3.2" - }, + "version": "19.0.23", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.23.tgz", + "integrity": "sha512-MeGkid9OeNILfT/qonaXHp4f2c15xaB28U/bcN7pqZej0Kx0+6+V7e9ZIXpPHm07zVatxA+QkMTPQEGfmvVOxA==", + "license": "MIT", "peerDependencies": { "expo": "*", "react-native": "*" } }, "node_modules/expo-font": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-13.0.4.tgz", - "integrity": "sha512-eAP5hyBgC8gafFtprsz0HMaB795qZfgJWqTmU0NfbSin1wUuVySFMEPMOrTkTgmazU73v4Cb4x7p86jY1XXYUw==", + "version": "14.0.12", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.12.tgz", + "integrity": "sha512-QQzunE2Mxk45AsCWm3tK7OpVljbtVnKD58q4/qliev+cbye1IOduUnRIdD+P7DyButw17G9MTX795kgaQiz5hQ==", + "license": "MIT", "dependencies": { "fontfaceobserver": "^2.1.0" }, "peerDependencies": { "expo": "*", - "react": "*" + "react": "*", + "react-native": "*" } }, "node_modules/expo-keep-awake": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-14.0.3.tgz", - "integrity": "sha512-6Jh94G6NvTZfuLnm2vwIpKe3GdOiVBuISl7FI8GqN0/9UOg9E0WXXp5cDcfAG8bn80RfgLJS8P7EPUGTZyOvhg==", + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", + "integrity": "sha512-YK9M1VrnoH1vLJiQzChZgzDvVimVoriibiDIFLbQMpjYBnvyfUeHJcin/Gx1a+XgupNXy92EQJLgI/9ZuXajYQ==", + "license": "MIT", "peerDependencies": { "expo": "*", "react": "*" } }, "node_modules/expo-modules-autolinking": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.8.tgz", - "integrity": "sha512-DezgnEYFQYic8hKGhkbztBA3QUmSftjaNDIKNAtS2iGJmzCcNIkatjN2slFDSWjSTNo8gOvPQyMKfyHWFvLpOQ==", + "version": "3.0.26", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.26.tgz", + "integrity": "sha512-WOaud6UKg16ciCOj8raKcMOoKFMHLXKI29U29yhgu1lf+Y7VxJyCktUcYo6AM+ccZ7zLD1uWZdMtgnpf+95OXA==", + "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.1.0", "commander": "^7.2.0", - "fast-glob": "^3.2.5", - "find-up": "^5.0.0", - "fs-extra": "^9.1.0", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0" }, @@ -4693,51 +4463,36 @@ "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, - "node_modules/expo-modules-autolinking/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/expo-modules-autolinking/node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "node_modules/expo-modules-core": { + "version": "3.0.30", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.30.tgz", + "integrity": "sha512-a6IrpAn/Jbmwxi9L+hMmXKpNqnkUpoF7WHOpn02rVLyax2J0gB1vvCVE5rNydplEnt41Q6WxQwvcOjZaIkcSUg==", + "license": "MIT", "dependencies": { - "universalify": "^2.0.0" + "invariant": "^2.2.4" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "peerDependencies": { + "react": "*", + "react-native": "*" } }, - "node_modules/expo-modules-autolinking/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/expo-server": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.7.tgz", + "integrity": "sha512-mcmyML3oXcqFUXUxtdtCL1O00ztNI2v76d+MdniXRUgHNxIcHZ05zo+DqBaOOT6LQnPk4vA4YHqQl7iGUfRb3g==", + "license": "MIT", "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/expo-modules-core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.2.3.tgz", - "integrity": "sha512-01QqZzpP/wWlxnNly4G06MsOBUTbMDj02DQigZoXfDh80vd/rk3/uVXqnZgOdLSggTs6DnvOgAUy0H2q30XdUg==", - "dependencies": { - "invariant": "^2.2.4" + "node": ">=20.16.0" } }, "node_modules/expo-status-bar": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.1.tgz", - "integrity": "sha512-AkIPX7jWHRPp83UBZ1iXtVvyr0g+DgBVvIXTtlmPtmUsm8Vq9Bb5IGj86PW8osuFlgoTVAg7HI/+Ok7yEYwiRg==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.9.tgz", + "integrity": "sha512-xyYyVg6V1/SSOZWh4Ni3U129XHCnFHBTcUo0dhWtFDrZbNp/duw5AGsQfb2sVeU0gxWHXSY1+5F0jnKYC7WuOw==", + "license": "MIT", + "dependencies": { + "react-native-is-edge-to-edge": "^1.2.1" + }, "peerDependencies": { "react": "*", "react-native": "*" @@ -4748,34 +4503,11 @@ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -4784,38 +4516,23 @@ "bser": "2.1.1" } }, - "node_modules/fbemitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", - "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", - "dependencies": { - "fbjs": "^3.0.0" - } - }, - "node_modules/fbjs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", - "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", - "dependencies": { - "cross-fetch": "^3.1.5", - "fbjs-css-vars": "^1.0.0", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^1.0.35" + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/fbjs-css-vars": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" - }, - "node_modules/fetch-retry": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-4.1.1.tgz", - "integrity": "sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==" - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4844,110 +4561,35 @@ "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flow-enums-runtime": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", - "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==" - }, - "node_modules/flow-estree": { - "version": "0.321.0", - "resolved": "https://registry.npmjs.org/flow-estree/-/flow-estree-0.321.0.tgz", - "integrity": "sha512-rQY7YKoo+PKpAHQjEP2cxyIefk04OCEKUlbtV4y6LAUG3Ly7guQX9YH8th6drSmYcNkMgpqWMaHRhhYaAF69CA==", - "engines": { - "node": ">=18" - } - }, - "node_modules/flow-parser": { - "version": "0.321.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.321.0.tgz", - "integrity": "sha512-9LNK2rp/NWWbwdEK6mxC54XfQRyD2lVV0iPVBYf+5o5vvqJl7ietkR1hX3/dZ39j0GAbL4PIFoeekDViOW0x/Q==", - "dependencies": { - "flow-estree": "0.321.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/fontfaceobserver": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", - "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==" - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.5.tgz", - "integrity": "sha512-j23EibVLnp4zNXGW7LjryXYa2X6U/M96yoOX+ybZxwkYajdxRNEqYY3zhh7y0i6kfISKS2jr+EJq1YTUDEv5+w==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.4", - "mime-types": "^2.1.35" - }, - "engines": { - "node": ">= 6" + "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==" + }, + "node_modules/fontfaceobserver": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", + "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==", + "license": "BSD-2-Clause" + }, "node_modules/freeport-async": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz", "integrity": "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4960,30 +4602,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5026,29 +4644,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -5057,118 +4652,66 @@ "node": ">=8.0.0" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/getenv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/getenv/-/getenv-1.0.0.tgz", - "integrity": "sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz", + "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "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", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", "engines": { - "node": ">= 6" + "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.2" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "18 || 20 || >=22" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "engines": { - "node": ">= 0.4" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/graceful-fs": { @@ -5184,31 +4727,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", @@ -5221,22 +4739,25 @@ } }, "node_modules/hermes-estree": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz", - "integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==" + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" }, "node_modules/hermes-parser": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz", - "integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==", + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", "dependencies": { - "hermes-estree": "0.23.1" + "hermes-estree": "0.29.1" } }, "node_modules/hosted-git-info": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -5247,7 +4768,8 @@ "node_modules/hosted-git-info/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" }, "node_modules/http-errors": { "version": "2.0.1", @@ -5276,12 +4798,17 @@ "node": ">= 0.8" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, "engines": { - "node": ">=10.17.0" + "node": ">= 14" } }, "node_modules/ieee754": { @@ -5307,6 +4834,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -5325,26 +4853,6 @@ "node": ">=16.x" } }, - "node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "engines": { - "node": ">=4" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5353,14 +4861,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5379,19 +4879,8 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dependencies": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "engines": { - "node": ">=6" - } + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" }, "node_modules/invariant": { "version": "2.2.4", @@ -5401,32 +4890,6 @@ "loose-envify": "^1.0.0" } }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/is-core-module": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", @@ -5441,14 +4904,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -5463,14 +4918,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5479,17 +4926,6 @@ "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5498,22 +4934,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -5522,25 +4942,6 @@ "node": ">=8" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5557,14 +4958,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -5596,20 +4989,6 @@ "semver": "bin/semver.js" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -5796,12 +5175,8 @@ "node_modules/jimp-compact": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", - "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==" - }, - "node_modules/join-component": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz", - "integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==" + "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -5822,6 +5197,7 @@ "url": "https://github.com/sponsors/nodeca" } ], + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -5829,48 +5205,11 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsc-android": { - "version": "250231.0.0", - "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", - "integrity": "sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==" - }, "node_modules/jsc-safe-url": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==" }, - "node_modules/jscodeshift": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.14.0.tgz", - "integrity": "sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==", - "dependencies": { - "@babel/core": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/preset-flow": "^7.13.13", - "@babel/preset-typescript": "^7.13.0", - "@babel/register": "^7.13.16", - "babel-core": "^7.0.0-bridge.0", - "chalk": "^4.1.2", - "flow-parser": "0.*", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "neo-async": "^2.5.0", - "node-dir": "^0.1.17", - "recast": "^0.21.0", - "temp": "^0.8.4", - "write-file-atomic": "^2.3.0" - }, - "bin": { - "jscodeshift": "bin/jscodeshift.js" - }, - "peerDependencies": { - "@babel/preset-env": "^7.1.6" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -5882,11 +5221,6 @@ "node": ">=6" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -5898,30 +5232,24 @@ "node": ">=6" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/lan-network": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.2.1.tgz", + "integrity": "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==", + "license": "MIT", + "bin": { + "lan-network": "dist/lan-network-cli.js" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -5953,11 +5281,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/lightningcss": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", - "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "license": "MPL-2.0", "dependencies": { - "detect-libc": "^1.0.3" + "detect-libc": "^2.0.3" }, "engines": { "node": ">= 12.0.0" @@ -5967,25 +5296,47 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.27.0", - "lightningcss-darwin-x64": "1.27.0", - "lightningcss-freebsd-x64": "1.27.0", - "lightningcss-linux-arm-gnueabihf": "1.27.0", - "lightningcss-linux-arm64-gnu": "1.27.0", - "lightningcss-linux-arm64-musl": "1.27.0", - "lightningcss-linux-x64-gnu": "1.27.0", - "lightningcss-linux-x64-musl": "1.27.0", - "lightningcss-win32-arm64-msvc": "1.27.0", - "lightningcss-win32-x64-msvc": "1.27.0" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", - "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -5999,12 +5350,13 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", - "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -6018,12 +5370,13 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", - "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], + "license": "MPL-2.0", "optional": true, "os": [ "freebsd" @@ -6037,12 +5390,13 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", - "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6056,12 +5410,13 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", - "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6075,12 +5430,13 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", - "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6094,12 +5450,13 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", - "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6113,12 +5470,13 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", - "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6132,12 +5490,13 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", - "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], + "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -6151,12 +5510,13 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", - "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], + "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -6166,28 +5526,15 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/parcel" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -6202,6 +5549,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "license": "MIT", "dependencies": { "chalk": "^2.0.1" }, @@ -6213,6 +5561,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -6224,6 +5573,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6237,6 +5587,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -6244,12 +5595,14 @@ "node_modules/log-symbols/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/log-symbols/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -6258,6 +5611,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } @@ -6266,6 +5620,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -6292,26 +5647,6 @@ "yallist": "^3.0.2" } }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -6325,38 +5660,6 @@ "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==" }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/md5-file": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz", - "integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==", - "dependencies": { - "buffer-alloc": "^1.1.0" - }, - "bin": { - "md5-file": "cli.js" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -6383,53 +5686,45 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, "node_modules/metro": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro/-/metro-0.81.5.tgz", - "integrity": "sha512-YpFF0DDDpDVygeca2mAn7K0+us+XKmiGk4rIYMz/CRdjFoCGqAei/IQSpV0UrGfQbToSugpMQeQJveaWSH88Hg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.7.tgz", + "integrity": "sha512-SPaPEyvTsTmd0LpT7RaZciQyDw2i/JB7+iY9L5VfBo72+psescFxBqpI1TL9dnL+pmnfkU+l/J1mEEGLeF65EQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", + "@babel/code-frame": "^7.29.0", "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.3", - "@babel/types": "^7.25.2", - "accepts": "^1.3.7", - "chalk": "^4.0.0", + "@babel/generator": "^7.29.1", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "accepts": "^2.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", - "debug": "^2.2.0", + "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", - "hermes-parser": "0.25.1", + "hermes-parser": "0.35.0", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", - "metro-babel-transformer": "0.81.5", - "metro-cache": "0.81.5", - "metro-cache-key": "0.81.5", - "metro-config": "0.81.5", - "metro-core": "0.81.5", - "metro-file-map": "0.81.5", - "metro-resolver": "0.81.5", - "metro-runtime": "0.81.5", - "metro-source-map": "0.81.5", - "metro-symbolicate": "0.81.5", - "metro-transform-plugins": "0.81.5", - "metro-transform-worker": "0.81.5", - "mime-types": "^2.1.27", + "metro-babel-transformer": "0.83.7", + "metro-cache": "0.83.7", + "metro-cache-key": "0.83.7", + "metro-config": "0.83.7", + "metro-core": "0.83.7", + "metro-file-map": "0.83.7", + "metro-resolver": "0.83.7", + "metro-runtime": "0.83.7", + "metro-source-map": "0.83.7", + "metro-symbolicate": "0.83.7", + "metro-transform-plugins": "0.83.7", + "metro-transform-worker": "0.83.7", + "mime-types": "^3.0.1", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", @@ -6441,97 +5736,107 @@ "metro": "src/cli.js" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-babel-transformer": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.5.tgz", - "integrity": "sha512-oKCQuajU5srm+ZdDcFg86pG/U8hkSjBlkyFjz380SZ4TTIiI5F+OQB830i53D8hmqmcosa4wR/pnKv8y4Q3dLw==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.7.tgz", + "integrity": "sha512-sBqBkt6kNut/88bv+Ucvm4yqdPetbvAEsHzi3MAgJEifOSYYzX5Z5Kgw3TFOrwf/mHJTOBG2ONlaMHoyfP15TA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", - "hermes-parser": "0.25.1", + "hermes-parser": "0.35.0", + "metro-cache-key": "0.83.7", "nullthrows": "^1.1.1" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-babel-transformer/node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz", + "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==", + "license": "MIT" }, "node_modules/metro-babel-transformer/node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz", + "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==", + "license": "MIT", "dependencies": { - "hermes-estree": "0.25.1" + "hermes-estree": "0.35.0" } }, "node_modules/metro-cache": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.5.tgz", - "integrity": "sha512-wOsXuEgmZMZ5DMPoz1pEDerjJ11AuMy9JifH4yNW7NmWS0ghCRqvDxk13LsElzLshey8C+my/tmXauXZ3OqZgg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.7.tgz", + "integrity": "sha512-E9SRePXQ1Zvlj79VcOk57q7VC7rMHMFQ+jhmPHBiq+dJ0bJB5BL87lWZF6oh5X76Cci5tpDuQNaDwwuSCToEeg==", + "license": "MIT", "dependencies": { "exponential-backoff": "^3.1.1", "flow-enums-runtime": "^0.0.6", - "metro-core": "0.81.5" + "https-proxy-agent": "^7.0.5", + "metro-core": "0.83.7" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-cache-key": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.5.tgz", - "integrity": "sha512-lGWnGVm1UwO8faRZ+LXQUesZSmP1LOg14OVR+KNPBip8kbMECbQJ8c10nGesw28uQT7AE0lwQThZPXlxDyCLKQ==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.7.tgz", + "integrity": "sha512-W1c2Nmx8MiJTJt+eWhMO08z9VKi3kZOaz99IYGdqeqDgY9j+yZjXl62rUav4Di0heZfh4/n2s722PqRL1OODeg==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-config": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.5.tgz", - "integrity": "sha512-oDRAzUvj6RNRxratFdcVAqtAsg+T3qcKrGdqGZFUdwzlFJdHGR9Z413sW583uD2ynsuOjA2QB6US8FdwiBdNKg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.7.tgz", + "integrity": "sha512-83mjWFbFOt2GeJ6pFIum5mSnc1uTsZJAtD8o4ej0s4NVsYsA7fB+pHvTfHhFrpeMONaobu2riKavkPei05Er/Q==", + "license": "MIT", "dependencies": { "connect": "^3.6.5", - "cosmiconfig": "^5.0.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", - "metro": "0.81.5", - "metro-cache": "0.81.5", - "metro-core": "0.81.5", - "metro-runtime": "0.81.5" + "metro": "0.83.7", + "metro-cache": "0.83.7", + "metro-core": "0.83.7", + "metro-runtime": "0.83.7", + "yaml": "^2.6.1" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-core": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.5.tgz", - "integrity": "sha512-+2R0c8ByfV2N7CH5wpdIajCWa8escUFd8TukfoXyBq/vb6yTCsznoA25FhNXJ+MC/cz1L447Zj3vdUfCXIZBwg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.7.tgz", + "integrity": "sha512-6yn3w1wnltT6RQl7p7YES2l95ArC+mWrOssEiH8p5/DDrJS65/szf9LsC9JrBv8c5DdvSY3V3f0GRYg0Ox7hCg==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", "lodash.throttle": "^4.1.1", - "metro-resolver": "0.81.5" + "metro-resolver": "0.83.7" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-file-map": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.5.tgz", - "integrity": "sha512-mW1PKyiO3qZvjeeVjj1brhkmIotObA3/9jdbY1fQQYvEWM6Ml7bN/oJCRDGn2+bJRlG+J8pwyJ+DgdrM4BsKyg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.7.tgz", + "integrity": "sha512-+j0F1m+FQYVAQ6syf+mwhIPV5GoFQrkInX8bppuc50IzNsZbMrp8R5H/Sx/K2daQ3YEa9F/XwkeZT8gzJfgeCw==", + "license": "MIT", "dependencies": { - "debug": "^2.2.0", + "debug": "^4.4.0", "fb-watchman": "^2.0.0", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", @@ -6542,85 +5847,76 @@ "walker": "^1.0.7" }, "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-file-map/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node": ">=20.19.4" } }, - "node_modules/metro-file-map/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/metro-minify-terser": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.5.tgz", - "integrity": "sha512-/mn4AxjANnsSS3/Bb+zA1G5yIS5xygbbz/OuPaJYs0CPcZCaWt66D+65j4Ft/nJkffUxcwE9mk4ubpkl3rjgtw==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.7.tgz", + "integrity": "sha512-MfJar2IS4tBRuLb9svwb0Gu5l9BsH+pcRm8eGcEi/wy8MzZinfinh5dFLt2nWkocnulIgtGB5NkFDdbXqMXKhQ==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", "terser": "^5.15.0" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-resolver": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.5.tgz", - "integrity": "sha512-6BX8Nq3g3go3FxcyXkVbWe7IgctjDTk6D9flq+P201DfHHQ28J+DWFpVelFcrNTn4tIfbP/Bw7u/0g2BGmeXfQ==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.7.tgz", + "integrity": "sha512-WSJIENlMcoSsuz66IfBHOkgfp3KJt2UW2TnEHPf1b8pIG2eEXNOVmo2+03A0H17WY2XGXWgxL0CG7FAopqgB1A==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-runtime": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.5.tgz", - "integrity": "sha512-M/Gf71ictUKP9+77dV/y8XlAWg7xl76uhU7ggYFUwEdOHHWPG6gLBr1iiK0BmTjPFH8yRo/xyqMli4s3oGorPQ==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.7.tgz", + "integrity": "sha512-9GKkJURaB2iyYoEExKnedzAHzxmKtSi+k0tsZUvMoU27tBZJElchYt7JH/Ai/XzYAI9lCAaV7u5HZSI8J5Z+wQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-source-map": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.5.tgz", - "integrity": "sha512-Jz+CjvCKLNbJZYJTBeN3Kq9kIJf6b61MoLBdaOQZJ5Ajhw6Pf95Nn21XwA8BwfUYgajsi6IXsp/dTZsYJbN00Q==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.7.tgz", + "integrity": "sha512-JgA1h7oc1a1jydBe1GhVFsUoMYo3wLPk7oRA32rjlDsq+sP2JLt9x2p2lWbNSxTm/u8NV4VRid3hvEJgcX8tKw==", + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.3", - "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", - "@babel/types": "^7.25.2", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", - "metro-symbolicate": "0.81.5", + "metro-symbolicate": "0.83.7", "nullthrows": "^1.1.1", - "ob1": "0.81.5", + "ob1": "0.83.7", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-symbolicate": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.5.tgz", - "integrity": "sha512-X3HV3n3D6FuTE11UWFICqHbFMdTavfO48nXsSpnNGFkUZBexffu0Xd+fYKp+DJLNaQr3S+lAs8q9CgtDTlRRuA==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.7.tgz", + "integrity": "sha512-g4suyxw20WOHWI680c+Kq4wC/NF+Hx5pRH9afrMp+sMTxqLeKcPR1Xf4wMhsjlbvx7LbIREdke6q928jEjvJWw==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", - "metro-source-map": "0.81.5", + "metro-source-map": "0.83.7", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" @@ -6629,52 +5925,55 @@ "metro-symbolicate": "src/index.js" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-transform-plugins": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.5.tgz", - "integrity": "sha512-MmHhVx/1dJC94FN7m3oHgv5uOjKH8EX8pBeu1pnPMxbJrx6ZuIejO0k84zTSaQTZ8RxX1wqwzWBpXAWPjEX8mA==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.7.tgz", + "integrity": "sha512-Ss0FpBiZDjX2kwhukMDl5sNdYK8T/06IPqxNE4H6PTlRlfs9q11cef13c/xESY/Pm4VCkp1yJUZO3kXzvMxQFA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.3", + "@babel/generator": "^7.29.1", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", "flow-enums-runtime": "^0.0.6", "nullthrows": "^1.1.1" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro-transform-worker": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.5.tgz", - "integrity": "sha512-lUFyWVHa7lZFRSLJEv+m4jH8WrR5gU7VIjUlg4XmxQfV8ngY4V10ARKynLhMYPeQGl7Qvf+Ayg0eCZ272YZ4Mg==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.7.tgz", + "integrity": "sha512-UegCo7ygB2fT64mRK2nbAjQVJ1zSwIIHy8d96jJv2nKZFDaViYBiughEdu5HM/Ceq0WN3LZrZk3zhl9aoiLYFw==", + "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/types": "^7.25.2", + "@babel/generator": "^7.29.1", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", - "metro": "0.81.5", - "metro-babel-transformer": "0.81.5", - "metro-cache": "0.81.5", - "metro-cache-key": "0.81.5", - "metro-minify-terser": "0.81.5", - "metro-source-map": "0.81.5", - "metro-transform-plugins": "0.81.5", + "metro": "0.83.7", + "metro-babel-transformer": "0.83.7", + "metro-cache": "0.83.7", + "metro-cache-key": "0.83.7", + "metro-minify-terser": "0.83.7", + "metro-source-map": "0.83.7", + "metro-transform-plugins": "0.83.7", "nullthrows": "^1.1.1" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/metro/node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", @@ -6684,41 +5983,70 @@ "node": ">=6.9.0" } }, - "node_modules/metro/node_modules/ci-info": { + "node_modules/metro/node_modules/accepts": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "node_modules/metro/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" } }, + "node_modules/metro/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT" + }, "node_modules/metro/node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==" + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz", + "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==", + "license": "MIT" }, "node_modules/metro/node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz", + "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==", + "license": "MIT", "dependencies": { - "hermes-estree": "0.25.1" + "hermes-estree": "0.35.0" } }, - "node_modules/metro/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "node_modules/metro/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/metro/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, "node_modules/metro/node_modules/ws": { - "version": "7.5.11", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", - "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -6773,6 +6101,7 @@ "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6800,6 +6129,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -6827,112 +6157,21 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", - "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "node": ">= 18" } }, "node_modules/ms": { @@ -6944,6 +6183,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -6951,15 +6191,16 @@ } }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -6975,50 +6216,11 @@ "node": ">= 0.6" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, "node_modules/nested-error-stacks": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz", - "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", - "dependencies": { - "minimatch": "^3.0.2" - }, - "engines": { - "node": ">= 0.10.5" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } + "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==", + "license": "MIT" }, "node_modules/node-forge": { "version": "1.4.0", @@ -7053,6 +6255,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "license": "ISC", "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", @@ -7063,25 +6266,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "engines": { - "node": ">=4" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -7099,20 +6283,22 @@ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "node_modules/ob1": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.5.tgz", - "integrity": "sha512-iNpbeXPLmaiT9I5g16gFFFjsF3sGxLpYG2EGP3dfFB4z+l9X60mp/yRzStHhMtuNt8qmf7Ww80nOPQHngHhnIQ==", + "version": "0.83.7", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.7.tgz", + "integrity": "sha512-9M5kpuOLyTPogMtZiQUIxdAZxl7Dxs6tVBbJErSumsqGMuhVSoUbkfeZ3XNPpLpwBBtqY5QDUzGwggLHX3slQg==", + "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" }, "engines": { - "node": ">=18.18" + "node": ">=20.19.4" } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7132,6 +6318,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7148,6 +6335,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "license": "MIT", "dependencies": { "mimic-fn": "^1.0.0" }, @@ -7174,6 +6362,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "license": "MIT", "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", @@ -7186,18 +6375,11 @@ "node": ">=6" } }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "engines": { - "node": ">=6" - } - }, "node_modules/ora/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -7209,6 +6391,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -7222,6 +6405,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -7229,12 +6413,14 @@ "node_modules/ora/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/ora/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -7243,25 +6429,16 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/ora/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -7269,18 +6446,11 @@ "node": ">=4" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7291,34 +6461,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -7327,27 +6469,11 @@ "node": ">=6" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/parse-png": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==", + "license": "MIT", "dependencies": { "pngjs": "^3.3.0" }, @@ -7393,31 +6519,28 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": "20 || >=22" } }, "node_modules/picocolors": { @@ -7426,24 +6549,17 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.2.tgz", - "integrity": "sha512-cfDHL6LStTEKlNilboNtobT/kEa30PtAf2Q1OgszfrG/rpVl1xaFWT9ktfkS306GmHgmnad1Sw4wabhlvFtsTw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", @@ -7452,77 +6568,11 @@ "node": ">= 6" } }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, "node_modules/plist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", + "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.9.10", "base64-js": "^1.5.1", @@ -7536,22 +6586,16 @@ "version": "0.9.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", "engines": { "node": ">=14.6" } }, - "node_modules/plist/node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "engines": { - "node": ">=8.0" - } - }, "node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -7574,6 +6618,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", @@ -7587,6 +6632,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -7622,6 +6668,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -7630,22 +6677,16 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dependencies": { - "asap": "~2.0.3" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -7654,30 +6695,6 @@ "node": ">= 6" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7702,25 +6719,6 @@ "inherits": "~2.0.3" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -7733,6 +6731,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -7744,29 +6743,29 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-devtools-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-5.3.2.tgz", - "integrity": "sha512-crr9HkVrDiJ0A4zot89oS0Cgv0Oa4OG1Em4jit3P3ZxZSKPMYyMjfwMqgcJna9o625g8oN87rBm8SWWrSTBZxg==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz", + "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==", + "license": "MIT", "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "node_modules/react-devtools-core/node_modules/ws": { - "version": "7.5.11", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", - "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -7789,43 +6788,40 @@ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-native": { - "version": "0.76.9", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.9.tgz", - "integrity": "sha512-+LRwecWmTDco7OweGsrECIqJu0iyrREd6CTCgC/uLLYipiHvk+MH9nd6drFtCw/6Blz6eoKTcH9YTTJusNtrWg==", - "dependencies": { - "@jest/create-cache-key-function": "^29.6.3", - "@react-native/assets-registry": "0.76.9", - "@react-native/codegen": "0.76.9", - "@react-native/community-cli-plugin": "0.76.9", - "@react-native/gradle-plugin": "0.76.9", - "@react-native/js-polyfills": "0.76.9", - "@react-native/normalize-colors": "0.76.9", - "@react-native/virtualized-lists": "0.76.9", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz", + "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==", + "license": "MIT", + "dependencies": { + "@jest/create-cache-key-function": "^29.7.0", + "@react-native/assets-registry": "0.81.5", + "@react-native/codegen": "0.81.5", + "@react-native/community-cli-plugin": "0.81.5", + "@react-native/gradle-plugin": "0.81.5", + "@react-native/js-polyfills": "0.81.5", + "@react-native/normalize-colors": "0.81.5", + "@react-native/virtualized-lists": "0.81.5", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-jest": "^29.7.0", - "babel-plugin-syntax-hermes-parser": "^0.23.1", + "babel-plugin-syntax-hermes-parser": "0.29.1", "base64-js": "^1.5.1", - "chalk": "^4.0.0", "commander": "^12.0.0", - "event-target-shim": "^5.0.1", "flow-enums-runtime": "^0.0.6", "glob": "^7.1.1", "invariant": "^2.2.4", - "jest-environment-node": "^29.6.3", - "jsc-android": "^250231.0.0", + "jest-environment-node": "^29.7.0", "memoize-one": "^5.0.0", - "metro-runtime": "^0.81.0", - "metro-source-map": "^0.81.0", - "mkdirp": "^0.5.1", + "metro-runtime": "^0.83.1", + "metro-source-map": "^0.83.1", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", - "react-devtools-core": "^5.3.1", + "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", - "scheduler": "0.24.0-canary-efb381bbf-20230505", + "scheduler": "0.26.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0", @@ -7836,11 +6832,11 @@ "react-native": "cli.js" }, "engines": { - "node": ">=18" + "node": ">= 20.19.4" }, "peerDependencies": { - "@types/react": "^18.2.6", - "react": "^18.2.0" + "@types/react": "^19.1.0", + "react": "^19.1.0" }, "peerDependenciesMeta": { "@types/react": { @@ -7848,10 +6844,21 @@ } } }, + "node_modules/react-native-is-edge-to-edge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.3.1.tgz", + "integrity": "sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-svg": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.8.0.tgz", - "integrity": "sha512-KHJzKpgOjwj1qeZzsBjxNdoIgv2zNCO9fVcoq2TEhTRsVV5DGTZ9JzUZwybd7q4giT/H3RdtqC3u44dWdO0Ffw==", + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.1.tgz", + "integrity": "sha512-vCuZJDf8a5aNC2dlMovEv4Z0jjEUET53lm/iILFnFewa15b4atjVxU6Wirm6O9y6dEsdjDZVD7Q3QM4T1wlI8g==", + "license": "MIT", "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", @@ -7863,9 +6870,10 @@ } }, "node_modules/react-native-webview": { - "version": "13.12.5", - "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.12.5.tgz", - "integrity": "sha512-INOKPom4dFyzkbxbkuQNfeRG9/iYnyRDzrDkJeyvSWgJAW2IDdJkWFJBS2v0RxIL4gqLgHkiIZDOfiLaNnw83Q==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.15.0.tgz", + "integrity": "sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ==", + "license": "MIT", "dependencies": { "escape-string-regexp": "^4.0.0", "invariant": "2.2.4" @@ -7875,14 +6883,6 @@ "react-native": "*" } }, - "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz", - "integrity": "sha512-uNLD0tk2tLUjGFdmCk+u/3FEw2o+BAwW4g+z2QVlxJrzZYOOPADroEcNtTPt5lNiScctaUmnsTkVEnOwZUOLhA==", - "dependencies": { - "hermes-parser": "0.23.1" - } - }, "node_modules/react-native/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -7935,33 +6935,6 @@ "node": ">=0.10.0" } }, - "node_modules/readline": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", - "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" - }, - "node_modules/recast": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.21.5.tgz", - "integrity": "sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==", - "dependencies": { - "ast-types": "0.15.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/recast/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -8015,11 +6988,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/remove-trailing-slash": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz", - "integrity": "sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==" - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8032,6 +7000,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8053,6 +7022,7 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "license": "MIT", "dependencies": { "path-parse": "^1.0.5" } @@ -8088,12 +7058,14 @@ "node_modules/resolve-workspace-root": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz", - "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==" + "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==", + "license": "MIT" }, "node_modules/resolve.exports": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "license": "MIT", "engines": { "node": ">=10" } @@ -8102,6 +7074,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "license": "MIT", "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -8110,20 +7083,6 @@ "node": ">=4" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8159,28 +7118,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8198,35 +7135,23 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" } }, "node_modules/scheduler": { - "version": "0.24.0-canary-efb381bbf-20230505", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz", - "integrity": "sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" }, "node_modules/semver": { "version": "7.8.5", @@ -8332,27 +7257,11 @@ "node": ">= 0.8" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8373,9 +7282,10 @@ } }, "node_modules/shell-quote": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", - "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8384,38 +7294,27 @@ } }, "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/simple-plist": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "license": "MIT", "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "^3.0.5" } }, - "node_modules/simple-plist/node_modules/bplist-creator": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", - "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", - "dependencies": { - "stream-buffers": "2.2.x" - } - }, "node_modules/simple-plist/node_modules/bplist-parser": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "license": "MIT", "dependencies": { "big-integer": "1.6.x" }, @@ -8426,7 +7325,8 @@ "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", @@ -8440,6 +7340,7 @@ "version": "1.6.9", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -8456,6 +7357,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -8482,17 +7384,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -8529,116 +7420,39 @@ } }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-buffers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "license": "Unlicense", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">= 0.10.0" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "license": "MIT", "engines": { "node": ">=6" } @@ -8647,6 +7461,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8654,19 +7469,21 @@ "node_modules/structured-headers": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz", - "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==" + "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==", + "license": "MIT" }, "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { @@ -8681,6 +7498,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -8700,6 +7518,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -8720,163 +7539,35 @@ } }, "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "deprecated": "Old versions of tar 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", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "version": "7.5.20", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.20.tgz", + "integrity": "sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==", + "license": "BlueOak-1.0.0", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/temp": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", - "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", - "dependencies": { - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/temp/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/tempy": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.7.1.tgz", - "integrity": "sha512-vXPxwOyaNVi9nyczO16mxmHGpl6ASC5/TVhRRHpqeYHvKQm58EaWNvZXxAhR0lYYnBOQFjXjhzeLsaXdjxLjRg==", - "dependencies": { - "del": "^6.0.0", - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" @@ -8947,6 +7638,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -8955,6 +7647,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -8967,6 +7660,22 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -8991,20 +7700,11 @@ "node": ">=0.6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" }, "node_modules/type-detect": { "version": "4.0.8", @@ -9023,10 +7723,11 @@ } }, "node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9035,35 +7736,11 @@ "node": ">=14.17" } }, - "node_modules/ua-parser-js": { - "version": "1.0.41", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", - "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "bin": { - "ua-parser-js": "script/cli.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/undici": { "version": "6.27.0", "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "license": "MIT", "engines": { "node": ">=18.17" } @@ -9109,47 +7786,6 @@ "node": ">=4" } }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -9196,10 +7832,11 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -9208,6 +7845,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9216,6 +7854,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -9242,37 +7881,16 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/whatwg-url-without-unicode": { "version": "8.0.0-3", "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", @@ -9311,7 +7929,8 @@ "node_modules/wonka": { "version": "6.3.6", "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.6.tgz", - "integrity": "sha512-MXH+6mDHAZ2GuMpgKS055FR6v0xVP3XwquxIMYXgiW+FejHQlMGlvVRZT4qMCxR+bEo/FCtIdKxwej9WV3YQag==" + "integrity": "sha512-MXH+6mDHAZ2GuMpgKS055FR6v0xVP3XwquxIMYXgiW+FejHQlMGlvVRZT4qMCxR+bEo/FCtIdKxwej9WV3YQag==", + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -9329,52 +7948,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -9409,25 +7982,11 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -9448,6 +8007,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "license": "Apache-2.0", "dependencies": { "simple-plist": "^1.1.0", "uuid": "^7.0.3" @@ -9456,19 +8016,11 @@ "node": ">=10.0.0" } }, - "node_modules/xcode/node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/xml2js": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==", + "license": "MIT", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -9481,14 +8033,16 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", "engines": { "node": ">=4.0" } }, "node_modules/xmlbuilder": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-14.0.0.tgz", - "integrity": "sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", "engines": { "node": ">=8.0" } @@ -9506,6 +8060,21 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { "version": "17.7.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", @@ -9564,6 +8133,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/apps/mobile/package.json b/apps/mobile/package.json index cad5245..a06fe34 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -3,19 +3,19 @@ "version": "1.0.0", "main": "index.ts", "dependencies": { - "@react-native-async-storage/async-storage": "^1.23.1", + "@react-native-async-storage/async-storage": "2.2.0", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", - "expo": "^52.0.49", - "expo-status-bar": "~2.0.1", - "react": "18.3.1", - "react-native": "0.76.9", - "react-native-svg": "^15.8.0", - "react-native-webview": "13.12.5" + "expo": "^54.0.36", + "expo-status-bar": "~3.0.9", + "react": "19.1.0", + "react-native": "0.81.5", + "react-native-svg": "15.12.1", + "react-native-webview": "13.15.0" }, "devDependencies": { - "@types/react": "~19.2.2", - "typescript": "~6.0.3" + "@types/react": "~19.1.10", + "typescript": "~5.9.2" }, "scripts": { "start": "expo start", diff --git a/apps/mobile/plugins/withFmtConstevalFix.js b/apps/mobile/plugins/withFmtConstevalFix.js new file mode 100644 index 0000000..26c9c2b --- /dev/null +++ b/apps/mobile/plugins/withFmtConstevalFix.js @@ -0,0 +1,44 @@ +const { withDangerousMod } = require("@expo/config-plugins"); +const fs = require("fs"); +const path = require("path"); + +// React Native 0.81 vendors {fmt} 11.0.2, whose compile-time format-string +// checking uses `consteval` in a way Xcode 26's stricter Clang rejects +// ("call to consteval function … is not a constant expression"). Fixed upstream +// in fmt 12, but only pulled into RN >= 0.83.9 — NOT back-ported to 0.81. +// +// Scoped workaround: build ONLY the fmt pod as C++17. `consteval` didn't exist +// pre-C++20, so fmt skips the compile-time path and falls back to runtime +// format-string validation. Everything else keeps its C++20 setting. +// +// ios/ is regenerated by `expo prebuild`, so this runs as a config plugin to +// re-apply on every prebuild. Remove once RN bumps fmt (>= 0.83.9 / 0.85.x). +const SNIPPET = ` + installer.pods_project.targets.each do |target| + if target.name == 'fmt' + target.build_configurations.each do |bc| + bc.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++17' + end + end + end +`; + +module.exports = function withFmtConstevalFix(config) { + return withDangerousMod(config, [ + "ios", + (cfg) => { + const podfile = path.join(cfg.modRequest.platformProjectRoot, "Podfile"); + let contents = fs.readFileSync(podfile, "utf8"); + if (!contents.includes("target.name == 'fmt'")) { + // Insert AFTER react_native_post_install(...) so this wins if it also + // touches build settings. Matches the multi-line call up to its closing `)`. + contents = contents.replace( + /(react_native_post_install\([\s\S]*?\n\s*\)\n)/, + `$1${SNIPPET}`, + ); + fs.writeFileSync(podfile, contents); + } + return cfg; + }, + ]); +}; From 124b1e88f52393d02f03bac6c3ff87fd0e3ee2a1 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 19 Jul 2026 21:14:57 +0200 Subject: [PATCH 52/83] docs(mobile): update iOS publishing guide for Xcode 26 / SDK 54 (platform+metal downloads, proven build recipe) --- docs/publishing-ios.md | 47 +++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/docs/publishing-ios.md b/docs/publishing-ios.md index 91e1dd4..695c453 100644 --- a/docs/publishing-ios.md +++ b/docs/publishing-ios.md @@ -52,35 +52,44 @@ release. ¹ Declares the app uses only standard/exempt encryption (OS-provided TLS/SSH/WebSocket — no custom crypto). Correct for Ateam; revisit if you ever add proprietary encryption. -## Build & upload — Route A: local Xcode archive (recommended first) +## Toolchain requirements (Xcode 26) -Reuses the exact toolchain that already produces working device builds (SwiftTerm -module, SDK-52 / Xcode-16.2 pinning): +Apple requires builds made with **Xcode 26 / the iOS 26 SDK**. That needs **macOS ≥ 26**, +and Xcode 26 splits several pieces into on-demand downloads — install them once: ```bash -cd apps/mobile -npx expo prebuild -p ios # regenerate ios/ from app.json (SwiftTerm re-autolinks) - -open ios/mobile.xcworkspace -# in Xcode: -# 1. select scheme "mobile", destination "Any iOS Device (arm64)" -# 2. Signing & Capabilities → team X2VZX44YM2, automatic signing -# 3. Product ▸ Archive (Release) -# 4. Organizer opens → Distribute App ▸ App Store Connect ▸ Upload +sudo xcodebuild -license accept && sudo xcodebuild -runFirstLaunch +xcodebuild -downloadPlatform iOS # device platform (~8.5 GB) — separate from the SDK +xcodebuild -downloadComponent MetalToolchain # ~688 MB — the SwiftTerm .metal shaders need it ``` -Headless equivalent (for later CI): +Build with **Node ≥ 20.19.4** (SDK 54 requirement). The repo already carries the SDK-54 +fixes: `.npmrc` (legacy-peer-deps), `plugins/withFmtConstevalFix.js` (fmt→C++17 for Xcode 26), +`newArchEnabled: false` (keep legacy arch so SwiftTerm needs no Fabric rewrite), and a Metro +config that resolves nested transitive deps. + +## Build & upload — Route A: local archive (proven) ```bash -xcodebuild -workspace ios/mobile.xcworkspace -scheme mobile \ +cd apps/mobile +# bump ios.buildNumber in app.json first (App Store Connect rejects a duplicate version+build) +npx expo prebuild -p ios # regenerate ios/ (applies the fmt plugin; SwiftTerm re-autolinks) +( cd ios && pod install ) # ensure the fmt→C++17 Podfile change lands in the Pods project + +xcodebuild -workspace ios/AteamGo.xcworkspace -scheme AteamGo \ -configuration Release -destination 'generic/platform=iOS' \ - -archivePath build/Ateam.xcarchive archive -xcodebuild -exportArchive -archivePath build/Ateam.xcarchive \ - -exportOptionsPlist ios/ExportOptions.plist -exportPath build/export -xcrun altool --upload-app -f build/export/mobile.ipa -t ios \ - --apiKey "$ASC_KEY_ID" --apiIssuer "$ASC_ISSUER_ID" # App Store Connect API key + -archivePath build/AteamGo.xcarchive \ + DEVELOPMENT_TEAM=X2VZX44YM2 CODE_SIGN_STYLE=Automatic -allowProvisioningUpdates archive +xcodebuild -exportArchive -archivePath build/AteamGo.xcarchive \ + -exportOptionsPlist ios/ExportOptions.plist -exportPath build/export -allowProvisioningUpdates +xcrun altool --upload-app -f build/export/AteamGo.ipa -t ios \ + --apiKey 5H64P4APJ8 --apiIssuer # Team API key in ~/.appstoreconnect/private_keys/ ``` +`ios/ExportOptions.plist` (regenerate after `prebuild --clean`): `method` = `app-store-connect`, +`teamID` = `X2VZX44YM2`, `signingStyle` = `automatic`. Automatic signing + `-allowProvisioningUpdates` +mints the Apple Distribution cert on first run. + ## Build & upload — Route B: EAS (scalable follow-up) Cloud-reproducible and CI-friendly, but needs an `eas.json` + credentials setup that From 26784387a2bec28ef046612f5f5df3a6101710a7 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 20 Jul 2026 17:54:15 +0200 Subject: [PATCH 53/83] feat(mobile): auto-reattach to the box on foreground / after a drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The daemon already keeps agents + PTYs alive across disconnects, but the mobile client held a single WS with no reconnect path — backgrounding iOS or a network flip left a dead socket and a frozen board. Add client-side reattach: - connection.ts: surface an unexpected socket drop via connect(url,{onClose}) — distinguished from an app-initiated close(); add ping() (timed handshake) to tell a live socket from a half-open one. - App.tsx: remember the connect target as intent; reattach on socket drop and on AppState 'active' (probe first, only reconnect if dead), with capped backoff (1s->15s). connGen bumps per (re)connect so the board's event stream and any open terminal rebind to the fresh api (terminal remounts + re-resolves its still-alive PTY). Explicit Disconnect clears the intent so it stays down. - app.json: bump ios.buildNumber to 2. Reuses RN-core AppState + the transport's existing onClose — no new native deps. Verified: typecheck, lint, expo export (713 modules). On-device behaviour pending. --- apps/mobile/App.tsx | 122 ++++++++++++++++++++++++++++++++-- apps/mobile/app.json | 2 +- apps/mobile/src/connection.ts | 30 ++++++++- 3 files changed, 146 insertions(+), 8 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 4ec0ff6..6376e87 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -12,6 +12,7 @@ import type { AgentDTO, ProjectDTO, TaskDTO } from "@ateam/protocol"; import { useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, + AppState, KeyboardAvoidingView, Modal, Platform, @@ -445,6 +446,17 @@ export default function App() { const [browserOpen, setBrowserOpen] = useState(false); const conn = useRef(null); + // Auto-reattach bookkeeping. `target` is the box we intend to stay connected to + // (set on connect, cleared on explicit Disconnect) — the trigger for reconnecting. + // `connGen` bumps on every successful (re)connect: it keys the open terminal so it + // remounts onto the fresh `api` and cleanly re-resolves its still-alive PTY session. + const target = useRef<{ host: string; port: string } | null>(null); + const [connGen, setConnGen] = useState(0); + const reconnectRef = useRef<() => void>(() => {}); + const attempting = useRef(false); + const backoff = useRef(0); + const retryTimer = useRef | null>(null); + const refresh = useCallback(async () => { const api = conn.current?.api; if (!api) return; @@ -462,6 +474,9 @@ export default function App() { }, []); // Live updates: merge each pushed task in place (replace by id, or prepend if new). + // Re-subscribes on `connGen` too, so after an auto-reattach the stream binds to the + // fresh connection's api rather than the dead one's. + // biome-ignore lint/correctness/useExhaustiveDependencies: connGen re-binds api after reconnect useEffect(() => { const api = conn.current?.api; if (!api || view !== "board") return; @@ -475,26 +490,50 @@ export default function App() { }); }); return off; - }, [view]); + }, [view, connGen]); - // The one connect path — used by the Connect button and the launch auto-connect. + // The one connect path — used by the Connect button, the launch auto-connect, and + // the auto-reattach below. Returns whether it connected, so reconnect() can decide + // to retry. On success it records the `target` (so drops reattach) and bumps + // `connGen` (so the board + any open terminal rebind to the fresh api). const connectTo = useCallback( - async (h: string, p: string) => { + async (h: string, p: string): Promise => { + const port = p || "8787"; + if (retryTimer.current) { + clearTimeout(retryTimer.current); + retryTimer.current = null; + } setConnecting(true); setError(null); try { conn.current?.close(); - const c = await connect(`ws://${h}:${p || "8787"}`); + const c = await connect(`ws://${h}:${port}`, { + onClose: () => { + // This connection dropped on its own (network flip, box restart, NAT + // reap). If it's still the live one and we still want the box, reattach. + if (conn.current !== c || !target.current) return; + c.close(); // stop its keepalive; socket is already gone + conn.current = null; + setConnected(false); + backoff.current = 0; + reconnectRef.current(); + }, + }); conn.current = c; - await saveConnection({ host: h, port: p || "8787" }); + target.current = { host: h, port }; + backoff.current = 0; + await saveConnection({ host: h, port }); setConnected(true); + setConnGen((g) => g + 1); void c.api.agents.list().then(setAgents); setView("board"); await refresh(); + return true; } catch (err) { conn.current = null; setConnected(false); setError(err instanceof Error ? err.message : String(err)); + return false; } finally { setConnecting(false); } @@ -502,6 +541,62 @@ export default function App() { [refresh], ); + // Reattach to the intended box: try once, and on failure schedule a capped + // exponential backoff retry (1s → 15s) so a still-down box keeps getting picked up. + const reconnect = useCallback(async () => { + const t = target.current; + if (!t || attempting.current) return; + if (retryTimer.current) { + clearTimeout(retryTimer.current); + retryTimer.current = null; + } + attempting.current = true; + let ok = false; + try { + ok = await connectTo(t.host, t.port); + } finally { + attempting.current = false; + } + if (!ok && target.current) { + const delay = Math.min(15_000, 1_000 * 2 ** backoff.current); + backoff.current += 1; + retryTimer.current = setTimeout(() => { + retryTimer.current = null; + void reconnect(); + }, delay); + } + }, [connectTo]); + + // Break the connectTo ⇄ reconnect cycle: connectTo's onClose calls through this ref. + useEffect(() => { + reconnectRef.current = () => void reconnect(); + }, [reconnect]); + + // Reattach when the app returns to the foreground — the #1 case (app-switching). The + // socket iOS suspended in the background is usually dead with no close event, so probe + // it and only reconnect if the probe fails (avoids churning a still-live session). + useEffect(() => { + const sub = AppState.addEventListener("change", (s) => { + if (s !== "active" || !target.current || attempting.current) return; + void (async () => { + const alive = conn.current ? await conn.current.ping() : false; + if (!alive) { + backoff.current = 0; + void reconnect(); + } + })(); + }); + return () => sub.remove(); + }, [reconnect]); + + // Cancel any pending retry on unmount. + useEffect( + () => () => { + if (retryTimer.current) clearTimeout(retryTimer.current); + }, + [], + ); + const onConnect = useCallback(() => { if (!host.trim()) { setError("Enter the box's Tailscale IP or hostname."); @@ -524,6 +619,12 @@ export default function App() { }, []); const onDisconnect = useCallback(() => { + target.current = null; // intent: stay disconnected — no auto-reattach + if (retryTimer.current) { + clearTimeout(retryTimer.current); + retryTimer.current = null; + } + backoff.current = 0; conn.current?.close(); conn.current = null; setConnected(false); @@ -565,7 +666,16 @@ export default function App() { // A tapped task opens its live terminal (api comes from the live connection). if (openTask && conn.current) { const Term = USE_NATIVE_TERMINAL ? NativeTerminalScreen : TerminalScreen; - return setOpenTask(null)} />; + // key={connGen}: an auto-reattach swaps in a fresh api — remount so the terminal + // cleanly re-resolves (attach-if-live) its still-alive PTY on the new connection. + return ( + setOpenTask(null)} + /> + ); } // The project browser is a full-screen view-swap (NOT a nested modal — presenting diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 874a1c9..4e58179 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -11,7 +11,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "1", + "buildNumber": "2", "infoPlist": { "ITSAppUsesNonExemptEncryption": false } diff --git a/apps/mobile/src/connection.ts b/apps/mobile/src/connection.ts index 4cd2274..af1f370 100644 --- a/apps/mobile/src/connection.ts +++ b/apps/mobile/src/connection.ts @@ -30,22 +30,44 @@ const mobileNative: NativeClientApi = { export interface Connection { api: AteamApi; info: SystemInfo; + /** Fast liveness probe — a timed handshake. False if the socket is dead/half-open. */ + ping(): Promise; /** Close the socket; the daemon and its live sessions live on. */ close(): void; } +export interface ConnectOptions { + /** + * Fired once when the socket drops on its OWN (network flip, box restart, NAT + * reap) — NOT when the app calls `close()`. The app uses this to auto-reattach + * to the still-alive daemon session. See the connectivity decision doc. + */ + onClose?: () => void; +} + const CONNECT_TIMEOUT_MS = 15_000; +const PING_TIMEOUT_MS = 4_000; /** Connect to `ws://host:port` (the box's Tailscale address + WS port). */ -export async function connect(url: string): Promise { +export async function connect(url: string, opts: ConnectOptions = {}): Promise { const client = wsClientTransport(url); const rpc = createRpcClient(client.transport); + + // Distinguish an app-initiated close() from an unexpected drop: only the latter + // should trigger a reattach. Registered before the handshake so a drop mid-connect + // is still classified correctly (the throw path below sets `intentional`). + let intentional = false; + client.transport.onClose?.(() => { + if (!intentional) opts.onClose?.(); + }); + let info: SystemInfo; try { // A bad host / firewalled port leaves the socket hanging with no error, so // cap the handshake — the UI must not wait forever on connect. info = await withTimeout(serverHandshake(rpc), CONNECT_TIMEOUT_MS); } catch (err) { + intentional = true; // a failed connect isn't a drop to reattach from client.close(); throw err; } @@ -67,7 +89,13 @@ export async function connect(url: string): Promise { return { api: buildAteamApi(rpc, mobileNative), info, + ping: () => + withTimeout(serverHandshake(rpc), PING_TIMEOUT_MS).then( + () => true, + () => false, + ), close: () => { + intentional = true; clearInterval(keepalive); client.close(); }, From 5c5a9ccc4dc82e09b337a3b81f319fcadee99e73 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 21 Jul 2026 22:13:35 +0200 Subject: [PATCH 54/83] feat(mobile): remember the last-selected project across launches Reopening the app dropped you on project #1 every time. Persist the picked project and restore it on launch: - storage.ts: save/loadSelectedProject (AsyncStorage), mirroring the connection. - App.tsx: persist on every explicit pick (dropdown + after registering a new project); load the saved id BEFORE the first connect so refresh() prefers it, with a self-correcting fallback to project #1 if it no longer exists on the box. Typecheck + lint clean. --- apps/mobile/App.tsx | 37 +++++++++++++++++++++++++++++++------ apps/mobile/src/storage.ts | 18 ++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 6376e87..2bd2d4a 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -30,7 +30,12 @@ import { Composer, type ComposerSubmit } from "./src/Composer"; import { type Connection, connect } from "./src/connection"; import { NativeTerminalScreen } from "./src/NativeTerminalScreen"; import { ProjectBrowser } from "./src/ProjectBrowser"; -import { loadConnection, saveConnection } from "./src/storage"; +import { + loadConnection, + loadSelectedProject, + saveConnection, + saveSelectedProject, +} from "./src/storage"; import { TerminalScreen } from "./src/TerminalScreen"; // SPIKE flag: evaluate the native SwiftTerm terminal (native scroll/select/copy) @@ -457,6 +462,10 @@ export default function App() { const backoff = useRef(0); const retryTimer = useRef | null>(null); + // The project to restore on launch (loaded from storage before the first connect, + // so refresh() prefers it over project #1). Updated on every explicit pick. + const preferredProjectId = useRef(null); + const refresh = useCallback(async () => { const api = conn.current?.api; if (!api) return; @@ -464,7 +473,12 @@ export default function App() { try { const projs: ProjectDTO[] = await api.projects.list(); setProjects(projs); - setSelectedProjectId((cur) => cur ?? projs[0]?.id ?? null); + setSelectedProjectId((cur) => { + if (cur) return cur; // keep the live selection across refreshes/reconnects + const pref = preferredProjectId.current; + if (pref && projs.some((p) => p.id === pref)) return pref; // restore last pick + return projs[0]?.id ?? null; // fallback: first project (or none) + }); const perProject = await Promise.all(projs.map((p) => api.tasks.list(p.id))); const all = perProject.flat().sort((a, b) => (b.lastEventAt ?? 0) - (a.lastEventAt ?? 0)); setTasks(all); @@ -605,17 +619,28 @@ export default function App() { void connectTo(host.trim(), port.trim()); }, [host, port, connectTo]); + // Pick a project and remember it, so the next launch lands on it (not project #1). + const selectProject = useCallback((id: string) => { + preferredProjectId.current = id; + setSelectedProjectId(id); + void saveSelectedProject(id); + }, []); + // On launch: prefill the last box and auto-reconnect to it, so reopening the app // lands straight on the live board (no retyping/tapping). On failure it falls back // to the connection screen with the error, fields prefilled. // biome-ignore lint/correctness/useExhaustiveDependencies: one-shot on mount useEffect(() => { - void loadConnection().then((saved) => { + void (async () => { + // Load the remembered project BEFORE connecting, so the first refresh() restores + // it instead of racing to project #1. + const [saved, savedProject] = await Promise.all([loadConnection(), loadSelectedProject()]); + preferredProjectId.current = savedProject; if (!saved?.host) return; setHost(saved.host); setPort(saved.port); void connectTo(saved.host, saved.port); - }); + })(); }, []); const onDisconnect = useCallback(() => { @@ -687,7 +712,7 @@ export default function App() { onClose={() => setBrowserOpen(false)} onRegistered={(project) => { setBrowserOpen(false); - setSelectedProjectId(project.id); + selectProject(project.id); void refresh(); }} /> @@ -716,7 +741,7 @@ export default function App() { connColor={connected ? C.green : C.faint} projects={projects} selectedProjectId={selectedProjectId} - onSelectProject={setSelectedProjectId} + onSelectProject={selectProject} agents={agents} tasks={tasks} loading={loading} diff --git a/apps/mobile/src/storage.ts b/apps/mobile/src/storage.ts index aad16a2..870abd0 100644 --- a/apps/mobile/src/storage.ts +++ b/apps/mobile/src/storage.ts @@ -4,6 +4,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; const KEY = "ateam.connection"; +const PROJECT_KEY = "ateam.selectedProject"; export interface SavedConnection { host: string; @@ -26,3 +27,20 @@ export async function saveConnection(conn: SavedConnection): Promise { /* best-effort — a failed persist just means a blank field next launch */ } } + +/** Remember the last-picked project so reopening the app lands on it, not project #1. */ +export async function loadSelectedProject(): Promise { + try { + return await AsyncStorage.getItem(PROJECT_KEY); + } catch { + return null; + } +} + +export async function saveSelectedProject(id: string): Promise { + try { + await AsyncStorage.setItem(PROJECT_KEY, id); + } catch { + /* best-effort — a failed persist just falls back to the first project */ + } +} From 73cbcae515166e1b031f7009d068804f6878dafb Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 21 Jul 2026 22:23:40 +0200 Subject: [PATCH 55/83] feat(mobile): open the box's dev server in the phone browser (#73) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A one-tap preview of what the agent is building. No tunnel or port-forward: the phone is already on the tailnet, so the box's dev server is directly reachable at the same host we connected to. - App.tsx: a ↗ button in the board header opens a modal showing http://: with an editable port (default 3000, remembered); Open → Linking.openURL. Host is target.current.host — the connected box's Tailscale address, filled automatically; disabled when not connected. - storage.ts: load/savePreviewPort. RN-core Linking, no new deps. Typecheck + lint + expo export clean. --- apps/mobile/App.tsx | 185 +++++++++++++++++++++++++++++++++---- apps/mobile/src/storage.ts | 18 ++++ 2 files changed, 185 insertions(+), 18 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 2bd2d4a..83511bb 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -14,6 +14,7 @@ import { ActivityIndicator, AppState, KeyboardAvoidingView, + Linking, Modal, Platform, Pressable, @@ -32,8 +33,10 @@ import { NativeTerminalScreen } from "./src/NativeTerminalScreen"; import { ProjectBrowser } from "./src/ProjectBrowser"; import { loadConnection, + loadPreviewPort, loadSelectedProject, saveConnection, + savePreviewPort, saveSelectedProject, } from "./src/storage"; import { TerminalScreen } from "./src/TerminalScreen"; @@ -342,7 +345,65 @@ function ConnectionScreen({ ); } -// ── Board screen — status dot (left) · project dropdown (center) · composer ── +// ── Dev-server preview — open http://: in the phone browser ── +// No tunnel needed: the phone is already on the tailnet, so the box's dev server +// is directly reachable at the same host we connected to. Port is user-set (default +// 3000) and remembered. See issue #73. + +function PreviewModal({ + visible, + host, + port, + setPort, + onOpen, + onClose, +}: { + visible: boolean; + host: string | null; + port: string; + setPort: (t: string) => void; + onOpen: () => void; + onClose: () => void; +}) { + return ( + + + {/* Inner Pressable swallows taps so touching the card doesn't dismiss it. */} + {}}> + Open preview + + Opens a dev server running on the box in your browser, over Tailscale. + + + + http://{host ?? "—"}: + + + + + Open in browser + + + + + ); +} + +// ── Board screen — status dot (left) · project dropdown (center) · preview (right) ── function BoardScreen({ connColor, @@ -357,6 +418,7 @@ function BoardScreen({ onOpenTask, onCreate, onAddProject, + onOpenPreview, }: { connColor: string; projects: ProjectDTO[]; @@ -370,6 +432,7 @@ function BoardScreen({ onOpenTask: (task: TaskDTO) => void; onCreate: (input: ComposerSubmit) => void; onAddProject: () => void; + onOpenPreview: () => void; }) { const shown = tasks.filter((t) => t.projectId === selectedProjectId); return ( @@ -390,7 +453,11 @@ function BoardScreen({ onAddProject={onAddProject} /> - + + + + + (null); const [browserOpen, setBrowserOpen] = useState(false); + const [previewOpen, setPreviewOpen] = useState(false); + const [previewPort, setPreviewPort] = useState("3000"); const conn = useRef(null); // Auto-reattach bookkeeping. `target` is the box we intend to stay connected to @@ -626,6 +695,17 @@ export default function App() { void saveSelectedProject(id); }, []); + // Open the box's dev server in the phone browser. The box IP is exactly the host we + // connected to (already on the tailnet) — no tunnel, no discovery. Remember the port. + const openPreview = useCallback(() => { + const h = target.current?.host; + if (!h) return; + const p = previewPort.trim() || "3000"; + void savePreviewPort(p); + setPreviewOpen(false); + void Linking.openURL(`http://${h}:${p}`); + }, [previewPort]); + // On launch: prefill the last box and auto-reconnect to it, so reopening the app // lands straight on the live board (no retyping/tapping). On failure it falls back // to the connection screen with the error, fields prefilled. @@ -633,9 +713,14 @@ export default function App() { useEffect(() => { void (async () => { // Load the remembered project BEFORE connecting, so the first refresh() restores - // it instead of racing to project #1. - const [saved, savedProject] = await Promise.all([loadConnection(), loadSelectedProject()]); + // it instead of racing to project #1. Preview port is a plain UI default. + const [saved, savedProject, savedPreviewPort] = await Promise.all([ + loadConnection(), + loadSelectedProject(), + loadPreviewPort(), + ]); preferredProjectId.current = savedProject; + if (savedPreviewPort) setPreviewPort(savedPreviewPort); if (!saved?.host) return; setHost(saved.host); setPort(saved.port); @@ -737,20 +822,31 @@ export default function App() { } return ( - setView("connect")} - onOpenTask={setOpenTask} - onCreate={onCreate} - onAddProject={() => setBrowserOpen(true)} - /> + <> + setView("connect")} + onOpenTask={setOpenTask} + onCreate={onCreate} + onAddProject={() => setBrowserOpen(true)} + onOpenPreview={() => setPreviewOpen(true)} + /> + setPreviewOpen(false)} + /> + ); } @@ -786,6 +882,18 @@ const styles = StyleSheet.create({ statusHit: { width: 44, alignItems: "flex-start", justifyContent: "center" }, statusDot: { width: 12, height: 12, borderRadius: 6 }, headerCenter: { flex: 1, alignItems: "center" }, + previewHit: { width: 44, alignItems: "flex-end", justifyContent: "center" }, + previewBtn: { + width: 30, + height: 30, + borderRadius: 8, + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + alignItems: "center", + justifyContent: "center", + }, + previewGlyph: { color: C.ink, fontSize: 15, fontWeight: "700", marginTop: -1 }, projPill: { flexDirection: "row", alignItems: "center", @@ -828,6 +936,47 @@ const styles = StyleSheet.create({ modalRowText: { color: C.ink, fontSize: 15, flex: 1 }, modalAdd: { color: C.accent, fontSize: 15, width: 7, textAlign: "center", fontWeight: "700" }, + // dev-server preview modal + previewCard: { + width: 300, + backgroundColor: C.surface, + borderWidth: 1, + borderColor: C.line, + borderRadius: 12, + padding: 16, + }, + previewTitle: { color: C.ink, fontSize: 16, fontWeight: "700", letterSpacing: -0.2 }, + previewSub: { color: C.muted, fontSize: 12, lineHeight: 17, marginTop: 6 }, + previewUrlRow: { + flexDirection: "row", + alignItems: "center", + backgroundColor: C.sunken, + borderWidth: 1, + borderColor: C.line, + borderRadius: 8, + paddingHorizontal: 12, + paddingVertical: 4, + marginTop: 14, + }, + previewUrlText: { color: C.muted, fontSize: 13, fontVariant: ["tabular-nums"], flexShrink: 1 }, + previewPortInput: { + color: C.ink, + fontSize: 13, + fontVariant: ["tabular-nums"], + fontWeight: "700", + paddingVertical: 8, + minWidth: 56, + }, + previewOpenBtn: { + backgroundColor: C.ink, + borderRadius: 8, + paddingVertical: 11, + alignItems: "center", + marginTop: 14, + }, + previewOpenBtnDisabled: { opacity: 0.4 }, + previewOpenText: { color: "#15151a", fontSize: 14, fontWeight: "800" }, + // connection nav navBar: { flexDirection: "row", diff --git a/apps/mobile/src/storage.ts b/apps/mobile/src/storage.ts index 870abd0..35dfe6d 100644 --- a/apps/mobile/src/storage.ts +++ b/apps/mobile/src/storage.ts @@ -5,6 +5,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; const KEY = "ateam.connection"; const PROJECT_KEY = "ateam.selectedProject"; +const PREVIEW_PORT_KEY = "ateam.previewPort"; export interface SavedConnection { host: string; @@ -44,3 +45,20 @@ export async function saveSelectedProject(id: string): Promise { /* best-effort — a failed persist just falls back to the first project */ } } + +/** Remember the dev-server port used for the on-box preview (defaults to 3000). */ +export async function loadPreviewPort(): Promise { + try { + return await AsyncStorage.getItem(PREVIEW_PORT_KEY); + } catch { + return null; + } +} + +export async function savePreviewPort(port: string): Promise { + try { + await AsyncStorage.setItem(PREVIEW_PORT_KEY, port); + } catch { + /* best-effort — a failed persist just falls back to the default port */ + } +} From 2d27fa5ec69a3356d7a1602cc0d5ff67c5a00243 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 21 Jul 2026 22:33:49 +0200 Subject: [PATCH 56/83] feat(mobile): attach a photo/screenshot to the agent (#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A +img button leads the terminal's key bar. Pick an image → stage its bytes on the box via util.writeImageBytes → TYPE the returned path into the PTY. Typed keystrokes (not a paste) are what trigger the agent's path→[Image #N] detection — same mechanism (and same escapePath) the desktop terminal uses on a file drop. - NativeTerminalScreen.tsx: +img key, attachImage handler, escapePath/extFromAsset. - app.json: expo-image-picker plugin + photo-library permission string. - deps: expo-image-picker ~17.0.11. - bump ios.buildNumber to 3. Reuses the existing writeImageBytes RPC — no server/protocol change. Typecheck + lint + expo export clean; on-device attach path pending. --- apps/mobile/app.json | 68 +++++++++++++----------- apps/mobile/package-lock.json | 22 ++++++++ apps/mobile/package.json | 1 + apps/mobile/src/NativeTerminalScreen.tsx | 53 ++++++++++++++++++ 4 files changed, 114 insertions(+), 30 deletions(-) diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 4e58179..a7333ae 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -1,32 +1,40 @@ { - "expo": { - "name": "Ateam Go", - "slug": "ateam", - "version": "1.0.0", - "orientation": "portrait", - "icon": "./assets/icon.png", - "userInterfaceStyle": "light", - "newArchEnabled": false, - "plugins": ["./plugins/withFmtConstevalFix"], - "ios": { - "supportsTablet": true, - "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "2", - "infoPlist": { - "ITSAppUsesNonExemptEncryption": false - } - }, - "android": { - "adaptiveIcon": { - "backgroundColor": "#E6F4FE", - "foregroundImage": "./assets/android-icon-foreground.png", - "backgroundImage": "./assets/android-icon-background.png", - "monochromeImage": "./assets/android-icon-monochrome.png" - }, - "predictiveBackGestureEnabled": false - }, - "web": { - "favicon": "./assets/favicon.png" - } - } + "expo": { + "name": "Ateam Go", + "slug": "ateam", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "light", + "newArchEnabled": false, + "plugins": [ + "./plugins/withFmtConstevalFix", + [ + "expo-image-picker", + { + "photosPermission": "Ateam attaches a photo or screenshot you pick to the agent running on your box." + } + ] + ], + "ios": { + "supportsTablet": true, + "bundleIdentifier": "com.clawnify.ateam", + "buildNumber": "3", + "infoPlist": { + "ITSAppUsesNonExemptEncryption": false + } + }, + "android": { + "adaptiveIcon": { + "backgroundColor": "#E6F4FE", + "foregroundImage": "./assets/android-icon-foreground.png", + "backgroundImage": "./assets/android-icon-background.png", + "monochromeImage": "./assets/android-icon-monochrome.png" + }, + "predictiveBackGestureEnabled": false + }, + "web": { + "favicon": "./assets/favicon.png" + } + } } diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index 9bb89d2..1d6b64f 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -12,6 +12,7 @@ "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", "expo": "^54.0.36", + "expo-image-picker": "~17.0.11", "expo-status-bar": "~3.0.9", "react": "19.1.0", "react-native": "0.81.5", @@ -4437,6 +4438,27 @@ "react-native": "*" } }, + "node_modules/expo-image-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-6.0.0.tgz", + "integrity": "sha512-nKs/xnOGw6ACb4g26xceBD57FKLFkSwEUTDXEDF3Gtcu3MqF3ZIYd3YM+sSb1/z9AKV1dYT7rMSGVNgsveXLIQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-picker": { + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-17.0.11.tgz", + "integrity": "sha512-/apkoyukDvsCHHb9fzP+F34A1uQqSzUtYH/2P/xJACNEwq+mwEXjXvVU8bzlJq6ih0Qo1+tpVivIa7B9kYSwOQ==", + "license": "MIT", + "dependencies": { + "expo-image-loader": "~6.0.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-keep-awake": { "version": "15.0.8", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a06fe34..a4a6846 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -7,6 +7,7 @@ "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", "expo": "^54.0.36", + "expo-image-picker": "~17.0.11", "expo-status-bar": "~3.0.9", "react": "19.1.0", "react-native": "0.81.5", diff --git a/apps/mobile/src/NativeTerminalScreen.tsx b/apps/mobile/src/NativeTerminalScreen.tsx index 03cd93f..8bdb7b3 100644 --- a/apps/mobile/src/NativeTerminalScreen.tsx +++ b/apps/mobile/src/NativeTerminalScreen.tsx @@ -5,6 +5,7 @@ // separate from TerminalScreen so the webview path stays intact while we evaluate. import type { AteamApi, PtyDataEvent, TaskDTO } from "@ateam/protocol"; +import * as ImagePicker from "expo-image-picker"; import { useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, @@ -52,6 +53,17 @@ const KEYS: { label: string; bytes: string; scroll?: boolean }[] = [ { label: "PgDn", bytes: "\x1b[6~", scroll: true }, ]; +// Backslash-escape shell-special chars so a typed path survives the shell — same +// convention the desktop terminal uses for dropped/attached file paths. +const escapePath = (p: string) => p.replace(/([ '"\\!$&*()[\]{};<>?#~`|])/g, "\\$1"); + +// Best-effort file extension for the staged image (the server sanitizes it anyway). +function extFromAsset(a: ImagePicker.ImagePickerAsset): string { + const fromMime = a.mimeType?.split("/")[1]; + if (fromMime) return fromMime; + return a.uri.match(/\.([a-z0-9]+)$/i)?.[1] ?? "png"; +} + export function NativeTerminalScreen({ api, task, @@ -65,6 +77,7 @@ export function NativeTerminalScreen({ const [terminalId, setTerminalId] = useState(null); const [status, setStatus] = useState<"connecting" | "live" | "error">("connecting"); const [detail, setDetail] = useState("resolving session…"); + const [attaching, setAttaching] = useState(false); const keyboardUp = useKeyboardVisible(); const buffered = useRef([]); @@ -203,6 +216,32 @@ export function NativeTerminalScreen({ [api, terminalId], ); + // Attach a photo/screenshot to the agent: pick → stage the bytes on the box + // (util.writeImageBytes) → TYPE the returned path into the PTY. Typed keystrokes + // (not a paste) are what trigger the agent's "path → [Image #N]" detection — same + // mechanism the desktop terminal uses on a file drop. + const attachImage = useCallback(async () => { + const id = terminalId; + if (!id || attaching) return; + try { + const res = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ["images"], + base64: true, + quality: 0.9, + }); + const asset = res.canceled ? null : res.assets[0]; + if (!asset?.base64) return; + setAttaching(true); + const path = await api.utils.writeImageBytes(asset.base64, extFromAsset(asset)); + api.pty.write(id, `${escapePath(path)} `); + termRef.current?.focusKeyboard(); + } catch (err) { + setDetail(err instanceof Error ? err.message : "couldn't attach image"); + } finally { + setAttaching(false); + } + }, [api, terminalId, attaching]); + return ( + + {attaching ? ( + + ) : ( + +img + )} + {KEYS.map((k) => ( Date: Wed, 22 Jul 2026 09:03:23 +0200 Subject: [PATCH 57/83] refine(mobile): tmp-dir image staging, paperclip icon, neutral attach button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-ups on the image-attach feature: - server: writeImageBytes stages under /ateam-attachments (like Termius) instead of /attachments — transient, OS-cleaned, still pruned by the engine on startup. Applies to every client (desktop included); agent readability unchanged. Test + prune updated to match. - mobile: the terminal attach button now shows a Feather paperclip icon (bundled, no new dep) instead of the +img text, styled like the other keys (no accent). - bump ios.buildNumber to 4. --- apps/mobile/app.json | 2 +- apps/mobile/src/NativeTerminalScreen.tsx | 12 +++--------- packages/server/src/dispatcher.ts | 6 ++++-- packages/server/src/engine.ts | 13 ++++++++----- packages/server/test/fs-util.test.ts | 4 ++-- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/apps/mobile/app.json b/apps/mobile/app.json index a7333ae..7d59a3e 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -19,7 +19,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "3", + "buildNumber": "4", "infoPlist": { "ITSAppUsesNonExemptEncryption": false } diff --git a/apps/mobile/src/NativeTerminalScreen.tsx b/apps/mobile/src/NativeTerminalScreen.tsx index 8bdb7b3..3645bb7 100644 --- a/apps/mobile/src/NativeTerminalScreen.tsx +++ b/apps/mobile/src/NativeTerminalScreen.tsx @@ -5,6 +5,7 @@ // separate from TerminalScreen so the webview path stays intact while we evaluate. import type { AteamApi, PtyDataEvent, TaskDTO } from "@ateam/protocol"; +import Feather from "@expo/vector-icons/Feather"; import * as ImagePicker from "expo-image-picker"; import { useCallback, useEffect, useRef, useState } from "react"; import { @@ -281,16 +282,11 @@ export function NativeTerminalScreen({ ]} keyboardShouldPersistTaps="always" > - + {attaching ? ( ) : ( - +img + )} {KEYS.map((k) => ( @@ -386,8 +382,6 @@ const styles = StyleSheet.create({ justifyContent: "center", }, keyText: { color: C.ink, fontSize: 14, fontWeight: "600" }, - attachKey: { borderColor: "#3a3550", backgroundColor: "#221f30" }, - attachKeyText: { color: "#b9a8ff", fontSize: 14, fontWeight: "700" }, retryBtn: { marginTop: 8, paddingHorizontal: 16, diff --git a/packages/server/src/dispatcher.ts b/packages/server/src/dispatcher.ts index ab6f4ca..0d387a4 100644 --- a/packages/server/src/dispatcher.ts +++ b/packages/server/src/dispatcher.ts @@ -5,7 +5,7 @@ // server will adapt a JSON-RPC channel → handle(). One body, many transports. import { randomUUID } from "node:crypto"; import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; -import { homedir } from "node:os"; +import { homedir, tmpdir } from "node:os"; import { basename, dirname, join, resolve } from "node:path"; import { agentCommand, getAgent, listAgents } from "@ateam/agents"; import { repo } from "@ateam/db"; @@ -420,7 +420,9 @@ export function createDispatcher(engine: Engine): Dispatcher { }, [CH.utilWriteImageBytes]: async (base64: string, ext?: string) => { const safeExt = (ext ?? "png").replace(/[^a-z0-9]/gi, "").toLowerCase() || "png"; - const dir = join(services.userDataDir, "attachments"); + // Stage in the OS temp dir (like Termius): transient, OS-cleaned, and readable + // by the agent running on this box. The engine also prunes it on startup. + const dir = join(tmpdir(), "ateam-attachments"); if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); // Random name: an attachment is handed to the agent immediately; the engine // prunes this dir on startup so temp images never accumulate unboundedly. diff --git a/packages/server/src/engine.ts b/packages/server/src/engine.ts index aa496e8..1343f58 100644 --- a/packages/server/src/engine.ts +++ b/packages/server/src/engine.ts @@ -6,7 +6,7 @@ // notifications) drive the exact same engine. import { EventEmitter } from "node:events"; import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from "node:fs"; -import { homedir } from "node:os"; +import { homedir, tmpdir } from "node:os"; import { join } from "node:path"; import { createDb, repo } from "@ateam/db"; import type { @@ -52,7 +52,10 @@ interface EngineEventMap { export interface Engine { readonly services: Services; - on(event: K, listener: (...args: EngineEventMap[K]) => void): () => void; + on( + event: K, + listener: (...args: EngineEventMap[K]) => void, + ): () => void; /** Re-read a task and emit taskUpdated (used across handlers + loops). */ sendTaskUpdated(taskId: string): void; /** Emit taskRemoved so every client drops the deleted task's card. */ @@ -99,10 +102,10 @@ export async function createEngine(opts: EngineOptions): Promise { } const db = createDb(dbPath); - // Prune stale image attachments (written by util:writeImageBytes when a remote - // client attaches an image) older than a week, so temp files never accumulate + // Prune stale image attachments (written by util:writeImageBytes to the OS temp dir + // when a client attaches an image) older than a week, so temp files never accumulate // unboundedly. A path handed to an agent is read within the session it's given. - const attachmentsDir = join(dataDir, "attachments"); + const attachmentsDir = join(tmpdir(), "ateam-attachments"); if (existsSync(attachmentsDir)) { const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000; for (const name of readdirSync(attachmentsDir)) { diff --git a/packages/server/test/fs-util.test.ts b/packages/server/test/fs-util.test.ts index 6213b4b..43adf0b 100644 --- a/packages/server/test/fs-util.test.ts +++ b/packages/server/test/fs-util.test.ts @@ -59,7 +59,7 @@ describe("util:writeImageBytes (remote image attach)", () => { const file = (await d.handle(CH.utilWriteImageBytes, [png.toString("base64")])) as string; - expect(file.startsWith(join(dataDir, "attachments"))).toBe(true); + expect(file.startsWith(join(tmpdir(), "ateam-attachments"))).toBe(true); expect(file.endsWith(".png")).toBe(true); expect(existsSync(file)).toBe(true); expect(readFileSync(file).equals(png)).toBe(true); @@ -71,6 +71,6 @@ describe("util:writeImageBytes (remote image attach)", () => { const file = (await d.handle(CH.utilWriteImageBytes, ["", "../evil.jpg"])) as string; // Non-alphanumerics stripped: "../evil.jpg" → "eviljpg"; no traversal survives. expect(file.endsWith(".eviljpg")).toBe(true); - expect(file.startsWith(join(dataDir, "attachments"))).toBe(true); + expect(file.startsWith(join(tmpdir(), "ateam-attachments"))).toBe(true); }); }); From 9c5411f50c849486321d2a255c226f52495841a2 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sat, 25 Jul 2026 14:04:35 +0200 Subject: [PATCH 58/83] feat(mobile): center content on iPad (cap width, keep phone layout intact) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit supportsTablet was already on, so the app installs on iPad — but the phone layout stretched edge-to-edge. Cap the board, connection form, and composer to a centered CONTENT_MAX (720) column; the terminal stays full-width (more columns is better). No-op on iPhone (720 > any screen), a centered column on iPad. No new deps. Typecheck + lint + expo export clean. --- apps/mobile/App.tsx | 134 +++++++++++++++++--------------- apps/mobile/src/Composer.tsx | 144 ++++++++++++++++++----------------- 2 files changed, 149 insertions(+), 129 deletions(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 83511bb..82a3a7c 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -77,6 +77,11 @@ const COLUMNS: { key: TaskDTO["column"]; label: string; tint: string }[] = [ { key: "merged", label: "Done", tint: C.green }, ]; +// Cap the phone-first content to a comfortable reading column and center it. A no-op +// on iPhone (wider than any screen), it stops the board/composer/form from stretching +// edge-to-edge on iPad. The terminal is intentionally exempt — more columns is better. +const CONTENT_MAX = 720; + function taskNote(t: TaskDTO): string { if (t.column === "needs_attention") return "awaiting your input"; if (t.agentStatus === "running") return "running"; @@ -302,44 +307,46 @@ function ConnectionScreen({ - - - Box - - - - - - - {error ? ( - - {error} + + + + Box + + + + - ) : null} - {connected ? ( - - Disconnect - - ) : null} + {error ? ( + + {error} + + ) : null} - - The phone opens a WebSocket to your box's `ateam` listener over Tailscale — WireGuard is - the encryption and the auth boundary. Enable it on the box with{" "} - ATEAM_WS_ADDR=<tailscale-ip>:<port>. - + {connected ? ( + + Disconnect + + ) : null} + + + The phone opens a WebSocket to your box's `ateam` listener over Tailscale — WireGuard is + the encryption and the auth boundary. Enable it on the box with{" "} + ATEAM_WS_ADDR=<tailscale-ip>:<port>. + + ); @@ -466,33 +473,35 @@ function BoardScreen({ showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled" > - {loading && shown.length === 0 ? ( - - - loading board… - - ) : shown.length === 0 ? ( - - no tasks yet — start one below - - ) : ( - COLUMNS.map((col) => { - const inCol = shown.filter((t) => t.column === col.key); - if (inCol.length === 0) return null; - return ( - - - - {col.label} - {inCol.length} + + {loading && shown.length === 0 ? ( + + + loading board… + + ) : shown.length === 0 ? ( + + no tasks yet — start one below + + ) : ( + COLUMNS.map((col) => { + const inCol = shown.filter((t) => t.column === col.key); + if (inCol.length === 0) return null; + return ( + + + + {col.label} + {inCol.length} + + {inCol.map((t) => ( + onOpenTask(t)} /> + ))} - {inCol.map((t) => ( - onOpenTask(t)} /> - ))} - - ); - }) - )} + ); + }) + )} + @@ -1064,6 +1073,9 @@ const styles = StyleSheet.create({ // board board: { flex: 1 }, boardContent: { padding: 16, paddingBottom: 24 }, + // Centered, width-capped content column (see CONTENT_MAX) — keeps the phone layout + // from stretching on iPad; a no-op on iPhone. + contentColumn: { width: "100%", maxWidth: CONTENT_MAX, alignSelf: "center" }, centerPad: { alignItems: "center", paddingVertical: 48, gap: 12 }, zone: { marginBottom: 22 }, card: { diff --git a/apps/mobile/src/Composer.tsx b/apps/mobile/src/Composer.tsx index 3c277c6..b147ca0 100644 --- a/apps/mobile/src/Composer.tsx +++ b/apps/mobile/src/Composer.tsx @@ -22,6 +22,9 @@ const C = { amber: "#fbbf24", }; +// Match App's CONTENT_MAX: center + cap the composer content on iPad (no-op on iPhone). +const CONTENT_MAX = 720; + export interface ComposerSubmit { /** The agent's first instruction (normal mode). Empty in agent mode. */ prompt: string; @@ -74,82 +77,87 @@ export function Composer({ return ( - {/* Agent mode passes no prompt — but we still need to name the worktree, so + + {/* Agent mode passes no prompt — but we still need to name the worktree, so the field becomes an explicit task-name input (clearly labelled). */} - {agentMode ? TASK NAME : null} - - - {/* Agent picker: show only the current agent; tap to open the popover. */} - setPickerOpen(true)} hitSlop={4}> - - {current?.label.replace(/ Code$/, "") ?? "Agent"} - {pickable.length > 1 ? : null} - - setPickerOpen(false)} - > - setPickerOpen(false)}> - - {pickable.map((a) => ( - { - setAgentId(a.id); - setPickerOpen(false); - }} - > - - {a.label} - {a.id === agentId ? : null} - - ))} - + {agentMode ? TASK NAME : null} + + + {/* Agent picker: show only the current agent; tap to open the popover. */} + setPickerOpen(true)} hitSlop={4}> + + {current?.label.replace(/ Code$/, "") ?? "Agent"} + {pickable.length > 1 ? : null} + + setPickerOpen(false)} + > + setPickerOpen(false)}> + + {pickable.map((a) => ( + { + setAgentId(a.id); + setPickerOpen(false); + }} + > + + {a.label} + {a.id === agentId ? : null} + + ))} + + + + + {/* Auto mode (yolo) */} + setYolo((v) => !v)} + hitSlop={4} + > + auto + + {/* Agent mode (claude agents) */} + setAgentMode((v) => !v)} + hitSlop={4} + > + agents + + {/* Send */} + + - - - {/* Auto mode (yolo) */} - setYolo((v) => !v)} - hitSlop={4} - > - auto - - {/* Agent mode (claude agents) */} - setAgentMode((v) => !v)} - hitSlop={4} - > - agents - - {/* Send */} - - - + ); } const styles = StyleSheet.create({ + inner: { width: "100%", maxWidth: CONTENT_MAX, alignSelf: "center" }, wrap: { borderTopWidth: 1, borderTopColor: C.line, From 022db823b7caf0a282f5ce420252e425a7e31c90 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sat, 25 Jul 2026 14:06:19 +0200 Subject: [PATCH 59/83] chore(mobile): bump ios.buildNumber to 5 (iPad centering build) --- apps/mobile/app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 7d59a3e..6b108dd 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -19,7 +19,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "4", + "buildNumber": "5", "infoPlist": { "ITSAppUsesNonExemptEncryption": false } From a03bdac3ffe61ed9a3482f37a8fee447d423faae Mon Sep 17 00:00:00 2001 From: pallaoro Date: Mon, 27 Jul 2026 16:54:14 +0200 Subject: [PATCH 60/83] feat(mobile): built-in demo mode (offline canned board + terminal) for App Review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ateam is local-first with no shared backend a reviewer could sign into, so App Store guideline 2.1 points to a built-in demo instead of demo credentials. Add a 'Try the demo — no box needed' button on the connection screen that enters a fully offline Connection: canned projects/tasks/agents and a realistic Claude Code terminal. - src/demo.ts: fakes the RPC *transport* (answers the channels the app calls with canned DTOs) fed through the real createRpcClient + buildAteamApi, so every screen renders unchanged. No UI fork. Demo never reattaches and persists nothing. - connection.ts: export mobileNative so demo reuses the same native stub. - App.tsx: startDemo entry + the connection-screen button. - bump ios.buildNumber to 6. Also unblocks deterministic App Store screenshots. Typecheck + lint + expo export clean. --- apps/mobile/App.tsx | 48 +++++++++ apps/mobile/app.json | 2 +- apps/mobile/src/connection.ts | 2 +- apps/mobile/src/demo.ts | 194 ++++++++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 apps/mobile/src/demo.ts diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 82a3a7c..6d82998 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -29,6 +29,7 @@ import { import { AgentIcon } from "./src/AgentIcon"; import { Composer, type ComposerSubmit } from "./src/Composer"; import { type Connection, connect } from "./src/connection"; +import { demoConnection } from "./src/demo"; import { NativeTerminalScreen } from "./src/NativeTerminalScreen"; import { ProjectBrowser } from "./src/ProjectBrowser"; import { @@ -264,6 +265,7 @@ function ConnectionScreen({ onConnect, onBack, onDisconnect, + onDemo, connecting, connected, error, @@ -275,6 +277,7 @@ function ConnectionScreen({ onConnect: () => void; onBack: () => void; onDisconnect: () => void; + onDemo: () => void; connecting: boolean; connected: boolean; error: string | null; @@ -329,6 +332,19 @@ function ConnectionScreen({ /> + {!connected ? ( + + + or + + + ) : null} + {!connected ? ( + + Try the demo — no box needed + + ) : null} + {error ? ( {error} @@ -697,6 +713,24 @@ export default function App() { void connectTo(host.trim(), port.trim()); }, [host, port, connectTo]); + // Enter demo mode: a fully offline Connection (canned board + terminal). No box, no + // reattach, no saved connection — for App Review (guideline 2.1) and first-look onboarding. + const startDemo = useCallback(async () => { + target.current = null; // demo never reattaches + if (retryTimer.current) { + clearTimeout(retryTimer.current); + retryTimer.current = null; + } + conn.current?.close(); + conn.current = demoConnection(); + setConnected(true); + setError(null); + setConnGen((g) => g + 1); + void conn.current.api.agents.list().then(setAgents); + setView("board"); + await refresh(); + }, [refresh]); + // Pick a project and remember it, so the next launch lands on it (not project #1). const selectProject = useCallback((id: string) => { preferredProjectId.current = id; @@ -823,6 +857,7 @@ export default function App() { onConnect={onConnect} onBack={() => setView("board")} onDisconnect={onDisconnect} + onDemo={startDemo} connecting={connecting} connected={connected} error={error} @@ -1067,6 +1102,19 @@ const styles = StyleSheet.create({ alignItems: "center", }, disconnectText: { color: C.red, fontSize: 14, fontWeight: "700" }, + demoRow: { flexDirection: "row", alignItems: "center", gap: 12, marginTop: 20 }, + demoRule: { flex: 1, height: 1, backgroundColor: C.line }, + demoOr: { color: C.faint, fontSize: 12 }, + demoBtn: { + marginTop: 14, + borderWidth: 1, + borderColor: C.line, + backgroundColor: C.surface, + borderRadius: 10, + paddingVertical: 13, + alignItems: "center", + }, + demoText: { color: C.ink, fontSize: 14, fontWeight: "700" }, formNote: { color: C.faint, fontSize: 12, lineHeight: 18, marginTop: 18, paddingHorizontal: 2 }, mono: { color: C.muted, fontVariant: ["tabular-nums"] }, diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 6b108dd..2131664 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -19,7 +19,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "5", + "buildNumber": "6", "infoPlist": { "ITSAppUsesNonExemptEncryption": false } diff --git a/apps/mobile/src/connection.ts b/apps/mobile/src/connection.ts index af1f370..665d179 100644 --- a/apps/mobile/src/connection.ts +++ b/apps/mobile/src/connection.ts @@ -17,7 +17,7 @@ import { // A remote client owns no local dialogs or clipboard: folder-pick and image // attach flow over RPC (fs.listDir / util.writeImageBytes) instead, so this // client-native slice is inert here. Single-window, so the window surface stubs too. -const mobileNative: NativeClientApi = { +export const mobileNative: NativeClientApi = { pathForFile: () => "", pick: async () => null, pickFiles: async () => [], diff --git a/apps/mobile/src/demo.ts b/apps/mobile/src/demo.ts new file mode 100644 index 0000000..15bb793 --- /dev/null +++ b/apps/mobile/src/demo.ts @@ -0,0 +1,194 @@ +// Demo mode: a fully-offline Connection backed by canned data — no box, no WS, no +// Tailscale. It exists for two reasons: (1) App Review — Ateam is local-first with +// no shared backend a reviewer could sign into, so per App Store guideline 2.1 we +// offer a built-in demo instead of demo credentials; (2) onboarding — let someone +// see the app before they stand up a box. +// +// The trick: we don't fork the UI. We fake the *transport* (the RPC wire), run it +// through the real createRpcClient + buildAteamApi, and hand back a normal +// Connection. Every screen — board, composer, terminal, image attach — then renders +// against canned responses exactly as it would against a live daemon. +import { + type AgentDTO, + buildAteamApi, + CH, + type ClientTransport, + createRpcClient, + type DirListingDTO, + PROTOCOL_VERSION, + type ProjectDTO, + type PtySnapshot, + type ServerFrame, + type SessionDTO, + type SystemInfo, + type TaskDTO, +} from "@ateam/protocol"; +import { type Connection, mobileNative } from "./connection"; + +const INFO: SystemInfo = { protocolVersion: PROTOCOL_VERSION, agents: ["claude", "codex"] }; + +const AGENTS: AgentDTO[] = [ + { id: "claude", label: "Claude Code", description: "Anthropic's coding agent", available: true }, + { id: "codex", label: "Codex", description: "OpenAI's coding agent", available: true }, +]; + +const PROJECT: ProjectDTO = { + id: "demo-project", + repoPath: "/home/demo/ateam", + name: "ateam", + defaultBranch: "main", + githubOwner: "clawnify", + githubName: "ateam", + color: "#7c5cff", +}; + +const T0 = Date.now(); +function task( + id: string, + name: string, + column: TaskDTO["column"], + agentStatus: TaskDTO["agentStatus"], + extra: Partial = {}, +): TaskDTO { + return { + id, + projectId: PROJECT.id, + name, + description: null, + slug: id, + branch: `ateam/${id}`, + baseBranch: "main", + worktreePath: `/home/demo/ateam/.ateam/worktrees/${id}`, + column, + agentStatus, + agentId: "claude", + mergeStatus: null, + prNumber: null, + prUrl: null, + gitStatus: null, + lastEventAt: T0, + isUnread: false, + ...extra, + }; +} + +const TASKS: TaskDTO[] = [ + task("onboarding-copy", "Rewrite the onboarding copy", "needs_attention", "awaiting_input", { + lastEventAt: T0 - 30_000, + }), + task("dark-mode", "Add a dark-mode toggle to settings", "running", "running", { + lastEventAt: T0 - 5_000, + }), + task("stripe-webhooks", "Wire up the Stripe webhooks", "running", "running", { + agentId: "codex", + lastEventAt: T0 - 12_000, + }), + task("flaky-test", "Fix the flaky checkout test", "review", "idle", { + prNumber: 128, + prUrl: "https://github.com/clawnify/ateam/pull/128", + gitStatus: { ahead: 3, behind: 0, dirty: 0, updatedAt: T0 }, + }), + task("empty-states", "Design the empty states", "todo", null), + task("bump-deps", "Bump dependencies to latest", "merged", "stopped", { + prNumber: 121, + mergeStatus: null, + }), +]; + +// A believable Claude Code session, as an ANSI transcript. Static (not streamed) so +// it's deterministic — good for App Store screenshots and a stable review. +const TRANSCRIPT = + "\x1b[38;5;213m✻ Claude Code\x1b[0m \x1b[2m· ateam/dark-mode · claude-opus\x1b[0m\r\n\r\n" + + "\x1b[1m>\x1b[0m add a dark-mode toggle to Settings, wired to the theme store\r\n\r\n" + + "\x1b[2m● Reading\x1b[0m src/screens/Settings.tsx\r\n" + + "\x1b[2m● Reading\x1b[0m src/theme/store.ts\r\n\r\n" + + "\x1b[32m● Edited\x1b[0m src/screens/Settings.tsx \x1b[2m(+22 −1)\x1b[0m\r\n" + + " \x1b[2m added a bound to theme.mode, persisted via the store\x1b[0m\r\n" + + "\x1b[32m● Edited\x1b[0m src/theme/store.ts \x1b[2m(+9 −0)\x1b[0m\r\n\r\n" + + "\x1b[2m● Running\x1b[0m \x1b[36mnpm test -- theme\x1b[0m\r\n" + + " \x1b[32m✓\x1b[0m theme toggle persists across reloads\r\n" + + " \x1b[32m✓\x1b[0m respects the system preference on first launch\r\n\r\n" + + "\x1b[32m●\x1b[0m Done. The toggle lives in Settings → Appearance and updates the\r\n" + + " theme immediately. Want me to open a PR?\r\n\r\n" + + "\x1b[1m>\x1b[0m \x1b[7m \x1b[0m\r\n"; + +function sessionFor(taskId: string): SessionDTO { + const t = TASKS.find((x) => x.id === taskId); + return { + id: `sess-${taskId}`, + taskId, + agentId: t?.agentId ?? "claude", + terminalId: `demo-term-${taskId}`, + status: "running", + cwd: "/home/demo/ateam", + }; +} + +const LISTING: DirListingDTO = { + path: "/home/demo", + parent: "/home", + entries: [ + { name: "ateam", path: "/home/demo/ateam", isRepo: true }, + { name: "website", path: "/home/demo/website", isRepo: true }, + { name: "scratch", path: "/home/demo/scratch", isRepo: false }, + ], +}; + +/** Map an RPC method to its canned result. Unmapped methods resolve to undefined — + * the mobile UI only calls the handful covered here. */ +function handle(method: string, args: unknown[]): unknown { + switch (method) { + case CH.systemHello: + return INFO; + case CH.agentsList: + return AGENTS; + case CH.projectsList: + return [PROJECT]; + case CH.tasksList: + return TASKS; + case CH.tasksCreate: { + const input = args[0] as { projectId: string; name: string }; + return task(`new-${T0}`, input.name || "New task", "running", "running"); + } + case CH.ptyListForTask: + return [sessionFor(String(args[0]))]; + case CH.ptySpawnShell: + return { terminalId: `demo-term-${(args[0] as { taskId: string }).taskId}` }; + case CH.ptySpawnAgent: + return { terminalId: "demo-term-new" }; + case CH.ptySnapshot: + return { data: TRANSCRIPT, seq: 0 } satisfies PtySnapshot; + case CH.utilWriteImageBytes: + return "/tmp/ateam-attachments/demo.png"; + case CH.fsListDir: + return LISTING; + default: + // pty:write, pty:resize, pty:kill and anything else → a bare ack. + return undefined; + } +} + +/** A Connection whose api is served entirely from the canned data above. */ +export function demoConnection(): Connection { + let onFrame: ((f: ServerFrame) => void) | null = null; + const transport: ClientTransport = { + send: (frame) => { + const result = handle(frame.method, frame.args); + // Resolve on a later tick so it behaves like a real async round-trip. + setTimeout(() => onFrame?.({ t: "res", id: frame.id, ok: true, result }), 0); + }, + onFrame: (h) => { + onFrame = h; + }, + onClose: () => {}, + }; + const rpc = createRpcClient(transport); + return { + api: buildAteamApi(rpc, mobileNative), + info: INFO, + ping: async () => true, + close: () => { + onFrame = null; + }, + }; +} From 379027eac92f12614364abd604529743c805d279 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 28 Jul 2026 09:59:14 +0200 Subject: [PATCH 61/83] docs(appstore): App Store submission package for Ateam Go Privacy policy, App Review notes (demo-mode / guideline 2.1), listing copy (name/subtitle/description/keywords/age-rating/App-Privacy answers), and the publishing checklist + screenshot spec/pipeline. Text-only prep for the public listing; internal TestFlight remains review-free. --- docs/appstore/README.md | 66 ++++++++++++++++++++++++++++++ docs/appstore/listing.md | 71 +++++++++++++++++++++++++++++++++ docs/appstore/privacy-policy.md | 59 +++++++++++++++++++++++++++ docs/appstore/review-notes.md | 40 +++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 docs/appstore/README.md create mode 100644 docs/appstore/listing.md create mode 100644 docs/appstore/privacy-policy.md create mode 100644 docs/appstore/review-notes.md diff --git a/docs/appstore/README.md b/docs/appstore/README.md new file mode 100644 index 0000000..332607f --- /dev/null +++ b/docs/appstore/README.md @@ -0,0 +1,66 @@ +# Publishing Ateam Go to the App Store + +Working folder for the public App Store submission. Internal TestFlight already works with no +review; this is the checklist + copy for a **public listing** (which triggers App Review). + +See also [publishing-ios.md](../publishing-ios.md) for the build/upload mechanics. + +## Status + +| Item | State | +| --- | --- | +| Build on TestFlight | ✅ build 6 (`com.clawnify.ateam`, 1.0.0) | +| **2.1 backend blocker** — reviewer can reach the app | ✅ **built-in demo mode** ("Try the demo — no box needed") | +| Review notes | ✅ draft — [review-notes.md](./review-notes.md) | +| Privacy policy (text) | ✅ draft — [privacy-policy.md](./privacy-policy.md) · ⬜ **needs hosting at a public URL** | +| Listing copy (name/subtitle/description/keywords) | ✅ draft — [listing.md](./listing.md) | +| App Privacy label | ✅ "Data Not Collected" — see [listing.md](./listing.md) | +| Age rating | ✅ 4+ — see [listing.md](./listing.md) | +| Encryption / export compliance | ✅ `ITSAppUsesNonExemptEncryption: false` | +| **Screenshots** | ⬜ **to capture** — spec + pipeline below | + +**Remaining to submit:** (1) host the privacy policy → get a URL; (2) capture screenshots; +(3) paste the copy into App Store Connect and submit. + +## Screenshots + +Apple requires, for an app that supports iPad: +- **iPhone 6.9"** — `iPhone 16 Pro Max`, **1290 × 2796** (installed ✓) +- **iPad 13"** — `iPad Pro 13-inch (M4)`, **2064 × 2752** (installed ✓) + +`xcrun simctl io booted screenshot` captures at exact native (= App Store) resolution. Capture all +shots **in demo mode** — the canned data is deterministic, so shots are clean and reproducible. + +### Screens to capture (5 per device) +1. **Board** — populated with the demo tasks (the hero shot). +2. **Task terminal** — a task opened to its Claude Code session. +3. **Composer** — the board with the composer focused / a prompt typed. +4. **Dev-server preview** — the ↗ preview modal (or the paperclip image-attach). +5. **Connection screen** — showing "Try the demo" (tells the local-first story). + +### Capture commands (once the app is on the right screen) +```bash +# boot the device +xcrun simctl boot "iPhone 16 Pro Max" +open -a Simulator +# … get the app to the target screen … +xcrun simctl io booted screenshot ~/Desktop/ateam-shots/iphone-1-board.png +# repeat per screen; then for iPad: +xcrun simctl boot "iPad Pro 13-inch (M4)" +xcrun simctl io booted screenshot ~/Desktop/ateam-shots/ipad-1-board.png +``` + +### The navigation gap (and the fix) +`simctl` can capture but **cannot tap** — and `idb`/`fastlane` are not installed. So getting the app +onto screens 2–4 needs either: +- **Manual:** a person taps to each screen; the script captures. ~5 min for both devices. +- **Automated (recommended, repeatable):** add a `ateamgo://` **deep-link** handler so + `xcrun simctl openurl booted ateamgo://demo/terminal` jumps straight to a screen. Then a script + fully automates both device sets — reusable every release. Costs a URL scheme in `app.json`, a + small `Linking` handler in `App.tsx`, and one simulator build. + +## Order of operations to go live +1. Host `privacy-policy.md` → Privacy Policy URL. +2. Capture the 10 screenshots (5 × 2 devices). +3. App Store Connect: fill listing (from `listing.md`), App Privacy, age rating, review notes, + upload screenshots, attach build 6, **submit for review**. diff --git a/docs/appstore/listing.md b/docs/appstore/listing.md new file mode 100644 index 0000000..42b9e35 --- /dev/null +++ b/docs/appstore/listing.md @@ -0,0 +1,71 @@ +# App Store Listing — Ateam Go + +Copy for App Store Connect. Draft — tweak to taste before submitting. + +## Identity +- **Name:** Ateam Go +- **Subtitle (≤30 chars):** `Run AI coding agents remotely` (29) +- **Bundle ID:** com.clawnify.ateam +- **Primary category:** Developer Tools +- **Secondary category:** Productivity +- **Age rating:** 4+ (no objectionable content — see questionnaire below) + +## Promotional text (≤170 chars, updatable without review) +`Drive AI coding agents on your own server from your phone. Watch them work, jump into any session, and pick up where you left off — from anywhere.` + +## Description +``` +Ateam Go is a remote control for AI coding agents that run on your own server. + +Your agents (like Claude Code) do the work on a machine you own; Ateam Go is the +polished phone client on top — a live board of every task, a real terminal for each +one, and the ability to pick up exactly where you left off. + +LOCAL-FIRST, YOUR MACHINE +• Agents run on your box, not on our servers. There is no Ateam account and we collect + nothing — the app talks only to a server you control, over your own private network. + +A LIVE BOARD +• See every task across columns — Needs You, In Progress, Review, Backlog, Done. +• Start a new task and launch an agent from the composer. + +A REAL TERMINAL IN YOUR POCKET +• Open any task to a full terminal attached to its running agent. +• Sessions live on your server, so they survive disconnects and app switches — reopen + and you're right back in the running session. +• Attach a screenshot or photo straight into the agent. + +TRY IT FIRST +• Tap "Try the demo" to explore the whole app offline, no server required. + +Ateam Go pairs with the Ateam desktop app and an agent server you run yourself. +``` + +## Keywords (≤100 chars, comma-separated, no spaces after commas) +`ssh,terminal,claude,coding agent,ai,developer,remote,devops,server,tmux,console,shell,git` +_(96 chars — adjust if App Store Connect reports over.)_ + +## URLs +- **Support URL:** _needs a page_ — e.g. the repo or a Clawnify support page. +- **Marketing URL (optional):** a Clawnify/Ateam landing page if one exists. +- **Privacy Policy URL:** host `privacy-policy.md` (see that file's footer). + +## Age-rating questionnaire → all "None" / "No" +Cartoon/fantasy violence, realistic violence, sexual content, nudity, profanity, alcohol/ +tobacco/drugs, gambling, horror, mature themes, medical info, contests: **None**. +Unrestricted web access: **No** (the dev-server preview opens only a user-entered address on +their own network; not a general browser). → **Result: 4+**. + +## App Privacy ("nutrition label") → Data Not Collected +Declare **"Data Not Collected."** Rationale: +- No analytics, no accounts, no ads, no tracking SDKs. +- Photos the user attaches and all terminal traffic go to **the user's own server**, not to + Clawnify — this is not "collection" by the developer. +- Local settings (last box, project, port) stay on-device. +If App Store Connect pushes back on the photo point, the honest framing is: the app *accesses* +photos on device at the user's request and transmits the chosen one to the user's own server; the +developer neither collects nor receives it. + +## Encryption / export compliance +Already declared in `app.json`: `ITSAppUsesNonExemptEncryption: false` (only OS-standard +TLS/SSH/WebSocket; no proprietary crypto). No extra paperwork. diff --git a/docs/appstore/privacy-policy.md b/docs/appstore/privacy-policy.md new file mode 100644 index 0000000..b7850ff --- /dev/null +++ b/docs/appstore/privacy-policy.md @@ -0,0 +1,59 @@ +# Ateam Go — Privacy Policy + +_Last updated: 2026-07-28_ + +Ateam Go is a **local-first** remote control for AI coding agents that you run on **your own +server** ("your box"). This policy explains what the app does and does not do with your data. + +## The short version + +**Clawnify does not collect, store, or receive any of your data.** Ateam Go has no accounts, +no analytics, and no Clawnify-operated backend. The app talks **only to a server you own and +control**, over your own private network. + +## What the app connects to + +- When you connect, Ateam Go opens a WebSocket **directly to a box you operate**, reachable over + your own [Tailscale](https://tailscale.com) private network. Your commands, keystrokes, terminal + output, and any images you attach travel **between your phone and your box** — they are never + sent to Clawnify or any third party. +- Clawnify runs **no server** that participates in this connection and receives **none** of this + traffic. + +## Data the app accesses on your device + +- **Photos (optional).** If you tap the attach (paperclip) button, iOS asks permission to access + your photo library so you can pick an image to hand to the agent. The selected image is uploaded + **to your own box** (for your agent to read) and is **not** transmitted to Clawnify. The app does + not read your photo library for any other purpose. +- **Local settings.** The last box address, selected project, and preview port are stored **on your + device** (local storage) so the app remembers them between launches. This never leaves your device. + +## Demo mode + +The built-in **"Try the demo"** runs **entirely offline** with fabricated sample data. It makes no +network connections and accesses nothing on your device. + +## Analytics & tracking + +None. Ateam Go contains **no** analytics SDKs, advertising SDKs, or tracking of any kind. We do not +use the Advertising Identifier and we do not track you across apps or websites. + +## Children + +Ateam Go is a developer tool and is not directed at children. + +## Changes + +If this policy changes, the "Last updated" date above will change and the revised policy will be +posted at this URL. + +## Contact + +Questions: **pallaororm@gmail.com** + +--- + +> **To publish:** this file must be hosted at a public HTTPS URL (App Store Connect requires a +> Privacy Policy URL). Options: a page under a Clawnify domain, or GitHub Pages for the repo. +> The URL then goes in App Store Connect → App Privacy → Privacy Policy. diff --git a/docs/appstore/review-notes.md b/docs/appstore/review-notes.md new file mode 100644 index 0000000..fae786f --- /dev/null +++ b/docs/appstore/review-notes.md @@ -0,0 +1,40 @@ +# App Review Notes — Ateam Go + +_Paste into App Store Connect → App Review Information → Notes._ + +--- + +Ateam Go is a **local-first** remote control for AI coding agents (e.g. Claude Code) that a +developer runs on **their own server**. It is the companion to our macOS desktop app. + +**There is no account and no Clawnify-operated backend.** In normal use the app connects over the +user's own private [Tailscale](https://tailscale.com) network to a server the user operates. Because +that server is private to each user, we **cannot** provide demo credentials that reach "our" +backend — there is no shared backend. + +**Per Guideline 2.1, we provide a fully-featured built-in demo instead of a demo account.** + +## How to review the app + +1. Launch the app. On the first screen, tap **"Try the demo — no box needed"** (below the connection + form). +2. You'll land on the **board**, populated with sample tasks across the columns (Needs You / In + Progress / Review / Backlog / Done). +3. **Tap any task** to open its terminal — you'll see a representative AI coding-agent session. +4. The **composer** at the bottom creates a sample task; the **paperclip** in a task's terminal + attaches a photo; the **↗** button in the board header is a dev-server preview. + +Demo mode runs **entirely offline** with fabricated data — no login, no network, no external +resources required. + +## Notes on permissions + +- **Photo library**: requested only if the reviewer taps the attach (paperclip) button. Used solely + to let the user pick an image to send to their own server. No photos are sent to Clawnify. + +## Real-world use (context, not required to review) + +Outside demo mode, a user installs our open server on their own machine and connects over Tailscale. +There is nothing for Apple to provision. Everything a reviewer needs is in the demo. + +Contact for anything: **pallaororm@gmail.com** From 9b1f85ecb7fb87f9044cbaeebedfda167670c742 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Wed, 29 Jul 2026 11:50:56 +0200 Subject: [PATCH 62/83] docs(readme): reword intro and requirements copy --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0a5ed11..1628165 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@

      Ateam

      - Local-first orchestration for a crew of AI coding agents — Claude Code, - OpenCode, and Codex — each isolated in its own git worktree. + Orchestrate a crew of AI coding agents — Claude Code, OpenCode, and + Codex — each isolated in its own git worktree.

      @@ -23,13 +23,13 @@ Ateam — task panel with the changes view: file list and a GitHub-style diff beside the board

      -A lean, **local-first** desktop app to orchestrate a crew of AI coding agents +A lean desktop app to orchestrate a crew of AI coding agents (Claude Code, OpenCode, Codex) in parallel — each isolated in its own **git worktree**, organized by project, with built-in commit/push/pull/merge that **never disturbs another worktree's checkout**, and a Mission Control grid to watch several agents work at once. -No login, no cloud. Identity and all GitHub operations come from the `gh` CLI. +Identity and all GitHub operations come from the `gh` CLI. > **Install:** grab the signed & notarized DMG above (or any release from the > [Releases](https://github.com/clawnify/ateam/releases) page), drag Ateam to From eb98cf1a8726d0454b3ca1ef24f1dd98454622a1 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Wed, 29 Jul 2026 11:58:53 +0200 Subject: [PATCH 63/83] Readme update --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1628165..00890c4 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,11 @@ Identity and all GitHub operations come from the `gh` CLI. packages/git-core Safe worktree + git engine (no Electron, fully unit-tested) packages/db Local SQLite (Drizzle + better-sqlite3); bun:sqlite in tests packages/agents Agent registry (claude/opencode/codex) + availability probe +packages/protocol Transport-agnostic RPC contract + client API (the shared wire) +packages/server Headless engine + daemon: run agents on a box over SSH / WebSocket packages/panes Pane/split layout types apps/desktop Electron + React app (main · preload · renderer) +apps/mobile iOS client (Expo / React Native) — drive a box from your phone ``` ## Develop From 085a9588d2f6c681c0081c07aa23ebba81d416ad Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 2 Aug 2026 12:56:19 +0200 Subject: [PATCH 64/83] feat(desktop): multi-engine aggregation core for per-task environments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Groundwork for tagging each task with its environment (This Mac / a box) instead of the global connection switch. A pure, Electron-free router that holds several backends at once and: merges collection reads (projects/agents/loops), routes entity calls (tasks/git/pty) to the owning engine via a learned id->backend map (all ids are globally-unique UUIDs, so no namespacing), and falls back to local for un-routable calls. Environment = the owning backend; no new task state or migration. Unwired — host.ts keeps its single-active path untouched; this is the proven core. 7 unit tests (merge, route-by-project/terminal, create+learn, fallback); desktop typecheck excludes *.test.ts (tests run via bun test, keeping bun types out of the Electron-main tsconfig). --- apps/desktop/src/main/aggregate.test.ts | 102 ++++++++++++++++++ apps/desktop/src/main/aggregate.ts | 134 ++++++++++++++++++++++++ apps/desktop/tsconfig.node.json | 3 + 3 files changed, 239 insertions(+) create mode 100644 apps/desktop/src/main/aggregate.test.ts create mode 100644 apps/desktop/src/main/aggregate.ts diff --git a/apps/desktop/src/main/aggregate.test.ts b/apps/desktop/src/main/aggregate.test.ts new file mode 100644 index 0000000..de06346 --- /dev/null +++ b/apps/desktop/src/main/aggregate.test.ts @@ -0,0 +1,102 @@ +import { expect, test } from "bun:test"; +import { CH } from "@ateam/protocol"; +import { candidateId, createAggregate } from "./aggregate"; +import type { Backend } from "./backend"; + +// A fake engine: canned per-method results + a log of which methods it was asked. +function fake( + kind: "local" | "remote", + data: Record unknown>, +): Backend & { calls: string[] } { + const calls: string[] = []; + return { + kind, + methods: [], + calls, + handle(method, args) { + calls.push(method); + return data[method]?.(args); + }, + on: () => () => {}, + dispose: () => {}, + }; +} + +function fixtures() { + const local = fake("local", { + [CH.projectsList]: () => [{ id: "pA" }], + [CH.agentsList]: () => [{ id: "claude" }], + [CH.tasksList]: () => [{ id: "tA" }], + [CH.ptySpawnShell]: () => ({ terminalId: "termA" }), + [CH.ptyWrite]: () => undefined, + [CH.tasksCreate]: () => ({ id: "tA-new" }), + [CH.projectsRegister]: () => ({ id: "pA-new" }), + }); + const remote = fake("remote", { + [CH.projectsList]: () => [{ id: "pB" }], + [CH.agentsList]: () => [{ id: "claude" }, { id: "codex" }], + [CH.tasksList]: () => [{ id: "tB" }], + [CH.ptySpawnShell]: () => ({ terminalId: "termB" }), + [CH.ptyWrite]: () => undefined, + [CH.tasksCreate]: () => ({ id: "tB-new" }), + }); + return { local, remote, agg: createAggregate([local, remote], local) }; +} + +test("candidateId pulls the id from a string arg or an id-ish field", () => { + expect(candidateId(["term-1"])).toBe("term-1"); + expect(candidateId([{ taskId: "t-1" }])).toBe("t-1"); + expect(candidateId([{ projectId: "p-1" }])).toBe("p-1"); + expect(candidateId([{ nope: 1 }])).toBeUndefined(); +}); + +test("collection reads merge across backends (agents dedupe by id)", async () => { + const { agg } = fixtures(); + expect(await agg.handle(CH.projectsList, [])).toEqual([{ id: "pA" }, { id: "pB" }]); + // claude appears on both engines → deduped; codex only on remote. + expect(await agg.handle(CH.agentsList, [])).toEqual([{ id: "claude" }, { id: "codex" }]); +}); + +test("entity calls route to the owning backend, learned from prior reads", async () => { + const { local, remote, agg } = fixtures(); + await agg.handle(CH.projectsList, []); // learns pA→local, pB→remote + + await agg.handle(CH.tasksList, ["pB"]); + expect(remote.calls).toContain(CH.tasksList); + expect(local.calls).not.toContain(CH.tasksList); + + await agg.handle(CH.tasksList, ["pA"]); + expect(local.calls).toContain(CH.tasksList); +}); + +test("a spawned terminal is learned, so later pty calls route to its engine", async () => { + const { local, remote, agg } = fixtures(); + await agg.handle(CH.projectsList, []); + await agg.handle(CH.tasksList, ["pB"]); // learns tB→remote + await agg.handle(CH.ptySpawnShell, [{ taskId: "tB" }]); // routes to remote, learns termB→remote + await agg.handle(CH.ptyWrite, ["termB", "ls\n"]); + expect(remote.calls.filter((m) => m === CH.ptyWrite)).toHaveLength(1); + expect(local.calls).not.toContain(CH.ptyWrite); +}); + +test("tasksCreate routes by projectId and the new task is owned by that engine", async () => { + const { remote, agg } = fixtures(); + await agg.handle(CH.projectsList, []); // learns pB→remote + const created = (await agg.handle(CH.tasksCreate, [{ projectId: "pB", name: "x" }])) as { + id: string; + }; + expect(created.id).toBe("tB-new"); + expect(agg.ownerOf.get("tB-new")).toBe(remote); +}); + +test("un-routable calls fall back to the local engine", async () => { + const { local, agg } = fixtures(); + await agg.handle(CH.projectsRegister, ["/repo", {}]); + expect(local.calls).toContain(CH.projectsRegister); +}); + +test("an entity call with an unknown id falls back rather than throwing", async () => { + const { local, agg } = fixtures(); + await agg.handle(CH.gitStatus, ["unknown-task"]); + expect(local.calls).toContain(CH.gitStatus); +}); diff --git a/apps/desktop/src/main/aggregate.ts b/apps/desktop/src/main/aggregate.ts new file mode 100644 index 0000000..3928b17 --- /dev/null +++ b/apps/desktop/src/main/aggregate.ts @@ -0,0 +1,134 @@ +// Multi-engine aggregation — the core of "per-task environment" (see the Cursor +// study + the connectivity decision doc). Instead of the global switch in host.ts +// (one `active` backend, others disposed), the desktop can hold SEVERAL backends at +// once — the local Mac engine plus any connected boxes — and present ONE board that +// unions their tasks, each task's "environment" being simply the backend that owns it. +// +// There is no shared task store to add an `environment` column to: every engine is +// sovereign over its own SQLite (see @ateam/server engine.ts). So aggregation is a +// CLIENT concern, and it reduces to routing each RPC to the right engine + merging +// the collection reads. Because every id (project/task/terminal) is a globally-unique +// randomUUID (packages/db schema.ts), a flat `id → backend` registry routes safely — +// no per-engine id namespacing needed. +// +// This module is pure (no Electron) and, for now, UNWIRED — host.ts keeps its +// single-active path until this is proven and flag-gated in. It is the load-bearing +// slice: hold N backends, route every call correctly, merge the board. +import { CH } from "@ateam/protocol"; +import type { Backend } from "./backend"; + +/** Collection reads with no entity key — merge the results across every backend. */ +const MERGE = new Set([CH.projectsList, CH.agentsList, CH.loopsList]); + +/** Entity-scoped calls — route to the backend that owns the id in the args. */ +const ENTITY = new Set([ + CH.tasksList, // projectId + CH.tasksCreate, // {projectId} + CH.tasksRemove, + CH.tasksSetColumn, + CH.tasksCleanup, + CH.tasksCleanupPreview, + CH.tasksCleanupCandidates, + CH.projectsRemove, + CH.gitCommit, + CH.gitPush, + CH.gitUpdate, + CH.gitMerge, + CH.gitDiff, + CH.gitFileDiff, + CH.gitStatus, + CH.ptySpawnAgent, // {taskId} + CH.ptySpawnShell, // {taskId} + CH.ptyListForTask, // taskId + CH.ptyWrite, // terminalId + CH.ptyResize, + CH.ptyKill, + CH.ptySnapshot, +]); + +/** Pull the owning-entity id out of a call's args (string arg, or an id-ish field). */ +export function candidateId(args: unknown[]): string | undefined { + const a = args[0]; + if (typeof a === "string") return a; + if (a && typeof a === "object") { + const o = a as Record; + for (const k of ["taskId", "projectId", "terminalId", "id"]) { + if (typeof o[k] === "string") return o[k] as string; + } + } + return undefined; +} + +/** Register every id a result carries (project/task `id`, session `terminalId`) as + * owned by the backend that produced it, so later calls route back to it. */ +function learn(reg: Map, backend: Backend, result: unknown): void { + const add = (v: unknown): void => { + if (v && typeof v === "object") { + const o = v as Record; + for (const k of ["id", "terminalId"]) { + if (typeof o[k] === "string") reg.set(o[k] as string, backend); + } + } + }; + if (Array.isArray(result)) for (const item of result) add(item); + else add(result); +} + +/** Merge collection results from several backends; dedupe by `id` (agents overlap). */ +function merge(results: unknown[]): unknown[] { + const out: unknown[] = []; + const seen = new Set(); + for (const r of results) { + if (!Array.isArray(r)) continue; + for (const item of r) { + const id = + item && typeof item === "object" ? (item as Record).id : undefined; + if (typeof id === "string") { + if (seen.has(id)) continue; + seen.add(id); + } + out.push(item); + } + } + return out; +} + +export interface Aggregate { + /** Route/merge one request across the held backends (drop-in for Router.handle). */ + handle(method: string, args: unknown[]): Promise; + /** The learned id→backend map (which environment owns each entity). Read-only use. */ + readonly ownerOf: ReadonlyMap; +} + +/** + * Build an aggregate over `backends`, resolving un-routable calls (register, fs, + * writeImageBytes, handshake, loop mutations) to `fallback` — the local engine by + * convention. `backends` should include `fallback`. + */ +export function createAggregate(backends: readonly Backend[], fallback: Backend): Aggregate { + const reg = new Map(); + + async function handle(method: string, args: unknown[]): Promise { + if (MERGE.has(method)) { + const results = await Promise.all( + backends.map(async (b) => { + const r = await b.handle(method, args); + learn(reg, b, r); + return r; + }), + ); + return merge(results); + } + + let backend = fallback; + if (ENTITY.has(method)) { + const id = candidateId(args); + backend = (id && reg.get(id)) || fallback; + } + const result = await backend.handle(method, args); + learn(reg, backend, result); + return result; + } + + return { handle, ownerOf: reg }; +} diff --git a/apps/desktop/tsconfig.node.json b/apps/desktop/tsconfig.node.json index aa919ad..7863fb5 100644 --- a/apps/desktop/tsconfig.node.json +++ b/apps/desktop/tsconfig.node.json @@ -12,5 +12,8 @@ "src/preload/**/*.ts", "src/shared/**/*.ts", "electron.vite.config.ts" + ], + "exclude": [ + "src/**/*.test.ts" ] } From 19759e56a695cd58342a0b8ba899e50a805d82f3 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 2 Aug 2026 13:08:08 +0200 Subject: [PATCH 65/83] docs: move internal App Store/publishing docs out of the public repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The repo is public; these were internal operational runbooks. Remove the iOS publishing runbook (it exposed the Apple Team ID + ASC Key ID — identifiers, not the secret .p8, which was never committed) and the appstore/ package (checklist, review notes, listing strategy) — their content now lives in Clawnify knowledge. Keep the genuinely public docs: the online-ateam user guide and the privacy policy (moved to docs/privacy-policy.md; personal email replaced with a contact placeholder). Note: git history still contains the removed identifiers; rotate the ASC key if that matters (the private key itself was never exposed). --- docs/appstore/README.md | 66 -------------- docs/appstore/listing.md | 71 --------------- docs/appstore/review-notes.md | 40 --------- docs/{appstore => }/privacy-policy.md | 2 +- docs/publishing-ios.md | 124 -------------------------- 5 files changed, 1 insertion(+), 302 deletions(-) delete mode 100644 docs/appstore/README.md delete mode 100644 docs/appstore/listing.md delete mode 100644 docs/appstore/review-notes.md rename docs/{appstore => }/privacy-policy.md (95%) delete mode 100644 docs/publishing-ios.md diff --git a/docs/appstore/README.md b/docs/appstore/README.md deleted file mode 100644 index 332607f..0000000 --- a/docs/appstore/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Publishing Ateam Go to the App Store - -Working folder for the public App Store submission. Internal TestFlight already works with no -review; this is the checklist + copy for a **public listing** (which triggers App Review). - -See also [publishing-ios.md](../publishing-ios.md) for the build/upload mechanics. - -## Status - -| Item | State | -| --- | --- | -| Build on TestFlight | ✅ build 6 (`com.clawnify.ateam`, 1.0.0) | -| **2.1 backend blocker** — reviewer can reach the app | ✅ **built-in demo mode** ("Try the demo — no box needed") | -| Review notes | ✅ draft — [review-notes.md](./review-notes.md) | -| Privacy policy (text) | ✅ draft — [privacy-policy.md](./privacy-policy.md) · ⬜ **needs hosting at a public URL** | -| Listing copy (name/subtitle/description/keywords) | ✅ draft — [listing.md](./listing.md) | -| App Privacy label | ✅ "Data Not Collected" — see [listing.md](./listing.md) | -| Age rating | ✅ 4+ — see [listing.md](./listing.md) | -| Encryption / export compliance | ✅ `ITSAppUsesNonExemptEncryption: false` | -| **Screenshots** | ⬜ **to capture** — spec + pipeline below | - -**Remaining to submit:** (1) host the privacy policy → get a URL; (2) capture screenshots; -(3) paste the copy into App Store Connect and submit. - -## Screenshots - -Apple requires, for an app that supports iPad: -- **iPhone 6.9"** — `iPhone 16 Pro Max`, **1290 × 2796** (installed ✓) -- **iPad 13"** — `iPad Pro 13-inch (M4)`, **2064 × 2752** (installed ✓) - -`xcrun simctl io booted screenshot` captures at exact native (= App Store) resolution. Capture all -shots **in demo mode** — the canned data is deterministic, so shots are clean and reproducible. - -### Screens to capture (5 per device) -1. **Board** — populated with the demo tasks (the hero shot). -2. **Task terminal** — a task opened to its Claude Code session. -3. **Composer** — the board with the composer focused / a prompt typed. -4. **Dev-server preview** — the ↗ preview modal (or the paperclip image-attach). -5. **Connection screen** — showing "Try the demo" (tells the local-first story). - -### Capture commands (once the app is on the right screen) -```bash -# boot the device -xcrun simctl boot "iPhone 16 Pro Max" -open -a Simulator -# … get the app to the target screen … -xcrun simctl io booted screenshot ~/Desktop/ateam-shots/iphone-1-board.png -# repeat per screen; then for iPad: -xcrun simctl boot "iPad Pro 13-inch (M4)" -xcrun simctl io booted screenshot ~/Desktop/ateam-shots/ipad-1-board.png -``` - -### The navigation gap (and the fix) -`simctl` can capture but **cannot tap** — and `idb`/`fastlane` are not installed. So getting the app -onto screens 2–4 needs either: -- **Manual:** a person taps to each screen; the script captures. ~5 min for both devices. -- **Automated (recommended, repeatable):** add a `ateamgo://` **deep-link** handler so - `xcrun simctl openurl booted ateamgo://demo/terminal` jumps straight to a screen. Then a script - fully automates both device sets — reusable every release. Costs a URL scheme in `app.json`, a - small `Linking` handler in `App.tsx`, and one simulator build. - -## Order of operations to go live -1. Host `privacy-policy.md` → Privacy Policy URL. -2. Capture the 10 screenshots (5 × 2 devices). -3. App Store Connect: fill listing (from `listing.md`), App Privacy, age rating, review notes, - upload screenshots, attach build 6, **submit for review**. diff --git a/docs/appstore/listing.md b/docs/appstore/listing.md deleted file mode 100644 index 42b9e35..0000000 --- a/docs/appstore/listing.md +++ /dev/null @@ -1,71 +0,0 @@ -# App Store Listing — Ateam Go - -Copy for App Store Connect. Draft — tweak to taste before submitting. - -## Identity -- **Name:** Ateam Go -- **Subtitle (≤30 chars):** `Run AI coding agents remotely` (29) -- **Bundle ID:** com.clawnify.ateam -- **Primary category:** Developer Tools -- **Secondary category:** Productivity -- **Age rating:** 4+ (no objectionable content — see questionnaire below) - -## Promotional text (≤170 chars, updatable without review) -`Drive AI coding agents on your own server from your phone. Watch them work, jump into any session, and pick up where you left off — from anywhere.` - -## Description -``` -Ateam Go is a remote control for AI coding agents that run on your own server. - -Your agents (like Claude Code) do the work on a machine you own; Ateam Go is the -polished phone client on top — a live board of every task, a real terminal for each -one, and the ability to pick up exactly where you left off. - -LOCAL-FIRST, YOUR MACHINE -• Agents run on your box, not on our servers. There is no Ateam account and we collect - nothing — the app talks only to a server you control, over your own private network. - -A LIVE BOARD -• See every task across columns — Needs You, In Progress, Review, Backlog, Done. -• Start a new task and launch an agent from the composer. - -A REAL TERMINAL IN YOUR POCKET -• Open any task to a full terminal attached to its running agent. -• Sessions live on your server, so they survive disconnects and app switches — reopen - and you're right back in the running session. -• Attach a screenshot or photo straight into the agent. - -TRY IT FIRST -• Tap "Try the demo" to explore the whole app offline, no server required. - -Ateam Go pairs with the Ateam desktop app and an agent server you run yourself. -``` - -## Keywords (≤100 chars, comma-separated, no spaces after commas) -`ssh,terminal,claude,coding agent,ai,developer,remote,devops,server,tmux,console,shell,git` -_(96 chars — adjust if App Store Connect reports over.)_ - -## URLs -- **Support URL:** _needs a page_ — e.g. the repo or a Clawnify support page. -- **Marketing URL (optional):** a Clawnify/Ateam landing page if one exists. -- **Privacy Policy URL:** host `privacy-policy.md` (see that file's footer). - -## Age-rating questionnaire → all "None" / "No" -Cartoon/fantasy violence, realistic violence, sexual content, nudity, profanity, alcohol/ -tobacco/drugs, gambling, horror, mature themes, medical info, contests: **None**. -Unrestricted web access: **No** (the dev-server preview opens only a user-entered address on -their own network; not a general browser). → **Result: 4+**. - -## App Privacy ("nutrition label") → Data Not Collected -Declare **"Data Not Collected."** Rationale: -- No analytics, no accounts, no ads, no tracking SDKs. -- Photos the user attaches and all terminal traffic go to **the user's own server**, not to - Clawnify — this is not "collection" by the developer. -- Local settings (last box, project, port) stay on-device. -If App Store Connect pushes back on the photo point, the honest framing is: the app *accesses* -photos on device at the user's request and transmits the chosen one to the user's own server; the -developer neither collects nor receives it. - -## Encryption / export compliance -Already declared in `app.json`: `ITSAppUsesNonExemptEncryption: false` (only OS-standard -TLS/SSH/WebSocket; no proprietary crypto). No extra paperwork. diff --git a/docs/appstore/review-notes.md b/docs/appstore/review-notes.md deleted file mode 100644 index fae786f..0000000 --- a/docs/appstore/review-notes.md +++ /dev/null @@ -1,40 +0,0 @@ -# App Review Notes — Ateam Go - -_Paste into App Store Connect → App Review Information → Notes._ - ---- - -Ateam Go is a **local-first** remote control for AI coding agents (e.g. Claude Code) that a -developer runs on **their own server**. It is the companion to our macOS desktop app. - -**There is no account and no Clawnify-operated backend.** In normal use the app connects over the -user's own private [Tailscale](https://tailscale.com) network to a server the user operates. Because -that server is private to each user, we **cannot** provide demo credentials that reach "our" -backend — there is no shared backend. - -**Per Guideline 2.1, we provide a fully-featured built-in demo instead of a demo account.** - -## How to review the app - -1. Launch the app. On the first screen, tap **"Try the demo — no box needed"** (below the connection - form). -2. You'll land on the **board**, populated with sample tasks across the columns (Needs You / In - Progress / Review / Backlog / Done). -3. **Tap any task** to open its terminal — you'll see a representative AI coding-agent session. -4. The **composer** at the bottom creates a sample task; the **paperclip** in a task's terminal - attaches a photo; the **↗** button in the board header is a dev-server preview. - -Demo mode runs **entirely offline** with fabricated data — no login, no network, no external -resources required. - -## Notes on permissions - -- **Photo library**: requested only if the reviewer taps the attach (paperclip) button. Used solely - to let the user pick an image to send to their own server. No photos are sent to Clawnify. - -## Real-world use (context, not required to review) - -Outside demo mode, a user installs our open server on their own machine and connects over Tailscale. -There is nothing for Apple to provision. Everything a reviewer needs is in the demo. - -Contact for anything: **pallaororm@gmail.com** diff --git a/docs/appstore/privacy-policy.md b/docs/privacy-policy.md similarity index 95% rename from docs/appstore/privacy-policy.md rename to docs/privacy-policy.md index b7850ff..775d0c2 100644 --- a/docs/appstore/privacy-policy.md +++ b/docs/privacy-policy.md @@ -50,7 +50,7 @@ posted at this URL. ## Contact -Questions: **pallaororm@gmail.com** +Questions: **_[set a support/privacy contact address before publishing — e.g. privacy@clawnify.com]_** --- diff --git a/docs/publishing-ios.md b/docs/publishing-ios.md deleted file mode 100644 index 695c453..0000000 --- a/docs/publishing-ios.md +++ /dev/null @@ -1,124 +0,0 @@ -# Publishing the Ateam iOS app (TestFlight → App Store) - -The mobile app (`apps/mobile`) is an Expo SDK 52 **bare** app: `app.json` is the -source of truth and the native `ios/` project is **generated by `expo prebuild`** -(it's git-ignored — never hand-edit `ios/` and expect it to stick). The vendored -SwiftTerm terminal lives in the tracked `modules/expo-swiftterm` Expo module and -**re-autolinks on every prebuild**, so regenerating `ios/` is safe. - -## Distribution strategy - -Ship on **internal TestFlight first**, then widen only once onboarding is solved. -Why (the full reasoning is in the `/scalable` ruling in chat, condensed here): - -- **Internal TestFlight** — up to 100 team testers, **no App Review**, installs - immediately. This is OTA to your phone with zero gatekeeping. Start here. -- **External TestFlight** (up to 10k) and a **public App Store listing** both trigger - **Beta/App Review**, which requires a reviewer to reach a *working* backend. Ateam - needs a proprietary `ateam daemon` a reviewer can't stand up, so both need a - **review-only demo box** (see below). Same uploaded build, more rings flipped on — - no rebuild, no rework. -- **TestFlight builds expire after 90 days.** Your release cadence already beats that; - automate the upload (EAS or CI) rather than hand-cranking Xcode each quarter. - -## One-time setup - -1. **Apple Developer Program** — team **`X2VZX44YM2`** (the same Clawnify publishing - team used for the macOS releases; your macOS Developer ID proves it's enrolled). -2. **App Store Connect** → **My Apps → +** → new app: - - Platform: iOS · Bundle ID: **`com.clawnify.ateam`** · SKU: `ateam-mobile`. - - The bundle ID must first be registered as an App ID in **Certificates, - Identifiers & Profiles → Identifiers** (Explicit, no capabilities) under team - `X2VZX44YM2`, then it appears in the New App dialog's dropdown. It's permanent - once the app record exists. -3. **Signing** — easiest is Xcode's *Automatically manage signing* with team - `X2VZX44YM2`; it provisions the Apple Distribution cert + App Store profile. - -## Per-release checklist - -`app.json` already carries the release identity: - -| Field | Value | Becomes (native) | -| --- | --- | --- | -| `expo.name` | `Ateam Go` | `CFBundleDisplayName` (name under the icon; matches the App Store name) | -| `expo.version` | `1.0.0` | `CFBundleShortVersionString` (marketing version) | -| `expo.ios.buildNumber` | `1` | `CFBundleVersion` (**must increase every upload**) | -| `expo.ios.infoPlist.ITSAppUsesNonExemptEncryption` | `false` | skips the export-compliance prompt on every upload¹ | - -**Bump `ios.buildNumber` on every TestFlight upload** (App Store Connect rejects a -duplicate `version`+`buildNumber` pair). Keep `version` until you cut a user-visible -release. - -¹ Declares the app uses only standard/exempt encryption (OS-provided TLS/SSH/WebSocket — -no custom crypto). Correct for Ateam; revisit if you ever add proprietary encryption. - -## Toolchain requirements (Xcode 26) - -Apple requires builds made with **Xcode 26 / the iOS 26 SDK**. That needs **macOS ≥ 26**, -and Xcode 26 splits several pieces into on-demand downloads — install them once: - -```bash -sudo xcodebuild -license accept && sudo xcodebuild -runFirstLaunch -xcodebuild -downloadPlatform iOS # device platform (~8.5 GB) — separate from the SDK -xcodebuild -downloadComponent MetalToolchain # ~688 MB — the SwiftTerm .metal shaders need it -``` - -Build with **Node ≥ 20.19.4** (SDK 54 requirement). The repo already carries the SDK-54 -fixes: `.npmrc` (legacy-peer-deps), `plugins/withFmtConstevalFix.js` (fmt→C++17 for Xcode 26), -`newArchEnabled: false` (keep legacy arch so SwiftTerm needs no Fabric rewrite), and a Metro -config that resolves nested transitive deps. - -## Build & upload — Route A: local archive (proven) - -```bash -cd apps/mobile -# bump ios.buildNumber in app.json first (App Store Connect rejects a duplicate version+build) -npx expo prebuild -p ios # regenerate ios/ (applies the fmt plugin; SwiftTerm re-autolinks) -( cd ios && pod install ) # ensure the fmt→C++17 Podfile change lands in the Pods project - -xcodebuild -workspace ios/AteamGo.xcworkspace -scheme AteamGo \ - -configuration Release -destination 'generic/platform=iOS' \ - -archivePath build/AteamGo.xcarchive \ - DEVELOPMENT_TEAM=X2VZX44YM2 CODE_SIGN_STYLE=Automatic -allowProvisioningUpdates archive -xcodebuild -exportArchive -archivePath build/AteamGo.xcarchive \ - -exportOptionsPlist ios/ExportOptions.plist -exportPath build/export -allowProvisioningUpdates -xcrun altool --upload-app -f build/export/AteamGo.ipa -t ios \ - --apiKey 5H64P4APJ8 --apiIssuer # Team API key in ~/.appstoreconnect/private_keys/ -``` - -`ios/ExportOptions.plist` (regenerate after `prebuild --clean`): `method` = `app-store-connect`, -`teamID` = `X2VZX44YM2`, `signingStyle` = `automatic`. Automatic signing + `-allowProvisioningUpdates` -mints the Apple Distribution cert on first run. - -## Build & upload — Route B: EAS (scalable follow-up) - -Cloud-reproducible and CI-friendly, but needs an `eas.json` + credentials setup that -must account for the bun workspace + vendored native module. Do this **after** a first -successful manual submission, not as the way in: - -```bash -bunx eas-cli build -p ios --profile production -bunx eas-cli submit -p ios --latest -``` - -## After upload - -1. App Store Connect processes the build (~5–15 min). -2. **TestFlight** tab → add yourself under **Internal Testing** (no review) → install - the TestFlight app on your phone. Every later upload is OTA to all testers. -3. Each build is usable for **90 days**; ship a fresh one before it lapses. - -## Going wider (external testers / public listing) - -Both need a reviewer to exercise a live backend. Provide it via **App Review -Information → Demo account**: - -- Run a **review-only `ateam daemon`** on a box you control, with a demo project and - baked-in demo connection details. Keep it live during review (*"backend services - must be enabled and live"* — Apple guideline 2.1). -- This stays review-only, so it doesn't compromise Ateam's **local-first** model — - real users still self-host their own box (see [online-ateam.md](./online-ateam.md)). - -A public listing additionally needs: a real app name that isn't taken, a privacy -policy URL, an age rating, and screenshots. The app icon (`assets/icon.png`) is -already 1024×1024 with no alpha — App Store compliant. From eadb5066febd80dea3be86360c7349e0a77d03b0 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Sun, 2 Aug 2026 13:32:59 +0200 Subject: [PATCH 66/83] feat(mobile): add local-network permission + ateamgo:// deep links - NSLocalNetworkUsageDescription: connecting to a box over a LAN IP trips iOS's local-network privacy; without the string users get a generic prompt or a silent failure. Surfaced by a pre-submission App Review self-audit. - ateamgo:// URL scheme + a Linking handler: ateamgo://demo enters the offline demo, a trailing /task/ opens that task's terminal, /preview opens the preview modal. Primarily for driving screens for App Store screenshots, but a real deep-link primitive. Goes in the next TestFlight build (buildNumber bump deferred to that build). --- apps/mobile/App.tsx | 26 ++++++++++++++++++++++++++ apps/mobile/app.json | 4 +++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/mobile/App.tsx b/apps/mobile/App.tsx index 6d82998..1c4b525 100644 --- a/apps/mobile/App.tsx +++ b/apps/mobile/App.tsx @@ -771,6 +771,32 @@ export default function App() { })(); }, []); + // Deep links, mainly for driving the app to a screen for App Store screenshots + // (xcrun simctl openurl ateamgo://demo[/task/|/preview]). `ateamgo://demo` + // enters the offline demo; a trailing /task/ opens that task's terminal. + useEffect(() => { + const handle = (url: string | null): void => { + if (!url?.startsWith("ateamgo://demo")) return; + void (async () => { + await startDemo(); + const api = conn.current?.api; + if (!api) return; + const taskId = url.match(/\/task\/([^/?#]+)/)?.[1]; + if (taskId) { + const projs = await api.projects.list(); + const all = (await Promise.all(projs.map((p) => api.tasks.list(p.id)))).flat(); + const t = all.find((x) => x.id === taskId || x.slug === taskId); + if (t) setOpenTask(t); + } else if (url.includes("/preview")) { + setPreviewOpen(true); + } + })(); + }; + void Linking.getInitialURL().then(handle); + const sub = Linking.addEventListener("url", (e) => handle(e.url)); + return () => sub.remove(); + }, [startDemo]); + const onDisconnect = useCallback(() => { target.current = null; // intent: stay disconnected — no auto-reattach if (retryTimer.current) { diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 2131664..682c2e8 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -2,6 +2,7 @@ "expo": { "name": "Ateam Go", "slug": "ateam", + "scheme": "ateamgo", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", @@ -21,7 +22,8 @@ "bundleIdentifier": "com.clawnify.ateam", "buildNumber": "6", "infoPlist": { - "ITSAppUsesNonExemptEncryption": false + "ITSAppUsesNonExemptEncryption": false, + "NSLocalNetworkUsageDescription": "Ateam connects to a coding-agent server you run on your own machine or local network." } }, "android": { From 0573cf4a7137b5ac1993cb386a8979bf2d855fda Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 4 Aug 2026 15:09:45 +0200 Subject: [PATCH 67/83] =?UTF-8?q?chore(mobile):=20bump=20iOS=20build=206?= =?UTF-8?q?=E2=86=927,=20check=20in=20ExportOptions.plist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build 7 uploaded to TestFlight (adds NSLocalNetworkUsageDescription + ateamgo:// deep links over build 6). ExportOptions.plist previously lived only in the gitignored build/ dir and had to be reconstructed each release — tracking it makes the app-store-connect export reproducible. --- apps/mobile/ExportOptions.plist | 16 ++++++++++++++++ apps/mobile/app.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 apps/mobile/ExportOptions.plist diff --git a/apps/mobile/ExportOptions.plist b/apps/mobile/ExportOptions.plist new file mode 100644 index 0000000..69dac53 --- /dev/null +++ b/apps/mobile/ExportOptions.plist @@ -0,0 +1,16 @@ + + + + + method + app-store-connect + teamID + X2VZX44YM2 + signingStyle + automatic + uploadSymbols + + destination + export + + diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 682c2e8..5833c51 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -20,7 +20,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.clawnify.ateam", - "buildNumber": "6", + "buildNumber": "7", "infoPlist": { "ITSAppUsesNonExemptEncryption": false, "NSLocalNetworkUsageDescription": "Ateam connects to a coding-agent server you run on your own machine or local network." From 21f3dcafc52935cc724024a79561725d1a1234fa Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 4 Aug 2026 15:20:08 +0200 Subject: [PATCH 68/83] chore: release 0.1.30 --- apps/desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index e6b9bdc..43688a3 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@ateam/desktop", - "version": "0.1.29", + "version": "0.1.30", "private": true, "main": "./out/main/index.js", "scripts": { From d8a48ac8a64bc4f332c81c200bc5ed3b87c10c93 Mon Sep 17 00:00:00 2001 From: pallaoro Date: Tue, 4 Aug 2026 17:45:42 +0200 Subject: [PATCH 69/83] Desktop: per-task remote environments (run a task on a connected box) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hold multiple engines at once (this Mac + SSH boxes) and pick, per task, where it runs — the "Run on" pill in the New Task dialog. The engine seam is wired through the pre-existing multi-engine aggregate (routes each call to the owning engine by id), so no protocol/version churn. - main/host.ts: single-active swap → a Map + createAggregate as the router; additive connect + disconnect + connected() + origins(); events forwarded from every held engine. New provision(alias,{cloneUrl}) targets a specific box. - renderer: unify.ts groups the merged projects into one card per repo (by git identity), members = each engine's projectId; the composer's EnvironmentPicker (the old connection pill, moved into the dialog) picks Local or a box. - A box already holding the repo runs the task with no clone (aggregation surfaces it, the iOS model); a box without it clones+registers once from the repo's git remote (projects:clone), then reuses it. Gate is the repo's real `git remote`, not GitHub detection. Top-right global switcher removed. Bumps desktop 0.1.30 → 0.1.31. --- apps/desktop/package.json | 2 +- apps/desktop/src/main/host.ts | 128 +++++-- apps/desktop/src/preload/index.ts | 14 +- apps/desktop/src/renderer/src/App.tsx | 338 +++++++++++++----- .../src/components/ConnectionSwitcher.tsx | 216 ----------- .../src/components/EnvironmentPicker.tsx | 113 ++++++ .../src/components/NewTaskComposer.tsx | 15 +- apps/desktop/src/renderer/src/unify.test.ts | 58 +++ apps/desktop/src/renderer/src/unify.ts | Bin 0 -> 3016 bytes apps/desktop/src/shared/host.ts | 36 +- apps/desktop/tsconfig.web.json | 17 +- packages/git-core/src/index.ts | 8 +- packages/git-core/src/project.ts | 63 +++- packages/protocol/src/client-api.ts | 1 + packages/protocol/src/index.ts | 8 + packages/server/src/dispatcher.ts | 26 ++ 16 files changed, 657 insertions(+), 386 deletions(-) delete mode 100644 apps/desktop/src/renderer/src/components/ConnectionSwitcher.tsx create mode 100644 apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx create mode 100644 apps/desktop/src/renderer/src/unify.test.ts create mode 100644 apps/desktop/src/renderer/src/unify.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 43688a3..4ae741b 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@ateam/desktop", - "version": "0.1.30", + "version": "0.1.31", "private": true, "main": "./out/main/index.js", "scripts": { diff --git a/apps/desktop/src/main/host.ts b/apps/desktop/src/main/host.ts index 51554f2..addfd25 100644 --- a/apps/desktop/src/main/host.ts +++ b/apps/desktop/src/main/host.ts @@ -1,14 +1,16 @@ -// The connection controller: which engine drives the app, and swapping between -// them. Owns the always-alive local engine, the currently-active Backend, and the -// forwarding of that backend's push-events to the renderer. Connecting to a remote -// host opens an SSH transport (the `attach` relay over OpenSSH), handshakes (gating -// the protocol version), caches the result, and re-points the active backend + -// event stream at it. -import { ipcMain } from "electron"; +// The connection controller: which engines drive the app. Owns the always-alive +// local engine and holds any connected boxes CONCURRENTLY — one board unions their +// tasks, each task's "environment" being the engine that owns it. Every call is +// routed to the owning engine by createAggregate (main/aggregate.ts); every held +// engine's push-events are forwarded to the renderer. Connecting to a box opens an +// SSH transport (the `attach` relay over OpenSSH), handshakes (gating the protocol +// version), and ADDS it — connecting never drops the others. + import { CH, createRpcClient, PROTOCOL_VERSION, + type ProjectDTO, type RpcClient, type SystemInfo, } from "@ateam/protocol"; @@ -19,8 +21,16 @@ import { recordConnection, sshClientTransport, } from "@ateam/server"; -import { type Backend, type BackendEvent, localBackend, remoteBackend, type Router } from "./backend"; +import { ipcMain } from "electron"; import { HOST_CH, type HostStatus } from "../shared/host"; +import { type Aggregate, createAggregate } from "./aggregate"; +import { + type Backend, + type BackendEvent, + localBackend, + type Router, + remoteBackend, +} from "./backend"; // The one pre-quoted remote command (ssh space-joins remote args, so `bash -lc` // must arrive as a single element): a login shell (agent-CLI PATH) execing the @@ -30,7 +40,7 @@ const REMOTE_ATTACH = "bash -lc 'exec ateam attach --stdio'"; // error, and the UI must not wait forever. A live daemon replies in well under this. const CONNECT_TIMEOUT_MS = 20_000; -/** The push-events forwarded from the active backend to every window. */ +/** The push-events forwarded from every held backend to every window. */ const FORWARDED: { event: BackendEvent; channel: string }[] = [ { event: "taskUpdated", channel: CH.evtTaskUpdated }, { event: "taskRemoved", channel: CH.evtTaskRemoved }, @@ -45,7 +55,12 @@ export interface Host { readonly router: Router; list(): Promise; connect(alias: string | null): Promise; - current(): Promise; + disconnect(alias: string): void; + connected(): Promise; + /** id → owning-engine alias (null = local), from the aggregate's learned registry. */ + origins(): Record; + /** Connect the box if needed, then clone+register a repo ON it (from its remote URL). */ + provision(alias: string, input: { cloneUrl: string }): Promise; } export interface HostDeps { @@ -59,11 +74,17 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { const db = localEngine.services.db; const local = localBackend(localEngine); - let active: Backend = local; - let activeAlias: string | null = null; - // Bind the local engine's events immediately so it forwards from startup; swaps - // re-bind. Guarded by getWin() at emit time, so a not-yet-created window is fine. - let unbindEvents: () => void = bindEvents(local); + // alias → backend; `null` is the always-held local engine (insertion order: local + // first). Boxes are added on connect and removed on disconnect. + const backends = new Map([[null, local]]); + // Per-alias event unsubscribers, so disconnecting one box stops only its stream. + const unbinders = new Map void>(); + + // One aggregate over a LIVE backend array: connecting pushes onto it (so the + // learned id→engine registry survives), disconnecting rebuilds a fresh one (so a + // gone engine's ids stop routing). Both share the same array reference. + const backendList: Backend[] = [local]; + let agg: Aggregate = createAggregate(backendList, local); function bindEvents(backend: Backend): () => void { const offs = FORWARDED.map(({ event, channel }) => @@ -73,28 +94,27 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { for (const off of offs) off(); }; } + // Forward the local engine's events from startup; each connected box adds its own. + unbinders.set(null, bindEvents(local)); async function statusOf(backend: Backend, alias: string | null): Promise { const info = (await backend.handle(CH.systemHello, [])) as SystemInfo; return { mode: backend.kind, alias, info }; } - function swap(next: Backend, alias: string | null): void { - // Never dispose the local engine — it stays alive as the default backend and - // owns the connections-registry db. - if (active !== local && active !== next) active.dispose(); - unbindEvents(); - active = next; - activeAlias = alias; - unbindEvents = bindEvents(next); - void statusOf(next, alias).then((status) => broadcast(HOST_CH.evtChanged, status)); + function connected(): Promise { + return Promise.all([...backends.entries()].map(([alias, b]) => statusOf(b, alias))); + } + + function broadcastConnections(): void { + void connected().then((list) => broadcast(HOST_CH.evtConnectionsChanged, list)); } async function connect(alias: string | null): Promise { - if (alias === null) { - swap(local, null); - return statusOf(local, null); - } + // local is permanent; connecting to it (or to an already-held box) is a no-op. + if (alias === null) return statusOf(local, null); + const existing = backends.get(alias); + if (existing) return statusOf(existing, alias); const client = sshClientTransport(alias, [REMOTE_ATTACH]); const rpc: RpcClient = createRpcClient(client.transport); @@ -118,20 +138,59 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { agentsAvailable: info.agents, }); // The remote's method set matches the local dispatcher's (same contract). - swap(remoteBackend(rpc, local.methods, client.close), alias); + const backend = remoteBackend(rpc, local.methods, client.close); + backends.set(alias, backend); + backendList.push(backend); // the live aggregate now fans out to it too + unbinders.set(alias, bindEvents(backend)); + broadcastConnections(); return { mode: "remote", alias, info }; } + function disconnect(alias: string): void { + const backend = backends.get(alias); + if (!backend) return; // unknown alias / already gone (null never routes here — it's not a key) + unbinders.get(alias)?.(); + unbinders.delete(alias); + backend.dispose(); + backends.delete(alias); + const i = backendList.indexOf(backend); + if (i >= 0) backendList.splice(i, 1); + // Rebuild so the learned registry drops the gone engine's ids (no stale routing). + agg = createAggregate(backendList, local); + broadcastConnections(); + } + + function origins(): Record { + // Invert the aggregate's learned id→Backend registry into id→alias for the renderer. + const byBackend = new Map(); + for (const [alias, b] of backends) byBackend.set(b, alias); + const out: Record = {}; + for (const [id, b] of agg.ownerOf) out[id] = byBackend.get(b) ?? null; + return out; + } + + async function provision(alias: string, input: { cloneUrl: string }): Promise { + // Provisioning targets a SPECIFIC engine — the aggregate routes by learned id, + // but there's no id on the box yet, so call that backend's clone directly. + await connect(alias); // idempotent if already held + const backend = backends.get(alias); + if (!backend) throw new Error(`Not connected to "${alias}"`); + return backend.handle(CH.projectsClone, [input]) as Promise; + } + const router: Router = { methods: local.methods, - handle: (method, args) => active.handle(method, args), + handle: (method, args) => agg.handle(method, args), }; return { router, list: async (): Promise => listConnections(db), connect, - current: (): Promise => statusOf(active, activeAlias), + disconnect, + connected, + origins, + provision, }; } @@ -139,7 +198,12 @@ export function createHost({ localEngine, broadcast }: HostDeps): Host { export function registerHostIpc(host: Host): void { ipcMain.handle(HOST_CH.list, () => host.list()); ipcMain.handle(HOST_CH.connect, (_e, alias: string | null) => host.connect(alias)); - ipcMain.handle(HOST_CH.current, () => host.current()); + ipcMain.handle(HOST_CH.disconnect, (_e, alias: string) => host.disconnect(alias)); + ipcMain.handle(HOST_CH.connected, () => host.connected()); + ipcMain.handle(HOST_CH.origins, () => host.origins()); + ipcMain.handle(HOST_CH.provision, (_e, alias: string, input: { cloneUrl: string }) => + host.provision(alias, input), + ); } /** Reject (and clean up) if a promise doesn't settle in time. */ diff --git a/apps/desktop/src/preload/index.ts b/apps/desktop/src/preload/index.ts index b4b89f0..485ee92 100644 --- a/apps/desktop/src/preload/index.ts +++ b/apps/desktop/src/preload/index.ts @@ -15,6 +15,7 @@ const api: AteamApi = { projects: { pick: () => ipcRenderer.invoke(CH.projectsPick), register: (repoPath, opts) => ipcRenderer.invoke(CH.projectsRegister, repoPath, opts), + remoteUrl: (projectId) => ipcRenderer.invoke(CH.projectsRemoteUrl, projectId), list: () => ipcRenderer.invoke(CH.projectsList), remove: (id) => ipcRenderer.invoke(CH.projectsRemove, id), }, @@ -112,11 +113,14 @@ contextBridge.exposeInMainWorld("ateam", api); const host: AteamHost = { list: () => ipcRenderer.invoke(HOST_CH.list), connect: (alias) => ipcRenderer.invoke(HOST_CH.connect, alias), - current: () => ipcRenderer.invoke(HOST_CH.current), - onChanged: (cb: (status: HostStatus) => void) => { - const handler = (_: unknown, status: HostStatus) => cb(status); - ipcRenderer.on(HOST_CH.evtChanged, handler); - return () => ipcRenderer.off(HOST_CH.evtChanged, handler); + disconnect: (alias) => ipcRenderer.invoke(HOST_CH.disconnect, alias), + connected: () => ipcRenderer.invoke(HOST_CH.connected), + origins: () => ipcRenderer.invoke(HOST_CH.origins), + provision: (alias, input) => ipcRenderer.invoke(HOST_CH.provision, alias, input), + onConnectionsChanged: (cb: (connected: HostStatus[]) => void) => { + const handler = (_: unknown, connected: HostStatus[]) => cb(connected); + ipcRenderer.on(HOST_CH.evtConnectionsChanged, handler); + return () => ipcRenderer.off(HOST_CH.evtConnectionsChanged, handler); }, }; diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index cfd2af0..2b0eda8 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -1,3 +1,11 @@ +import type { + AgentDTO, + ConnectionDTO, + DiffResultDTO, + KanbanColumn, + ProjectDTO, + TaskDTO, +} from "@ateam/protocol"; import { ArrowDownToLine, ArrowUp, @@ -50,16 +58,8 @@ import { useRef, useState, } from "react"; -import type { - AgentDTO, - DiffResultDTO, - KanbanColumn, - ProjectDTO, - TaskDTO, -} from "@ateam/protocol"; import { AgentIcon } from "./components/AgentIcon"; import { CleanupDialog } from "./components/CleanupDialog"; -import { ConnectionSwitcher } from "./components/ConnectionSwitcher"; import { FileDiffView } from "./components/FileDiffView"; import { IconButton } from "./components/IconButton"; import { LoopsPanel } from "./components/LoopsPanel"; @@ -67,6 +67,7 @@ import { Menu } from "./components/Menu"; import { NewTaskComposer } from "./components/NewTaskComposer"; import { TerminalView } from "./components/Terminal"; import { usePrompt } from "./components/usePrompt"; +import { type Alias, aliasLabel, type UnifiedProject, unifyProjects } from "./unify"; const COLUMNS: { key: KanbanColumn; label: string }[] = [ { key: "todo", label: "Backlog" }, @@ -127,6 +128,15 @@ export function App() { // hides the project switcher; null in the main multi-project dashboard. const boundProjectId = useMemo(() => window.ateam.window.boundProjectId(), []); const [projects, setProjects] = useState([]); + // projectId/taskId → owning engine alias (null = local). Learned by the main-process + // aggregate from every engine's reads; drives unification + per-task origin badges. + const [origins, setOrigins] = useState>({}); + // The ~/.ssh/config boxes a task can be sent to run on (the composer's "Run on" + // list). Connecting + cloning the repo onto one happens at task-create time. + const [connections, setConnections] = useState([]); + // The active repo's `origin` remote URL (null = local-only). A task can go remote + // only if there's a remote to clone the project from onto the box. + const [activeRepoRemote, setActiveRepoRemote] = useState(null); const [activeProjectId, setActiveProjectId] = useState(null); const [tasksByProject, setTasksByProject] = useState>({}); const [selectedTaskId, setSelectedTaskId] = useState(null); @@ -208,11 +218,25 @@ export function App() { }, []); const loadProjects = useCallback(async () => { + // projects.list() merges every connected engine's projects (main/aggregate.ts); + // origins() then reports which engine owns each, learned during that same read. const list = await window.ateam.projects.list(); - // A detached window shows only its pinned project. const scoped = boundProjectId ? list.filter((p) => p.id === boundProjectId) : list; setProjects(scoped); - setActiveProjectId((cur) => boundProjectId ?? cur ?? scoped[0]?.id ?? null); + setOrigins(await window.ateamHost.origins()); + setActiveProjectId((cur) => { + if (boundProjectId) return boundProjectId; + // Keep the current project only if it still exists (a box may have dropped). + if (cur && scoped.some((p) => p.id === cur)) return cur; + return scoped[0]?.id ?? null; + }); + // Drop task buckets for projects that vanished (e.g. a disconnected box). + setTasksByProject((prev) => { + const live = new Set(scoped.map((p) => p.id)); + const next: Record = {}; + for (const [pid, tks] of Object.entries(prev)) if (live.has(pid)) next[pid] = tks; + return next; + }); }, [boundProjectId]); useEffect(() => { @@ -254,20 +278,27 @@ export function App() { if (activeProjectId) void loadTasks(activeProjectId); }, [activeProjectId, loadTasks]); - // Switching the active engine (this Mac ⇄ a remote box) means an entirely - // different set of projects/tasks/agents — every window is notified, so drop - // the current selection and reload from whichever engine is now driving. + // Engines are held concurrently now: connecting a box or dropping one doesn't + // swap the world, it changes which engines' projects are in the union. Reconcile + // additively — reload the merged projects/origins/agents WITHOUT wiping the + // current selection (loadProjects keeps the active project if it still exists and + // prunes tasks for any engine that vanished). useEffect(() => { - return window.ateamHost.onChanged(() => { - setSelectedTaskId(null); - setActiveProjectId(null); - setTasksByProject({}); - setTermByTask({}); + return window.ateamHost.onConnectionsChanged(() => { void loadProjects(); void window.ateam.agents.list().then(setAgents); }); }, [loadProjects]); + // The ~/.ssh/config box list for the composer's "Run on" picker, kept fresh as + // boxes connect/disconnect (their lastSeen updates too). + useEffect(() => { + void window.ateamHost.list().then(setConnections); + return window.ateamHost.onConnectionsChanged(() => { + void window.ateamHost.list().then(setConnections); + }); + }, []); + // Load every project's tasks so non-selected projects can surface their // attention state (pulsing dot); evtTaskUpdated keeps them fresh after. useEffect(() => { @@ -282,19 +313,77 @@ export function App() { if (p) document.title = p.name; }, [boundProjectId, projects]); - // Highest-priority alert among a non-selected project's tasks. - const projectAlert = (pid: string): "needs_attention" | "review" | null => { - if (pid === activeProjectId) return null; - const list = tasksByProject[pid] ?? []; + // Highest-priority alert among a non-selected card's tasks (across all its engines). + const cardAlert = (card: UnifiedProject): "needs_attention" | "review" | null => { + if (card.members.some((m) => m.projectId === activeProjectId)) return null; + const list = card.members.flatMap((m) => tasksByProject[m.projectId] ?? []); if (list.some((t) => t.column === "needs_attention")) return "needs_attention"; if (list.some((t) => t.column === "review")) return "review"; return null; }; // The project a detached window is pinned to (for its static header). - const boundProject = boundProjectId ? (projects.find((p) => p.id === boundProjectId) ?? null) : null; + const boundProject = boundProjectId + ? (projects.find((p) => p.id === boundProjectId) ?? null) + : null; + + // Group the merged projects into one card per repo (same GitHub owner/name across + // engines), remembering each engine's projectId — the routing key for its tasks. + const unifiedProjects = useMemo(() => unifyProjects(projects, origins), [projects, origins]); + // The card the active project belongs to, and every engine holding that repo. + const activeCard = useMemo( + () => + unifiedProjects.find((c) => c.members.some((m) => m.projectId === activeProjectId)) ?? null, + [unifiedProjects, activeProjectId], + ); + const activeMembers = activeCard?.members ?? []; + // Which engine a task runs on = the engine that owns its project (tasks never + // migrate between engines, so origin is intrinsic to the projectId). + const originOf = useCallback((projectId: string): Alias => origins[projectId] ?? null, [origins]); + + // "Run on" options for a new task: this Mac (if the repo is here) + every + // ~/.ssh/config box. A box clones the project from its git remote, so boxes are + // disabled for a repo with no remote (nothing to clone). + const activeRepoProjectId = + activeCard?.members.find((m) => m.alias === null)?.projectId ?? + activeCard?.members[0]?.projectId ?? + null; + // Fetch the active repo's remote from its owning engine whenever the card changes. + useEffect(() => { + if (!activeRepoProjectId) { + setActiveRepoRemote(null); + return; + } + let cancelled = false; + void window.ateam.projects.remoteUrl(activeRepoProjectId).then((url) => { + if (!cancelled) setActiveRepoRemote(url); + }); + return () => { + cancelled = true; + }; + }, [activeRepoProjectId]); + const canRemote = activeRepoRemote !== null; + const hasLocalMember = activeMembers.some((m) => m.alias === null); + const composerEnvs = useMemo(() => { + // A box is runnable if it ALREADY has this repo (a member — no clone needed) or + // the repo has a remote we could clone onto it. + const memberAliases = new Set(activeMembers.map((m) => m.alias)); + return [ + { alias: null as Alias, label: "Local", disabled: !hasLocalMember }, + ...connections.map((c) => ({ + alias: c.alias, + label: c.alias, + disabled: !memberAliases.has(c.alias) && !canRemote, + })), + ]; + }, [connections, canRemote, hasLocalMember, activeMembers]); - const activeTasks = activeProjectId ? (tasksByProject[activeProjectId] ?? []) : []; + // The active card's board unions tasks from every engine that has the repo. + const activeTasks = activeCard + ? activeMembers.flatMap((m) => tasksByProject[m.projectId] ?? []) + : activeProjectId + ? (tasksByProject[activeProjectId] ?? []) + : []; const selectedTask = activeTasks.find((t) => t.id === selectedTaskId) ?? null; // Sidebar list shows all tasks, including merged/done ones. const sidebarTasks = activeTasks; @@ -471,15 +560,53 @@ export function App() { agentId: string; yolo: boolean; files: string[]; + // Chosen environment: null = this Mac; an alias = that box. A box is connected + // and the repo cloned onto it (idempotent) before the task is created there. + alias: Alias; }) => run(async () => { - if (!activeProjectId) return; + const card = activeCard; + if (!card) return; setComposerOpen(false); - const task = await window.ateam.tasks.create({ - projectId: activeProjectId, - name: input.name, - }); - await loadTasks(activeProjectId); + // Resolve the engine's project row for this repo on the chosen environment. + let projectId: string; + if (input.alias === null) { + const localMember = card.members.find((m) => m.alias === null); + if (!localMember) { + setError("This repo isn't on your Mac."); + return; + } + projectId = localMember.projectId; + } else { + // If the box already has this repo (it's a member of the card, surfaced by + // aggregation), use it directly — no clone, no provision. This is the iOS + // path: the box already has its repos, you just create tasks against them. + const existing = card.members.find((m) => m.alias === input.alias); + if (existing) { + projectId = existing.projectId; + } else { + // First task on this box for this repo: it isn't here yet, so clone + + // register it from the repo's remote, then route the create to it. + if (!activeRepoRemote) { + setError("This repo has no git remote to clone onto a box."); + return; + } + setInfo(`Setting up ${card.name} on ${input.alias}…`); + let proj: ProjectDTO; + try { + proj = await window.ateamHost.provision(input.alias, { cloneUrl: activeRepoRemote }); + } finally { + setInfo(null); + } + // Re-list so the aggregate learns proj.id → this box; then create routes there. + await loadProjects(); + projectId = proj.id; + } + } + const task = await window.ateam.tasks.create({ projectId, name: input.name }); + // The created task's project is a member of the active card, so its tasks + // are already unioned into the board once loaded. + await loadTasks(projectId); setSelectedTaskId(task.id); // Keep whatever panel mode the user is already in: if they're // browsing the board (side), open the new task beside it; if they're @@ -517,20 +644,27 @@ export function App() {
      - {projects.map((p) => { - const alert = projectAlert(p.id); + {unifiedProjects.map((card) => { + const alert = cardAlert(card); + const primary = card.members.find((m) => m.alias === null) ?? card.members[0]; + if (!primary) return null; + const active = card.members.some((m) => m.projectId === activeProjectId); return ( ); @@ -598,41 +732,54 @@ export function App() {
      {!projectsCollapsed && - projects.map((p) => { - const alert = projectAlert(p.id); - return ( - // Double-click (or the hover button) detaches the project into its - // own window. Row and open-button are siblings so the button's - // click can't nest inside the row button. -
      window.ateam.window.openProject(p.id)} - > - - - window.ateam.window.openProject(p.id)} - /> - -
      - ); - })} + unifiedProjects.map((card) => { + const alert = cardAlert(card); + // Selecting/detaching acts on the local copy if present, else the first. + const primary = card.members.find((m) => m.alias === null) ?? card.members[0]; + if (!primary) return null; + const active = card.members.some((m) => m.projectId === activeProjectId); + // Show the environments this repo spans (Local · box) when it's on more + // than just this Mac — that's the multi-engine cue. + const multiEnv = + card.members.length > 1 || card.members.some((m) => m.alias !== null); + return ( + // Double-click (or the hover button) detaches the project into its + // own window. Row and open-button are siblings so the button's + // click can't nest inside the row button. +
      window.ateam.window.openProject(primary.projectId)} + > + + + window.ateam.window.openProject(primary.projectId)} + /> + +
      + ); + })} )} @@ -822,14 +969,6 @@ export function App() { New task - {/* Which machine runs the agents — this Mac or a remote box over SSH/ - Tailscale. Global to the app, so only the main window drives it. */} - {!boundProjectId && ( - <> - - - - )}
    @@ -841,6 +980,12 @@ export function App() { selectedId={selectedTaskId} onSelect={selectFromBoard} onDeselect={() => setSelectedTaskId(null)} + // Badge a card only when it runs on a box — Local is the default, so + // tagging it would be noise. `null` = no badge. + originLabel={(t) => { + const a = originOf(t.projectId); + return a ? aliasLabel(a) : null; + }} /> )} {selectedTask && ( @@ -901,9 +1046,10 @@ export function App() { onClose={() => setCleanupOpen(false)} /> )} - {composerOpen && activeProjectId && ( + {composerOpen && activeCard && ( setComposerOpen(false)} onCreate={composeTask} /> @@ -940,11 +1086,7 @@ function TaskRow({ // delete button share the trailing slot and swap in place on hover. return (
    - {t.agentStatus && } - +
    ); @@ -967,11 +1115,14 @@ function Board({ selectedId, onSelect, onDeselect, + originLabel, }: { tasks: TaskDTO[]; selectedId: string | null; onSelect: (id: string) => void; onDeselect: () => void; + /** Engine badge for a task (e.g. a box alias), or null to show none (Local). */ + originLabel: (t: TaskDTO) => string | null; }) { return ( // Clicking empty board space deselects; card clicks stopPropagation. @@ -996,6 +1147,11 @@ function Board({ > {t.agentStatus && }
    {t.name}
    + {originLabel(t) && ( + + {originLabel(t)} + + )}
    {t.branch}
    {t.gitStatus && ( @@ -1188,11 +1344,7 @@ function TaskPanel({ label="Launch agent (asks before dangerous actions)" onClick={() => launch(false)} /> - launch(true)} - /> + launch(true)} /> void }) { - const [current, setCurrent] = useState(null); - const [conns, setConns] = useState([]); - const [connecting, setConnecting] = useState(null); - const [error, setError] = useState(null); - const [pos, setPos] = useState<{ top: number; left: number } | null>(null); - const btnRef = useRef(null); - const popRef = useRef(null); - - const refresh = useCallback(async () => { - const [cur, list] = await Promise.all([ - window.ateamHost.current(), - window.ateamHost.list(), - ]); - setCurrent(cur); - setConns(list); - }, []); - - // Keep the button label live even when another window switches the engine. - useEffect(() => { - void refresh(); - return window.ateamHost.onChanged((status) => { - setCurrent(status); - void window.ateamHost.list().then(setConns); - }); - }, [refresh]); - - const close = () => setPos(null); - const open = () => { - const r = btnRef.current?.getBoundingClientRect(); - if (!r) return; - let left = Math.min(r.left, window.innerWidth - POP_W - 8); - left = Math.max(8, left); - setPos({ top: r.bottom + 6, left }); - setError(null); - void refresh(); - }; - - useEffect(() => { - if (!pos) return; - const onDoc = (e: MouseEvent) => { - const t = e.target as Node; - if (btnRef.current?.contains(t) || popRef.current?.contains(t)) return; - close(); - }; - document.addEventListener("mousedown", onDoc); - return () => document.removeEventListener("mousedown", onDoc); - }, [pos]); - - const pick = async (target: Target) => { - // Already there — just close. - const isActive = - target === "local" ? current?.mode === "local" : current?.alias === target; - if (isActive) { - close(); - return; - } - setConnecting(target); - setError(null); - try { - const status = await window.ateamHost.connect(target === "local" ? null : target); - setCurrent(status); - onChanged?.(status); - close(); - } catch (e) { - // Surface the real reason (box unreachable, daemon not running, protocol - // mismatch) — the main-process connect() throws a descriptive message. - setError(e instanceof Error ? e.message : String(e)); - } finally { - setConnecting(null); - } - }; - - const remote = current?.mode === "remote"; - const label = remote ? (current?.alias ?? "remote") : "Local"; - - return ( - <> - - {pos && - createPortal( -
    -
    - Run agents on - -
    - - {/* Local engine */} - } - title="This Mac" - subtitle="Runs locally, no connection" - active={current?.mode === "local"} - busy={connecting === "local"} - onClick={() => void pick("local")} - /> - -
    - - {conns.length === 0 ? ( -
    - No servers in ~/.ssh/config. -
    - Add a Host entry for your box to connect. -
    - ) : ( - conns.map((c) => { - const seen = ago(c.lastSeen); - const sub = c.hostName - ? c.known && seen - ? `${c.hostName} · seen ${seen}` - : c.hostName - : c.known - ? "saved host (not in ssh config)" - : "unknown host"; - return ( - } - title={c.alias} - subtitle={sub} - active={current?.mode === "remote" && current.alias === c.alias} - busy={connecting === c.alias} - onClick={() => void pick(c.alias)} - /> - ); - }) - )} - - {error && ( -
    - - {error} -
    - )} -
    , - document.body, - )} - - ); -} - -function ConnRow({ - icon, - title, - subtitle, - active, - busy, - onClick, -}: { - icon: React.ReactNode; - title: string; - subtitle: string; - active: boolean; - busy: boolean; - onClick: () => void; -}) { - return ( - - ); -} diff --git a/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx b/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx new file mode 100644 index 0000000..ec71641 --- /dev/null +++ b/apps/desktop/src/renderer/src/components/EnvironmentPicker.tsx @@ -0,0 +1,113 @@ +import { Check, Laptop, Server } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; + +// The task's "Run on" control — the pill + popover style the global connection +// switcher used, moved into the New Task dialog. `null` alias = this Mac; a box alias +// runs the task on that VPS (cloning the project there on first use). Disabled +// options (no git remote to clone from) show why they can't be picked. + +const POP_W = 260; + +export type EnvOption = { alias: string | null; label: string; disabled: boolean }; + +export function EnvironmentPicker({ + environments, + value, + onChange, +}: { + environments: EnvOption[]; + value: string | null; + onChange: (alias: string | null) => void; +}) { + const [pos, setPos] = useState<{ top: number; left: number } | null>(null); + const btnRef = useRef(null); + const popRef = useRef(null); + + const isRemote = value !== null; + const label = environments.find((e) => e.alias === value)?.label ?? "Local"; + + const close = () => setPos(null); + const open = () => { + const r = btnRef.current?.getBoundingClientRect(); + if (!r) return; + const height = Math.min(environments.length * 46 + 44, 340); + const left = Math.max(8, Math.min(r.left, window.innerWidth - POP_W - 8)); + // Open UPWARD — the composer footer sits low in the dialog. + setPos({ top: Math.max(8, r.top - height - 6), left }); + }; + + useEffect(() => { + if (!pos) return; + const onDoc = (e: MouseEvent) => { + const t = e.target as Node; + if (btnRef.current?.contains(t) || popRef.current?.contains(t)) return; + close(); + }; + document.addEventListener("mousedown", onDoc); + return () => document.removeEventListener("mousedown", onDoc); + }, [pos]); + + const pick = (env: EnvOption) => { + if (env.disabled) return; + onChange(env.alias); + close(); + }; + + return ( + <> + + {pos && + createPortal( +
    +
    + Run on +
    + {environments.map((env) => ( + + ))} +
    , + document.body, + )} + + ); +} diff --git a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx index ab87140..d27631c 100644 --- a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx +++ b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx @@ -1,6 +1,7 @@ +import type { AgentDTO } from "@ateam/protocol"; import { ArrowUp, Paperclip, X, Zap } from "lucide-react"; import { useState } from "react"; -import type { AgentDTO } from "@ateam/protocol"; +import { EnvironmentPicker } from "./EnvironmentPicker"; /** Last path segment, for a compact chip label. */ function baseName(p: string): string { @@ -28,10 +29,14 @@ function titleFromPrompt(p: string): string { */ export function NewTaskComposer({ agents, + environments, onClose, onCreate, }: { agents: AgentDTO[]; + /** Where the task can run: this Mac + each ~/.ssh/config box. `alias` null = Local. + * A box is disabled when the repo can't run there (no GitHub identity to clone). */ + environments: { alias: string | null; label: string; disabled: boolean }[]; onClose: () => void; onCreate: (input: { name: string; @@ -39,6 +44,7 @@ export function NewTaskComposer({ agentId: string; yolo: boolean; files: string[]; + alias: string | null; }) => void; }) { const [name, setName] = useState(""); @@ -47,6 +53,10 @@ export function NewTaskComposer({ const [yolo, setYolo] = useState(false); const [files, setFiles] = useState([]); const [dragging, setDragging] = useState(false); + // Default to the first runnable environment (Local, unless the repo isn't here). + const [alias, setAlias] = useState( + environments.find((e) => !e.disabled)?.alias ?? null, + ); const branch = slugify(name.trim() || titleFromPrompt(prompt)); const canSubmit = Boolean(name.trim() || prompt.trim() || files.length); @@ -70,7 +80,7 @@ export function NewTaskComposer({ if (!canSubmit) return; const finalName = name.trim() || titleFromPrompt(prompt) || `task ${new Date().toISOString().slice(0, 10)}`; - onCreate({ name: finalName, prompt: prompt.trim(), agentId, yolo, files }); + onCreate({ name: finalName, prompt: prompt.trim(), agentId, yolo, files, alias }); }; const onKeys = (e: React.KeyboardEvent) => { @@ -152,6 +162,7 @@ export function NewTaskComposer({ ))} + ))} + {onInstall && + (setup ? ( +
    + setDest(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") void submitInstall(); + if (e.key === "Escape" && !installing) { + setSetup(false); + setInstallError(null); + } + }} + /> + {log && ( +
    +											{log}
    +										
    + )} + + {installing + ? "Setting up the box…" + : (installError ?? "Installs the engine over SSH, then connects")} + + {!installing && ( + + )} +
    + ) : ( + + ))}
    , document.body, )} diff --git a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx index ab5154a..951e196 100644 --- a/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx +++ b/apps/desktop/src/renderer/src/components/NewTaskComposer.tsx @@ -32,6 +32,7 @@ export function NewTaskComposer({ environments, envAgents, onAdd, + onInstall, onClose, onCreate, }: { @@ -44,6 +45,8 @@ export function NewTaskComposer({ envAgents: Record; /** Connect a Tailscale endpoint typed into the picker. */ onAdd?: (endpoint: string) => Promise; + /** Set up a fresh box over SSH (install engine + connect) from the picker. */ + onInstall?: (dest: string, onLog: (chunk: string) => void) => Promise; onClose: () => void; onCreate: (input: { name: string; @@ -187,6 +190,7 @@ export function NewTaskComposer({ value={alias} onChange={setAlias} onAdd={onAdd} + onInstall={onInstall} /> +
    + + {started ? ( +
    +
      + {stages.map((s, i) => ( +
    • + {s} +
    • + ))} +
    + {log && ( +
    +								{log}
    +							
    + )} + {error &&
    {error}
    } + {!busy && ( +
    + + +
    + )} +
    + ) : ( +
    + + + + + {options ? ( + <> + + + {error &&
    {error}
    } + + + ) : ( + <> + {optsError &&
    {optsError}
    } + + + )} +
    Created on your Hetzner account.
    +
    + )} +
    +