From 92c48f0978b719906dabeca8176654592b2ccf30 Mon Sep 17 00:00:00 2001 From: Johan LEROY Date: Fri, 12 Jun 2026 18:20:21 +0200 Subject: [PATCH] =?UTF-8?q?P2:=20d=C3=A9couverte=20&=20reprise=20des=20ses?= =?UTF-8?q?sions=20Claude?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Arboretum découvre désormais toutes les sessions Claude de la machine (scan ~/.claude/projects + registre ~/.claude/sessions), distingue vivantes/mortes par pid+procStart, et permet de reprendre une morte (--resume dans son cwd d'origine) ou forker une vivante sans la corrompre. - shared: SessionSummary enrichi (source, claudeSessionId, pid, resumable, attachable, registryStatus) — additif, PROTOCOL_VERSION inchangé ; types REST resume/fork. - db: migration id:2 (claude_session_id, resumed_from). - core: jsonl-discovery (parseur tolérant, scan asynchrone non bloquant), session-registry (vivacité pid+procStart), discovery-service (cache + refresh périodique + diff/broadcast), pty-manager (resume/fork + capture du claudeSessionId via le registre). - routes: /sessions/:id/resume (garde-fou 409 anti-corruption sur session vivante) et /fork ; GET fusionné managées + découvertes ; relais WS. - web: badges managed/discovered + busy/idle/waiting, actions conditionnelles (Open/Observe/Kill vs Fork/View vs Resume/Fork), vue read-only des sessions externes, i18n EN/FR. - tests: jsonl-discovery, session-registry, discovery-service + resume/fork (130 verts) ; acceptation E2E acceptance-p2.mjs (sans quota) ALL GREEN. Conforme aux verdicts S1 (resume dans cwd d'origine, vivacité pid+procStart) et S4 (munge cwd, parseur tête+queue, priorité de titre). --- CLAUDE.md | 79 +++++++++ packages/server/scripts/acceptance-p2.mjs | 164 ++++++++++++++++++ packages/server/src/app.ts | 15 +- packages/server/src/config.ts | 9 + packages/server/src/core/claude-launcher.ts | 18 +- packages/server/src/core/discovery-service.ts | 137 +++++++++++++++ packages/server/src/core/jsonl-discovery.ts | 160 +++++++++++++++++ packages/server/src/core/pty-manager.ts | 82 ++++++++- packages/server/src/core/session-registry.ts | 92 ++++++++++ packages/server/src/db/index.ts | 9 + packages/server/src/index.ts | 4 +- packages/server/src/routes/sessions.ts | 44 ++++- packages/server/src/ws/gateway.ts | 14 +- packages/server/test/app.e2e.test.ts | 71 +++++++- .../server/test/discovery-service.test.ts | 111 ++++++++++++ packages/server/test/jsonl-discovery.test.ts | 93 ++++++++++ packages/server/test/pty-manager.test.ts | 67 +++++++ packages/server/test/session-registry.test.ts | 67 +++++++ packages/server/tsconfig.tsbuildinfo | 2 +- packages/shared/src/api.ts | 5 + packages/shared/src/protocol.ts | 21 +++ packages/shared/tsconfig.tsbuildinfo | 2 +- packages/web/src/i18n/en.ts | 11 ++ packages/web/src/i18n/fr.ts | 12 ++ packages/web/src/stores/sessions.ts | 27 ++- packages/web/src/views/SessionView.vue | 8 +- packages/web/src/views/SessionsListView.vue | 80 +++++++-- 27 files changed, 1363 insertions(+), 41 deletions(-) create mode 100644 CLAUDE.md create mode 100644 packages/server/scripts/acceptance-p2.mjs create mode 100644 packages/server/src/core/discovery-service.ts create mode 100644 packages/server/src/core/jsonl-discovery.ts create mode 100644 packages/server/src/core/session-registry.ts create mode 100644 packages/server/test/discovery-service.test.ts create mode 100644 packages/server/test/jsonl-discovery.test.ts create mode 100644 packages/server/test/session-registry.test.ts diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..020a3dc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,79 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Projet + +Arboretum : un daemon Node.js unique (`npx git-arboretum`) qui sert un dashboard web pour piloter les worktrees git et les sessions Claude Code qui tournent dessus, depuis n'importe quel appareil. Pré-MVP. L'étape **P1** (colonne vertébrale : monorepo, protocole WS, daemon, front, tests, CI) est terminée ; voir les `VERDICT.md` dans `spikes/` pour les décisions techniques actées avant implémentation. + +Les commentaires du code et la doc interne sont en **français** ; le README et les messages utilisateur en anglais. Conserver cette convention. + +## Commandes + +```bash +npm run build # build shared → server → web (l'ordre compte, voir ci-dessous) +npm run typecheck # tsc -b shared + server UNIQUEMENT (le web se typecheck via vue-tsc dans son build) +npm test # vitest run sur packages/*/test/**/*.test.ts +npx vitest run packages/server/test/ring-buffer.test.ts # un seul fichier +npx vitest run -t "flow control" # par nom de test +npm run dev:server # daemon en watch (tsc -b --watch + node --watch) +npm run dev:web # Vite ; proxifie /api et /ws vers le daemon sur :7317 (cf. note Origin) +npm run pack # build + npm pack du tarball git-arboretum + +node packages/server/scripts/acceptance-p1.mjs # acceptation E2E P1 (daemon réel + client WS réel) +node packages/server/scripts/acceptance-p2.mjs # acceptation E2E P2 (découverte/reprise : faux ~/.claude + faux binaire claude) +``` + +L'acceptation exige `npm run build` au préalable (elle lance `dist/index.js`) et utilise la commande `bash` plutôt que `claude` pour ne pas consommer de quota. + +**Node >= 22.16 est requis** (pas seulement recommandé) : la persistance utilise `node:sqlite` (`DatabaseSync`), natif et stable seulement à partir de cette version. `.nvmrc` = 22. + +## Monorepo (npm workspaces) + +- **`packages/shared`** (`@arboretum/shared`) — source unique de vérité du protocole WS (`protocol.ts`) et des types REST (`api.ts`), importée par le serveur ET le front. C'est une **dépendance runtime non publiée** : la CI pack les deux tarballs (`@arboretum/shared` + `git-arboretum`) et les installe ensemble. +- **`packages/server`** (`git-arboretum`) — le daemon Fastify, **le seul paquet publié sur npm** (bin `arboretum`). Embarque la SPA buildée dans `public/` via le hook `prepack` (`scripts/copy-web.mjs`). +- **`packages/web`** (`@arboretum/web`) — SPA Vue 3 (Pinia, vue-router, xterm.js, Tailwind 4), privée. + +Ordre de build imposé : `shared` se construit en premier (projets TS `composite` avec references) ; le front doit être buildé avant `prepack` du serveur pour être embarqué. + +## Architecture serveur + +`buildApp()` (`packages/server/src/app.ts`) câble tout : `AuthService`, `LoginRateLimiter`, `PtyManager`, les routes REST, la gateway WS, et le service statique de la SPA. `index.ts` est le bin (parse config, ouvre la db, écoute, gère le bootstrap token et le drain au SIGTERM/SIGINT). + +### Modèle de sécurité (central — ne pas affaiblir) +Un terminal web est de l'exécution de code à distance par conception. Les garde-fous sont structurants : +- Bind `127.0.0.1` par défaut ; `config.ts` **refuse** tout bind non-loopback sans `--i-know-this-exposes-a-terminal`. Accès distant recommandé via Tailscale Serve. +- Un hook `preValidation` global authentifie **toute** requête `/api/**` et `/ws`, et applique un **check Origin strict** quand l'en-tête est présent (anti cross-site WS hijacking — le cookie `SameSite=Strict` ne couvre pas les upgrades). Les routes statiques sont publiques ; les routes publiques explicites portent `config: { public: true }` (ex. login). +- Tokens stockés **hashés** (sha256), comparaison en temps constant. Le bootstrap token n'est affiché qu'une fois au premier démarrage. Le cookie de session est un payload signé HMAC. Le rate-limit du login est **global** (pas par IP : derrière Tailscale tout arrive de 127.0.0.1) avec backoff exponentiel. + +### Protocole WebSocket (`packages/shared/src/protocol.ts`) +Une **seule connexion multiplexée par client**, plusieurs canaux (channels) : +- Contrôle = frames **texte JSON** ; sortie terminal = frames **binaires** `[type u8][channel u32le][payload]`. Un chunk PTY peut couper un caractère UTF-8 en frontière de frame → le décodage est délégué à `xterm.write(Uint8Array)`, jamais au transport. +- **Flow control par watermarks** (`FLOW`). Invariant anti-deadlock à préserver absolument : `ACK_EVERY_BYTES <= LOW_WATERMARK`. Le PTY n'est mis en pause que quand **tous** les clients interactifs dépassent `HIGH` ; les observers ne freinent jamais le flux. Un client trop en retard (`LAGGING_BYTES`) est coupé puis resynchronisé. +- Handshake `hello`/`hello_ok` négocie `PROTOCOL_VERSION`. `parseClientMessage` valide/sanitise tout message entrant (bornes sur dims, longueurs) — toute nouvelle commande client doit y être validée. + +### PtyManager (`packages/server/src/core/pty-manager.ts`) +Lance `claude` (ou `bash`) dans node-pty. Sessions vivantes en mémoire (`Map`) ; l'historique est persisté dans la table `sessions` (sqlite). Chaque session a un `RingBuffer` (2 Mo) ; à l'attach, le client reçoit un **resync** = reset terminal + replay de la queue du ring (`REPLAY_TAIL_BYTES`). Outil mono-utilisateur : tout client interactif peut écrire, les observers sont read-only. `kill` envoie SIGTERM puis SIGKILL après un délai de grâce. + +### claude-launcher (`packages/server/src/core/claude-launcher.ts`) +Couture volontairement abstraite : Arboretum enveloppe le **CLI `claude` interactif** dans un PTY (pas l'Agent SDK, pas le mode headless). La commande `bash` sert aux tests sans quota. C'est ici que se brancherait un éventuel plan B. + +### Détails fastify à connaître +- La route `/ws` est enregistrée **après** le plugin `@fastify/websocket` dans un contexte encapsulé (`app.register(async (scoped) => ...)`) ; sinon le handler reçoit la signature REST `(request, reply)` au lieu de `(socket, req)`. +- `notFoundHandler` renvoie l'`index.html` de la SPA pour tout ce qui n'est pas `/api/` ou `/ws` (routing client-side). + +### Base de données (`packages/server/src/db/index.ts`) +`node:sqlite` en mode WAL. Migrations idempotentes versionnées dans le tableau `MIGRATIONS` + table `schema_migrations`. Tables : `settings`, `auth_tokens`, `sessions`. + +## Architecture web + +SPA Vue 3. Un **singleton `wsClient`** (`src/lib/ws-client.ts`) gère l'unique connexion : handshake, reconnexion avec backoff, ré-attache des terminaux ouverts, corrélation FIFO des `attached`, et le **flow control par ACK côté client** (compteur d'octets réellement traités par xterm, remis à zéro à chaque resync, avec un ACK traînant débouncé anti-deadlock). En dev, `vite.config.ts` proxifie `/api` et `/ws` vers le daemon en **réécrivant l'en-tête Origin** vers celle du daemon (sinon le check Origin strict rejette l'origine de Vite). Le garde de routeur vérifie la session via `GET /api/v1/auth/me`. + +## Spikes & roadmap + +Les `spikes/sN-*/VERDICT.md` documentent des décisions qui contraignent l'implémentation à venir, notamment : +- **`--resume` doit toujours s'exécuter dans le cwd d'origine** de la session (lu dans le JSONL). +- La **vivacité** d'une session se déduit de `pid` + `procStart`, **jamais** de la présence du fichier registre. +- La distinction d'états fins (busy / waiting / idle) du futur `claude-adapter` (P3) nécessite une lecture d'écran via `@xterm/headless` (le strip ANSI naïf mange les espaces) + le registre `~/.claude/sessions`. + +Les états de session du protocole sont aujourd'hui un sous-ensemble P1 (`starting`/`running`/`exited`) à étendre en P3. diff --git a/packages/server/scripts/acceptance-p2.mjs b/packages/server/scripts/acceptance-p2.mjs new file mode 100644 index 0000000..2bc2737 --- /dev/null +++ b/packages/server/scripts/acceptance-p2.mjs @@ -0,0 +1,164 @@ +#!/usr/bin/env node +// Acceptation P2 (sans navigateur, sans quota Claude) : découverte & reprise de sessions. +// Faux ~/.claude jetable (--claude-home) + faux binaire `claude` (script bash) injecté dans le PATH. +// Couvre : découverte d'une session morte (resumable) et vivante (registre + pid réel), +// resume refusé sur une vivante (409), fork autorisé, resume d'une morte dans SON CWD d'origine, +// broadcast WS d'une session découverte au rafraîchissement périodique. +import { spawn } from 'node:child_process'; +import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, chmodSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); +const WebSocket = require('ws'); + +const PORT = 7542; +const ORIGIN = `http://127.0.0.1:${PORT}`; +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); +const munge = (p) => p.replace(/[^A-Za-z0-9]/g, '-'); +const serverDir = join(dirname(fileURLToPath(import.meta.url)), '..'); +const results = []; +const check = (name, ok, detail = '') => { + results.push({ name, ok, detail }); + console.log(`${ok ? '✅' : '❌'} ${name}${detail ? ` — ${detail}` : ''}`); +}; + +const tmp = mkdtempSync(join(tmpdir(), 'arb-accept-p2-')); +const claudeHome = join(tmp, 'claude'); +const projects = join(claudeHome, 'projects'); +const sessions = join(claudeHome, 'sessions'); +const workDir = join(tmp, 'work'); // cwd d'origine des sessions découvertes +const fakeBin = join(tmp, 'bin'); +mkdirSync(projects, { recursive: true }); +mkdirSync(sessions, { recursive: true }); +mkdirSync(workDir, { recursive: true }); +mkdirSync(fakeBin, { recursive: true }); + +// Faux binaire `claude` : imprime ses arguments + son cwd, puis reste vivant un instant. +writeFileSync(join(fakeBin, 'claude'), '#!/usr/bin/env bash\necho "FAKE-CLAUDE args=[$*] cwd=$(pwd)"\nsleep 30\n'); +chmodSync(join(fakeBin, 'claude'), 0o755); + +function writeJsonl(cwd, sid) { + const d = join(projects, munge(cwd)); + mkdirSync(d, { recursive: true }); + writeFileSync(join(d, `${sid}.jsonl`), `${JSON.stringify({ type: 'user', sessionId: sid, cwd, message: { content: `prompt ${sid}` } })}\n`); +} + +// Session découverte MORTE (aucune entrée registre) → resumable. +writeJsonl(workDir, 'sid-dead'); + +// Session découverte VIVANTE : un vrai process `sleep` fournit pid + procStart concordants. +const liveProc = spawn('sleep', ['300']); +const livePid = liveProc.pid; +const liveStat = readFileSync(`/proc/${livePid}/stat`, 'utf8'); +const liveProcStart = liveStat.slice(liveStat.lastIndexOf(')') + 2).split(' ')[19]; +writeJsonl(workDir, 'sid-live'); +writeFileSync( + join(sessions, `${livePid}.json`), + JSON.stringify({ pid: livePid, procStart: liveProcStart, sessionId: 'sid-live', cwd: workDir, status: 'busy' }), +); + +const srv = spawn( + 'node', + [join(serverDir, 'dist', 'index.js'), '--port', String(PORT), '--db', join(tmp, 'a.db'), '--claude-home', claudeHome], + { env: { ...process.env, ARBORETUM_LOG: 'warn', PATH: `${fakeBin}:${process.env.PATH}` }, stdio: ['ignore', 'pipe', 'pipe'] }, +); +let srvOut = ''; +srv.stdout.on('data', (d) => (srvOut += d)); +srv.stderr.on('data', (d) => (srvOut += d)); + +function wsClient(cookie) { + const ws = new WebSocket(`ws://127.0.0.1:${PORT}/ws`, { headers: { Origin: ORIGIN, Cookie: cookie } }); + ws.binaryType = 'arraybuffer'; + const state = { msgs: [], outputs: new Map() }; + ws.on('message', (data, isBinary) => { + if (!isBinary) { + state.msgs.push(JSON.parse(String(data))); + return; + } + const buf = Buffer.from(data); + const type = buf.readUInt8(0); + const channel = buf.readUInt32LE(1); + const payload = buf.subarray(5); + const prev = type === 0x02 ? '' : (state.outputs.get(channel) ?? ''); + state.outputs.set(channel, (prev + payload.toString('latin1')).slice(-100000)); + }); + const waitMsg = async (pred, timeout = 8000) => { + const t0 = Date.now(); + while (Date.now() - t0 < timeout) { + const m = state.msgs.find(pred); + if (m) return m; + await sleep(50); + } + return null; + }; + return { ws, state, waitMsg, send: (m) => ws.send(JSON.stringify(m)) }; +} + +const postJson = (path, cookie) => + fetch(`${ORIGIN}${path}`, { method: 'POST', headers: { Origin: ORIGIN, Cookie: cookie } }); + +try { + await sleep(1500); + const token = /arb_[0-9a-f]+/.exec(srvOut)?.[0]; + check('boot + token bootstrap', !!token); + + const login = await fetch(`${ORIGIN}/api/v1/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', Origin: ORIGIN }, + body: JSON.stringify({ token }), + }); + const cookie = login.headers.get('set-cookie')?.split(';')[0] ?? ''; + check('login → cookie', login.status === 200 && cookie.startsWith('arb_session=')); + + // GET /sessions : la découverte (scan initial) doit exposer les deux sessions. + const listRes = await fetch(`${ORIGIN}/api/v1/sessions`, { headers: { Origin: ORIGIN, Cookie: cookie } }); + const list = (await listRes.json()).sessions; + const dead = list.find((s) => s.id === 'sid-dead'); + const live = list.find((s) => s.id === 'sid-live'); + check('découverte session morte (resumable, discovered)', dead?.source === 'discovered' && dead?.resumable === true && dead?.live === false); + check('découverte session vivante (live, registryStatus)', live?.live === true && live?.attachable === false && live?.registryStatus === 'busy'); + + // Garde-fou : resume d'une session VIVANTE refusé (409), fork autorisé (201). + const resumeLive = await postJson('/api/v1/sessions/sid-live/resume', cookie); + check('resume d’une session vivante → 409 SESSION_LIVE', resumeLive.status === 409 && (await resumeLive.json()).error.code === 'SESSION_LIVE'); + const forkLive = await postJson('/api/v1/sessions/sid-live/fork', cookie); + check('fork d’une session vivante → 201', forkLive.status === 201); + + // Resume d'une session MORTE → nouveau PTY managé claude, DANS SON CWD D'ORIGINE. + const c = wsClient(cookie); + await new Promise((res, rej) => (c.ws.on('open', res), c.ws.on('error', rej))); + c.send({ type: 'hello', protocol: 1 }); + await c.waitMsg((m) => m.type === 'hello_ok'); + c.send({ type: 'sub', topics: ['sessions'] }); + + const resumeDead = await postJson('/api/v1/sessions/sid-dead/resume', cookie); + const resumed = (await resumeDead.json()).session; + check('resume d’une session morte → 201 (PTY managé claude)', resumeDead.status === 201 && resumed?.command === 'claude' && resumed?.source === 'managed'); + + c.send({ type: 'attach', sessionId: resumed.id, mode: 'interactive', cols: 120, rows: 32 }); + const att = await c.waitMsg((m) => m.type === 'attached'); + await sleep(600); + const out = c.state.outputs.get(att?.channel) ?? ''; + check('resume lance `--resume sid-dead` dans le bon cwd', out.includes('args=[--resume sid-dead]') && out.includes(`cwd=${workDir}`), out.replace(/\s+/g, ' ').slice(0, 120)); + + // Broadcast : une nouvelle session découverte est poussée via session_update au rafraîchissement périodique. + writeJsonl(workDir, 'sid-new'); + const pushed = await c.waitMsg((m) => m.type === 'session_update' && m.session?.id === 'sid-new', 13000); + check('broadcast WS d’une session découverte (refresh périodique)', pushed?.session?.source === 'discovered'); + + c.ws.close(); +} catch (err) { + check('exception', false, String(err)); +} finally { + liveProc.kill('SIGKILL'); + srv.kill('SIGTERM'); + await sleep(1500); + check('arrêt propre du daemon (SIGTERM)', srv.exitCode === 0 || srv.signalCode === null || srv.exitCode === null); + rmSync(tmp, { recursive: true, force: true }); + const failed = results.filter((r) => !r.ok); + console.log(failed.length === 0 ? '\nACCEPTANCE P2: ALL GREEN' : `\nACCEPTANCE P2: ${failed.length} FAILURE(S)`); + process.exit(failed.length === 0 ? 0 : 1); +} diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index 4d5fc18..8d2daad 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -9,6 +9,7 @@ import type { Config } from './config.js'; import type { Db } from './db/index.js'; import { AuthService, LoginRateLimiter, type AuthContext } from './auth/service.js'; import { PtyManager } from './core/pty-manager.js'; +import { DiscoveryService } from './core/discovery-service.js'; import { registerAuthRoutes } from './routes/auth.js'; import { registerSessionRoutes } from './routes/sessions.js'; import { registerWsGateway } from './ws/gateway.js'; @@ -26,13 +27,19 @@ export interface AppBundle { app: FastifyInstance; auth: AuthService; manager: PtyManager; + discovery: DiscoveryService; } export function buildApp(config: Config, db: Db, serverVersion: string): AppBundle { const app = Fastify({ logger: { level: process.env.ARBORETUM_LOG ?? 'info' } }); const auth = new AuthService(db); const limiter = new LoginRateLimiter(); - const manager = new PtyManager(db); + const manager = new PtyManager(db, config.claudeSessionsDir); + const discovery = new DiscoveryService({ + ptyManager: manager, + projectsDir: config.claudeProjectsDir, + sessionsDir: config.claudeSessionsDir, + }); void app.register(fastifyCookie); void app.register(fastifyWebsocket, { @@ -72,11 +79,11 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund }); registerAuthRoutes(app, auth, limiter, serverVersion); - registerSessionRoutes(app, manager); + registerSessionRoutes(app, manager, discovery); // La route websocket doit être déclarée APRÈS le chargement du plugin (contexte // encapsulé) — sinon le handler reçoit la signature REST (request, reply). void app.register(async (scoped) => { - registerWsGateway(scoped, manager, serverVersion); + registerWsGateway(scoped, manager, discovery, serverVersion); }); // SPA buildée embarquée dans le paquet npm (public/) — absente en dev (vite dev sert le front) @@ -91,5 +98,5 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund }); } - return { app, auth, manager }; + return { app, auth, manager, discovery }; } diff --git a/packages/server/src/config.ts b/packages/server/src/config.ts index d63c201..4306128 100644 --- a/packages/server/src/config.ts +++ b/packages/server/src/config.ts @@ -11,6 +11,10 @@ export interface Config { /** origins supplémentaires autorisées (ex. https://machine.tailnet.ts.net) */ allowedOrigins: string[]; printToken: boolean; + /** ~/.claude/projects (transcripts JSONL) — surchargeable via --claude-home (tests). */ + claudeProjectsDir: string; + /** ~/.claude/sessions (registre des sessions CLI vivantes). */ + claudeSessionsDir: string; } export function loadConfig(argv = process.argv.slice(2)): Config { @@ -23,6 +27,8 @@ export function loadConfig(argv = process.argv.slice(2)): Config { 'allow-origin': { type: 'string', multiple: true }, 'print-token': { type: 'boolean', default: false }, 'i-know-this-exposes-a-terminal': { type: 'boolean', default: false }, + // racine de l'install Claude (~/.claude par défaut) — surchargée par les tests d'acceptation. + 'claude-home': { type: 'string' }, }, strict: true, }); @@ -39,6 +45,7 @@ export function loadConfig(argv = process.argv.slice(2)): Config { const dataDir = join(process.env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share'), 'arboretum'); mkdirSync(dataDir, { recursive: true }); + const claudeHome = values['claude-home'] ?? join(homedir(), '.claude'); return { port: Number(values.port), bind, @@ -46,5 +53,7 @@ export function loadConfig(argv = process.argv.slice(2)): Config { dataDir, allowedOrigins: values['allow-origin'] ?? [], printToken: values['print-token'] ?? false, + claudeProjectsDir: join(claudeHome, 'projects'), + claudeSessionsDir: join(claudeHome, 'sessions'), }; } diff --git a/packages/server/src/core/claude-launcher.ts b/packages/server/src/core/claude-launcher.ts index 44f9b52..3e459a3 100644 --- a/packages/server/src/core/claude-launcher.ts +++ b/packages/server/src/core/claude-launcher.ts @@ -6,6 +6,12 @@ export interface SpawnSpec { env: NodeJS.ProcessEnv; } +export interface SpawnOptions { + command: 'claude' | 'bash'; + /** reprise d'une session existante (P2) : `--resume `, `--fork-session` si fork. */ + resume?: { claudeSessionId: string; fork?: boolean }; +} + let cachedClaudeBin: string | null = null; export function resolveClaudeBin(): string { @@ -21,14 +27,20 @@ export function resolveClaudeBin(): string { } /** Module volontairement abstrait : le plan B « BYO API key / Agent SDK » se brancherait ici. */ -export function buildSpawnSpec(command: 'claude' | 'bash'): SpawnSpec { +export function buildSpawnSpec(opts: SpawnOptions): SpawnSpec { const env: NodeJS.ProcessEnv = { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor', }; - if (command === 'bash') { + if (opts.command === 'bash') { return { file: 'bash', args: ['--norc'], env }; } - return { file: resolveClaudeBin(), args: [], env }; + const args: string[] = []; + if (opts.resume) { + // `--resume` doit toujours s'exécuter dans le cwd d'origine (garanti par l'appelant — spike S1). + args.push('--resume', opts.resume.claudeSessionId); + if (opts.resume.fork) args.push('--fork-session'); + } + return { file: resolveClaudeBin(), args, env }; } diff --git a/packages/server/src/core/discovery-service.ts b/packages/server/src/core/discovery-service.ts new file mode 100644 index 0000000..32164e3 --- /dev/null +++ b/packages/server/src/core/discovery-service.ts @@ -0,0 +1,137 @@ +// Service de découverte : second producteur de SessionSummary (à côté du PtyManager). +// Scanne ~/.claude/projects (JSONL) + ~/.claude/sessions (registre), corrèle par claudeSessionId, +// calcule la vivacité, met en cache et notifie les changements. Lecture seule du disque. +import { EventEmitter } from 'node:events'; +import { homedir } from 'node:os'; +import { join } from 'node:path'; +import type { SessionSummary } from '@arboretum/shared'; +import { scanProjects, type DiscoveredJsonl } from './jsonl-discovery.js'; +import { readRegistry, type RegistryEntry } from './session-registry.js'; +import type { PtyManager } from './pty-manager.js'; + +const DEFAULT_REFRESH_MS = 10_000; + +export interface DiscoveryServiceEvents { + /** session découverte nouvelle ou modifiée (relayée en session_update par la gateway). */ + discovery_update: [SessionSummary]; +} + +export interface DiscoveryOptions { + ptyManager: PtyManager; + projectsDir?: string; + sessionsDir?: string; + refreshMs?: number; +} + +export class DiscoveryService extends EventEmitter { + private readonly projectsDir: string; + private readonly sessionsDir: string; + private readonly ptyManager: PtyManager; + private readonly refreshMs: number; + private timer: NodeJS.Timeout | null = null; + private cache: SessionSummary[] = []; + private byId = new Map(); + private prevJson = new Map(); + + constructor(opts: DiscoveryOptions) { + super(); + this.ptyManager = opts.ptyManager; + this.projectsDir = opts.projectsDir ?? join(homedir(), '.claude', 'projects'); + this.sessionsDir = opts.sessionsDir ?? join(homedir(), '.claude', 'sessions'); + this.refreshMs = opts.refreshMs ?? DEFAULT_REFRESH_MS; + } + + start(): void { + if (this.timer) return; + void this.refresh(); // premier scan asynchrone : ne bloque pas le boot + this.timer = setInterval(() => void this.refresh(), this.refreshMs); + this.timer.unref(); // ne maintient pas le process en vie + } + + stop(): void { + if (this.timer) { + clearInterval(this.timer); + this.timer = null; + } + } + + /** Cache courant (jamais de scan synchrone dans le chemin chaud). */ + list(): SessionSummary[] { + return this.cache; + } + + /** Session découverte (avec son cwd d'origine lu sur disque) — pour resume/fork. null si absente. */ + getDiscovered(claudeSessionId: string): DiscoveredJsonl | null { + return this.byId.get(claudeSessionId) ?? null; + } + + /** + * Vivacité FRAÎCHE d'une session (relit le registre, ne se fie pas au cache) — garde-fou + * anti-corruption : la route /resume doit refuser une session devenue vivante depuis le dernier scan. + */ + isClaudeSessionLive(claudeSessionId: string): boolean { + const entry = readRegistry(this.sessionsDir).find((r) => r.claudeSessionId === claudeSessionId); + return entry?.live ?? false; + } + + /** Recalcule le cache depuis le disque. Tolérant : ne lève jamais. */ + async refresh(): Promise { + const regBySid = new Map(); + for (const r of readRegistry(this.sessionsDir)) { + if (r.claudeSessionId) regBySid.set(r.claudeSessionId, r); + } + const known = this.ptyManager.knownClaudeSessionIds(); + + // Dédoublonnage des JSONL par claudeSessionId (on retient le plus récent). + const latest = new Map(); + for (const d of await scanProjects(this.projectsDir)) { + const prev = latest.get(d.claudeSessionId); + if (!prev || d.mtimeMs > prev.mtimeMs) latest.set(d.claudeSessionId, d); + } + + const summaries: SessionSummary[] = []; + const byId = new Map(); + for (const d of latest.values()) { + if (known.has(d.claudeSessionId)) continue; // déjà gérée comme session managée + byId.set(d.claudeSessionId, d); + const r = regBySid.get(d.claudeSessionId); + const live = r?.live ?? false; + summaries.push({ + id: d.claudeSessionId, // les découvertes s'identifient par leur claudeSessionId + cwd: d.cwd, + command: 'claude', + title: d.title, + status: live ? 'running' : 'exited', + live, + createdAt: new Date(d.mtimeMs).toISOString(), + endedAt: null, + exitCode: null, + clients: 0, + source: 'discovered', + claudeSessionId: d.claudeSessionId, + pid: live ? (r?.pid ?? null) : null, + resumable: !live, // morte → --resume direct ; vivante → fork/observe (jamais resume : corruption) + attachable: false, // Arboretum ne tient pas le PTY d'une session externe + registryStatus: r?.status ?? null, + }); + } + + this.cache = summaries; + this.byId = byId; + + // Diff : n'émettre que les sessions nouvelles ou modifiées. + const nextJson = new Map(); + for (const s of summaries) { + const j = JSON.stringify(s); + nextJson.set(s.id, j); + if (this.prevJson.get(s.id) !== j) this.emit('discovery_update', s); + } + this.prevJson = nextJson; + } +} + +/** Fusionne sessions managées + découvertes en dédoublonnant par claudeSessionId (managé prioritaire). */ +export function mergeSessions(managed: SessionSummary[], discovered: SessionSummary[]): SessionSummary[] { + const managedSids = new Set(managed.map((s) => s.claudeSessionId).filter((x): x is string => x != null)); + return [...managed, ...discovered.filter((s) => !(s.claudeSessionId && managedSids.has(s.claudeSessionId)))]; +} diff --git a/packages/server/src/core/jsonl-discovery.ts b/packages/server/src/core/jsonl-discovery.ts new file mode 100644 index 0000000..35b0050 --- /dev/null +++ b/packages/server/src/core/jsonl-discovery.ts @@ -0,0 +1,160 @@ +// Découverte des sessions Claude sur disque (~/.claude/projects/**/*.jsonl). +// Transcription TS du spike S4 (scan.mjs) : parseur strictement tolérant, lecture partielle +// tête+queue (~1,4 s pour 1300+ fichiers), 99,8 % des transcripts exploitables. +// I/O ASYNCHRONES : le scan rend la main à la boucle d'événements entre fichiers, pour ne pas +// figer le streaming des terminaux (il tourne périodiquement dans le DiscoveryService). +import { readdir, stat, open } from 'node:fs/promises'; +import { join } from 'node:path'; + +const HEAD_BYTES = 256 * 1024; +const TAIL_BYTES = 64 * 1024; +const TITLE_MAX = 120; + +/** Reproduit le nom de dossier ~/.claude/projects à partir d'un cwd (validé 100 % — spike S4). */ +export function munge(cwd: string): string { + return cwd.replace(/[^A-Za-z0-9]/g, '-'); +} + +export interface DiscoveredJsonl { + claudeSessionId: string; + cwd: string; + title: string | null; + gitBranch: string | null; + version: string | null; + mtimeMs: number; + /** chemin absolu du .jsonl */ + file: string; +} + +async function readChunk(path: string, position: number, length: number): Promise { + const fh = await open(path, 'r'); + try { + const buf = Buffer.alloc(length); + const { bytesRead } = await fh.read(buf, 0, length, position); + return buf.subarray(0, bytesRead).toString('utf8'); + } finally { + await fh.close(); + } +} + +/** Parse tolérant : chaque ligne en try/catch, lignes coupées/malformées ignorées (jamais de throw). */ +export function parseLines(text: string, partialFirst = false, partialLast = false): Array> { + const lines = text.split('\n'); + if (partialFirst) lines.shift(); // 1re ligne potentiellement coupée (lecture de queue) + if (partialLast) lines.pop(); // dernière ligne potentiellement coupée (lecture de tête) + const out: Array> = []; + for (const l of lines) { + if (!l.trim()) continue; + try { + const o = JSON.parse(l) as unknown; + if (o && typeof o === 'object') out.push(o as Record); + } catch { + /* ligne coupée ou malformée : ignorée */ + } + } + return out; +} + +interface Meta { + sessionId?: string; + cwd?: string; + gitBranch?: string; + version?: string; + aiTitle?: string; + summary?: string; + lastPrompt?: string; + firstUserPrompt?: string; +} + +function asString(v: unknown): string | undefined { + return typeof v === 'string' && v.length > 0 ? v : undefined; +} + +function extractMeta(objs: Array>, meta: Meta): void { + const setOnce = (key: 'sessionId' | 'cwd' | 'gitBranch' | 'version', v: unknown): void => { + if (meta[key] === undefined) { + const s = asString(v); + if (s) meta[key] = s; + } + }; + for (const o of objs) { + setOnce('sessionId', o.sessionId); + setOnce('cwd', o.cwd); + setOnce('gitBranch', o.gitBranch); + setOnce('version', o.version); + // Titre : on retient la dernière valeur vue (la plus récente) — head puis tail → la queue gagne. + const ai = asString(o.aiTitle); + if (ai) meta.aiTitle = ai; + const sum = asString(o.summary); + if (sum) meta.summary = sum; + const lp = asString(o.lastPrompt); + if (lp) meta.lastPrompt = lp; + // Premier prompt utilisateur (depuis la tête) : repli ultime pour le titre. + if (meta.firstUserPrompt === undefined && o.type === 'user') { + const msg = o.message; + if (msg && typeof msg === 'object') { + const text = asString((msg as Record).content); + if (text) meta.firstUserPrompt = text; + } + } + } +} + +/** Priorité de titre actée S4 : ai-title > summary > last-prompt > 1er prompt user. */ +function pickTitle(meta: Meta): string | null { + const raw = meta.aiTitle ?? meta.summary ?? meta.lastPrompt ?? meta.firstUserPrompt ?? null; + if (!raw) return null; + const t = raw.replace(/\s+/g, ' ').trim(); + return t.length > TITLE_MAX ? `${t.slice(0, TITLE_MAX - 1)}…` : t; +} + +/** + * Scanne `projectsDir` en lecture partielle tête+queue. Tolérant : un dossier/fichier illisible ou + * malformé est ignoré (jamais de throw). Un fichier sans sessionId+cwd exploitables est écarté. + */ +export async function scanProjects(projectsDir: string): Promise { + let dirs: string[]; + try { + dirs = await readdir(projectsDir); + } catch { + return []; // dossier absent (Claude jamais lancé) : pas une erreur + } + const out: DiscoveredJsonl[] = []; + for (const dir of dirs) { + const dirPath = join(projectsDir, dir); + let entries; + try { + entries = await readdir(dirPath, { withFileTypes: true }); + } catch { + continue; + } + for (const e of entries) { + if (!e.isFile() || !e.name.endsWith('.jsonl')) continue; + const fp = join(dirPath, e.name); + try { + const st = await stat(fp); + if (st.size === 0) continue; + const meta: Meta = {}; + const head = await readChunk(fp, 0, Math.min(HEAD_BYTES, st.size)); + extractMeta(parseLines(head, false, st.size > HEAD_BYTES), meta); + if (st.size > HEAD_BYTES + TAIL_BYTES) { + const tail = await readChunk(fp, st.size - TAIL_BYTES, TAIL_BYTES); + extractMeta(parseLines(tail, true, false), meta); + } + if (!meta.sessionId || !meta.cwd) continue; // pas une session exploitable + out.push({ + claudeSessionId: meta.sessionId, + cwd: meta.cwd, + title: pickTitle(meta), + gitBranch: meta.gitBranch ?? null, + version: meta.version ?? null, + mtimeMs: st.mtimeMs, + file: fp, + }); + } catch { + /* fichier illisible : ignoré */ + } + } + } + return out; +} diff --git a/packages/server/src/core/pty-manager.ts b/packages/server/src/core/pty-manager.ts index 5631782..5f3c542 100644 --- a/packages/server/src/core/pty-manager.ts +++ b/packages/server/src/core/pty-manager.ts @@ -1,14 +1,20 @@ import { EventEmitter } from 'node:events'; import { existsSync, statSync } from 'node:fs'; import { randomUUID } from 'node:crypto'; +import { homedir } from 'node:os'; +import { join } from 'node:path'; import pty from '@homebridge/node-pty-prebuilt-multiarch'; import { FLOW, REPLAY_TAIL_BYTES, type SessionSummary } from '@arboretum/shared'; import { RingBuffer } from './ring-buffer.js'; import { buildSpawnSpec } from './claude-launcher.js'; +import { findByPid } from './session-registry.js'; import type { Db } from '../db/index.js'; const RING_CAPACITY = 2 * 1024 * 1024; const KILL_GRACE_MS = 5000; +/** Capture du claudeSessionId après spawn : poll du registre par pid (waitReady validé S1). */ +const CLAUDE_ID_POLL_MS = 400; +const CLAUDE_ID_TIMEOUT_MS = 60_000; /** Lien entre un client WS attaché et une session. La gateway fournit les callbacks d'envoi. */ export interface ClientBinding { @@ -36,6 +42,8 @@ interface ManagedSession { paused: boolean; exited: { exitCode: number | null; signal: number | null } | null; killTimer: NodeJS.Timeout | null; + /** ID interne du CLI claude, résolu via le registre après spawn (null pour bash / pas encore prêt). */ + claudeSessionId: string | null; } export interface PtyManagerEvents { @@ -46,17 +54,21 @@ export interface PtyManagerEvents { export class PtyManager extends EventEmitter { private readonly live = new Map(); - constructor(private readonly db: Db) { + constructor( + private readonly db: Db, + private readonly sessionsDir: string = join(homedir(), '.claude', 'sessions'), + ) { super(); } - spawn(opts: { cwd: string; command?: 'claude' | 'bash' }): SessionSummary { + spawn(opts: { cwd: string; command?: 'claude' | 'bash'; resume?: { claudeSessionId: string; fork?: boolean } }): SessionSummary { const cwd = opts.cwd; if (!existsSync(cwd) || !statSync(cwd).isDirectory()) { throw Object.assign(new Error(`Not a directory: ${cwd}`), { statusCode: 400 }); } - const command = opts.command ?? 'claude'; - const spec = buildSpawnSpec(command); + // Un resume/fork est toujours une session claude (le cwd d'origine est garanti par l'appelant — S1). + const command = opts.resume ? 'claude' : (opts.command ?? 'claude'); + const spec = buildSpawnSpec({ command, ...(opts.resume ? { resume: opts.resume } : {}) }); const id = randomUUID(); const proc = pty.spawn(spec.file, spec.args, { name: 'xterm-256color', @@ -77,26 +89,66 @@ export class PtyManager extends EventEmitter { paused: false, exited: null, killTimer: null, + claudeSessionId: null, }; this.live.set(id, session); this.db - .prepare('INSERT INTO sessions (id, cwd, command, created_at) VALUES (?, ?, ?, ?)') - .run(id, cwd, command, session.createdAt); + .prepare('INSERT INTO sessions (id, cwd, command, created_at, resumed_from) VALUES (?, ?, ?, ?, ?)') + .run(id, cwd, command, session.createdAt, opts.resume?.claudeSessionId ?? null); proc.onData((data) => this.handleOutput(session, Buffer.from(data, 'utf8'))); proc.onExit(({ exitCode, signal }) => this.handleExit(session, exitCode, signal ?? null)); + if (command === 'claude') this.captureClaudeSessionId(session); const summary = this.summarize(session); this.emit('session_update', summary); return summary; } + /** Résout le claudeSessionId du CLI en pollant le registre par pid, puis le persiste (waitReady — S1). */ + private captureClaudeSessionId(s: ManagedSession): void { + const deadline = Date.now() + CLAUDE_ID_TIMEOUT_MS; + const tick = (): void => { + if (s.exited || s.claudeSessionId) return; + const entry = findByPid(this.sessionsDir, s.proc.pid); + if (entry?.claudeSessionId) { + s.claudeSessionId = entry.claudeSessionId; + this.db.prepare('UPDATE sessions SET claude_session_id = ? WHERE id = ?').run(entry.claudeSessionId, s.id); + this.emit('session_update', this.summarize(s)); + return; + } + if (Date.now() < deadline) setTimeout(tick, CLAUDE_ID_POLL_MS).unref(); + }; + setTimeout(tick, CLAUDE_ID_POLL_MS).unref(); + } + + /** Session managée VIVANTE portant ce claudeSessionId (garde-fou anti-resume d'une session vivante). */ + findLiveByClaudeSessionId(claudeSessionId: string): SessionSummary | null { + for (const s of this.live.values()) { + if (s.claudeSessionId === claudeSessionId) return this.summarize(s); + } + return null; + } + + /** + * Ensemble des claudeSessionId déjà connus d'Arboretum (sessions managées vivantes + historique DB). + * Sert au DiscoveryService à exclure les doublons (une managée ne doit pas réapparaître en découverte). + */ + knownClaudeSessionIds(): Set { + const rows = this.db + .prepare('SELECT claude_session_id FROM sessions WHERE claude_session_id IS NOT NULL') + .all() as Array<{ claude_session_id: string }>; + const set = new Set(rows.map((r) => r.claude_session_id)); + for (const s of this.live.values()) if (s.claudeSessionId) set.add(s.claudeSessionId); + return set; + } + list(): SessionSummary[] { const liveSummaries = [...this.live.values()].map((s) => this.summarize(s)); const liveIds = new Set(this.live.keys()); const rows = this.db - .prepare('SELECT id, cwd, command, title, created_at, ended_at, exit_code FROM sessions ORDER BY created_at DESC LIMIT 100') - .all() as Array<{ id: string; cwd: string; command: string; title: string | null; created_at: string; ended_at: string | null; exit_code: number | null }>; + .prepare('SELECT id, cwd, command, title, created_at, ended_at, exit_code, claude_session_id FROM sessions ORDER BY created_at DESC LIMIT 100') + .all() as Array<{ id: string; cwd: string; command: string; title: string | null; created_at: string; ended_at: string | null; exit_code: number | null; claude_session_id: string | null }>; const historical: SessionSummary[] = rows .filter((r) => !liveIds.has(r.id)) .map((r) => ({ @@ -110,6 +162,13 @@ export class PtyManager extends EventEmitter { endedAt: r.ended_at, exitCode: r.exit_code, clients: 0, + source: 'managed', + claudeSessionId: r.claude_session_id, + pid: null, + // une session claude morte avec un claudeSessionId connu est reprenable (--resume direct). + resumable: r.command === 'claude' && r.claude_session_id != null, + attachable: false, + registryStatus: null, })); return [...liveSummaries, ...historical]; } @@ -265,6 +324,13 @@ export class PtyManager extends EventEmitter { endedAt: null, exitCode: s.exited?.exitCode ?? null, clients: s.clients.size, + source: 'managed', + claudeSessionId: s.claudeSessionId, + pid: s.exited ? null : s.proc.pid, + // une managée vivante ne se resume pas (corruption) ; une managée claude morte oui. + resumable: !!s.exited && s.command === 'claude' && s.claudeSessionId != null, + attachable: !s.exited, + registryStatus: null, // P2 : statut fin des managées via claude-adapter (P3-B) }; } } diff --git a/packages/server/src/core/session-registry.ts b/packages/server/src/core/session-registry.ts new file mode 100644 index 0000000..ad00bf4 --- /dev/null +++ b/packages/server/src/core/session-registry.ts @@ -0,0 +1,92 @@ +// Lecture du registre ~/.claude/sessions (un fichier .json par session CLI vive). +// Module partagé : P2 l'utilise pour la vivacité + le lookup par pid ; P3-B (claude-adapter) +// s'en sert comme source primaire d'état fin (busy/idle/waiting + waitingFor). +import { readdirSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import type { SessionRegistryStatus } from '@arboretum/shared'; + +export interface RegistryEntry { + claudeSessionId: string | null; + cwd: string | null; + pid: number; + procStart: string | null; + status: SessionRegistryStatus | null; + waitingFor: string | null; + /** vivacité réelle = pid + procStart concordants (jamais la simple présence du fichier). */ + live: boolean; +} + +/** starttime (champ 22 de /proc//stat) ou null si le process n'existe pas. Linux-only. */ +export function readProcStart(pid: number): string | null { + try { + const stat = readFileSync(`/proc/${pid}/stat`, 'utf8'); + // Le nom du process (champ 2) peut contenir espaces/parenthèses → parser après le dernier ')'. + const after = stat.slice(stat.lastIndexOf(')') + 2).split(' '); + return after[19] ?? null; // champ 22 global = index 19 après le champ 3 + } catch { + return null; + } +} + +/** + * Vivacité par pid + procStart (spike S1/S4) : jamais la présence d'un fichier registre (stale possible). + * "Incertain → vivant" : si le process existe mais que le registre n'a pas de procStart, on traite vivant. + */ +export function isLive(pid: number, procStart: string | number | null | undefined): boolean { + const actual = readProcStart(pid); + if (actual === null) return false; // process absent → mort + if (procStart === null || procStart === undefined) return true; // incertain → vivant + return String(procStart) === actual; // procStart discordant → pid recyclé → stale → mort +} + +function normalizeStatus(v: unknown): SessionRegistryStatus | null { + return v === 'busy' || v === 'idle' || v === 'waiting' ? v : null; +} + +function toEntry(r: Record): RegistryEntry | null { + const pid = typeof r.pid === 'number' ? r.pid : Number(r.pid); + if (!Number.isInteger(pid)) return null; + const procStart = r.procStart === undefined || r.procStart === null ? null : String(r.procStart); + return { + claudeSessionId: typeof r.sessionId === 'string' ? r.sessionId : null, + cwd: typeof r.cwd === 'string' ? r.cwd : null, + pid, + procStart, + status: normalizeStatus(r.status), + waitingFor: typeof r.waitingFor === 'string' ? r.waitingFor : null, + live: isLive(pid, procStart), + }; +} + +/** + * Lit toutes les entrées de `sessionsDir`. Tolérant aux fichiers en cours d'écriture / JSON invalide + * (ignorés). Dossier absent → tableau vide (pas une erreur). + */ +export function readRegistry(sessionsDir: string): RegistryEntry[] { + let files: string[]; + try { + files = readdirSync(sessionsDir); + } catch { + return []; + } + const out: RegistryEntry[] = []; + for (const f of files) { + if (!f.endsWith('.json')) continue; + try { + const r = JSON.parse(readFileSync(join(sessionsDir, f), 'utf8')) as Record; + const entry = toEntry(r); + if (entry) out.push(entry); + } catch { + /* fichier en cours d'écriture / JSON invalide : ignoré */ + } + } + return out; +} + +/** + * Entrée registre correspondant à un pid donné (le CLI nomme son fichier .json, mais on + * matche sur le champ `pid` pour ne pas dépendre du nommage). null si absente/illisible. + */ +export function findByPid(sessionsDir: string, pid: number): RegistryEntry | null { + return readRegistry(sessionsDir).find((e) => e.pid === pid) ?? null; +} diff --git a/packages/server/src/db/index.ts b/packages/server/src/db/index.ts index 24d2752..9fbb1df 100644 --- a/packages/server/src/db/index.ts +++ b/packages/server/src/db/index.ts @@ -27,6 +27,15 @@ const MIGRATIONS: Array<{ id: number; sql: string }> = [ ); `, }, + { + // P2 — découverte & reprise : corrélation avec les sessions Claude sur disque. + id: 2, + sql: ` + ALTER TABLE sessions ADD COLUMN claude_session_id TEXT; + ALTER TABLE sessions ADD COLUMN resumed_from TEXT; + CREATE INDEX idx_sessions_claude_session_id ON sessions(claude_session_id); + `, + }, ]; export type Db = DatabaseSync; diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index e707c47..b1afe5c 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -13,10 +13,11 @@ const pkg = JSON.parse( async function main(): Promise { const config = loadConfig(); const db = openDb(config.dbPath); - const { app, auth, manager } = buildApp(config, db, pkg.version); + const { app, auth, manager, discovery } = buildApp(config, db, pkg.version); const bootstrapToken = auth.ensureBootstrapToken(); await app.listen({ port: config.port, host: config.bind }); + discovery.start(); // scan initial + rafraîchissement périodique des sessions découvertes const url = `http://${config.bind === '0.0.0.0' ? '127.0.0.1' : config.bind}:${config.port}`; app.log.info(`Arboretum v${pkg.version} — ${url}`); @@ -36,6 +37,7 @@ async function main(): Promise { if (shuttingDown) return; shuttingDown = true; app.log.info(`${signal} received — draining sessions then exiting`); + discovery.stop(); manager.shutdown(); setTimeout(() => { void app.close().then(() => process.exit(0)); diff --git a/packages/server/src/routes/sessions.ts b/packages/server/src/routes/sessions.ts index b740e07..387a05e 100644 --- a/packages/server/src/routes/sessions.ts +++ b/packages/server/src/routes/sessions.ts @@ -1,10 +1,11 @@ import type { FastifyInstance } from 'fastify'; import type { CreateSessionRequest, SessionResponse, SessionsListResponse } from '@arboretum/shared'; import type { PtyManager } from '../core/pty-manager.js'; +import { mergeSessions, type DiscoveryService } from '../core/discovery-service.js'; -export function registerSessionRoutes(app: FastifyInstance, manager: PtyManager): void { +export function registerSessionRoutes(app: FastifyInstance, manager: PtyManager, discovery: DiscoveryService): void { app.get('/api/v1/sessions', async (): Promise => { - return { sessions: manager.list() }; + return { sessions: mergeSessions(manager.list(), discovery.list()) }; }); app.post('/api/v1/sessions', async (req, reply) => { @@ -25,6 +26,45 @@ export function registerSessionRoutes(app: FastifyInstance, manager: PtyManager) } }); + // Reprise d'une session morte : nouveau PTY managé `--resume ` DANS SON CWD D'ORIGINE (spike S1). + // Le cwd n'est jamais fourni par le client : il est lu sur disque via la découverte. + app.post('/api/v1/sessions/:id/resume', async (req, reply) => { + const { id } = req.params as { id: string }; + const discovered = discovery.getDiscovered(id); + if (!discovered) { + return reply.status(404).send({ error: { code: 'NOT_FOUND', message: 'No resumable session with this id' } }); + } + // Garde-fou anti-corruption : jamais de resume direct d'une session vivante (vérif FRAÎCHE). + if (discovery.isClaudeSessionLive(id) || manager.findLiveByClaudeSessionId(id)) { + return reply.status(409).send({ error: { code: 'SESSION_LIVE', message: 'Session is live — fork it instead' } }); + } + try { + const session = manager.spawn({ cwd: discovered.cwd, resume: { claudeSessionId: id } }); + const res: SessionResponse = { session }; + return reply.status(201).send(res); + } catch (err) { + const statusCode = (err as { statusCode?: number }).statusCode ?? 500; + return reply.status(statusCode).send({ error: { code: 'SPAWN_FAILED', message: (err as Error).message } }); + } + }); + + // Fork : duplique une session (vivante ou morte) sans la corrompre (`--resume --fork-session`). + app.post('/api/v1/sessions/:id/fork', async (req, reply) => { + const { id } = req.params as { id: string }; + const discovered = discovery.getDiscovered(id); + if (!discovered) { + return reply.status(404).send({ error: { code: 'NOT_FOUND', message: 'No session with this id to fork' } }); + } + try { + const session = manager.spawn({ cwd: discovered.cwd, resume: { claudeSessionId: id, fork: true } }); + const res: SessionResponse = { session }; + return reply.status(201).send(res); + } catch (err) { + const statusCode = (err as { statusCode?: number }).statusCode ?? 500; + return reply.status(statusCode).send({ error: { code: 'SPAWN_FAILED', message: (err as Error).message } }); + } + }); + app.delete('/api/v1/sessions/:id', async (req, reply) => { const { id } = req.params as { id: string }; if (!manager.kill(id)) { diff --git a/packages/server/src/ws/gateway.ts b/packages/server/src/ws/gateway.ts index 39e39e8..5102921 100644 --- a/packages/server/src/ws/gateway.ts +++ b/packages/server/src/ws/gateway.ts @@ -9,6 +9,7 @@ import { type SessionSummary, } from '@arboretum/shared'; import type { ClientBinding, PtyManager } from '../core/pty-manager.js'; +import type { DiscoveryService } from '../core/discovery-service.js'; const HEARTBEAT_MS = 30_000; @@ -17,7 +18,12 @@ interface ChannelState { binding: ClientBinding; } -export function registerWsGateway(app: FastifyInstance, manager: PtyManager, serverVersion: string): void { +export function registerWsGateway( + app: FastifyInstance, + manager: PtyManager, + discovery: DiscoveryService, + serverVersion: string, +): void { app.get('/ws', { websocket: true }, (socket: WebSocket, req) => { // L'auth + le check Origin ont eu lieu dans le preValidation global (app.ts). const channels = new Map(); @@ -39,8 +45,13 @@ export function registerWsGateway(app: FastifyInstance, manager: PtyManager, ser const onSessionExit = (e: { sessionId: string; exitCode: number | null; signal: number | null }): void => { if (subscribedSessions) send({ type: 'session_exit', ...e }); }; + // Les sessions découvertes (DiscoveryService) sont relayées sur le même flux que les managées. + const onDiscoveryUpdate = (session: SessionSummary): void => { + if (subscribedSessions) send({ type: 'session_update', session }); + }; manager.on('session_update', onSessionUpdate); manager.on('session_exit', onSessionExit); + discovery.on('discovery_update', onDiscoveryUpdate); const heartbeat = setInterval(() => { if (!alive) { @@ -148,6 +159,7 @@ export function registerWsGateway(app: FastifyInstance, manager: PtyManager, ser clearInterval(heartbeat); manager.off('session_update', onSessionUpdate); manager.off('session_exit', onSessionExit); + discovery.off('discovery_update', onDiscoveryUpdate); for (const [, st] of channels) manager.detach(st.sessionId, st.binding); channels.clear(); }); diff --git a/packages/server/test/app.e2e.test.ts b/packages/server/test/app.e2e.test.ts index 8767026..4902264 100644 --- a/packages/server/test/app.e2e.test.ts +++ b/packages/server/test/app.e2e.test.ts @@ -1,11 +1,16 @@ -import { mkdtempSync, rmSync } from 'node:fs'; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; import { buildApp, type AppBundle } from '../src/app.js'; import { openDb, type Db } from '../src/db/index.js'; +import { munge } from '../src/core/jsonl-discovery.js'; +import { readProcStart } from '../src/core/session-registry.js'; import type { Config } from '../src/config.js'; +// resolveClaudeBin() fait `which claude` : on le stub pour ne pas dépendre d'un claude réel en PATH. +vi.mock('node:child_process', () => ({ execFileSync: () => '/usr/bin/claude\n' })); + // Aucun vrai PTY en CI : le module node-pty est remplacé par un faux inerte. vi.mock('@homebridge/node-pty-prebuilt-multiarch', () => { class FakePty { @@ -49,6 +54,9 @@ function makeApp(name: string): TestApp { dataDir: dir, allowedOrigins: [ALLOWED_ORIGIN], printToken: false, + // ~/.claude jetable, propre à chaque app (jamais le vrai HOME). + claudeProjectsDir: join(dir, `${name}-claude`, 'projects'), + claudeSessionsDir: join(dir, `${name}-claude`, 'sessions'), }; const bundle = buildApp(config, db, '0.0.0-test'); const token = bundle.auth.ensureBootstrapToken(); @@ -268,3 +276,64 @@ describe('app e2e — rate limit du login', () => { expect(blocked.json()).toMatchObject({ error: { code: 'RATE_LIMITED' } }); }); }); + +describe('app e2e — découverte, resume & fork (P2)', () => { + let t: TestApp; + let projectsDir: string; + let sessionsDir: string; + + const bearer = (): Record => ({ authorization: `Bearer ${t.token}` }); + + function writeDiscoveredJsonl(cwd: string, sid: string): void { + const d = join(projectsDir, munge(cwd)); + mkdirSync(d, { recursive: true }); + writeFileSync(join(d, `${sid}.jsonl`), `${JSON.stringify({ type: 'user', sessionId: sid, cwd, message: { content: `prompt ${sid}` } })}\n`); + } + + beforeAll(() => { + t = makeApp('resume'); + projectsDir = join(dir, 'resume-claude', 'projects'); + sessionsDir = join(dir, 'resume-claude', 'sessions'); + mkdirSync(sessionsDir, { recursive: true }); + }); + + it('resume / fork d’un id inconnu → 404', async () => { + const r = await t.bundle.app.inject({ method: 'POST', url: '/api/v1/sessions/nope/resume', headers: bearer() }); + expect(r.statusCode).toBe(404); + const f = await t.bundle.app.inject({ method: 'POST', url: '/api/v1/sessions/nope/fork', headers: bearer() }); + expect(f.statusCode).toBe(404); + }); + + it('session morte découverte → listée puis resume 201 (PTY claude dans son cwd)', async () => { + writeDiscoveredJsonl(dir, 'dead-e2e'); // cwd = dir (existe), donc le spawn de resume réussit + await t.bundle.discovery.refresh(); + + const list = await t.bundle.app.inject({ method: 'GET', url: '/api/v1/sessions', headers: bearer() }); + const found = (list.json() as { sessions: Array<{ id: string; source: string; resumable: boolean }> }).sessions.find( + (s) => s.id === 'dead-e2e', + ); + expect(found).toMatchObject({ source: 'discovered', resumable: true }); + + const res = await t.bundle.app.inject({ method: 'POST', url: '/api/v1/sessions/dead-e2e/resume', headers: bearer() }); + expect(res.statusCode).toBe(201); + expect((res.json() as { session: { command: string; source: string } }).session).toMatchObject({ command: 'claude', source: 'managed' }); + }); + + it('session vivante découverte → resume refusé (409), fork autorisé (201)', async () => { + const sid = 'live-e2e'; + writeDiscoveredJsonl(dir, sid); + const ps = readProcStart(process.pid) as string; + writeFileSync( + join(sessionsDir, `${process.pid}.json`), + JSON.stringify({ pid: process.pid, procStart: ps, sessionId: sid, cwd: dir, status: 'busy' }), + ); + await t.bundle.discovery.refresh(); + + const resume = await t.bundle.app.inject({ method: 'POST', url: `/api/v1/sessions/${sid}/resume`, headers: bearer() }); + expect(resume.statusCode).toBe(409); + expect(resume.json()).toMatchObject({ error: { code: 'SESSION_LIVE' } }); + + const fork = await t.bundle.app.inject({ method: 'POST', url: `/api/v1/sessions/${sid}/fork`, headers: bearer() }); + expect(fork.statusCode).toBe(201); + }); +}); diff --git a/packages/server/test/discovery-service.test.ts b/packages/server/test/discovery-service.test.ts new file mode 100644 index 0000000..0580dcf --- /dev/null +++ b/packages/server/test/discovery-service.test.ts @@ -0,0 +1,111 @@ +import { describe, expect, it, beforeEach, afterEach } from 'vitest'; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import type { SessionSummary } from '@arboretum/shared'; +import { DiscoveryService, mergeSessions } from '../src/core/discovery-service.js'; +import { munge } from '../src/core/jsonl-discovery.js'; +import { readProcStart } from '../src/core/session-registry.js'; +import { PtyManager } from '../src/core/pty-manager.js'; +import { openDb, type Db } from '../src/db/index.js'; + +function writeJsonl(projectsDir: string, cwd: string, sid: string): void { + const dir = join(projectsDir, munge(cwd)); + mkdirSync(dir, { recursive: true }); + writeFileSync( + join(dir, `${sid}.jsonl`), + `${JSON.stringify({ type: 'user', sessionId: sid, cwd, message: { content: `prompt ${sid}` } })}\n`, + ); +} + +describe('DiscoveryService', () => { + let projectsDir: string; + let sessionsDir: string; + let db: Db; + let manager: PtyManager; + let svc: DiscoveryService; + + beforeEach(() => { + projectsDir = mkdtempSync(join(tmpdir(), 'arb-proj-')); + sessionsDir = mkdtempSync(join(tmpdir(), 'arb-sess-')); + db = openDb(':memory:'); + manager = new PtyManager(db, sessionsDir); + svc = new DiscoveryService({ ptyManager: manager, projectsDir, sessionsDir }); + }); + afterEach(() => { + svc.stop(); + rmSync(projectsDir, { recursive: true, force: true }); + rmSync(sessionsDir, { recursive: true, force: true }); + }); + + it('session morte (pas d’entrée registre) → resumable, non attachable', async () => { + writeJsonl(projectsDir, '/home/u/dead', 'dead-sid'); + await svc.refresh(); + const s = svc.list().find((x) => x.id === 'dead-sid'); + expect(s).toMatchObject({ source: 'discovered', live: false, resumable: true, attachable: false, cwd: '/home/u/dead' }); + expect(svc.getDiscovered('dead-sid')?.cwd).toBe('/home/u/dead'); + }); + + it('session vivante (registre + pid vivant) → live, non resumable, registryStatus exposé', async () => { + writeJsonl(projectsDir, '/home/u/live', 'live-sid'); + const ps = readProcStart(process.pid) as string; + writeFileSync( + join(sessionsDir, `${process.pid}.json`), + JSON.stringify({ pid: process.pid, procStart: ps, sessionId: 'live-sid', cwd: '/home/u/live', status: 'waiting', waitingFor: 'permission prompt' }), + ); + await svc.refresh(); + const s = svc.list().find((x) => x.id === 'live-sid'); + expect(s).toMatchObject({ live: true, resumable: false, attachable: false, registryStatus: 'waiting', pid: process.pid }); + }); + + it('exclut une session déjà connue d’Arboretum (managée / historique)', async () => { + writeJsonl(projectsDir, '/home/u/managed', 'managed-sid'); + db.prepare('INSERT INTO sessions (id, cwd, command, created_at, claude_session_id) VALUES (?, ?, ?, ?, ?)').run( + 'uuid-1', + '/home/u/managed', + 'claude', + new Date().toISOString(), + 'managed-sid', + ); + await svc.refresh(); + expect(svc.list().find((x) => x.id === 'managed-sid')).toBeUndefined(); + }); + + it('émet discovery_update sur changement uniquement', async () => { + writeJsonl(projectsDir, '/home/u/x', 'sid-x'); + const seen: SessionSummary[] = []; + svc.on('discovery_update', (s) => seen.push(s)); + await svc.refresh(); + expect(seen.map((s) => s.id)).toContain('sid-x'); + seen.length = 0; + await svc.refresh(); // rien n'a changé → aucune ré-émission + expect(seen).toHaveLength(0); + }); +}); + +describe('mergeSessions', () => { + const mk = (id: string, claudeSessionId: string | null, source: 'managed' | 'discovered'): SessionSummary => ({ + id, + cwd: '/x', + command: 'claude', + title: null, + status: 'exited', + live: false, + createdAt: '', + endedAt: null, + exitCode: null, + clients: 0, + source, + claudeSessionId, + pid: null, + resumable: false, + attachable: false, + registryStatus: null, + }); + + it('dédoublonne par claudeSessionId, managé prioritaire', () => { + const managed = [mk('uuid', 'sid-1', 'managed')]; + const discovered = [mk('sid-1', 'sid-1', 'discovered'), mk('sid-2', 'sid-2', 'discovered')]; + expect(mergeSessions(managed, discovered).map((s) => s.id)).toEqual(['uuid', 'sid-2']); + }); +}); diff --git a/packages/server/test/jsonl-discovery.test.ts b/packages/server/test/jsonl-discovery.test.ts new file mode 100644 index 0000000..825eb6d --- /dev/null +++ b/packages/server/test/jsonl-discovery.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it, beforeEach, afterEach } from 'vitest'; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { munge, parseLines, scanProjects } from '../src/core/jsonl-discovery.js'; + +function writeJsonl(projectsDir: string, cwd: string, sid: string, lines: object[]): void { + const dir = join(projectsDir, munge(cwd)); + mkdirSync(dir, { recursive: true }); + writeFileSync(join(dir, `${sid}.jsonl`), `${lines.map((l) => JSON.stringify(l)).join('\n')}\n`); +} + +describe('munge', () => { + it('reproduit le nom de dossier ~/.claude/projects', () => { + expect(munge('/home/x/My Project!')).toBe('-home-x-My-Project-'); + expect(munge('/home/johan/WebstormProjects/arboretum')).toBe('-home-johan-WebstormProjects-arboretum'); + }); +}); + +describe('parseLines (tolérance)', () => { + it('ignore les lignes vides, coupées ou malformées sans throw', () => { + const text = '{"a":1}\n\n{not json}\n{"b":2}\n{"c":'; + expect(parseLines(text)).toEqual([{ a: 1 }, { b: 2 }]); + }); + it('shift/pop les lignes partielles en bord de chunk', () => { + const text = 'partial}\n{"ok":1}\n{also partial'; + expect(parseLines(text, true, true)).toEqual([{ ok: 1 }]); + }); +}); + +describe('scanProjects', () => { + let dir: string; + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), 'arb-jsonl-')); + }); + afterEach(() => { + rmSync(dir, { recursive: true, force: true }); + }); + + it('dossier absent → tableau vide', async () => { + expect(await scanProjects(join(dir, 'nope'))).toEqual([]); + }); + + it('extrait claudeSessionId + cwd + branche + version', async () => { + writeJsonl(dir, '/home/u/proj', 'sid-1', [ + { type: 'user', sessionId: 'sid-1', cwd: '/home/u/proj', gitBranch: 'main', version: '2.1.170', message: { content: 'hello world' } }, + ]); + const res = await scanProjects(dir); + expect(res).toHaveLength(1); + expect(res[0]).toMatchObject({ claudeSessionId: 'sid-1', cwd: '/home/u/proj', gitBranch: 'main', version: '2.1.170' }); + }); + + it('écarte un fichier sans cwd (queue-operation only)', async () => { + writeJsonl(dir, '/x', 'sid-q', [{ type: 'queue-operation', sessionId: 'sid-q' }]); + expect(await scanProjects(dir)).toEqual([]); + }); + + it('survit à une ligne malformée et reste exploitable', async () => { + const d = join(dir, munge('/home/u/p2')); + mkdirSync(d, { recursive: true }); + writeFileSync( + join(d, 'sid-2.jsonl'), + `{bad json\n${JSON.stringify({ type: 'user', sessionId: 'sid-2', cwd: '/home/u/p2', message: { content: 'ok' } })}\n`, + ); + const res = await scanProjects(dir); + expect(res).toHaveLength(1); + expect(res[0].claudeSessionId).toBe('sid-2'); + }); + + describe('priorité de titre (ai-title > summary > last-prompt > 1er user)', () => { + it('ai-title gagne sur tout', async () => { + writeJsonl(dir, '/t/1', 's', [ + { type: 'user', sessionId: 's', cwd: '/t/1', message: { content: 'premier prompt' } }, + { type: 'summary', sessionId: 's', summary: 'un résumé' }, + { type: 'last-prompt', sessionId: 's', lastPrompt: 'dernier prompt' }, + { type: 'ai-title', sessionId: 's', aiTitle: 'Titre IA' }, + ]); + expect((await scanProjects(dir))[0].title).toBe('Titre IA'); + }); + it('summary gagne sur last-prompt et user', async () => { + writeJsonl(dir, '/t/2', 's', [ + { type: 'user', sessionId: 's', cwd: '/t/2', message: { content: 'premier prompt' } }, + { type: 'last-prompt', sessionId: 's', lastPrompt: 'dernier prompt' }, + { type: 'summary', sessionId: 's', summary: 'un résumé' }, + ]); + expect((await scanProjects(dir))[0].title).toBe('un résumé'); + }); + it('repli ultime sur le premier prompt user', async () => { + writeJsonl(dir, '/t/3', 's', [{ type: 'user', sessionId: 's', cwd: '/t/3', message: { content: 'premier prompt' } }]); + expect((await scanProjects(dir))[0].title).toBe('premier prompt'); + }); + }); +}); diff --git a/packages/server/test/pty-manager.test.ts b/packages/server/test/pty-manager.test.ts index 980ad02..916d8bc 100644 --- a/packages/server/test/pty-manager.test.ts +++ b/packages/server/test/pty-manager.test.ts @@ -1,9 +1,14 @@ import { tmpdir } from 'node:os'; +import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; +import { join } from 'node:path'; import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest'; import { FLOW, REPLAY_TAIL_BYTES, type SessionSummary } from '@arboretum/shared'; import { PtyManager, type ClientBinding } from '../src/core/pty-manager.js'; import { openDb, type Db } from '../src/db/index.js'; +// resolveClaudeBin() fait `which claude` : on le stub pour ne pas dépendre d'un claude réel en PATH. +vi.mock('node:child_process', () => ({ execFileSync: () => '/usr/bin/claude\n' })); + interface FakePty { pid: number; file: string; @@ -135,6 +140,68 @@ describe('PtyManager (pty mocké)', () => { const row = db.prepare('SELECT COUNT(*) AS n FROM sessions').get() as { n: number }; expect(row.n).toBe(0); }); + + it('summarize expose les champs P2 (source/attachable/resumable/pid)', () => { + const { summary } = spawnBash(); + expect(summary).toMatchObject({ + source: 'managed', + attachable: true, + resumable: false, + registryStatus: null, + claudeSessionId: null, + }); + expect(summary.pid).toBeGreaterThan(0); + }); + }); + + describe('resume / fork (P2)', () => { + it('resume → pty claude avec --resume, command forcé à claude, resumed_from persisté', () => { + const summary = manager.spawn({ cwd, resume: { claudeSessionId: 'abc-123' } }); + const p = lastPty(); + expect(summary.command).toBe('claude'); + expect(summary.source).toBe('managed'); + expect(summary.attachable).toBe(true); + expect(p.file).toBe('/usr/bin/claude'); + expect(p.args).toEqual(['--resume', 'abc-123']); + const row = db.prepare('SELECT resumed_from, command FROM sessions WHERE id = ?').get(summary.id) as { + resumed_from: string | null; + command: string; + }; + expect(row).toEqual({ resumed_from: 'abc-123', command: 'claude' }); + }); + + it('fork → --resume --fork-session', () => { + manager.spawn({ cwd, resume: { claudeSessionId: 'xyz', fork: true } }); + expect(lastPty().args).toEqual(['--resume', 'xyz', '--fork-session']); + }); + + it('session claude morte avec claudeSessionId connu → resumable dans list()', () => { + const summary = manager.spawn({ cwd, resume: { claudeSessionId: 'sid-known' } }); + // simule la capture du claudeSessionId (normalement résolue via le registre) + db.prepare('UPDATE sessions SET claude_session_id = ? WHERE id = ?').run('sid-known', summary.id); + lastPty().emitExit(0); + const listed = manager.list().find((s) => s.id === summary.id); + expect(listed).toMatchObject({ live: false, resumable: true, claudeSessionId: 'sid-known' }); + }); + + it('capture le claudeSessionId via le registre (poll par pid) → findLiveByClaudeSessionId', () => { + vi.useFakeTimers(); + const sessDir = mkdtempSync(join(tmpdir(), 'arb-sess-')); + try { + const m = new PtyManager(db, sessDir); + const summary = m.spawn({ cwd, command: 'claude' }); + const p = lastPty(); + writeFileSync(join(sessDir, `${p.pid}.json`), JSON.stringify({ pid: p.pid, sessionId: 'captured-sid', status: 'idle' })); + expect(m.findLiveByClaudeSessionId('captured-sid')).toBeNull(); // pas encore capturé + vi.advanceTimersByTime(400); + const found = m.findLiveByClaudeSessionId('captured-sid'); + expect(found?.id).toBe(summary.id); + expect(found?.claudeSessionId).toBe('captured-sid'); + } finally { + vi.useRealTimers(); + rmSync(sessDir, { recursive: true, force: true }); + } + }); }); describe('attach', () => { diff --git a/packages/server/test/session-registry.test.ts b/packages/server/test/session-registry.test.ts new file mode 100644 index 0000000..bf9a886 --- /dev/null +++ b/packages/server/test/session-registry.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, it, beforeEach, afterEach } from 'vitest'; +import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { readProcStart, isLive, readRegistry, findByPid } from '../src/core/session-registry.js'; + +const DEAD_PID = 2 ** 31 - 1; // pid quasi impossible à attribuer + +describe('readProcStart / isLive', () => { + it('lit le procStart du process courant et le valide', () => { + const ps = readProcStart(process.pid); + expect(ps).not.toBeNull(); + expect(isLive(process.pid, ps as string)).toBe(true); + }); + it('process absent → mort', () => { + expect(readProcStart(DEAD_PID)).toBeNull(); + expect(isLive(DEAD_PID, '123')).toBe(false); + }); + it('procStart discordant (pid recyclé) → stale → mort', () => { + expect(isLive(process.pid, 'definitely-not-the-real-starttime')).toBe(false); + }); + it('procStart inconnu mais process vivant → incertain → vivant', () => { + expect(isLive(process.pid, null)).toBe(true); + }); +}); + +describe('readRegistry', () => { + let dir: string; + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), 'arb-reg-')); + }); + afterEach(() => { + rmSync(dir, { recursive: true, force: true }); + }); + + it('dossier absent → vide', () => { + expect(readRegistry(join(dir, 'nope'))).toEqual([]); + }); + + it('calcule live par pid+procStart et ignore les fichiers malformés', () => { + const ps = readProcStart(process.pid) as string; + writeFileSync( + join(dir, `${process.pid}.json`), + JSON.stringify({ pid: process.pid, procStart: ps, sessionId: 'live-sid', cwd: '/x', status: 'busy' }), + ); + writeFileSync( + join(dir, `${DEAD_PID}.json`), + JSON.stringify({ pid: DEAD_PID, procStart: '999', sessionId: 'dead-sid', cwd: '/y', status: 'idle' }), + ); + writeFileSync(join(dir, 'broken.json'), '{ not json'); + + const entries = readRegistry(dir); + expect(entries).toHaveLength(2); + const live = entries.find((e) => e.pid === process.pid); + expect(live?.live).toBe(true); + expect(live?.status).toBe('busy'); + expect(live?.claudeSessionId).toBe('live-sid'); + const dead = entries.find((e) => e.pid === DEAD_PID); + expect(dead?.live).toBe(false); + expect(findByPid(dir, process.pid)?.claudeSessionId).toBe('live-sid'); + }); + + it('normalise un status inconnu en null', () => { + writeFileSync(join(dir, `${DEAD_PID}.json`), JSON.stringify({ pid: DEAD_PID, status: 'weird' })); + expect(readRegistry(dir)[0].status).toBeNull(); + }); +}); diff --git a/packages/server/tsconfig.tsbuildinfo b/packages/server/tsconfig.tsbuildinfo index 07a954e..bff1f20 100644 --- a/packages/server/tsconfig.tsbuildinfo +++ b/packages/server/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/fast-uri/types/index.d.ts","../../node_modules/ajv/dist/compile/codegen/code.d.ts","../../node_modules/ajv/dist/compile/codegen/scope.d.ts","../../node_modules/ajv/dist/compile/codegen/index.d.ts","../../node_modules/ajv/dist/compile/rules.d.ts","../../node_modules/ajv/dist/compile/util.d.ts","../../node_modules/ajv/dist/compile/validate/subschema.d.ts","../../node_modules/ajv/dist/compile/errors.d.ts","../../node_modules/ajv/dist/compile/validate/index.d.ts","../../node_modules/ajv/dist/compile/validate/dataType.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalItems.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/items2020.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/contains.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/dependencies.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/propertyNames.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalProperties.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/not.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/anyOf.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/oneOf.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/if.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/index.d.ts","../../node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts","../../node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts","../../node_modules/ajv/dist/vocabularies/validation/pattern.d.ts","../../node_modules/ajv/dist/vocabularies/validation/required.d.ts","../../node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/const.d.ts","../../node_modules/ajv/dist/vocabularies/validation/enum.d.ts","../../node_modules/ajv/dist/vocabularies/validation/index.d.ts","../../node_modules/ajv/dist/vocabularies/format/format.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/dependentRequired.d.ts","../../node_modules/ajv/dist/vocabularies/discriminator/types.d.ts","../../node_modules/ajv/dist/vocabularies/discriminator/index.d.ts","../../node_modules/ajv/dist/vocabularies/errors.d.ts","../../node_modules/ajv/dist/types/json-schema.d.ts","../../node_modules/ajv/dist/types/jtd-schema.d.ts","../../node_modules/ajv/dist/runtime/validation_error.d.ts","../../node_modules/ajv/dist/compile/ref_error.d.ts","../../node_modules/ajv/dist/core.d.ts","../../node_modules/ajv/dist/compile/resolve.d.ts","../../node_modules/ajv/dist/compile/index.d.ts","../../node_modules/ajv/dist/types/index.d.ts","../../node_modules/ajv/dist/ajv.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/error.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/type.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/enum.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/elements.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/properties.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/discriminator.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/values.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/index.d.ts","../../node_modules/ajv/dist/jtd.d.ts","../../node_modules/@fastify/ajv-compiler/types/index.d.ts","../../node_modules/@fastify/error/types/index.d.ts","../../node_modules/fast-json-stringify/types/index.d.ts","../../node_modules/@fastify/fast-json-stringify-compiler/types/index.d.ts","../../node_modules/find-my-way/index.d.ts","../../node_modules/light-my-request/types/index.d.ts","../../node_modules/fastify/types/utils.d.ts","../../node_modules/fastify/types/schema.d.ts","../../node_modules/fastify/types/type-provider.d.ts","../../node_modules/fastify/types/reply.d.ts","../../node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/compatibility/index.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/@types/node/web-globals/events.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/file.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/filereader.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/inspector.generated.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/pino-std-serializers/index.d.ts","../../node_modules/sonic-boom/types/index.d.ts","../../node_modules/thread-stream/index.d.ts","../../node_modules/pino/pino.d.ts","../../node_modules/fastify/types/logger.d.ts","../../node_modules/fastify/types/plugin.d.ts","../../node_modules/fastify/types/register.d.ts","../../node_modules/fastify/types/instance.d.ts","../../node_modules/fastify/types/hooks.d.ts","../../node_modules/fastify/types/route.d.ts","../../node_modules/fastify/types/context.d.ts","../../node_modules/fastify/types/request.d.ts","../../node_modules/fastify/types/content-type-parser.d.ts","../../node_modules/fastify/types/errors.d.ts","../../node_modules/fastify/types/server-factory.d.ts","../../node_modules/fastify/fastify.d.ts","../../node_modules/@fastify/cookie/types/plugin.d.ts","../../node_modules/@types/ws/index.d.ts","../../node_modules/@fastify/websocket/types/index.d.ts","../../node_modules/@fastify/static/types/index.d.ts","./src/config.ts","./src/db/index.ts","./src/auth/service.ts","../../node_modules/@homebridge/node-pty-prebuilt-multiarch/typings/node-pty.d.ts","../shared/dist/protocol.d.ts","../shared/dist/api.d.ts","../shared/dist/index.d.ts","./src/core/ring-buffer.ts","./src/core/claude-launcher.ts","./src/core/pty-manager.ts","./src/routes/auth.ts","./src/routes/sessions.ts","../../node_modules/@types/ws/index.d.mts","./src/ws/gateway.ts","./src/app.ts","./src/index.ts"],"fileIdsList":[[102,106,115,131,180,197,198],[131,180,197,198,230,246,249,250,265],[131,180,197,198],[118,131,180,197,198],[131,180,192,197,198,230,246,247,249,265],[125,131,180,194,197,198,230,239,240,246,247,248,250,265],[131,177,178,180,197,198],[131,179,180,197,198],[180,197,198],[131,180,185,197,198,215],[131,180,181,186,191,197,198,200,212,223],[131,180,181,182,191,197,198,200],[126,127,128,131,180,197,198],[131,180,183,197,198,224],[131,180,184,185,192,197,198,201],[131,180,185,197,198,212,220],[131,180,186,188,191,197,198,200],[131,179,180,187,197,198],[131,180,188,189,197,198],[131,180,190,191,197,198],[131,179,180,191,197,198],[131,180,191,192,193,197,198,212,223],[131,180,191,192,193,197,198,207,212,215],[131,173,180,188,191,194,197,198,200,212,223],[131,180,191,192,194,195,197,198,200,212,220,223],[131,180,194,196,197,198,212,220,223],[129,130,131,132,133,134,135,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229],[131,180,191,197,198],[131,180,197,198,199,223],[131,180,188,191,197,198,200,212],[131,180,197,198,201],[131,180,197,198,202],[131,179,180,197,198,203],[131,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229],[131,180,197,198,205],[131,180,197,198,206],[131,180,191,197,198,207,208],[131,180,197,198,207,209,224,226],[131,180,192,197,198],[131,180,191,197,198,212,213,215],[131,180,197,198,214,215],[131,180,197,198,212,213],[131,180,197,198,215],[131,180,197,198,216],[131,177,180,197,198,212,217,223],[131,180,191,197,198,218,219],[131,180,197,198,218,219],[131,180,185,197,198,200,212,220],[131,180,197,198,221],[131,180,197,198,200,222],[131,180,194,197,198,206,223],[131,180,185,197,198,224],[131,180,197,198,212,225],[131,180,197,198,199,226],[131,180,197,198,227],[131,173,180,197,198],[131,173,180,191,193,197,198,203,212,215,223,225,226,228],[131,180,197,198,212,229],[131,180,191,194,196,197,198,200,212,220,223,229,230],[65,66,70,97,98,100,101,102,104,105,131,180,197,198],[63,64,131,180,197,198],[63,131,180,197,198],[65,105,131,180,197,198],[65,66,102,103,105,131,180,197,198],[105,131,180,197,198],[62,105,106,131,180,197,198],[65,66,104,105,131,180,197,198],[65,66,68,69,104,105,131,180,197,198],[65,66,67,104,105,131,180,197,198],[65,66,70,97,98,99,100,101,104,105,131,180,197,198],[65,70,99,100,101,102,104,105,114,131,180,197,198],[62,65,66,70,102,104,131,180,197,198],[70,105,131,180,197,198],[72,73,74,75,76,77,78,79,80,81,105,131,180,197,198],[95,105,131,180,197,198],[71,82,90,91,92,93,94,96,131,180,197,198],[95,105,107,131,180,197,198],[105,107,131,180,197,198],[105,108,109,110,111,112,113,131,180,197,198],[70,105,107,131,180,197,198],[75,105,131,180,197,198],[83,84,85,86,87,88,89,105,131,180,197,198],[106,131,180,197,198],[116,117,119,120,121,122,123,124,125,131,180,194,195,196,197,198,200,235,236,237,238,239,240,241,242,243,244,245],[122,123,124,131,180,197,198,240,242],[122,131,180,197,198,240],[117,131,180,197,198],[117,122,123,124,125,131,180,197,198,212,235,236,237,238,240,242],[117,120,121,122,123,124,125,131,180,194,197,198,200,235,237,239,240,242,243,246],[117,122,123,124,125,131,180,197,198,234,238,240,242],[122,124,131,180,197,198,235,238],[122,131,180,197,198,235,236,238,246],[122,123,124,131,180,197,198,235,238,240,242],[116,122,123,124,131,180,197,198,235,238,240,241],[117,120,122,123,124,125,131,180,197,198,235,238,239,241,242],[116,119,131,180,197,198,246],[122,131,180,194,195,196,197,198],[122,123,131,180,197,198,240],[131,180,194,195,196,197,198],[131,180,194,195,197,198],[131,180,194,197,198,212],[131,180,194,197,198,230],[131,180,191,197,198,228,231,232,233],[131,180,191,197,198,230],[131,180,191,197,198,228],[131,145,149,180,197,198,223],[131,145,180,197,198,212,223],[131,140,180,197,198],[131,142,145,180,197,198,220,223],[131,180,197,198,200,220],[131,180,197,198,230],[131,140,180,197,198,230],[131,142,145,180,197,198,200,223],[131,137,138,141,144,180,191,197,198,212,223],[131,145,152,180,197,198],[131,137,143,180,197,198],[131,145,166,167,180,197,198],[131,141,145,180,197,198,215,223,230],[131,166,180,197,198,230],[131,139,140,180,197,198,230],[131,145,180,197,198],[131,139,140,141,142,143,144,145,146,147,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,167,168,169,170,171,172,180,197,198],[131,145,160,180,197,198],[131,145,152,153,180,197,198],[131,143,145,153,154,180,197,198],[131,144,180,197,198],[131,137,140,145,180,197,198],[131,145,149,153,154,180,197,198],[131,149,180,197,198],[131,143,145,148,180,197,198,223],[131,137,142,145,152,180,197,198],[131,180,197,198,212],[131,140,145,166,180,197,198,228,230],[131,180,192,197,198,202,223,246,247,249,250,251,252,253,260,261,262,264],[131,180,185,197,198,252],[131,180,192,197,198,201,202,224],[131,180,181,197,198],[131,180,185,191,192,197,198,252,254,257,258,259],[131,180,197,198,211],[131,180,192,197,198,202,223,251,252,265],[131,180,197,198,246,253,257],[131,180,197,198,246,257,260],[131,180,197,198,246,257,260,263],[131,180,197,198,255],[131,180,197,198,255,256]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"84bcc7c6b06f4d643a55dc63b56be0c81d990f8d549b66ea615c553268774dc3","impliedFormat":1},{"version":"2d225e7bda2871c066a7079c88174340950fb604f624f2586d3ea27bb9e5f4ff","impliedFormat":1},{"version":"6a785f84e63234035e511817dd48ada756d984dd8f9344e56eb8b2bdcd8fd001","impliedFormat":1},{"version":"c1422d016f7df2ccd3594c06f2923199acd09898f2c42f50ea8159f1f856f618","impliedFormat":1},{"version":"2973b1b7857ca144251375b97f98474e9847a890331e27132d5a8b3aea9350a8","impliedFormat":1},{"version":"0eb6152d37c84d6119295493dfcc20c331c6fda1304a513d159cdaa599dcb78b","impliedFormat":1},{"version":"237df26f8c326ca00cd9d2deb40214a079749062156386b6d75bdcecc6988a6b","impliedFormat":1},{"version":"cd44995ee13d5d23df17a10213fed7b483fabfd5ea08f267ab52c07ce0b6b4da","impliedFormat":1},{"version":"58ce1486f851942bd2d3056b399079bc9cb978ec933fe9833ea417e33eab676e","impliedFormat":1},{"version":"7557d4d7f19f94341f4413575a3453ba7f6039c9591015bcf4282a8e75414043","impliedFormat":1},{"version":"a3b2cc16f3ce2d882eca44e1066f57a24751545f2a5e4a153d4de31b4cac9bb5","impliedFormat":1},{"version":"ac2b3b377d3068bfb6e1cb8889c99098f2c875955e2325315991882a74d92cc8","impliedFormat":1},{"version":"8deb39d89095469957f73bd194d11f01d9894b8c1f1e27fbf3f6e8122576b336","impliedFormat":1},{"version":"a38a9c41f433b608a0d37e645a31eecf7233ef3d3fffeb626988d3219f80e32f","impliedFormat":1},{"version":"8e1428dcba6a984489863935049893631170a37f9584c0479f06e1a5b1f04332","impliedFormat":1},{"version":"1fce9ecb87a2d3898941c60df617e52e50fb0c03c9b7b2ba8381972448327285","impliedFormat":1},{"version":"5ef0597b8238443908b2c4bf69149ed3894ac0ddd0515ac583d38c7595b151f1","impliedFormat":1},{"version":"ac52b775a80badff5f4ac329c5725a26bd5aaadd57afa7ad9e98b4844767312a","impliedFormat":1},{"version":"6ae5b4a63010c82bf2522b4ecfc29ffe6a8b0c5eea6b2b35120077e9ac54d7a1","impliedFormat":1},{"version":"dd7109c49f416f218915921d44f0f28975df78e04e437c62e1e1eb3be5e18a35","impliedFormat":1},{"version":"eee181112e420b345fc78422a6cc32385ede3d27e2eaf8b8c4ad8b2c29e3e52e","impliedFormat":1},{"version":"25fbe57c8ee3079e2201fe580578fab4f3a78881c98865b7c96233af00bf9624","impliedFormat":1},{"version":"62cc8477858487b4c4de7d7ae5e745a8ce0015c1592f398b63ee05d6e64ca295","impliedFormat":1},{"version":"cc2a9ec3cb10e4c0b8738b02c31798fad312d21ef20b6a2f5be1d077e9f5409d","impliedFormat":1},{"version":"4b4fadcda7d34034737598c07e2dca5d7e1e633cb3ba8dd4d2e6a7782b30b296","impliedFormat":1},{"version":"360fdc8829a51c5428636f1f83e7db36fef6c5a15ed4411b582d00a1c2bd6e97","impliedFormat":1},{"version":"1cf0d15e6ab1ecabbf329b906ae8543e6b8955133b7f6655f04d433e3a0597ab","impliedFormat":1},{"version":"7c9f98fe812643141502b30fb2b5ec56d16aaf94f98580276ae37b7924dd44a4","impliedFormat":1},{"version":"b3547893f24f59d0a644c52f55901b15a3fa1a115bc5ea9a582911469b9348b7","impliedFormat":1},{"version":"596e5b88b6ca8399076afcc22af6e6e0c4700c7cd1f420a78d637c3fb44a885e","impliedFormat":1},{"version":"adddf736e08132c7059ee572b128fdacb1c2650ace80d0f582e93d097ed4fbaf","impliedFormat":1},{"version":"d4cad9dc13e9c5348637170ddd5d95f7ed5fdfc856ddca40234fa55518bc99a6","impliedFormat":1},{"version":"d70675ba7ba7d02e52b7070a369957a70827e4b2bca2c1680c38a832e87b61fd","impliedFormat":1},{"version":"3be71f4ce8988a01e2f5368bdd58e1d60236baf511e4510ee9291c7b3729a27e","impliedFormat":1},{"version":"423d2ccc38e369a7527988d682fafc40267bcd6688a7473e59c5eea20a29b64f","impliedFormat":1},{"version":"2f9fde0868ed030277c678b435f63fcf03d27c04301299580a4017963cc04ce6","impliedFormat":1},{"version":"feeb73d48cc41c6dd23d17473521b0af877751504c30c18dc84267c8eeea429a","impliedFormat":1},{"version":"25f1159094dc0bf3a71313a74e0885426af21c5d6564a254004f2cadf9c5b052","impliedFormat":1},{"version":"cde493e09daad4bb29922fe633f760be9f0e8e2f39cdca999cce3b8690b5e13a","impliedFormat":1},{"version":"3d7f9eb12aface876f7b535cc89dcd416daf77f0b3573333f16ec0a70bcf902a","impliedFormat":1},{"version":"4304f640f7cb4724ea82441accb7c7607fa7207541182470d625adda99b2900b","impliedFormat":1},{"version":"e0205f04611bea8b5b82168065b8ef1476a8e96236201494eb8c785331c43118","impliedFormat":1},{"version":"62d26d8ba4fa15ab425c1b57a050ed76c5b0ecbffaa53f182110aa3a02405a07","impliedFormat":1},{"version":"9941cbf7ca695e95d588f5f1692ab040b078d44a95d231fa9a8f828186b7b77d","impliedFormat":1},{"version":"41b8775befd7ded7245a627e9f4de6110236688ce4c124d2d40c37bc1a3bfe05","impliedFormat":1},{"version":"a6613ee552418429af38391e37389036654a882c342a1b81f2711e8ddac597f2","impliedFormat":1},{"version":"da47cb979ae4a849f9b983f43ef34365b7050c4f5ae2ebf818195858774e1d67","impliedFormat":1},{"version":"ac3bcb82d7280fc313a967f311764258d18caf33db6d2b1a0243cde607ff01a0","impliedFormat":1},{"version":"c9b5632d6665177030428d02603aeac3e920d31ec83ac500b55d44c7da74bd84","impliedFormat":1},{"version":"46456824df16d60f243a7e386562b27bac838aaba66050b9bc0f31e1ab34c1f2","impliedFormat":1},{"version":"b91034069e217212d8dda6c92669ee9f180b4c36273b5244c3be2c657f9286c7","impliedFormat":1},{"version":"0697277dd829ac2610d68fe1b457c9e758105bb52d40e149d9c15e5e2fe6dca4","impliedFormat":1},{"version":"b0d06dbb409369169143ede5df1fb58b2fca8d44588e199bd624b6f6d966bf08","impliedFormat":1},{"version":"88dfdb2a44912a28aea3ebb657dc7fcec6ba59f7233005e3405824995b713dac","impliedFormat":1},{"version":"f38a45cbc0356dfb6455211e75ecd0f8aeaedbacd4cb8d6646c818d36a46d195","impliedFormat":1},{"version":"cc2d5d5687bdf9d7c49b6946b8769ac7abcbdcd1701d9bb9ca70a8bc1b003e8b","impliedFormat":1},{"version":"6f1fabd39b8c9a66a3232030a4b28ed4fb4f857dcffef0add3220dab4bbba77a","impliedFormat":1},{"version":"9c0623d67471ddc5b9d82b4e06252c746d54f7ae8ccff8701cd51c249f7e7694","impliedFormat":1},{"version":"71654f68a41362f16a2690ec215e583d3cfa913d49327e43c3c7f354022f67a3","impliedFormat":1},{"version":"f69b484edf398d636992757d587e7e38ea91844a66dbca9d682c9cf7858b77cf","impliedFormat":1},{"version":"37d852b3e6b30b974178674dbf2a7974a1ea4bbdbec26d0bdb8f34632cab94a2","impliedFormat":1},{"version":"c3ccf44723b474b5d7a87c53eed9711e81422f0e29b3e8f8f8d42775fa802243","impliedFormat":1},{"version":"faeaf9586ba4505448bd0fdb332509a7e3ecca5d8ae10208950a5d03e8b4ea28","impliedFormat":1},{"version":"c3a0295707fde0cb51ca784ecb799aa95ca71c40337b5ee4a81a8f7134dd7e92","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"9018e9493596e2d041fc531f5101a0d05f9d2e1311f4ae3c74345b1766158c08","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"4fe80f12b1d5189384a219095c2eabadbb389c2d3703aae7c5376dbaa56061df","impliedFormat":1},{"version":"9eb1d2dceae65d1c82fc6be7e9b6b19cf3ca93c364678611107362b6ad4d2d41","impliedFormat":1},{"version":"eb81f582c0e1ae21f004b39c268c68ad13222cd7e72f45080d6cdf9b994dfecf","impliedFormat":1},{"version":"e40f9840e4686053a5d42b39fddfd6774172a3d12fa61c1edb8c35b452a5e74a","impliedFormat":1},{"version":"c034433fe3ebd5391d0078de0193306591f61e421697a217cbeb92bd5e0f6ebc","impliedFormat":1},{"version":"479a021fec9328c8ab37f9372dcdc1022d79aeedde6febf03942b4456d1591c9","impliedFormat":1},{"version":"68d25a0614893e256a9e6fe18e2b125dbdad694381b57e63320de6a7518e47fc","impliedFormat":1},{"version":"49b89a0b4b3b3e18cbf726a9c608d622b4f6d49304076fc01c10f93833c70f09","impliedFormat":1},{"version":"4f62dc739ef3b99a93779255f85e51f02ce411d63cf294ee654258ff8c1978e4","impliedFormat":1},{"version":"3fa13ab73c7307a308bba2f9ca5cea92b74cbdae348a7ba1f5ac094fde7286c2","impliedFormat":1},{"version":"64102e00cb41de7f423608037d17dff83954904383e5c45f1054c2246cf5e184","impliedFormat":1},{"version":"5cf7ebe883e54b764af73548dbbef8887c640f1fd896f4d8b935b027d9989728","impliedFormat":1},{"version":"05e29a500e59cc5697947ee0fa9390e88ff008ec76be1f859152bda8ec01f13d","impliedFormat":1},{"version":"c89237cc87fc6e004290ae667babd0fa242e87c7de1cb49d4e5aba53391923f4","impliedFormat":1},{"version":"44b227ad122395768f07a8f1b84041b096220335b34ff7af3b8caa61731b294d","impliedFormat":1},{"version":"cfac258f114785ee4591fed69b045070da61d3ea03a9fabd750d682cc501253f","impliedFormat":1},{"version":"99dd60ecf4b17a5478ddc7a3a4e41500eba9b4fdbded73fa01e0ad525f7ff90d","impliedFormat":1},{"version":"1ba59c8bbeed2cb75b239bb12041582fa3e8ef32f8d0bd0ec802e38442d3f317","impliedFormat":1},{"version":"1bf1497c5e7ced001b52ed69657f472870edf3ef34641842046fc5cc47359fd0","impliedFormat":1},{"version":"36c1793e93c8a2dff0dcc67145b992e78fef0a67dd1f69d9f689b108a3598341","impliedFormat":1},{"version":"289302cd21b99f1b34e25812ed3119af56bab4740f10726c7a5a7db80df69e33","signature":"51cc114c75ade7761ead7dbeb917357947a820feb3c4c7589d6fc859804b117b","impliedFormat":99},{"version":"837f71558d52d6517b050cec1800f278a85fcff00dba7029801efc79bdd5e978","signature":"e1f8eff69d223ca308faac04131a51f40a811ad66005ea8553acd5b0a7884273","impliedFormat":99},{"version":"44374830e8530b42058a2b9a713f0e94b0171cd2887b53a19343ae80d6b0230b","signature":"b2389a3050e376a1e5e258f76d72c5c8baf0a80bc992c9ba65c263f9257c08a8","impliedFormat":99},{"version":"e2b0a3b2ab5fa5a3f31d8150ab3b93f29828131871a898379b117a16655888b0","impliedFormat":1},{"version":"155aa8c32f0815cb7f44246680859e2724428459727e6067d0d434a666b72e5b","impliedFormat":99},{"version":"0eaa5ca815f0d1f498a205737cc71a5259671ee1ffc96eb881ee721c2d60bf30","impliedFormat":99},{"version":"8b93a53483cf3bb55c754db9dffd3cc1e3d05f87fe7158aceb4b30f5521a14fc","impliedFormat":99},{"version":"94df841d67dcf657c26c5aa60fe3b3a9daca4bd156baae524d5a4ecd9e90b401","signature":"1ddb6de962eac59d919fc52f07ce8b3c0af0c61da427b94b684d925c6ad6eb71","impliedFormat":99},{"version":"9c1e42f6390d8a66639fdead79e7cf2616f7708c2d8dba1dbf8db158ffa4d63c","signature":"d8396e56d160d98eb7f4fe538cb89f7db9345afa65563b3c7c1e030f6cee1bb5","impliedFormat":99},{"version":"f38ed4bcd27c8054ccbfca5c93217ffc805f11c9421a9867851f8d77ea9525f1","signature":"b00d1b92b69461390eaecc1805d508328e6e1238c490bb4fc7d8f95dba9150c2","impliedFormat":99},{"version":"58089e4ae3cf5595f123796153c3852ab492073a464cf16875ca6f51dd2b89e7","signature":"9a427255affacd5f9393e9540bcdea7258ad97021bde8044493990e8dd2fd2ab","impliedFormat":99},{"version":"0aa5e375691619ba68ba72383a1641d5e8cb6781903b6cb714233a7a04f82787","signature":"d036d9eed1f11cdee9a3bb9a4ffe86cbeee21d03500f6c42de7219d53b660fa4","impliedFormat":99},{"version":"316f1486e15cbf7896425f0a16dfe12d447dd57cfb3244b8b119c77df870858f","impliedFormat":99},{"version":"303ab2a1b823b7ee483a89ab4ae9d720dc94a65886f6f0430577c63dfefb78f0","signature":"7f23a8041aff693c3a2cf7ff178e0f514a9dfa7d565e80fe5113ab60a575884e","impliedFormat":99},{"version":"c72437f83e5f35d3c6bc42889a22438fa8cb3f837d3a75e12bd45c7010f109e0","signature":"3c903ff9ca7961c70214302108a0dd27044b7130b8d551ac891744fdb4bee60d","impliedFormat":99},{"version":"b0fef4d6b65da4b34876e3dc008d9b157c4f094a17855fcff92a18464c677179","signature":"43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012","impliedFormat":99}],"root":[[251,253],[258,262],[264,266]],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"verbatimModuleSyntax":true},"referencedMap":[[116,1],[247,2],[117,3],[119,4],[250,5],[249,6],[254,3],[177,7],[178,7],[179,8],[131,9],[180,10],[181,11],[182,12],[126,3],[129,13],[127,3],[128,3],[183,14],[184,15],[185,16],[186,17],[187,18],[188,19],[189,19],[190,20],[191,21],[192,22],[193,23],[132,3],[130,3],[194,24],[195,25],[196,26],[230,27],[197,28],[198,3],[199,29],[200,30],[201,31],[202,32],[203,33],[204,34],[205,35],[206,36],[207,37],[208,37],[209,38],[210,3],[211,39],[212,40],[214,41],[213,42],[215,43],[216,44],[217,45],[218,46],[219,47],[220,48],[221,49],[222,50],[223,51],[224,52],[225,53],[226,54],[227,55],[133,3],[134,3],[135,3],[174,56],[175,3],[176,3],[228,57],[229,58],[263,59],[248,59],[106,60],[63,3],[65,61],[64,62],[69,63],[104,64],[101,65],[103,66],[66,65],[67,67],[71,67],[70,68],[68,69],[102,70],[115,71],[100,65],[105,72],[98,3],[99,3],[72,73],[77,65],[79,65],[74,65],[75,73],[81,65],[82,74],[73,65],[78,65],[80,65],[76,65],[96,75],[95,65],[97,76],[91,65],[112,77],[110,78],[109,65],[107,63],[114,79],[111,80],[108,78],[113,78],[93,65],[92,65],[88,65],[94,81],[89,65],[90,82],[83,65],[84,65],[85,65],[86,65],[87,65],[136,3],[118,83],[62,3],[246,84],[243,85],[241,86],[244,87],[239,88],[238,89],[235,90],[236,91],[237,92],[125,93],[242,94],[240,95],[123,96],[245,97],[124,98],[122,99],[120,100],[121,101],[231,102],[234,103],[232,104],[233,105],[60,3],[61,3],[12,3],[11,3],[2,3],[13,3],[14,3],[15,3],[16,3],[17,3],[18,3],[19,3],[20,3],[3,3],[21,3],[22,3],[4,3],[23,3],[27,3],[24,3],[25,3],[26,3],[28,3],[29,3],[30,3],[5,3],[31,3],[32,3],[33,3],[34,3],[6,3],[38,3],[35,3],[36,3],[37,3],[39,3],[7,3],[40,3],[45,3],[46,3],[41,3],[42,3],[43,3],[44,3],[8,3],[50,3],[47,3],[48,3],[49,3],[51,3],[9,3],[52,3],[53,3],[54,3],[56,3],[55,3],[57,3],[58,3],[10,3],[59,3],[1,3],[152,106],[162,107],[151,106],[172,108],[143,109],[142,110],[171,111],[165,112],[170,113],[145,114],[159,115],[144,116],[168,117],[140,118],[139,111],[169,119],[141,120],[146,121],[147,3],[150,121],[137,3],[173,122],[163,123],[154,124],[155,125],[157,126],[153,127],[156,128],[166,111],[148,129],[149,130],[158,131],[138,132],[161,123],[160,121],[164,3],[167,133],[265,134],[253,135],[251,136],[259,137],[260,138],[258,3],[252,139],[266,140],[261,141],[262,142],[264,143],[256,144],[257,145],[255,3]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file +{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/fast-uri/types/index.d.ts","../../node_modules/ajv/dist/compile/codegen/code.d.ts","../../node_modules/ajv/dist/compile/codegen/scope.d.ts","../../node_modules/ajv/dist/compile/codegen/index.d.ts","../../node_modules/ajv/dist/compile/rules.d.ts","../../node_modules/ajv/dist/compile/util.d.ts","../../node_modules/ajv/dist/compile/validate/subschema.d.ts","../../node_modules/ajv/dist/compile/errors.d.ts","../../node_modules/ajv/dist/compile/validate/index.d.ts","../../node_modules/ajv/dist/compile/validate/dataType.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalItems.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/items2020.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/contains.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/dependencies.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/propertyNames.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalProperties.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/not.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/anyOf.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/oneOf.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/if.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/index.d.ts","../../node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts","../../node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts","../../node_modules/ajv/dist/vocabularies/validation/pattern.d.ts","../../node_modules/ajv/dist/vocabularies/validation/required.d.ts","../../node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/const.d.ts","../../node_modules/ajv/dist/vocabularies/validation/enum.d.ts","../../node_modules/ajv/dist/vocabularies/validation/index.d.ts","../../node_modules/ajv/dist/vocabularies/format/format.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/dependentRequired.d.ts","../../node_modules/ajv/dist/vocabularies/discriminator/types.d.ts","../../node_modules/ajv/dist/vocabularies/discriminator/index.d.ts","../../node_modules/ajv/dist/vocabularies/errors.d.ts","../../node_modules/ajv/dist/types/json-schema.d.ts","../../node_modules/ajv/dist/types/jtd-schema.d.ts","../../node_modules/ajv/dist/runtime/validation_error.d.ts","../../node_modules/ajv/dist/compile/ref_error.d.ts","../../node_modules/ajv/dist/core.d.ts","../../node_modules/ajv/dist/compile/resolve.d.ts","../../node_modules/ajv/dist/compile/index.d.ts","../../node_modules/ajv/dist/types/index.d.ts","../../node_modules/ajv/dist/ajv.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/error.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/type.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/enum.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/elements.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/properties.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/discriminator.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/values.d.ts","../../node_modules/ajv/dist/vocabularies/jtd/index.d.ts","../../node_modules/ajv/dist/jtd.d.ts","../../node_modules/@fastify/ajv-compiler/types/index.d.ts","../../node_modules/@fastify/error/types/index.d.ts","../../node_modules/fast-json-stringify/types/index.d.ts","../../node_modules/@fastify/fast-json-stringify-compiler/types/index.d.ts","../../node_modules/find-my-way/index.d.ts","../../node_modules/light-my-request/types/index.d.ts","../../node_modules/fastify/types/utils.d.ts","../../node_modules/fastify/types/schema.d.ts","../../node_modules/fastify/types/type-provider.d.ts","../../node_modules/fastify/types/reply.d.ts","../../node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/compatibility/index.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/@types/node/web-globals/events.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/file.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/filereader.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/inspector.generated.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/pino-std-serializers/index.d.ts","../../node_modules/sonic-boom/types/index.d.ts","../../node_modules/thread-stream/index.d.ts","../../node_modules/pino/pino.d.ts","../../node_modules/fastify/types/logger.d.ts","../../node_modules/fastify/types/plugin.d.ts","../../node_modules/fastify/types/register.d.ts","../../node_modules/fastify/types/instance.d.ts","../../node_modules/fastify/types/hooks.d.ts","../../node_modules/fastify/types/route.d.ts","../../node_modules/fastify/types/context.d.ts","../../node_modules/fastify/types/request.d.ts","../../node_modules/fastify/types/content-type-parser.d.ts","../../node_modules/fastify/types/errors.d.ts","../../node_modules/fastify/types/server-factory.d.ts","../../node_modules/fastify/fastify.d.ts","../../node_modules/@fastify/cookie/types/plugin.d.ts","../../node_modules/@types/ws/index.d.ts","../../node_modules/@fastify/websocket/types/index.d.ts","../../node_modules/@fastify/static/types/index.d.ts","./src/config.ts","./src/db/index.ts","./src/auth/service.ts","../../node_modules/@homebridge/node-pty-prebuilt-multiarch/typings/node-pty.d.ts","../shared/dist/protocol.d.ts","../shared/dist/api.d.ts","../shared/dist/index.d.ts","./src/core/ring-buffer.ts","./src/core/claude-launcher.ts","./src/core/session-registry.ts","./src/core/pty-manager.ts","./src/core/jsonl-discovery.ts","./src/core/discovery-service.ts","./src/routes/auth.ts","./src/routes/sessions.ts","../../node_modules/@types/ws/index.d.mts","./src/ws/gateway.ts","./src/app.ts","./src/index.ts"],"fileIdsList":[[102,106,115,131,180,197,198],[131,180,197,198,230,246,249,250,268],[131,180,197,198],[118,131,180,197,198],[131,180,192,197,198,230,246,247,249,268],[125,131,180,194,197,198,230,239,240,246,247,248,250,268],[131,177,178,180,197,198],[131,179,180,197,198],[180,197,198],[131,180,185,197,198,215],[131,180,181,186,191,197,198,200,212,223],[131,180,181,182,191,197,198,200],[126,127,128,131,180,197,198],[131,180,183,197,198,224],[131,180,184,185,192,197,198,201],[131,180,185,197,198,212,220],[131,180,186,188,191,197,198,200],[131,179,180,187,197,198],[131,180,188,189,197,198],[131,180,190,191,197,198],[131,179,180,191,197,198],[131,180,191,192,193,197,198,212,223],[131,180,191,192,193,197,198,207,212,215],[131,173,180,188,191,194,197,198,200,212,223],[131,180,191,192,194,195,197,198,200,212,220,223],[131,180,194,196,197,198,212,220,223],[129,130,131,132,133,134,135,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229],[131,180,191,197,198],[131,180,197,198,199,223],[131,180,188,191,197,198,200,212],[131,180,197,198,201],[131,180,197,198,202],[131,179,180,197,198,203],[131,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229],[131,180,197,198,205],[131,180,197,198,206],[131,180,191,197,198,207,208],[131,180,197,198,207,209,224,226],[131,180,192,197,198],[131,180,191,197,198,212,213,215],[131,180,197,198,214,215],[131,180,197,198,212,213],[131,180,197,198,215],[131,180,197,198,216],[131,177,180,197,198,212,217,223],[131,180,191,197,198,218,219],[131,180,197,198,218,219],[131,180,185,197,198,200,212,220],[131,180,197,198,221],[131,180,197,198,200,222],[131,180,194,197,198,206,223],[131,180,185,197,198,224],[131,180,197,198,212,225],[131,180,197,198,199,226],[131,180,197,198,227],[131,173,180,197,198],[131,173,180,191,193,197,198,203,212,215,223,225,226,228],[131,180,197,198,212,229],[131,180,191,194,196,197,198,200,212,220,223,229,230],[65,66,70,97,98,100,101,102,104,105,131,180,197,198],[63,64,131,180,197,198],[63,131,180,197,198],[65,105,131,180,197,198],[65,66,102,103,105,131,180,197,198],[105,131,180,197,198],[62,105,106,131,180,197,198],[65,66,104,105,131,180,197,198],[65,66,68,69,104,105,131,180,197,198],[65,66,67,104,105,131,180,197,198],[65,66,70,97,98,99,100,101,104,105,131,180,197,198],[65,70,99,100,101,102,104,105,114,131,180,197,198],[62,65,66,70,102,104,131,180,197,198],[70,105,131,180,197,198],[72,73,74,75,76,77,78,79,80,81,105,131,180,197,198],[95,105,131,180,197,198],[71,82,90,91,92,93,94,96,131,180,197,198],[95,105,107,131,180,197,198],[105,107,131,180,197,198],[105,108,109,110,111,112,113,131,180,197,198],[70,105,107,131,180,197,198],[75,105,131,180,197,198],[83,84,85,86,87,88,89,105,131,180,197,198],[106,131,180,197,198],[116,117,119,120,121,122,123,124,125,131,180,194,195,196,197,198,200,235,236,237,238,239,240,241,242,243,244,245],[122,123,124,131,180,197,198,240,242],[122,131,180,197,198,240],[117,131,180,197,198],[117,122,123,124,125,131,180,197,198,212,235,236,237,238,240,242],[117,120,121,122,123,124,125,131,180,194,197,198,200,235,237,239,240,242,243,246],[117,122,123,124,125,131,180,197,198,234,238,240,242],[122,124,131,180,197,198,235,238],[122,131,180,197,198,235,236,238,246],[122,123,124,131,180,197,198,235,238,240,242],[116,122,123,124,131,180,197,198,235,238,240,241],[117,120,122,123,124,125,131,180,197,198,235,238,239,241,242],[116,119,131,180,197,198,246],[122,131,180,194,195,196,197,198],[122,123,131,180,197,198,240],[131,180,194,195,196,197,198],[131,180,194,195,197,198],[131,180,194,197,198,212],[131,180,194,197,198,230],[131,180,191,197,198,228,231,232,233],[131,180,191,197,198,230],[131,180,191,197,198,228],[131,145,149,180,197,198,223],[131,145,180,197,198,212,223],[131,140,180,197,198],[131,142,145,180,197,198,220,223],[131,180,197,198,200,220],[131,180,197,198,230],[131,140,180,197,198,230],[131,142,145,180,197,198,200,223],[131,137,138,141,144,180,191,197,198,212,223],[131,145,152,180,197,198],[131,137,143,180,197,198],[131,145,166,167,180,197,198],[131,141,145,180,197,198,215,223,230],[131,166,180,197,198,230],[131,139,140,180,197,198,230],[131,145,180,197,198],[131,139,140,141,142,143,144,145,146,147,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,167,168,169,170,171,172,180,197,198],[131,145,160,180,197,198],[131,145,152,153,180,197,198],[131,143,145,153,154,180,197,198],[131,144,180,197,198],[131,137,140,145,180,197,198],[131,145,149,153,154,180,197,198],[131,149,180,197,198],[131,143,145,148,180,197,198,223],[131,137,142,145,152,180,197,198],[131,180,197,198,212],[131,140,145,166,180,197,198,228,230],[131,180,192,197,198,202,223,246,247,249,250,251,252,253,261,263,264,265,267],[131,180,185,197,198,252],[131,180,192,197,198,201,202,224],[131,180,181,197,198],[131,180,191,197,198,201,202,257,260,261,262],[131,180,193,197,198,202],[131,180,185,191,192,197,198,201,202,252,254,257,258,259,260],[131,180,192,197,198,202,257],[131,180,197,198,211],[131,180,192,197,198,202,223,251,252,268],[131,180,197,198,246,253,257],[131,180,197,198,246,257,261,263],[131,180,197,198,246,257,261,263,266],[131,180,197,198,255],[131,180,197,198,255,256]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"84bcc7c6b06f4d643a55dc63b56be0c81d990f8d549b66ea615c553268774dc3","impliedFormat":1},{"version":"2d225e7bda2871c066a7079c88174340950fb604f624f2586d3ea27bb9e5f4ff","impliedFormat":1},{"version":"6a785f84e63234035e511817dd48ada756d984dd8f9344e56eb8b2bdcd8fd001","impliedFormat":1},{"version":"c1422d016f7df2ccd3594c06f2923199acd09898f2c42f50ea8159f1f856f618","impliedFormat":1},{"version":"2973b1b7857ca144251375b97f98474e9847a890331e27132d5a8b3aea9350a8","impliedFormat":1},{"version":"0eb6152d37c84d6119295493dfcc20c331c6fda1304a513d159cdaa599dcb78b","impliedFormat":1},{"version":"237df26f8c326ca00cd9d2deb40214a079749062156386b6d75bdcecc6988a6b","impliedFormat":1},{"version":"cd44995ee13d5d23df17a10213fed7b483fabfd5ea08f267ab52c07ce0b6b4da","impliedFormat":1},{"version":"58ce1486f851942bd2d3056b399079bc9cb978ec933fe9833ea417e33eab676e","impliedFormat":1},{"version":"7557d4d7f19f94341f4413575a3453ba7f6039c9591015bcf4282a8e75414043","impliedFormat":1},{"version":"a3b2cc16f3ce2d882eca44e1066f57a24751545f2a5e4a153d4de31b4cac9bb5","impliedFormat":1},{"version":"ac2b3b377d3068bfb6e1cb8889c99098f2c875955e2325315991882a74d92cc8","impliedFormat":1},{"version":"8deb39d89095469957f73bd194d11f01d9894b8c1f1e27fbf3f6e8122576b336","impliedFormat":1},{"version":"a38a9c41f433b608a0d37e645a31eecf7233ef3d3fffeb626988d3219f80e32f","impliedFormat":1},{"version":"8e1428dcba6a984489863935049893631170a37f9584c0479f06e1a5b1f04332","impliedFormat":1},{"version":"1fce9ecb87a2d3898941c60df617e52e50fb0c03c9b7b2ba8381972448327285","impliedFormat":1},{"version":"5ef0597b8238443908b2c4bf69149ed3894ac0ddd0515ac583d38c7595b151f1","impliedFormat":1},{"version":"ac52b775a80badff5f4ac329c5725a26bd5aaadd57afa7ad9e98b4844767312a","impliedFormat":1},{"version":"6ae5b4a63010c82bf2522b4ecfc29ffe6a8b0c5eea6b2b35120077e9ac54d7a1","impliedFormat":1},{"version":"dd7109c49f416f218915921d44f0f28975df78e04e437c62e1e1eb3be5e18a35","impliedFormat":1},{"version":"eee181112e420b345fc78422a6cc32385ede3d27e2eaf8b8c4ad8b2c29e3e52e","impliedFormat":1},{"version":"25fbe57c8ee3079e2201fe580578fab4f3a78881c98865b7c96233af00bf9624","impliedFormat":1},{"version":"62cc8477858487b4c4de7d7ae5e745a8ce0015c1592f398b63ee05d6e64ca295","impliedFormat":1},{"version":"cc2a9ec3cb10e4c0b8738b02c31798fad312d21ef20b6a2f5be1d077e9f5409d","impliedFormat":1},{"version":"4b4fadcda7d34034737598c07e2dca5d7e1e633cb3ba8dd4d2e6a7782b30b296","impliedFormat":1},{"version":"360fdc8829a51c5428636f1f83e7db36fef6c5a15ed4411b582d00a1c2bd6e97","impliedFormat":1},{"version":"1cf0d15e6ab1ecabbf329b906ae8543e6b8955133b7f6655f04d433e3a0597ab","impliedFormat":1},{"version":"7c9f98fe812643141502b30fb2b5ec56d16aaf94f98580276ae37b7924dd44a4","impliedFormat":1},{"version":"b3547893f24f59d0a644c52f55901b15a3fa1a115bc5ea9a582911469b9348b7","impliedFormat":1},{"version":"596e5b88b6ca8399076afcc22af6e6e0c4700c7cd1f420a78d637c3fb44a885e","impliedFormat":1},{"version":"adddf736e08132c7059ee572b128fdacb1c2650ace80d0f582e93d097ed4fbaf","impliedFormat":1},{"version":"d4cad9dc13e9c5348637170ddd5d95f7ed5fdfc856ddca40234fa55518bc99a6","impliedFormat":1},{"version":"d70675ba7ba7d02e52b7070a369957a70827e4b2bca2c1680c38a832e87b61fd","impliedFormat":1},{"version":"3be71f4ce8988a01e2f5368bdd58e1d60236baf511e4510ee9291c7b3729a27e","impliedFormat":1},{"version":"423d2ccc38e369a7527988d682fafc40267bcd6688a7473e59c5eea20a29b64f","impliedFormat":1},{"version":"2f9fde0868ed030277c678b435f63fcf03d27c04301299580a4017963cc04ce6","impliedFormat":1},{"version":"feeb73d48cc41c6dd23d17473521b0af877751504c30c18dc84267c8eeea429a","impliedFormat":1},{"version":"25f1159094dc0bf3a71313a74e0885426af21c5d6564a254004f2cadf9c5b052","impliedFormat":1},{"version":"cde493e09daad4bb29922fe633f760be9f0e8e2f39cdca999cce3b8690b5e13a","impliedFormat":1},{"version":"3d7f9eb12aface876f7b535cc89dcd416daf77f0b3573333f16ec0a70bcf902a","impliedFormat":1},{"version":"4304f640f7cb4724ea82441accb7c7607fa7207541182470d625adda99b2900b","impliedFormat":1},{"version":"e0205f04611bea8b5b82168065b8ef1476a8e96236201494eb8c785331c43118","impliedFormat":1},{"version":"62d26d8ba4fa15ab425c1b57a050ed76c5b0ecbffaa53f182110aa3a02405a07","impliedFormat":1},{"version":"9941cbf7ca695e95d588f5f1692ab040b078d44a95d231fa9a8f828186b7b77d","impliedFormat":1},{"version":"41b8775befd7ded7245a627e9f4de6110236688ce4c124d2d40c37bc1a3bfe05","impliedFormat":1},{"version":"a6613ee552418429af38391e37389036654a882c342a1b81f2711e8ddac597f2","impliedFormat":1},{"version":"da47cb979ae4a849f9b983f43ef34365b7050c4f5ae2ebf818195858774e1d67","impliedFormat":1},{"version":"ac3bcb82d7280fc313a967f311764258d18caf33db6d2b1a0243cde607ff01a0","impliedFormat":1},{"version":"c9b5632d6665177030428d02603aeac3e920d31ec83ac500b55d44c7da74bd84","impliedFormat":1},{"version":"46456824df16d60f243a7e386562b27bac838aaba66050b9bc0f31e1ab34c1f2","impliedFormat":1},{"version":"b91034069e217212d8dda6c92669ee9f180b4c36273b5244c3be2c657f9286c7","impliedFormat":1},{"version":"0697277dd829ac2610d68fe1b457c9e758105bb52d40e149d9c15e5e2fe6dca4","impliedFormat":1},{"version":"b0d06dbb409369169143ede5df1fb58b2fca8d44588e199bd624b6f6d966bf08","impliedFormat":1},{"version":"88dfdb2a44912a28aea3ebb657dc7fcec6ba59f7233005e3405824995b713dac","impliedFormat":1},{"version":"f38a45cbc0356dfb6455211e75ecd0f8aeaedbacd4cb8d6646c818d36a46d195","impliedFormat":1},{"version":"cc2d5d5687bdf9d7c49b6946b8769ac7abcbdcd1701d9bb9ca70a8bc1b003e8b","impliedFormat":1},{"version":"6f1fabd39b8c9a66a3232030a4b28ed4fb4f857dcffef0add3220dab4bbba77a","impliedFormat":1},{"version":"9c0623d67471ddc5b9d82b4e06252c746d54f7ae8ccff8701cd51c249f7e7694","impliedFormat":1},{"version":"71654f68a41362f16a2690ec215e583d3cfa913d49327e43c3c7f354022f67a3","impliedFormat":1},{"version":"f69b484edf398d636992757d587e7e38ea91844a66dbca9d682c9cf7858b77cf","impliedFormat":1},{"version":"37d852b3e6b30b974178674dbf2a7974a1ea4bbdbec26d0bdb8f34632cab94a2","impliedFormat":1},{"version":"c3ccf44723b474b5d7a87c53eed9711e81422f0e29b3e8f8f8d42775fa802243","impliedFormat":1},{"version":"faeaf9586ba4505448bd0fdb332509a7e3ecca5d8ae10208950a5d03e8b4ea28","impliedFormat":1},{"version":"c3a0295707fde0cb51ca784ecb799aa95ca71c40337b5ee4a81a8f7134dd7e92","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"9018e9493596e2d041fc531f5101a0d05f9d2e1311f4ae3c74345b1766158c08","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"4fe80f12b1d5189384a219095c2eabadbb389c2d3703aae7c5376dbaa56061df","impliedFormat":1},{"version":"9eb1d2dceae65d1c82fc6be7e9b6b19cf3ca93c364678611107362b6ad4d2d41","impliedFormat":1},{"version":"eb81f582c0e1ae21f004b39c268c68ad13222cd7e72f45080d6cdf9b994dfecf","impliedFormat":1},{"version":"e40f9840e4686053a5d42b39fddfd6774172a3d12fa61c1edb8c35b452a5e74a","impliedFormat":1},{"version":"c034433fe3ebd5391d0078de0193306591f61e421697a217cbeb92bd5e0f6ebc","impliedFormat":1},{"version":"479a021fec9328c8ab37f9372dcdc1022d79aeedde6febf03942b4456d1591c9","impliedFormat":1},{"version":"68d25a0614893e256a9e6fe18e2b125dbdad694381b57e63320de6a7518e47fc","impliedFormat":1},{"version":"49b89a0b4b3b3e18cbf726a9c608d622b4f6d49304076fc01c10f93833c70f09","impliedFormat":1},{"version":"4f62dc739ef3b99a93779255f85e51f02ce411d63cf294ee654258ff8c1978e4","impliedFormat":1},{"version":"3fa13ab73c7307a308bba2f9ca5cea92b74cbdae348a7ba1f5ac094fde7286c2","impliedFormat":1},{"version":"64102e00cb41de7f423608037d17dff83954904383e5c45f1054c2246cf5e184","impliedFormat":1},{"version":"5cf7ebe883e54b764af73548dbbef8887c640f1fd896f4d8b935b027d9989728","impliedFormat":1},{"version":"05e29a500e59cc5697947ee0fa9390e88ff008ec76be1f859152bda8ec01f13d","impliedFormat":1},{"version":"c89237cc87fc6e004290ae667babd0fa242e87c7de1cb49d4e5aba53391923f4","impliedFormat":1},{"version":"44b227ad122395768f07a8f1b84041b096220335b34ff7af3b8caa61731b294d","impliedFormat":1},{"version":"cfac258f114785ee4591fed69b045070da61d3ea03a9fabd750d682cc501253f","impliedFormat":1},{"version":"99dd60ecf4b17a5478ddc7a3a4e41500eba9b4fdbded73fa01e0ad525f7ff90d","impliedFormat":1},{"version":"1ba59c8bbeed2cb75b239bb12041582fa3e8ef32f8d0bd0ec802e38442d3f317","impliedFormat":1},{"version":"1bf1497c5e7ced001b52ed69657f472870edf3ef34641842046fc5cc47359fd0","impliedFormat":1},{"version":"36c1793e93c8a2dff0dcc67145b992e78fef0a67dd1f69d9f689b108a3598341","impliedFormat":1},{"version":"d00564db880b55513bd16eeb57ef120669790465473440b0b0ae7c963adab8f5","signature":"411e1debdff0e62082bb76ce5e708e1e328ea88f95d39803a2cf388687af9e4d","impliedFormat":99},{"version":"503e5317e3f7d73ecf4b94ffab3e0291bbc8a25ae7f48183a3150ceb33f3f977","signature":"e1f8eff69d223ca308faac04131a51f40a811ad66005ea8553acd5b0a7884273","impliedFormat":99},{"version":"44374830e8530b42058a2b9a713f0e94b0171cd2887b53a19343ae80d6b0230b","signature":"b2389a3050e376a1e5e258f76d72c5c8baf0a80bc992c9ba65c263f9257c08a8","impliedFormat":99},{"version":"e2b0a3b2ab5fa5a3f31d8150ab3b93f29828131871a898379b117a16655888b0","impliedFormat":1},{"version":"73471c44b708394862ca437720c349b8d5908f32513d4567fc976788ab8616f8","impliedFormat":99},{"version":"a7bdda672cb666a33351bcc01d644986eb746a385aa929c486d232e27770ab4c","impliedFormat":99},{"version":"8b93a53483cf3bb55c754db9dffd3cc1e3d05f87fe7158aceb4b30f5521a14fc","impliedFormat":99},{"version":"94df841d67dcf657c26c5aa60fe3b3a9daca4bd156baae524d5a4ecd9e90b401","signature":"1ddb6de962eac59d919fc52f07ce8b3c0af0c61da427b94b684d925c6ad6eb71","impliedFormat":99},{"version":"642b49a85c57c3088587db9f0575923c7c22d42704e5cc93ec6246a3a1225aaa","signature":"1c9905581b1af0a47a59496b473b325dbc18cbbdf4f6355deebd6d1da80383f7","impliedFormat":99},{"version":"eb50cb43622cdd4d5bccf49c9bc653975fe78b7c0cbffb30cbbe9272bf2765f4","signature":"d7670195d0fa7790d8ff2feffe18f30056d14aa7d6de122ea4495de74b3add44","impliedFormat":99},{"version":"c5bf2057c42d961d5d1e78b547f9e023372cc7fd7a2e542f7b6cce34503d2074","signature":"723fb8423074e8ba911313cc15b20fbe9e1d2a245d6a71a252915db1be004520","impliedFormat":99},{"version":"77f6c5368f15202d8886a044697adc340542f04c87848fbd8b6cc851f93a60ca","signature":"4a886c674cfd43c0a5bc88c5388a65443ec256d8f6b75d9c03e4da72d61798ef","impliedFormat":99},{"version":"35a4b626ce78e4b7d01f4c68d8489ec210c01b4e02d2a3da7992a5c4fe00e1f5","signature":"ae95ba1041093162fa3360a623597b3b9932169530349a7a8d4e4c3b9d669f7e","impliedFormat":99},{"version":"58089e4ae3cf5595f123796153c3852ab492073a464cf16875ca6f51dd2b89e7","signature":"9a427255affacd5f9393e9540bcdea7258ad97021bde8044493990e8dd2fd2ab","impliedFormat":99},{"version":"3d136535b1e7339b0ed2b4a5fa161d3937e9e615a33bf1c7597ade1b57d6efc2","signature":"f85fbbf4af48be05c5ae941971e4cfc9d4383c36747c5b3ac968e9d93601a3cc","impliedFormat":99},{"version":"316f1486e15cbf7896425f0a16dfe12d447dd57cfb3244b8b119c77df870858f","impliedFormat":99},{"version":"c49d8c0f230114742376db74ecab18b0be84be821da30395abc6b90b7489a3ef","signature":"b04200136e688a45038c2b597a4f5dfd8b93493383fa40143198d5c9a1f1fd28","impliedFormat":99},{"version":"3e62d10f1a9962c4bd2cb4c1721dcf9062f8e90f45a7fed2bd94d38ccf525895","signature":"ac6454f06ce215142a2c29f1a2908a3ef1945eafa58a361ad3eb833ae776d371","impliedFormat":99},{"version":"2faf78eb060f306db5b9a4d240e5c6d4306a1e4db181827f5daccd1881926883","signature":"43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012","impliedFormat":99}],"root":[[251,253],[258,265],[267,269]],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"verbatimModuleSyntax":true},"referencedMap":[[116,1],[247,2],[117,3],[119,4],[250,5],[249,6],[254,3],[177,7],[178,7],[179,8],[131,9],[180,10],[181,11],[182,12],[126,3],[129,13],[127,3],[128,3],[183,14],[184,15],[185,16],[186,17],[187,18],[188,19],[189,19],[190,20],[191,21],[192,22],[193,23],[132,3],[130,3],[194,24],[195,25],[196,26],[230,27],[197,28],[198,3],[199,29],[200,30],[201,31],[202,32],[203,33],[204,34],[205,35],[206,36],[207,37],[208,37],[209,38],[210,3],[211,39],[212,40],[214,41],[213,42],[215,43],[216,44],[217,45],[218,46],[219,47],[220,48],[221,49],[222,50],[223,51],[224,52],[225,53],[226,54],[227,55],[133,3],[134,3],[135,3],[174,56],[175,3],[176,3],[228,57],[229,58],[266,59],[248,59],[106,60],[63,3],[65,61],[64,62],[69,63],[104,64],[101,65],[103,66],[66,65],[67,67],[71,67],[70,68],[68,69],[102,70],[115,71],[100,65],[105,72],[98,3],[99,3],[72,73],[77,65],[79,65],[74,65],[75,73],[81,65],[82,74],[73,65],[78,65],[80,65],[76,65],[96,75],[95,65],[97,76],[91,65],[112,77],[110,78],[109,65],[107,63],[114,79],[111,80],[108,78],[113,78],[93,65],[92,65],[88,65],[94,81],[89,65],[90,82],[83,65],[84,65],[85,65],[86,65],[87,65],[136,3],[118,83],[62,3],[246,84],[243,85],[241,86],[244,87],[239,88],[238,89],[235,90],[236,91],[237,92],[125,93],[242,94],[240,95],[123,96],[245,97],[124,98],[122,99],[120,100],[121,101],[231,102],[234,103],[232,104],[233,105],[60,3],[61,3],[12,3],[11,3],[2,3],[13,3],[14,3],[15,3],[16,3],[17,3],[18,3],[19,3],[20,3],[3,3],[21,3],[22,3],[4,3],[23,3],[27,3],[24,3],[25,3],[26,3],[28,3],[29,3],[30,3],[5,3],[31,3],[32,3],[33,3],[34,3],[6,3],[38,3],[35,3],[36,3],[37,3],[39,3],[7,3],[40,3],[45,3],[46,3],[41,3],[42,3],[43,3],[44,3],[8,3],[50,3],[47,3],[48,3],[49,3],[51,3],[9,3],[52,3],[53,3],[54,3],[56,3],[55,3],[57,3],[58,3],[10,3],[59,3],[1,3],[152,106],[162,107],[151,106],[172,108],[143,109],[142,110],[171,111],[165,112],[170,113],[145,114],[159,115],[144,116],[168,117],[140,118],[139,111],[169,119],[141,120],[146,121],[147,3],[150,121],[137,3],[173,122],[163,123],[154,124],[155,125],[157,126],[153,127],[156,128],[166,111],[148,129],[149,130],[158,131],[138,132],[161,123],[160,121],[164,3],[167,133],[268,134],[253,135],[251,136],[259,137],[263,138],[262,139],[261,140],[258,3],[260,141],[252,142],[269,143],[264,144],[265,145],[267,146],[256,147],[257,148],[255,3]],"latestChangedDtsFile":"./dist/core/discovery-service.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/shared/src/api.ts b/packages/shared/src/api.ts index 158f848..f725085 100644 --- a/packages/shared/src/api.ts +++ b/packages/shared/src/api.ts @@ -29,3 +29,8 @@ export interface SessionsListResponse { export interface SessionResponse { session: SessionSummary; } + +// POST /sessions/:id/resume et /sessions/:id/fork (P2) : aucun corps — cwd et command +// sont TOUJOURS dérivés du :id (lu sur disque), jamais fournis par le client (cf. spike S1). +export type ResumeSessionRequest = Record; +export type ForkSessionRequest = Record; diff --git a/packages/shared/src/protocol.ts b/packages/shared/src/protocol.ts index 3f4a069..47f49d2 100644 --- a/packages/shared/src/protocol.ts +++ b/packages/shared/src/protocol.ts @@ -60,6 +60,14 @@ export type SessionRuntimeStatus = | 'running' // P1 : pas encore de distinction busy/waiting/idle (P3 via claude-adapter) | 'exited'; +/** Origine d'une session listée par Arboretum. */ +export type SessionSource = + | 'managed' // PTY lancé par Arboretum (vit dans le PtyManager) + | 'discovered'; // session Claude externe lue sur disque (~/.claude) + +/** Statut brut tel qu'écrit par le CLI dans ~/.claude/sessions (interprété finement en P3). */ +export type SessionRegistryStatus = 'busy' | 'idle' | 'waiting'; + export interface SessionSummary { id: string; cwd: string; @@ -71,6 +79,19 @@ export interface SessionSummary { endedAt: string | null; exitCode: number | null; clients: number; + // ---- P2 : découverte & reprise (additif) ---- + /** 'managed' = PtyManager ; 'discovered' = lue sur disque. */ + source: SessionSource; + /** ID interne du CLI claude (clé de corrélation managé↔découvert) ; null pour bash ou claude pas encore prêt. */ + claudeSessionId: string | null; + /** pid du process claude (découvertes vivantes & managées vivantes) ; null sinon. */ + pid: number | null; + /** true si un `--resume` direct est sûr (session morte) ; false pour une vivante (corruption). */ + resumable: boolean; + /** true si Arboretum tient le PTY (managée vivante) ; jamais pour une découverte. */ + attachable: boolean; + /** statut brut du registre ~/.claude/sessions (P2) ; interprété finement en P3 (claude-adapter). */ + registryStatus: SessionRegistryStatus | null; } // ---- Messages client → serveur ---- diff --git a/packages/shared/tsconfig.tsbuildinfo b/packages/shared/tsconfig.tsbuildinfo index 68f838d..574ddb9 100644 --- a/packages/shared/tsconfig.tsbuildinfo +++ b/packages/shared/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/protocol.ts","./src/api.ts","./src/index.ts","../../node_modules/@types/deep-eql/index.d.ts","../../node_modules/assertion-error/index.d.ts","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/compatibility/index.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/@types/node/web-globals/events.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/file.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/filereader.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/inspector.generated.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/ws/index.d.ts"],"fileIdsList":[[65,66,74,123,140,141],[74,123,140,141],[74,120,121,123,140,141],[74,122,123,140,141],[123,140,141],[74,123,128,140,141,158],[74,123,124,129,134,140,141,143,155,166],[74,123,124,125,134,140,141,143],[69,70,71,74,123,140,141],[74,123,126,140,141,167],[74,123,127,128,135,140,141,144],[74,123,128,140,141,155,163],[74,123,129,131,134,140,141,143],[74,122,123,130,140,141],[74,123,131,132,140,141],[74,123,133,134,140,141],[74,122,123,134,140,141],[74,123,134,135,136,140,141,155,166],[74,123,134,135,136,140,141,150,155,158],[74,116,123,131,134,137,140,141,143,155,166],[74,123,134,135,137,138,140,141,143,155,163,166],[74,123,137,139,140,141,155,163,166],[72,73,74,75,76,77,78,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],[74,123,134,140,141],[74,123,140,141,142,166],[74,123,131,134,140,141,143,155],[74,123,140,141,144],[74,123,140,141,145],[74,122,123,140,141,146],[74,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],[74,123,140,141,148],[74,123,140,141,149],[74,123,134,140,141,150,151],[74,123,140,141,150,152,167,169],[74,123,135,140,141],[74,123,134,140,141,155,156,158],[74,123,140,141,157,158],[74,123,140,141,155,156],[74,123,140,141,158],[74,123,140,141,159],[74,120,123,140,141,155,160,166],[74,123,134,140,141,161,162],[74,123,140,141,161,162],[74,123,128,140,141,143,155,163],[74,123,140,141,164],[74,123,140,141,143,165],[74,123,137,140,141,149,166],[74,123,128,140,141,167],[74,123,140,141,155,168],[74,123,140,141,142,169],[74,123,140,141,170],[74,116,123,140,141],[74,116,123,134,136,140,141,146,155,158,166,168,169,171],[74,123,140,141,155,172],[74,123,134,137,139,140,141,143,155,163,166,172,173],[74,88,92,123,140,141,166],[74,88,123,140,141,155,166],[74,83,123,140,141],[74,85,88,123,140,141,163,166],[74,123,140,141,143,163],[74,123,140,141,173],[74,83,123,140,141,173],[74,85,88,123,140,141,143,166],[74,80,81,84,87,123,134,140,141,155,166],[74,88,95,123,140,141],[74,80,86,123,140,141],[74,88,109,110,123,140,141],[74,84,88,123,140,141,158,166,173],[74,109,123,140,141,173],[74,82,83,123,140,141,173],[74,88,123,140,141],[74,82,83,84,85,86,87,88,89,90,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,110,111,112,113,114,115,123,140,141],[74,88,103,123,140,141],[74,88,95,96,123,140,141],[74,86,88,96,97,123,140,141],[74,87,123,140,141],[74,80,83,88,123,140,141],[74,88,92,96,97,123,140,141],[74,92,123,140,141],[74,86,88,91,123,140,141,166],[74,80,85,88,95,123,140,141],[74,123,140,141,155],[74,83,88,109,123,140,141,171,173],[62,74,123,140,141],[62,63,74,123,140,141]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd3f497a20129961ff2798627df44b34b84b54b3f45f18d286a0398a379cbc17","signature":"155aa8c32f0815cb7f44246680859e2724428459727e6067d0d434a666b72e5b","impliedFormat":99},{"version":"a12d76034419dd99ec4b201711bce3870bc140f3c1fa7a9eb9efbc22295cfa32","signature":"0eaa5ca815f0d1f498a205737cc71a5259671ee1ffc96eb881ee721c2d60bf30","impliedFormat":99},{"version":"8b93a53483cf3bb55c754db9dffd3cc1e3d05f87fe7158aceb4b30f5521a14fc","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"9018e9493596e2d041fc531f5101a0d05f9d2e1311f4ae3c74345b1766158c08","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"1ba59c8bbeed2cb75b239bb12041582fa3e8ef32f8d0bd0ec802e38442d3f317","impliedFormat":1}],"root":[[62,64]],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"verbatimModuleSyntax":true},"referencedMap":[[67,1],[65,2],[68,2],[120,3],[121,3],[122,4],[74,5],[123,6],[124,7],[125,8],[69,2],[72,9],[70,2],[71,2],[126,10],[127,11],[128,12],[129,13],[130,14],[131,15],[132,15],[133,16],[134,17],[135,18],[136,19],[75,2],[73,2],[137,20],[138,21],[139,22],[173,23],[140,24],[141,2],[142,25],[143,26],[144,27],[145,28],[146,29],[147,30],[148,31],[149,32],[150,33],[151,33],[152,34],[153,2],[154,35],[155,36],[157,37],[156,38],[158,39],[159,40],[160,41],[161,42],[162,43],[163,44],[164,45],[165,46],[166,47],[167,48],[168,49],[169,50],[170,51],[76,2],[77,2],[78,2],[117,52],[118,2],[119,2],[171,53],[172,54],[174,55],[66,2],[79,2],[60,2],[61,2],[12,2],[11,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[19,2],[20,2],[3,2],[21,2],[22,2],[4,2],[23,2],[27,2],[24,2],[25,2],[26,2],[28,2],[29,2],[30,2],[5,2],[31,2],[32,2],[33,2],[34,2],[6,2],[38,2],[35,2],[36,2],[37,2],[39,2],[7,2],[40,2],[45,2],[46,2],[41,2],[42,2],[43,2],[44,2],[8,2],[50,2],[47,2],[48,2],[49,2],[51,2],[9,2],[52,2],[53,2],[54,2],[56,2],[55,2],[57,2],[58,2],[10,2],[59,2],[1,2],[95,56],[105,57],[94,56],[115,58],[86,59],[85,60],[114,61],[108,62],[113,63],[88,64],[102,65],[87,66],[111,67],[83,68],[82,61],[112,69],[84,70],[89,71],[90,2],[93,71],[80,2],[116,72],[106,73],[97,74],[98,75],[100,76],[96,77],[99,78],[109,61],[91,79],[92,80],[101,81],[81,82],[104,73],[103,71],[107,2],[110,83],[63,84],[64,85],[62,2]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"} \ No newline at end of file +{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","./src/protocol.ts","./src/api.ts","./src/index.ts","../../node_modules/@types/deep-eql/index.d.ts","../../node_modules/assertion-error/index.d.ts","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/compatibility/index.d.ts","../../node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/@types/node/web-globals/events.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/undici-types/header.d.ts","../../node_modules/undici-types/readable.d.ts","../../node_modules/undici-types/file.d.ts","../../node_modules/undici-types/fetch.d.ts","../../node_modules/undici-types/formdata.d.ts","../../node_modules/undici-types/connector.d.ts","../../node_modules/undici-types/client.d.ts","../../node_modules/undici-types/errors.d.ts","../../node_modules/undici-types/dispatcher.d.ts","../../node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/undici-types/global-origin.d.ts","../../node_modules/undici-types/pool-stats.d.ts","../../node_modules/undici-types/pool.d.ts","../../node_modules/undici-types/handlers.d.ts","../../node_modules/undici-types/balanced-pool.d.ts","../../node_modules/undici-types/agent.d.ts","../../node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/undici-types/mock-agent.d.ts","../../node_modules/undici-types/mock-client.d.ts","../../node_modules/undici-types/mock-pool.d.ts","../../node_modules/undici-types/mock-errors.d.ts","../../node_modules/undici-types/proxy-agent.d.ts","../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/undici-types/retry-handler.d.ts","../../node_modules/undici-types/retry-agent.d.ts","../../node_modules/undici-types/api.d.ts","../../node_modules/undici-types/interceptors.d.ts","../../node_modules/undici-types/util.d.ts","../../node_modules/undici-types/cookies.d.ts","../../node_modules/undici-types/patch.d.ts","../../node_modules/undici-types/websocket.d.ts","../../node_modules/undici-types/eventsource.d.ts","../../node_modules/undici-types/filereader.d.ts","../../node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/undici-types/content-type.d.ts","../../node_modules/undici-types/cache.d.ts","../../node_modules/undici-types/index.d.ts","../../node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/inspector.generated.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/ws/index.d.ts"],"fileIdsList":[[65,66,74,123,140,141],[74,123,140,141],[74,120,121,123,140,141],[74,122,123,140,141],[123,140,141],[74,123,128,140,141,158],[74,123,124,129,134,140,141,143,155,166],[74,123,124,125,134,140,141,143],[69,70,71,74,123,140,141],[74,123,126,140,141,167],[74,123,127,128,135,140,141,144],[74,123,128,140,141,155,163],[74,123,129,131,134,140,141,143],[74,122,123,130,140,141],[74,123,131,132,140,141],[74,123,133,134,140,141],[74,122,123,134,140,141],[74,123,134,135,136,140,141,155,166],[74,123,134,135,136,140,141,150,155,158],[74,116,123,131,134,137,140,141,143,155,166],[74,123,134,135,137,138,140,141,143,155,163,166],[74,123,137,139,140,141,155,163,166],[72,73,74,75,76,77,78,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],[74,123,134,140,141],[74,123,140,141,142,166],[74,123,131,134,140,141,143,155],[74,123,140,141,144],[74,123,140,141,145],[74,122,123,140,141,146],[74,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],[74,123,140,141,148],[74,123,140,141,149],[74,123,134,140,141,150,151],[74,123,140,141,150,152,167,169],[74,123,135,140,141],[74,123,134,140,141,155,156,158],[74,123,140,141,157,158],[74,123,140,141,155,156],[74,123,140,141,158],[74,123,140,141,159],[74,120,123,140,141,155,160,166],[74,123,134,140,141,161,162],[74,123,140,141,161,162],[74,123,128,140,141,143,155,163],[74,123,140,141,164],[74,123,140,141,143,165],[74,123,137,140,141,149,166],[74,123,128,140,141,167],[74,123,140,141,155,168],[74,123,140,141,142,169],[74,123,140,141,170],[74,116,123,140,141],[74,116,123,134,136,140,141,146,155,158,166,168,169,171],[74,123,140,141,155,172],[74,123,134,137,139,140,141,143,155,163,166,172,173],[74,88,92,123,140,141,166],[74,88,123,140,141,155,166],[74,83,123,140,141],[74,85,88,123,140,141,163,166],[74,123,140,141,143,163],[74,123,140,141,173],[74,83,123,140,141,173],[74,85,88,123,140,141,143,166],[74,80,81,84,87,123,134,140,141,155,166],[74,88,95,123,140,141],[74,80,86,123,140,141],[74,88,109,110,123,140,141],[74,84,88,123,140,141,158,166,173],[74,109,123,140,141,173],[74,82,83,123,140,141,173],[74,88,123,140,141],[74,82,83,84,85,86,87,88,89,90,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,110,111,112,113,114,115,123,140,141],[74,88,103,123,140,141],[74,88,95,96,123,140,141],[74,86,88,96,97,123,140,141],[74,87,123,140,141],[74,80,83,88,123,140,141],[74,88,92,96,97,123,140,141],[74,92,123,140,141],[74,86,88,91,123,140,141,166],[74,80,85,88,95,123,140,141],[74,123,140,141,155],[74,83,88,109,123,140,141,171,173],[62,74,123,140,141],[62,63,74,123,140,141]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"5da3075354d70da75795eda8a993445bd77bc25ceee4b3a9cfd0da9a9582f515","signature":"73471c44b708394862ca437720c349b8d5908f32513d4567fc976788ab8616f8","impliedFormat":99},{"version":"dda609a75f2c87e919fa4d45222a6ec0ad89d0c2dc5350d8af983bc5eee843f5","signature":"a7bdda672cb666a33351bcc01d644986eb746a385aa929c486d232e27770ab4c","impliedFormat":99},{"version":"8b93a53483cf3bb55c754db9dffd3cc1e3d05f87fe7158aceb4b30f5521a14fc","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"58647d85d0f722a1ce9de50955df60a7489f0593bf1a7015521efe901c06d770","impliedFormat":1},{"version":"9018e9493596e2d041fc531f5101a0d05f9d2e1311f4ae3c74345b1766158c08","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"80523c00b8544a2000ae0143e4a90a00b47f99823eb7926c1e03c494216fc363","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"746911b62b329587939560deb5c036aca48aece03147b021fa680223255d5183","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"1ba59c8bbeed2cb75b239bb12041582fa3e8ef32f8d0bd0ec802e38442d3f317","impliedFormat":1}],"root":[[62,64]],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"verbatimModuleSyntax":true},"referencedMap":[[67,1],[65,2],[68,2],[120,3],[121,3],[122,4],[74,5],[123,6],[124,7],[125,8],[69,2],[72,9],[70,2],[71,2],[126,10],[127,11],[128,12],[129,13],[130,14],[131,15],[132,15],[133,16],[134,17],[135,18],[136,19],[75,2],[73,2],[137,20],[138,21],[139,22],[173,23],[140,24],[141,2],[142,25],[143,26],[144,27],[145,28],[146,29],[147,30],[148,31],[149,32],[150,33],[151,33],[152,34],[153,2],[154,35],[155,36],[157,37],[156,38],[158,39],[159,40],[160,41],[161,42],[162,43],[163,44],[164,45],[165,46],[166,47],[167,48],[168,49],[169,50],[170,51],[76,2],[77,2],[78,2],[117,52],[118,2],[119,2],[171,53],[172,54],[174,55],[66,2],[79,2],[60,2],[61,2],[12,2],[11,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[19,2],[20,2],[3,2],[21,2],[22,2],[4,2],[23,2],[27,2],[24,2],[25,2],[26,2],[28,2],[29,2],[30,2],[5,2],[31,2],[32,2],[33,2],[34,2],[6,2],[38,2],[35,2],[36,2],[37,2],[39,2],[7,2],[40,2],[45,2],[46,2],[41,2],[42,2],[43,2],[44,2],[8,2],[50,2],[47,2],[48,2],[49,2],[51,2],[9,2],[52,2],[53,2],[54,2],[56,2],[55,2],[57,2],[58,2],[10,2],[59,2],[1,2],[95,56],[105,57],[94,56],[115,58],[86,59],[85,60],[114,61],[108,62],[113,63],[88,64],[102,65],[87,66],[111,67],[83,68],[82,61],[112,69],[84,70],[89,71],[90,2],[93,71],[80,2],[116,72],[106,73],[97,74],[98,75],[100,76],[96,77],[99,78],[109,61],[91,79],[92,80],[101,81],[81,82],[104,73],[103,71],[107,2],[110,83],[63,84],[64,85],[62,2]],"latestChangedDtsFile":"./dist/api.d.ts","version":"5.9.3"} \ No newline at end of file diff --git a/packages/web/src/i18n/en.ts b/packages/web/src/i18n/en.ts index 762d124..d360344 100644 --- a/packages/web/src/i18n/en.ts +++ b/packages/web/src/i18n/en.ts @@ -27,9 +27,14 @@ export default { creating: 'Creating…', open: 'Open', observe: 'Observe', + view: 'View', + resume: 'Resume', + fork: 'Fork', kill: 'Kill', confirmKill: 'Confirm kill', live: 'live', + resumable: 'resumable', + sourceDiscovered: 'discovered', clients: 'no client | 1 client | {n} clients', exitCode: 'exit code {code}', statusLabel: { @@ -37,11 +42,17 @@ export default { running: 'running', exited: 'exited', }, + registryStatus: { + busy: 'busy', + idle: 'idle', + waiting: 'waiting', + }, }, terminal: { observer: 'observer (read-only)', sessionEnded: 'Session ended', back: 'Sessions', + notAttachable: 'This session runs outside Arboretum — fork it to interact, or resume it once it has stopped.', }, ws: { reconnecting: 'Connection lost — reconnecting…', diff --git a/packages/web/src/i18n/fr.ts b/packages/web/src/i18n/fr.ts index 4c75c46..4fa649a 100644 --- a/packages/web/src/i18n/fr.ts +++ b/packages/web/src/i18n/fr.ts @@ -29,9 +29,14 @@ const fr: typeof en = { creating: 'Création…', open: 'Ouvrir', observe: 'Observer', + view: 'Voir', + resume: 'Reprendre', + fork: 'Dupliquer', kill: 'Tuer', confirmKill: 'Confirmer', live: 'en cours', + resumable: 'reprenable', + sourceDiscovered: 'découverte', clients: 'aucun client | 1 client | {n} clients', exitCode: 'code de sortie {code}', statusLabel: { @@ -39,11 +44,18 @@ const fr: typeof en = { running: 'en cours', exited: 'terminée', }, + registryStatus: { + busy: 'occupée', + idle: 'inactive', + waiting: 'en attente', + }, }, terminal: { observer: 'observateur (lecture seule)', sessionEnded: 'Session terminée', back: 'Sessions', + notAttachable: + 'Cette session tourne hors d’Arboretum — dupliquez-la pour interagir, ou reprenez-la une fois arrêtée.', }, ws: { reconnecting: 'Connexion perdue — reconnexion…', diff --git a/packages/web/src/stores/sessions.ts b/packages/web/src/stores/sessions.ts index 98dea77..6d8e9e7 100644 --- a/packages/web/src/stores/sessions.ts +++ b/packages/web/src/stores/sessions.ts @@ -72,5 +72,30 @@ export const useSessionsStore = defineStore('sessions', () => { await api.delete<{ ok: true }>(`/api/v1/sessions/${id}`); } - return { sessions, loading, loadError, fetchSessions, startRealtime, stopRealtime, createSession, killSession }; + // Reprise d'une session morte (nouveau PTY managé dans son cwd d'origine, côté serveur). + async function resumeSession(id: string): Promise { + const res = await api.post(`/api/v1/sessions/${id}/resume`); + upsert(res.session); + return res.session; + } + + // Fork d'une session (vivante ou morte) — ne corrompt jamais l'originale. + async function forkSession(id: string): Promise { + const res = await api.post(`/api/v1/sessions/${id}/fork`); + upsert(res.session); + return res.session; + } + + return { + sessions, + loading, + loadError, + fetchSessions, + startRealtime, + stopRealtime, + createSession, + killSession, + resumeSession, + forkSession, + }; }); diff --git a/packages/web/src/views/SessionView.vue b/packages/web/src/views/SessionView.vue index e5a1c95..4ff739c 100644 --- a/packages/web/src/views/SessionView.vue +++ b/packages/web/src/views/SessionView.vue @@ -12,7 +12,11 @@ - + + +
+

{{ t('terminal.notAttachable') }}

+
@@ -31,6 +35,8 @@ const store = useSessionsStore(); const sessionId = computed(() => String(route.params.id)); const mode = computed<'interactive' | 'observer'>(() => (route.query.mode === 'observer' ? 'observer' : 'interactive')); const session = computed(() => store.sessions.find((s) => s.id === sessionId.value) ?? null); +// défaut true : une navigation directe (liste pas encore chargée) tente l'attache d'une session managée. +const attachable = computed(() => session.value?.attachable ?? true); onMounted(() => { // navigation directe : la liste n'est pas encore chargée (en-tête cwd/commande) diff --git a/packages/web/src/views/SessionsListView.vue b/packages/web/src/views/SessionsListView.vue index 0ebf00f..e8f2e90 100644 --- a/packages/web/src/views/SessionsListView.vue +++ b/packages/web/src/views/SessionsListView.vue @@ -39,6 +39,7 @@

{{ createError }}

+

{{ actionError }}

{{ store.loadError }}

@@ -54,32 +55,49 @@ >

{{ s.command }} + + {{ t('sessions.sourceDiscovered') }} + - {{ t('sessions.live') }} + {{ s.registryStatus ? t(`sessions.registryStatus.${s.registryStatus}`) : t('sessions.live') }} + {{ t('sessions.resumable') }} {{ t('sessions.statusLabel.exited') }} {{ formatDate(s.createdAt) }}
-

{{ s.cwd }}

+

{{ s.title }}

+

{{ s.cwd }}

- {{ t(`sessions.statusLabel.${s.status}`) }} - · {{ t('sessions.clients', s.clients) }} + {{ t('sessions.clients', s.clients) }} · {{ t('sessions.exitCode', { code: s.exitCode }) }} -
- - {{ t('sessions.open') }} - - - {{ t('sessions.observe') }} - -