@wrongstack/core 0.268.0 → 0.269.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-UhojbpWx.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
- package/dist/{agent-subagent-runner-Bvtf1o9K.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
- package/dist/{brain-69wzMKp1.d.ts → brain-BYcK__Ym.d.ts} +1 -1
- package/dist/{compactor-CBQAJoDc.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
- package/dist/{config-VKfOZ-6X.d.ts → config-C_ae2k86.d.ts} +11 -2
- package/dist/{context-C0U8B9NF.d.ts → context-Dp87Bcaq.d.ts} +24 -1
- package/dist/coordination/index.d.ts +22 -16
- package/dist/coordination/index.js +233 -86
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +272 -69
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -15
- package/dist/execution/index.js +116 -19
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-KByEFFBa.d.ts → global-mailbox-Bvrz1P3f.d.ts} +2 -1
- package/dist/{goal-preamble-CrYjmdw4.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
- package/dist/{goal-store-Y_zdLZ3q.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
- package/dist/hq/index.d.ts +15 -6
- package/dist/hq/index.js +55 -8
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-CtQnmkaS.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
- package/dist/{index-gCv830d7.d.ts → index-W4VJCzHa.d.ts} +5 -5
- package/dist/{index-BfaS-f_m.d.ts → index-whDfTANu.d.ts} +2 -2
- package/dist/index.d.ts +41 -41
- package/dist/index.js +531 -167
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +3 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/{mcp-servers-HT3Fi7Bl.d.ts → mcp-servers-DJdZiRcv.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-Bvcl3Vaa.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-BACjsmkC.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
- package/dist/{null-fleet-bus-DA7fvhUg.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-Ci71gYu_.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -9
- package/dist/{path-resolver-O1IJnmKE.d.ts → path-resolver-CnQ8SIfh.d.ts} +3 -3
- package/dist/{permission-Bd-57Lbl.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
- package/dist/{permission-policy-uNXC6Kge.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -2
- package/dist/{pipeline-BDNvENyV.d.ts → pipeline-l_zzFRh3.d.ts} +2 -2
- package/dist/{plan-templates-EMsalEtN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
- package/dist/{provider-model-resolve-CEb9x886.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
- package/dist/{provider-runner-DWJbpo70.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
- package/dist/{retry-policy-C3s_lvdK.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +1 -1
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-Cgduf5xL.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-47LBnBVk.d.ts → selector-CXl2_y9W.d.ts} +1 -1
- package/dist/{session-event-bridge-Cw7oqmW2.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
- package/dist/{session-reader-DD4v2Obw.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +13 -11
- package/dist/storage/index.js +210 -64
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +110 -19
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +58 -24
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/chimera/SKILL.md +1 -1
- package/skills/typescript-strict/SKILL.md +3 -3
- package/skills/typescript-strict/SKILL.save.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/utils/atomic-write.ts","../../src/utils/message-invariants.ts","../../src/utils/term.ts","../../src/utils/color.ts","../../src/utils/deep-merge.ts","../../src/utils/error.ts","../../src/utils/regex-guard.ts","../../src/utils/safe-json.ts","../../src/utils/wstack-paths.ts","../../src/storage/session-store.ts","../../src/storage/queue-store.ts","../../src/storage/attachment-store.ts","../../src/types/memory.ts","../../src/storage/memory-backend.ts","../../src/storage/memory-store.ts","../../src/storage/memory-graph-backend.ts","../../src/storage/memory-consolidator.ts","../../src/types/errors.ts","../../src/storage/config-store.ts","../../src/security/secret-vault.ts","../../src/types/context-window.ts","../../src/types/default-config.ts","../../src/storage/config-loader.ts","../../src/storage/config-migration.ts","../../src/storage/recovery-lock.ts","../../src/storage/session-reader.ts","../../src/utils/session-scoped-path.ts","../../src/storage/annotations-store.ts","../../src/replay/hash.ts","../../src/storage/replay-log-store.ts","../../src/storage/session-recovery.ts","../../src/storage/tool-audit-log.ts","../../src/storage/session-analyzer.ts","../../src/session-registry.ts","../../src/agent-status-tracker.ts","../../src/fleet-notifier.ts","../../src/storage/session-rewinder.ts","../../src/storage/todos-checkpoint.ts","../../src/storage/plan-store.ts","../../src/storage/plan-templates.ts","../../src/storage/task-store.ts","../../src/storage/director-state.ts","../../src/storage/goal-store.ts","../../src/storage/prompt-store.ts","../../src/storage/cloud-sync.ts","../../src/storage/session-event-bridge.ts"],"names":["path","fs","stat","resolve","open","projectHash","randomBytes","path3","path4","fsp2","fsp3","path5","path6","fs2","writeFile","mkdir","fs3","deepMerge","fs5","path8","os2","fsp5","path9","randomUUID","fs6","createHash","storageErrorString","fs7","path10","fs8","path11","stableStringify","fs9","sortKeys","path12","projectSlug","fs10","pidAlive","path13","fs11","path14","fsp6","fsp7","fsp8","fsp9","fsp10","lock","hostname","fsp11","fs12","path15","path16","fs13","relative"],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import { toErrorMessage } from './error.js';\n\nexport interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: toErrorMessage(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: toErrorMessage(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack — global root. */\n globalRoot: string;\n /**\n * ~/.wrongstack — directory for user-global stateful config files\n * (mode.json, theme.json, …). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key — 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md — user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills — user-global skills. */\n globalSkills: string;\n /** ~/.wrongstack/prompts — user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/cache — fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json — cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir — NOT inside the repo — so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history — REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json — optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json — per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md — committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills — committed project skills. */\n inProjectSkills: string;\n /** <project>/.wrongstack/worktrees — git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json — goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/specs — SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs — SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json — SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json — plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase — AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/sync.json — CloudSync configuration */\n syncConfig: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state — config, secrets, logs, projects/, mailboxes — away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { randomBytes } from 'node:crypto';\nimport type { Dirent } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\nimport type {\n ResumedSession,\n SessionData,\n SessionEvent,\n SessionMetadata,\n SessionStore,\n SessionSummary,\n SessionWriter,\n} from '../types/session.js';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { toErrorMessage } from '../utils/index.js';\n// ─── Session ID naming ───────────────────────────────────────────────────────\n\n/** Sanitize a model name for use in filenames: alphanumeric + dash + underscore. */\nfunction sanitizeModel(model: string): string {\n return model\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n\n/**\n * Generate a session ID in the format:\n * `YYYY-MM-DD/HH-MM-SSZ[_model]_xxxx.jsonl`\n *\n * Examples:\n * `2026-06-06/12-30-45Z_claude-sonnet_a1b2.jsonl`\n * `2026-06-06/14-22-10Z_a1b2.jsonl` (no model)\n *\n * The date prefix becomes a subdirectory so sessions group naturally by day.\n * The model name (when available) lets you see at a glance which provider was\n * used, without opening the file. The 4-byte random suffix prevents collisions\n * within the same second.\n */\nfunction generateSessionId(startedAt: string, model?: string): string {\n const date = startedAt.slice(0, 10); // \"2026-06-06\"\n const time = startedAt.slice(11, 19).replace(/:/g, '-'); // \"12-30-45\"\n const suffix = randomBytes(2).toString('hex'); // \"a1b2\"\n const modelPart = model ? `_${sanitizeModel(model)}` : '';\n return `${date}/${time}Z${modelPart}_${suffix}`;\n}\n\nexport interface SessionStoreOptions {\n dir: string;\n /** Optional EventBus for emitting session diagnostics. */\n events?: EventBus | undefined;\n /**\n * Optional secret scrubber. When set, `user_input` and `llm_response` event\n * content is scrubbed before being persisted to the JSONL log and the\n * summary sidecar — so a secret a user pastes or the model echoes does not\n * sit in cleartext on disk (and does not ride along in history cloud-sync).\n * Tool output is already scrubbed upstream by the executor; this closes the\n * conversation-turn gap (finding F-06).\n */\n secretScrubber?: SecretScrubber | undefined;\n}\n\n/**\n * Cache entry for load() — stores the parsed SessionData along with the\n * file's mtimeMs and size at the time of loading. On subsequent calls,\n * if the file's mtimeMs+size match, we return the cached data without\n * re-reading or re-parsing the JSONL.\n */\ninterface LoadCacheEntry {\n mtimeMs: number;\n size: number;\n data: SessionData;\n}\n\nexport class DefaultSessionStore implements SessionStore {\n private readonly dir: string;\n private readonly events?: EventBus | undefined;\n private readonly secretScrubber?: SecretScrubber | undefined;\n\n /**\n * In-memory cache for load() results, keyed by session ID. The cache is\n * invalidated when the file's mtimeMs or size changes (indicating the\n * file was written to). This eliminates redundant full-file reads and\n * JSON parses when the same session is loaded multiple times within the\n * store's lifetime (e.g., webui session detail views, list() fallbacks).\n *\n * Max size is capped to prevent unbounded memory growth in long-running\n * processes. When the limit is reached, the oldest entry is evicted.\n */\n private readonly _loadCache = new Map<string, LoadCacheEntry>();\n private static readonly LOAD_CACHE_MAX_ENTRIES = 50;\n\n constructor(opts: SessionStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.secretScrubber = opts.secretScrubber;\n }\n\n /**\n * Clear the load() cache. Useful for testing or when the caller knows\n * the file has changed externally (e.g., another process wrote to it).\n */\n clearLoadCache(sessionId?: string): void {\n if (sessionId !== undefined) {\n this._loadCache.delete(sessionId);\n } else {\n this._loadCache.clear();\n }\n }\n\n // ── Storage event helpers ───────────────────────────────────────────────────\n\n private emitRead(\n sessionId: string,\n filePath: string,\n operation: 'load' | 'list' | 'summary' | 'index_read',\n outcome: 'success' | 'failure',\n durationMs: number,\n error?: string,\n ): void {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n outcome,\n durationMs,\n ...(error !== undefined ? { error } : {}),\n });\n }\n\n private emitWrite(\n sessionId: string,\n filePath: string,\n operation: 'create' | 'resume' | 'append' | 'flush' | 'close' | 'index_append' | 'compact' | 'checkpoint',\n outcome: 'success' | 'failure',\n durationMs: number,\n eventCount?: number,\n error?: string,\n ): void {\n this.events?.emit('storage.write', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n outcome,\n durationMs,\n ...(eventCount !== undefined ? { eventCount } : {}),\n ...(error !== undefined ? { error } : {}),\n });\n }\n\n private emitError(\n sessionId: string,\n filePath: string,\n operation: string,\n error: string,\n recoverable: boolean,\n ): void {\n this.events?.emit('storage.error', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n error,\n recoverable,\n });\n }\n\n /** Absolute path to the session index file. */\n private get indexFile(): string {\n return path.join(this.dir, '_index.jsonl');\n }\n\n /** Join session ID to its absolute path within the store directory. */\n private sessionPath(id: string, ext: '.jsonl' | '.summary.json'): string {\n return path.join(this.dir, `${id}${ext}`);\n }\n\n /**\n * Ensure the directory implied by the session ID exists. When the ID\n * contains a date prefix like `2026-06-06/...`, this creates the date\n * subdirectory so sessions group naturally by day.\n */\n private async ensureShardDir(id: string): Promise<string> {\n const dirPath = path.dirname(path.join(this.dir, id));\n await ensureDir(dirPath);\n return dirPath;\n }\n\n async create(meta: Omit<SessionMetadata, 'startedAt'>): Promise<SessionWriter> {\n const startedAt = new Date().toISOString();\n const id =\n meta.id && meta.id.length > 0\n ? meta.id\n : generateSessionId(startedAt, meta.model ?? meta.provider);\n const shardDir = await this.ensureShardDir(id);\n const file = path.join(shardDir, `${path.basename(id)}.jsonl`);\n const t0 = Date.now();\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n this.emitError(id, file, 'create', toErrorMessage(err), false);\n throw new Error(\n `Failed to open session file: ${toErrorMessage(err)}`,\n { cause: err },\n );\n }\n try {\n const writer = new FileSessionWriter(id, handle, startedAt, meta, this.events, {\n dir: shardDir,\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n });\n this.emitWrite(id, file, 'create', 'success', Date.now() - t0);\n return writer;\n /* v8 ignore start -- defensive: FileSessionWriter ctor does not throw in practice */\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n this.emitError(id, file, 'create', toErrorMessage(err), true);\n throw err;\n }\n /* v8 ignore stop */\n }\n\n async resume(id: string): Promise<ResumedSession> {\n const file = this.sessionPath(id, '.jsonl');\n const t0 = Date.now();\n const data = await this.load(id);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n /* v8 ignore start -- defensive: load() above already validated the file is readable */\n } catch (err) {\n this.emitError(id, file, 'resume', toErrorMessage(err), false);\n throw new Error(\n `Failed to open session \"${id}\" for append: ${toErrorMessage(err)}`,\n { cause: err },\n );\n }\n /* v8 ignore stop */\n try {\n const writer = new FileSessionWriter(\n id,\n handle,\n new Date().toISOString(),\n {\n id,\n model: data.metadata.model,\n provider: data.metadata.provider,\n },\n this.events,\n {\n resumed: true,\n // Shard directory (sessions/<date>/) — must match create() so the\n // .summary.json sidecar lands next to the JSONL instead of the\n // sessions root (where summaryFor() would never find it).\n dir: path.dirname(file),\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n },\n );\n this.emitWrite(id, file, 'resume', 'success', Date.now() - t0);\n return { writer, data };\n /* v8 ignore start -- defensive: FileSessionWriter ctor does not throw in practice */\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n this.emitError(id, file, 'resume', toErrorMessage(err), true);\n throw err;\n }\n /* v8 ignore stop */\n }\n\n async load(id: string): Promise<SessionData> {\n const file = this.sessionPath(id, '.jsonl');\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n let cacheHit = false;\n try {\n // Stat the file first to check the cache. The stat is cheap (no content\n // read) and lets us skip the full readFile + JSON parse when the file\n // hasn't changed since the last load.\n let stat: { mtimeMs: number; size: number };\n try {\n const s = await fsp.stat(file);\n stat = { mtimeMs: s.mtimeMs, size: s.size };\n } catch (err) {\n // File doesn't exist or can't be stat'd — fall through to the\n // readFile path which will throw the original ENOENT.\n throw err;\n }\n\n // Check cache: if mtimeMs AND size match, the file hasn't changed.\n const cached = this._loadCache.get(id);\n if (cached && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) {\n cacheHit = true;\n // Update insertion order to prevent frequent-access sessions from being\n // evicted by the LRU eviction logic.\n this._loadCache.delete(id);\n this._loadCache.set(id, cached);\n return cached.data;\n }\n\n // Cache miss — do the full read + parse.\n const raw = await fsp.readFile(file, 'utf8');\n const lines = raw.split('\\n').filter((l) => l.trim());\n const events: SessionEvent[] = [];\n for (const line of lines) {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\n ) {\n events.push(parsed as SessionEvent);\n }\n } catch {\n // skip malformed JSON\n }\n }\n const meta = this.metaFromEvents(id, events);\n const { messages, usage } = this.replay(events, id);\n // Extract tool_call_end events for TUI tool entry rendering on resume.\n const toolCallEnds = extractToolCallEnds(events);\n const data: SessionData = { metadata: meta, events, messages, usage, toolCallEnds };\n\n // Update the cache. Evict oldest entry if at capacity.\n if (this._loadCache.size >= DefaultSessionStore.LOAD_CACHE_MAX_ENTRIES) {\n // Map iteration order is insertion order — delete the first key.\n const oldest = this._loadCache.keys().next().value;\n if (oldest !== undefined) {\n this._loadCache.delete(oldest);\n }\n }\n this._loadCache.set(id, { mtimeMs: stat.mtimeMs, size: stat.size, data });\n\n return data;\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n throw err;\n } finally {\n this.emitRead(id, file, 'load', outcome, Date.now() - t0, errorMsg);\n if (cacheHit) {\n this.events?.emit('storage.cache_hit', {\n sessionId: id,\n store: 'session',\n filePath: file,\n operation: 'load',\n durationMs: Date.now() - t0,\n });\n }\n }\n }\n\n async list(limit = 20): Promise<SessionSummary[]> {\n try {\n await ensureDir(this.dir);\n // Try the index first; fall back to directory scan if the index is\n // missing, empty, or unreadable.\n const indexed = await this.readIndex();\n if (indexed.length > 0) {\n indexed.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return indexed.slice(0, limit);\n }\n // Index unavailable — fall back to full directory scan + summary parse.\n const ids = await this.collectSessionIds(this.dir);\n /* v8 ignore next -- summaryFor() never rejects for a collected id (its .jsonl exists) */\n const sessions = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const out = sessions.filter((s): s is SessionSummary => s !== null);\n out.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return out.slice(0, limit);\n } catch {\n return [];\n }\n }\n\n // ── Session index (_index.jsonl) ─────────────────────────────────────────\n //\n // One JSON line per closed session, appended atomically on close().\n // When a session is deleted, a tombstone {action:\"delete\",id:\"...\"} is\n // appended. On read, tombstones filter out matching session entries.\n // This keeps listing O(lines-in-index) instead of O(files-on-disk).\n //\n // The index auto-compacts every N appends to prevent unbounded growth\n // from tombstones and duplicate entries (resume cycles).\n\n private indexAppendCount = 0;\n private static readonly COMPACT_EVERY = 30;\n\n /** Append a session summary to the index. */\n private async appendToIndex(summary: SessionSummary): Promise<void> {\n // Note: storage.write for this operation is emitted by FileSessionWriter.doClose()\n // so it can include the traceId. Do NOT emit here to avoid duplicates.\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify(summary) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n // Auto-compact the index periodically to remove tombstones and duplicates.\n if (this.indexAppendCount >= DefaultSessionStore.COMPACT_EVERY) {\n await this.compactIndex();\n this.indexAppendCount = 0;\n }\n } catch {\n // best-effort — error surfaced via the storage.write event in doClose()\n }\n }\n\n /** Append a tombstone entry for a deleted session. */\n private async writeTombstone(id: string): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify({ action: 'delete', id }) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this.indexAppendCount++;\n } catch {\n // best-effort\n }\n }\n\n /**\n * Compact the index: read all entries, drop tombstones, deduplicate\n * (keep latest per session), and rewrite. Atomic via temp+rename.\n */\n private async compactIndex(): Promise<void> {\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n const entries = await this.readIndex();\n if (entries.length === 0) return;\n const tmp = `${this.indexFile}.compact.tmp`;\n const lines = entries.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n } finally {\n // Compact is internal — use 'session' as the session ID placeholder.\n this.emitWrite('~compact~', this.indexFile, 'compact', outcome, Date.now() - t0, undefined, errorMsg);\n }\n }\n\n /**\n * Read the index file and return deduplicated session summaries.\n * Entries with a matching tombstone are filtered out.\n * Returns empty array when the index doesn't exist or is corrupt.\n */\n private async readIndex(): Promise<SessionSummary[]> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.indexFile, 'utf8');\n } catch {\n return [];\n }\n const deleted = new Set<string>();\n const seen = new Map<string, SessionSummary>();\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as { action?: string | undefined; id?: string | undefined } & SessionSummary;\n if (entry.action === 'delete' && entry.id) {\n deleted.add(entry.id);\n seen.delete(entry.id);\n continue;\n }\n if (entry.id && !deleted.has(entry.id)) {\n // Keep the latest entry for each session (multiple appends on resume).\n seen.set(entry.id, entry as SessionSummary);\n }\n } catch {\n // skip corrupt lines\n }\n }\n return Array.from(seen.values());\n }\n\n /**\n * Rebuild the index from disk by scanning all sessions and writing a\n * fresh _index.jsonl. Useful after manual cleanup or index corruption.\n */\n async rebuildIndex(): Promise<number> {\n const ids = await this.collectSessionIds(this.dir);\n /* v8 ignore next -- summaryFor() never rejects for a collected id (its .jsonl exists) */\n const summaries = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const valid = summaries.filter((s): s is SessionSummary => s !== null);\n // Atomic rewrite: write to temp, then rename.\n const tmp = `${this.indexFile}.tmp`;\n const lines = valid.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n return valid.length;\n }\n\n /** Recursively collect session IDs from date-shard subdirectories.\n * IDs include the date-prefix path (e.g. \"2026-06-06/17-46-57Z_…\").\n * Skips `.jsonl`/`.summary.json` root files, dot-files, and\n * sub-directories that belong to fleet/subagent sessions. */\n private async collectSessionIds(\n dir: string,\n prefix = '',\n depth = 0,\n ): Promise<string[]> {\n const ids: string[] = [];\n let entries: Dirent[];\n try {\n entries = await fsp.readdir(dir, { withFileTypes: true });\n } catch {\n return ids;\n }\n for (const entry of entries) {\n // Skip dot-files and known non-session directories\n if (entry.name.startsWith('.') && entry.name !== '.wrongstack') continue;\n if (entry.name === 'shared' || entry.name === 'subagents' || entry.name === 'attachments')\n continue;\n if (entry.isDirectory()) {\n // Date-shard directories become the prefix for their contents\n const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;\n ids.push(...(await this.collectSessionIds(path.join(dir, entry.name), childPrefix, depth + 1)));\n } else if (entry.isFile() && entry.name.endsWith('.jsonl')) {\n // Skip the session index itself — it's bookkeeping, not a session log.\n // (Only skip THIS file at root, not every root-level jsonl: flat/legacy\n // sessions and the test fixtures live directly under the sessions dir.)\n if (entry.name === '_index.jsonl') continue;\n const base = entry.name.replace(/\\.jsonl$/, '');\n // Subagent session logs live under subagents/ which we skip above.\n ids.push(prefix ? `${prefix}/${base}` : base);\n }\n }\n return ids;\n }\n\n private async summaryFor(id: string): Promise<SessionSummary> {\n const manifest = this.sessionPath(id, '.summary.json');\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n const raw = await fsp.readFile(manifest, 'utf8');\n this.emitRead(id, manifest, 'summary', 'success', Date.now() - t0);\n return JSON.parse(raw) as SessionSummary;\n } catch {\n const full = this.sessionPath(id, '.jsonl');\n const stat = await fsp.stat(full);\n const summary = await this.summarize(id, stat.mtime.toISOString());\n await atomicWrite(manifest, JSON.stringify(summary), { mode: 0o600 }).catch((err) => {\n const msg = toErrorMessage(err);\n this.emitError(id, manifest, 'summary_fallback', msg, true);\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.manifest_write_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n outcome = 'failure';\n errorMsg = 'summary fallback — manifest rebuilt';\n this.emitRead(id, manifest, 'summary', outcome, Date.now() - t0, errorMsg);\n return summary;\n }\n }\n\n /**\n * Delete a session and all associated files: JSONL, summary, plan/todos\n * sidecars, and the session directory (fleet.json, shared/, subagents/).\n *\n * Individual file deletions are best-effort (logged as structured warnings),\n * but a tombstone is always written so readIndex() filters this session out.\n * If the session directory itself can't be removed, the error is surfaced\n * to the caller so prune() can report it.\n */\n private async deleteSession(id: string): Promise<void> {\n const jsonlPath = this.sessionPath(id, '.jsonl');\n const summaryPath = this.sessionPath(id, '.summary.json');\n const shardDir = path.dirname(path.join(this.dir, id));\n const base = path.basename(id);\n const sessDir = path.join(shardDir, base);\n\n const deletions: Array<Promise<void>> = [\n fsp.unlink(jsonlPath),\n fsp.unlink(summaryPath),\n fsp.unlink(path.join(shardDir, `${base}.plan.json`)),\n fsp.unlink(path.join(shardDir, `${base}.todos.json`)),\n ];\n\n const results = await Promise.allSettled(deletions);\n for (const r of results) {\n if (r.status === 'rejected') {\n const msg = r.reason instanceof Error ? r.reason.message : String(r.reason);\n // ENOENT is expected (file may not exist — sidecars are optional).\n if ((r.reason as NodeJS.ErrnoException)?.code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.delete_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n }\n\n // Remove the session directory (may contain fleet.json, shared/, subagents/).\n /* v8 ignore start -- defensive: rm with force:true rarely rejects */\n await fsp.rm(sessDir, { recursive: true, force: true }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.rmdir_failed',\n sessionId: id,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n });\n /* v8 ignore stop */\n\n // Write an index tombstone so readIndex() filters this session out.\n await this.writeTombstone(id);\n }\n\n async delete(id: string): Promise<void> {\n await this.deleteSession(id);\n }\n\n async prune(maxAgeDays = 30): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 86_400_000;\n let deleted = 0;\n\n // Read the active session lock to avoid pruning the current session.\n let activeSessionId: string | null = null;\n try {\n const raw = await fsp.readFile(path.join(this.dir, 'active.json'), 'utf8');\n const active = JSON.parse(raw) as { sessionId?: string | undefined };\n activeSessionId = active.sessionId ?? null;\n } catch {\n // no active.json — nothing to protect\n }\n\n const isPrunableJsonl = (name: string): boolean =>\n name.endsWith('.jsonl') &&\n name !== '_index.jsonl' &&\n name !== '_mailbox.jsonl' &&\n !name.endsWith('.replay.jsonl') &&\n !name.endsWith('.audit.jsonl');\n\n const pruneFile = async (dir: string, name: string, prefix: string): Promise<void> => {\n const jsonlPath = path.join(dir, name);\n try {\n const stat = await fsp.stat(jsonlPath);\n if (stat.mtimeMs >= cutoff) return;\n /* v8 ignore start -- defensive: file vanished between readdir and stat */\n } catch {\n return;\n }\n /* v8 ignore stop */\n const base = name.replace(/\\.jsonl$/, '');\n const id = prefix ? `${prefix}/${base}` : base;\n // Never prune the currently active session.\n if (activeSessionId && id === activeSessionId) return;\n await this.deleteSession(id);\n deleted++;\n };\n\n /* v8 ignore next -- defensive: store dir is ensured before prune runs */\n const entries = await fsp.readdir(this.dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (entry.isFile()) {\n // Flat legacy sessions at the sessions root — pre-shard layout.\n // A shard-only scan left these accumulating forever.\n if (isPrunableJsonl(entry.name)) await pruneFile(this.dir, entry.name, '');\n continue;\n }\n /* v8 ignore next -- defensive: root entries are only files or directories */\n if (!entry.isDirectory()) continue;\n // entry.name is a date-shard like \"2026-06-06\"\n const dateDir = path.join(this.dir, entry.name);\n /* v8 ignore next -- defensive: dateDir came from readdir and is readable */\n const files = await fsp.readdir(dateDir, { withFileTypes: true }).catch(() => []);\n for (const file of files) {\n if (!file.isFile() || !isPrunableJsonl(file.name)) continue;\n await pruneFile(dateDir, file.name, entry.name);\n }\n }\n if (deleted > 0) {\n // Compact the index to remove tombstones for deleted sessions.\n /* v8 ignore next -- best-effort: compactIndex swallows its own errors */\n await this.compactIndex().catch(() => undefined); /* best-effort */\n }\n // Clean up empty date-shard directories left behind after pruning.\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dateDir = path.join(this.dir, entry.name);\n try {\n const remaining = await fsp.readdir(dateDir);\n if (remaining.length === 0) {\n /* v8 ignore next -- best-effort: rmdir of a confirmed-empty dir does not reject */\n await fsp.rmdir(dateDir).catch(() => undefined);\n }\n } catch {\n // best-effort\n }\n }\n return deleted;\n }\n\n async clearHistory(id: string): Promise<void> {\n await this.ensureShardDir(id);\n const file = this.sessionPath(id, '.jsonl');\n const meta = this.sessionPath(id, '.summary.json');\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id,\n model: 'unknown',\n provider: 'unknown',\n })}\\n`;\n await fsp.writeFile(file, record, 'utf8');\n await fsp.unlink(meta).catch(() => undefined);\n }\n\n private async summarize(id: string, mtime: string): Promise<SessionSummary> {\n try {\n const data = await this.load(id);\n const firstUser = data.events.find((e) => e.type === 'user_input');\n const title =\n firstUser && firstUser.type === 'user_input'\n ? userInputTitle(firstUser.content)\n : '(empty session)';\n\n // Compute enriched stats from events.\n let iterationCount = 0;\n let toolCallCount = 0;\n let toolErrorCount = 0;\n let fileChangeCount = 0;\n const toolBreakdown: Record<string, number> = {};\n let outcome: SessionSummary['outcome'] ;\n const lastEvent = data.events[data.events.length - 1];\n\n for (const e of data.events) {\n if (e.type === 'in_flight_start') iterationCount++;\n else if (e.type === 'tool_call_start') {\n toolCallCount++;\n toolBreakdown[e.name] = (toolBreakdown[e.name] ?? 0) + 1;\n } else if (e.type === 'tool_result' && e.isError) toolErrorCount++;\n else if (e.type === 'file_snapshot') fileChangeCount += e.files.length;\n }\n\n // Determine outcome from the last event.\n if (lastEvent?.type === 'session_end') {\n outcome = 'completed';\n } else if (lastEvent?.type === 'in_flight_start') {\n outcome = 'aborted';\n } else if (data.events.some((e) => e.type === 'error')) {\n outcome = 'error';\n }\n\n return {\n id,\n title,\n startedAt: data.metadata.startedAt,\n endedAt: data.metadata.endedAt,\n model: data.metadata.model ?? 'unknown',\n provider: data.metadata.provider ?? 'unknown',\n tokenTotal: data.usage.input + data.usage.output,\n iterationCount: iterationCount > 0 ? iterationCount : undefined,\n toolCallCount: toolCallCount > 0 ? toolCallCount : undefined,\n toolErrorCount: toolErrorCount > 0 ? toolErrorCount : undefined,\n fileChangeCount: fileChangeCount > 0 ? fileChangeCount : undefined,\n toolBreakdown: Object.keys(toolBreakdown).length > 0 ? toolBreakdown : {},\n outcome,\n };\n } catch {\n return {\n id,\n title: '(damaged)',\n startedAt: mtime,\n model: 'unknown',\n provider: 'unknown',\n tokenTotal: 0,\n };\n }\n }\n\n private metaFromEvents(id: string, events: SessionEvent[]): SessionMetadata {\n const start = events.find((e) => e.type === 'session_start');\n // Use the LAST session_end: resume cycles append a new session_end on\n // every clean exit, and legacy /save commands wrote mid-stream markers.\n const end = events.findLast((e) => e.type === 'session_end');\n return {\n id,\n startedAt: start?.ts ?? new Date(0).toISOString(),\n endedAt: end?.ts,\n model: start?.model,\n provider: start?.provider,\n pendingToolUses: end?.pendingToolUses,\n };\n }\n\n private replay(\n events: SessionEvent[],\n sessionId = 'unknown',\n ): { messages: Message[]; usage: SessionData['usage'] } {\n const messages: Message[] = [];\n let usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n const openToolUses = new Set<string>();\n for (const e of events) {\n if (e.type === 'user_input') {\n openToolUses.clear();\n messages.push({ role: 'user', content: e.content, ts: e.ts });\n } else if (e.type === 'llm_response') {\n messages.push({ role: 'assistant', content: e.content, ts: e.ts });\n for (const b of e.content) {\n if (b.type === 'tool_use') openToolUses.add(b.id);\n }\n usage = {\n input: usage.input + (e.usage.input ?? 0),\n output: usage.output + (e.usage.output ?? 0),\n cacheRead: (usage.cacheRead ?? 0) + (e.usage.cacheRead ?? 0),\n cacheWrite: (usage.cacheWrite ?? 0) + (e.usage.cacheWrite ?? 0),\n };\n } else if (e.type === 'tool_result') {\n if (!openToolUses.has(e.id)) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `Orphan tool_result \"${e.id}\" has no matching tool_use`,\n });\n continue;\n }\n openToolUses.delete(e.id);\n // Provider protocol: tool_result blocks live in a USER message that\n // follows the assistant's tool_use turn — never inside the assistant\n // message itself (repairToolUseAdjacency would treat that as broken\n // adjacency and strip the tool_use blocks, silently dropping the\n // assistant turn on resume). Consecutive results from one turn are\n // grouped into a single user message.\n const resultBlock: ContentBlock = {\n type: 'tool_result',\n tool_use_id: e.id,\n content: typeof e.content === 'string' ? e.content : JSON.stringify(e.content),\n is_error: e.isError,\n };\n const last = messages[messages.length - 1];\n const lastIsToolResultUser =\n last?.role === 'user' &&\n Array.isArray(last.content) &&\n last.content.every((b) => (b as ContentBlock).type === 'tool_result');\n if (lastIsToolResultUser && Array.isArray(last.content)) {\n last.content.push(resultBlock);\n } else {\n messages.push({ role: 'user', content: [resultBlock], ts: e.ts });\n }\n }\n }\n if (openToolUses.size > 0) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `${openToolUses.size} tool_use blocks without matching results - replay repaired`,\n });\n }\n const repaired = repairToolUseAdjacency(messages);\n if (repaired.report.changed) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail:\n `Repaired replay adjacency: removed ${repaired.report.removedToolUses.length} tool_use, ` +\n `${repaired.report.removedToolResults.length} tool_result, ` +\n `${repaired.report.removedMessages} empty messages`,\n });\n }\n return { messages: repaired.messages, usage };\n }\n}\n\n/**\n * Extract tool execution records from `tool_call_end` events in the JSONL.\n * These are used by the TUI to render tool entries (name, duration, ok/error)\n * when a session is resumed. Events are returned in JSONL order (the order\n * they appear in the file, which is chronological insertion order).\n */\nfunction extractToolCallEnds(events: SessionEvent[]): SessionData['toolCallEnds'] {\n const result: SessionData['toolCallEnds'] = [];\n for (const e of events) {\n if (e.type === 'tool_call_end') {\n result.push({\n name: e.name,\n id: e.id,\n durationMs: e.durationMs,\n ok: e.ok ?? false,\n outputBytes: e.outputBytes,\n outputTokens: e.outputTokens,\n outputLines: e.outputLines,\n });\n }\n }\n return result;\n}\n\nclass FileSessionWriter implements SessionWriter {\n private closed = false;\n private closePromise: Promise<void> | null = null;\n private manifestFile: string;\n private summary: SessionSummary;\n private tokenIn = 0;\n private tokenOut = 0;\n private readonly filePath: string;\n get transcriptPath(): string | undefined {\n return this.filePath || undefined;\n }\n /**\n * Lazy session_start/session_resumed init, shared by all appenders.\n * A single promise (not a boolean) so a second append racing the first\n * can't push its event into the buffer BEFORE the first append's event —\n * every appender awaits the same init and resumes in FIFO call order.\n */\n private initPromise: Promise<void> | null = null;\n private ensureInit(): Promise<void> {\n if (!this.initPromise) this.initPromise = this.writeSessionStartLazy();\n return this.initPromise;\n }\n private readonly resumed: boolean;\n private appendFailCount = 0;\n private lastAppendWarnAt = 0;\n private readonly secretScrubber?: SecretScrubber | undefined;\n private readonly onCloseCb?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n /** Implements SessionWriter.traceId — propagated from ContextInit.traceId. */\n traceId: string | undefined;\n\n // ── Write buffer — batches events to reduce per-event disk I/O ─────────\n //\n // Every append() pushes the scrubbed event into an in-memory buffer instead\n // of calling handle.appendFile() synchronously. The buffer flushes to disk\n // when it reaches FLUSH_SIZE events OR after FLUSH_INTERVAL_MS of inactivity.\n // This cuts the number of disk writes by ~95% without changing the on-disk\n // format — the JSONL is still one JSON object per line.\n private writeBuffer: SessionEvent[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly FLUSH_INTERVAL_MS = 500;\n private static readonly FLUSH_SIZE = 50;\n\n // ── Write serialization ─────────────────────────────────────────────────\n //\n // All disk writes are funneled through a FIFO promise chain. Without it,\n // a timer-driven flush racing an explicit flush()/close() issues two\n // concurrent appendFile() calls on the shared O_APPEND handle — the kernel\n // may complete them out of order (chronology breaks) or, for large\n // batches, interleave partial writes (torn JSONL lines). The chain keeps\n // exactly one write in flight; failures don't break the chain.\n private writeChain: Promise<void> = Promise.resolve();\n\n /** Enqueue a write on the FIFO chain. Resolves/rejects with that write. */\n private enqueueWrite(data: string): Promise<void> {\n const write = this.writeChain.then(() => this.handle.appendFile(data, 'utf8'));\n this.writeChain = write.then(\n () => undefined,\n () => undefined,\n );\n return write;\n }\n\n // ── Enriched summary tracking ──────────────────────────────────────────\n private iterationCount = 0;\n private toolCallCount = 0;\n private toolErrorCount = 0;\n private toolBreakdown: Record<string, number> = {};\n private fileChangeCount = 0;\n private compactionCount = 0;\n private outcome: SessionSummary['outcome'] = undefined;\n\n /**\n * Scrub secrets out of conversation-turn events before they are observed\n * for the summary, written to the JSONL log, or surfaced on resume. Only\n * `user_input` / `llm_response` carry free-form user/model text; other event\n * types either have no secret-bearing content or are already scrubbed\n * upstream (tool results). Returns the event unchanged when no scrubber is\n * configured.\n */\n private scrubEvent(event: SessionEvent): SessionEvent {\n const s = this.secretScrubber;\n if (!s) return event;\n if (event.type === 'user_input') {\n return {\n ...event,\n content:\n typeof event.content === 'string' ? s.scrub(event.content) : s.scrubObject(event.content),\n };\n }\n if (event.type === 'llm_response') {\n return { ...event, content: s.scrubObject(event.content) };\n }\n return event;\n }\n\n private pendingFileSnapshots: Array<{\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }> = [];\n /** Tracks open tool_use IDs during the current run to serialize on close for resume. */\n private openToolUses = new Set<string>();\n\n recordFileChange(input: {\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }): void {\n this.pendingFileSnapshots.push(input);\n }\n\n constructor(\n public readonly id: string,\n private handle: fsp.FileHandle,\n private readonly startedAt: string,\n private readonly meta: Omit<SessionMetadata, 'startedAt'>,\n private readonly events?: EventBus | undefined,\n opts: {\n resumed?: boolean | undefined;\n dir?: string | undefined;\n filePath?: string | undefined;\n secretScrubber?: SecretScrubber | undefined;\n /** Called on close() with the finalized summary for index/sidecar writes. */\n onClose?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n } = {},\n traceId?: string | undefined,\n ) {\n this.resumed = opts.resumed ?? false;\n // id already contains a date-prefix shard (e.g. \"2026-06-06/17-46-57Z_…\").\n // opts.dir is the shard directory — join with basename so the manifest\n // lives next to the JSONL file instead of creating a double-nested path.\n this.manifestFile = opts.dir ? path.join(opts.dir, `${path.basename(id)}.summary.json`) : '';\n this.filePath = opts.filePath ?? '';\n this.secretScrubber = opts.secretScrubber;\n this.onCloseCb = opts.onClose;\n this.summary = {\n id,\n title: '(empty session)',\n startedAt,\n model: meta.model ?? 'unknown',\n provider: meta.provider ?? 'unknown',\n tokenTotal: 0,\n };\n // Propagated from ContextInit.traceId via SessionWriter.traceId so that\n // storage events carry the run-level trace ID without needing a Context\n // handle in every storage operation.\n this.traceId = traceId;\n }\n\n get pendingToolUses(): string[] {\n return Array.from(this.openToolUses);\n }\n\n private async writeSessionStartLazy(): Promise<void> {\n // Write through the SAME file handle that flushBuffer() uses — avoids\n // cross-fd issues on Windows where a separate fsp.writeFile can contend\n // with the already-open append-mode handle. The handle was opened with\n // O_APPEND so this write lands at the current end-of-file regardless of\n // whether the file is empty or already contains prior session data.\n const record = `${JSON.stringify({\n type: this.resumed ? 'session_resumed' : 'session_start',\n ts: this.startedAt,\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n try {\n await this.enqueueWrite(record);\n } catch {\n // best-effort\n }\n }\n\n async append(event: SessionEvent): Promise<void> {\n if (this.closed) return;\n await this.ensureInit();\n // Scrub before observing (the summary title is derived from user_input\n // content) and before buffering, so neither the JSONL nor the sidecar\n // ever holds a cleartext secret.\n const scrubbed = this.scrubEvent(event);\n // observeForSummary MUST run synchronously here — the summary counters\n // (toolCallCount, tokenIn/Out, outcome) drive the .summary.json sidecar\n // and the session index. Deferring observation to flush time would leave\n // the summary stale if close() fires before the next timer tick.\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n // Buffer full — flush immediately. Cancel any pending timer so we\n // don't double-flush on the next tick.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n async appendBatch(events: SessionEvent[]): Promise<void> {\n if (this.closed || events.length === 0) return;\n await this.ensureInit();\n for (const event of events) {\n const scrubbed = this.scrubEvent(event);\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n }\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n /**\n * Flush buffered events to disk immediately. Critical events\n * (user_input, llm_response) call this so they survive SIGKILL/crash\n * instead of sitting in the in-memory buffer for up to 500ms.\n *\n * Idempotent — cancels any pending timer and writes whatever has\n * accumulated in the buffer. Safe to call even when the buffer\n * is empty (no-op).\n */\n async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n }\n\n /** Schedule a deferred flush. No-op if a timer is already pending. */\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n /* v8 ignore start -- defensive: flushBuffer logs its own errors; this guards the timer callback */\n this.flushBuffer().catch(() => {\n // flushBuffer already logs via the throttled-warning path;\n // this catch prevents an unhandled rejection in the timer callback.\n });\n /* v8 ignore stop */\n }, FileSessionWriter.FLUSH_INTERVAL_MS);\n }\n\n /**\n * Flush all buffered events to disk as a single appendFile call.\n * Errors use the same throttled-warning pattern the old per-event\n * append path used — one warning every 5s with a suppressed count.\n * On failure the buffer is cleared (events are best-effort, same as\n * the old per-event path where a failed write was silently dropped).\n */\n private async flushBuffer(): Promise<void> {\n if (this.writeBuffer.length === 0) return;\n const eventCount = this.writeBuffer.length;\n const batch = this.writeBuffer.map((e) => JSON.stringify(e)).join('\\n') + '\\n';\n this.writeBuffer = [];\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n await this.enqueueWrite(batch);\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n this.appendFailCount += eventCount;\n const now = Date.now();\n if (now - this.lastAppendWarnAt > 5000) {\n const suppressed = this.appendFailCount - 1;\n const tail = suppressed > 0 ? ` (+${suppressed} suppressed)` : '';\n console.warn(\n '[session] flush failed:',\n toErrorMessage(err),\n tail,\n );\n this.lastAppendWarnAt = now;\n this.appendFailCount = 0;\n }\n } finally {\n this.events?.emit('storage.write', {\n sessionId: this.id,\n store: 'session',\n filePath: this.filePath,\n operation: 'flush',\n outcome,\n durationMs: Date.now() - t0,\n ...(errorMsg !== undefined ? { error: errorMsg } : {}),\n ...(eventCount !== undefined ? { eventCount } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n }\n\n private observeForSummary(event: SessionEvent): void {\n // Track open tool uses so we can serialize them on close for resume.\n // The authoritative source is the llm_response content (a core event,\n // always written at every audit level); the legacy 'tool_use' event is\n // kept for alternate writers that still emit it.\n if (event.type === 'llm_response') {\n for (const block of event.content) {\n if (block.type === 'tool_use') this.openToolUses.add(block.id);\n }\n }\n if (event.type === 'tool_use') {\n this.openToolUses.add(event.id);\n } else if (event.type === 'tool_call_start') {\n this.toolCallCount++;\n this.toolBreakdown[event.name] = (this.toolBreakdown[event.name] ?? 0) + 1;\n } else if (event.type === 'tool_result') {\n this.openToolUses.delete(event.id);\n if (event.isError) {\n this.toolErrorCount++;\n this.outcome = 'error';\n }\n } else if (event.type === 'file_snapshot') {\n this.fileChangeCount += event.files.length;\n } else if (event.type === 'compaction') {\n this.compactionCount++;\n }\n // Error events (provider errors, execution errors) mark the session as failed.\n if (event.type === 'error' || event.type === 'provider_error') {\n this.outcome = 'error';\n }\n if (event.type === 'user_input' && this.summary.title === '(empty session)') {\n this.summary = { ...this.summary, title: userInputTitle(event.content) };\n } else if (event.type === 'llm_response') {\n this.tokenIn += event.usage.input;\n this.tokenOut += event.usage.output;\n this.summary = { ...this.summary, tokenTotal: this.tokenIn + this.tokenOut };\n } else if (event.type === 'session_end') {\n const total = event.usage.input + event.usage.output;\n if (total > 0) this.summary = { ...this.summary, tokenTotal: total };\n } else if (event.type === 'in_flight_start') {\n this.iterationCount++;\n }\n }\n\n async close(): Promise<void> {\n // Idempotent AND awaitable: concurrent/repeat callers share the same\n // promise, so nobody proceeds (e.g. to tear down the session directory)\n // while the first close is still flushing.\n if (this.closePromise) return this.closePromise;\n this.closePromise = this.doClose();\n return this.closePromise;\n }\n\n private async doClose(): Promise<void> {\n this.closed = true;\n // Flush any buffered events before finalizing. The summary counters\n // (toolCallCount, tokenIn/Out, outcome) are already up to date because\n // observeForSummary runs synchronously on every append, but the JSONL\n // must have all events on disk before we write the .summary.json sidecar.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain any write enqueued outside flushBuffer (e.g. the lazy\n // session_start record) before the handle is closed.\n await this.writeChain;\n // Finalize the summary before writing.\n this.summary = {\n ...this.summary,\n endedAt: new Date().toISOString(),\n iterationCount: this.iterationCount,\n toolCallCount: this.toolCallCount,\n toolErrorCount: this.toolErrorCount,\n fileChangeCount: this.fileChangeCount,\n compactionCount: this.compactionCount > 0 ? this.compactionCount : undefined,\n toolBreakdown:\n { ...this.toolBreakdown },\n outcome: this.outcome ?? 'completed',\n };\n // Emit storage.write for the manifest sidecar.\n if (this.manifestFile) {\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 0o600 });\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n // manifest write is best-effort\n } finally {\n this.events?.emit('storage.write', {\n sessionId: this.id,\n store: 'session',\n filePath: this.manifestFile,\n operation: 'close',\n outcome,\n durationMs: Date.now() - t0,\n ...(errorMsg !== undefined ? { error: errorMsg } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n }\n // Notify the store so it can update the session index. Await so the\n // index write completes before close() resolves — otherwise the\n // fire-and-forget _index.jsonl append races callers that tear down the\n // session directory right after close() (e.g. ENOTEMPTY on Windows).\n // Emit storage.write here so it carries this.traceId; the actual I/O\n // is delegated to onCloseCb (appendToIndex) which no longer emits.\n const idxT0 = Date.now();\n let idxOutcome: 'success' | 'failure' = 'success';\n let idxError: string | undefined;\n try {\n await this.onCloseCb?.(this.summary);\n /* v8 ignore start -- best-effort: appendToIndex swallows its own errors */\n } catch (err) {\n idxOutcome = 'failure';\n idxError = toErrorMessage(err);\n // best-effort\n } finally {\n /* v8 ignore stop */\n this.events?.emit('storage.write', {\n sessionId: this.summary.id,\n store: 'session',\n filePath: this.filePath,\n operation: 'index_append',\n outcome: idxOutcome,\n durationMs: Date.now() - idxT0,\n ...(idxError !== undefined ? { error: idxError } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n try {\n await this.handle.close();\n } catch {\n // ignore\n }\n }\n\n async writeCheckpoint(promptIndex: number, promptPreview: string): Promise<void> {\n const fileCount = this.pendingFileSnapshots.length;\n if (fileCount > 0) {\n await this.writeFileSnapshot(promptIndex, [...this.pendingFileSnapshots]);\n this.pendingFileSnapshots = [];\n }\n await this.append({\n type: 'checkpoint',\n ts: new Date().toISOString(),\n promptIndex,\n promptPreview,\n });\n this.events?.emit('checkpoint.written', {\n promptIndex,\n promptPreview,\n ts: new Date().toISOString(),\n fileCount,\n });\n }\n\n async writeFileSnapshot(\n promptIndex: number,\n files: import('../types/session.js').FileSnapshot[],\n ): Promise<void> {\n await this.append({\n type: 'file_snapshot',\n ts: new Date().toISOString(),\n promptIndex,\n files,\n });\n }\n\n async truncateToCheckpoint(targetPromptIndex: number): Promise<number> {\n /* v8 ignore next -- defensive: filePath is always set for a live writer */\n if (!this.filePath) return 0;\n // Flush buffered events to disk before reading — otherwise the in-memory\n // events that haven't hit the JSONL yet would be invisible to the\n // truncation logic and would be silently dropped by the rewrite.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain the write chain so no in-flight write straddles the\n // close → rename → reopen sequence below.\n await this.writeChain;\n const raw = await fsp.readFile(this.filePath, 'utf8');\n const lines = raw.split('\\n');\n const kept: string[] = [];\n let removedCount = 0;\n\n let targetCheckpointLine = -1;\n let afterTarget = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = expectDefined(lines[i]);\n if (!line.trim()) continue;\n\n let event: { type?: string | undefined; promptIndex?: number | undefined };\n try {\n event = JSON.parse(line);\n } catch {\n kept.push(line);\n continue;\n }\n\n if (event.type === 'checkpoint') {\n if ((event as { promptIndex: number }).promptIndex === targetPromptIndex) {\n targetCheckpointLine = kept.length;\n afterTarget = true;\n } else if ((event as { promptIndex: number }).promptIndex > targetPromptIndex) {\n afterTarget = true;\n }\n }\n\n if (event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n removedCount++;\n } else if (event.promptIndex === undefined) {\n if (!afterTarget || targetCheckpointLine === -1) {\n kept.push(line);\n } else {\n removedCount++;\n }\n } else {\n kept.push(line);\n }\n }\n\n const truncated = kept.join('\\n');\n // Windows EPERM fix: close the append-mode handle, write via temp file\n // and rename, then reopen. This is needed because rename() fails on\n // Windows when the target has an open file handle.\n const tmpPath = `${this.filePath}.rewind.tmp`;\n await fsp.writeFile(tmpPath, truncated + '\\n', 'utf8');\n try {\n await this.handle.close();\n await fsp.rename(tmpPath, this.filePath);\n // Re-open in append mode for continued use of this file.\n this.handle = await fsp.open(this.filePath, 'a', 0o600);\n /* v8 ignore start -- defensive: close/rename/reopen of a just-written temp file */\n } catch (err) {\n await fsp.unlink(tmpPath).catch(() => undefined);\n throw err;\n }\n /* v8 ignore stop */\n\n await this.append({\n type: 'rewound',\n ts: new Date().toISOString(),\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n });\n\n this.events?.emit('session.rewound', {\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n removedEvents: removedCount,\n });\n\n return removedCount;\n }\n\n async clearSession(): Promise<void> {\n /* v8 ignore next -- defensive: filePath is always set for a live writer */\n if (!this.filePath) return;\n // Discard any buffered events — the caller is explicitly resetting the\n // session to a clean slate. Cancel the timer so it doesn't fire and\n // append stale events to the freshly-cleared file.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.writeBuffer = [];\n // Let any in-flight append land first — otherwise it would re-append\n // stale events AFTER the reset record below.\n await this.writeChain;\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n await fsp.writeFile(this.filePath, record, 'utf8');\n }\n\n /**\n * Idea #1 — write an in-flight marker. The agent loop should call\n * this at the start of each long-running operation; a matching\n * `clearInFlightMarker` follows on clean exit. A stale marker\n * (no end) is what `SessionRecovery.detectStale` looks for.\n */\n async writeInFlightMarker(context: string): Promise<void> {\n if (!context || context.length > 500) {\n throw new Error('In-flight context must be 1..500 chars');\n }\n await this.append({\n type: 'in_flight_start',\n ts: new Date().toISOString(),\n context,\n });\n this.events?.emit('in_flight.started', { context, ts: new Date().toISOString() });\n }\n\n /**\n * Idea #1 — close the in-flight marker. Idempotent in spirit\n * (you can call it after a successful iteration even if you\n * didn't open one this round) — but the session log records\n * every call so postmortem tooling can see \"the agent finished\n * cleanly X times, then died without finishing Y\".\n */\n async clearInFlightMarker(reason: 'clean' | 'aborted' | 'recovered'): Promise<void> {\n await this.append({\n type: 'in_flight_end',\n ts: new Date().toISOString(),\n reason,\n });\n this.events?.emit('in_flight.ended', { reason, ts: new Date().toISOString() });\n }\n}\n\nfunction userInputTitle(content: string | ContentBlock[]): string {\n const text =\n typeof content === 'string'\n ? content\n : content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join(' ');\n return (text || '(non-text input)').slice(0, 60);\n}\n","import * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * The persisted form of a single queued user message. The TUI's\n * in-memory QueueItem has a render id; that's pure UI bookkeeping, so\n * we drop it when serializing — fresh ids are assigned on rehydrate.\n */\nexport interface PersistedQueueItem {\n displayText: string;\n blocks: ContentBlock[];\n}\n\n/**\n * Side-file storage for a session's pending input queue. Lives at\n * `<sessionDir>/queue.json` next to the attachment spool. Reads are\n * tolerant (missing/malformed file → empty array); writes are atomic\n * (tmp + rename) so a crash mid-write can never leave a partial file\n * the next launch would choke on.\n *\n * The contract is \"snapshot replacement\": every mutation hands the\n * full queue and we rewrite the file. The queue is small (rarely more\n * than a handful of messages), so this is cheaper than delta logging\n * and avoids the replay complexity.\n */\nexport class QueueStore {\n private readonly file: string;\n // Use `| undefined` (not `?`) so exactOptionalPropertyTypes doesn't\n // reject assigning an optional constructor parameter to these fields.\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n\n constructor(opts: { dir: string; events?: EventBus; traceId?: string }) {\n this.file = path.join(opts.dir, 'queue.json');\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n async write(items: PersistedQueueItem[]): Promise<void> {\n const t0 = Date.now();\n if (items.length === 0) {\n // Empty queue → remove the file rather than write `[]`. Keeps\n // a clean idle state on disk and makes `read()` cheaper.\n await this.clear();\n return;\n }\n try {\n await atomicWrite(this.file, JSON.stringify(items), { mode: 0o600 });\n this.events?.emit('storage.write', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'write',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'write',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.write_failed',\n path: this.file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n async read(): Promise<PersistedQueueItem[]> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.read_failed',\n path: this.file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n if (!Array.isArray(parsed)) {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n const out: PersistedQueueItem[] = [];\n for (const v of parsed) {\n if (isPersistedQueueItem(v)) out.push(v);\n }\n return out;\n }\n\n async clear(): Promise<void> {\n const t0 = Date.now();\n try {\n await fsp.unlink(this.file);\n this.events?.emit('storage.write', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'clear',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'clear',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n // Best-effort: a permission/lock error during clear is rare and\n // the queue slash command is non-critical. Warn so it's observable\n // but don't throw so the slash command doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.clear_failed',\n path: this.file,\n message: (err as Error).message,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n}\n\nfunction isPersistedQueueItem(v: unknown): v is PersistedQueueItem {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return typeof o['displayText'] === 'string' && Array.isArray(o['blocks']);\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type {\n AddAttachmentInput,\n Attachment,\n AttachmentKind,\n AttachmentRef,\n AttachmentStore,\n} from '../types/attachment.js';\nimport type { ContentBlock } from '../types/blocks.js';\n\nexport interface AttachmentStoreOptions {\n /**\n * Directory for spooling payloads larger than `spoolThresholdBytes`.\n * When omitted, all payloads stay in memory.\n */\n spoolDir?: string | undefined;\n spoolThresholdBytes?: number | undefined;\n}\n\nconst DEFAULT_SPOOL_THRESHOLD = 256 * 1024; // 256 KB\n// Two placeholder shapes:\n// - seq-keyed `[<kind> #<seq>…]` — kind is `pasted` / `image` / `file`. A\n// cosmetic suffix after the seq (e.g. `, 123 lines`) is tolerated so the\n// TUI can render `[pasted #1, 123 lines]` while still resolving by seq.\n// - path-keyed `[file:<path>]` — resolves to the most recent file ref whose\n// stored path matches, so the TUI can show a human-readable file chip.\nconst PLACEHOLDER_RE = /\\[(pasted|image|file) #(\\d+)[^\\]]*\\]|\\[file:([^\\]]+)\\]/g;\n\n/**\n * In-memory attachment store with optional disk spool. Placeholder syntax\n * is `[<kind> #<seq>]` (seq-keyed) or `[file:<path>]` (path-keyed) where kind\n * is `pasted` / `image` / `file`. Unknown placeholders are passed through\n * as-is so users can write that literal text without losing it.\n */\nexport class DefaultAttachmentStore implements AttachmentStore {\n private readonly items = new Map<string, Attachment>();\n private readonly refs: AttachmentRef[] = [];\n private nextSeq: Record<AttachmentKind, number> = { text: 0, image: 0, file: 0 };\n private readonly spoolDir: string | undefined;\n private readonly spoolThreshold: number;\n\n constructor(opts: AttachmentStoreOptions = {}) {\n this.spoolDir = opts.spoolDir;\n this.spoolThreshold = opts.spoolThresholdBytes ?? DEFAULT_SPOOL_THRESHOLD;\n }\n\n async add(input: AddAttachmentInput): Promise<AttachmentRef> {\n const seq = ++this.nextSeq[input.kind];\n const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes(3).toString('hex')}`;\n const bytes = Buffer.byteLength(input.data, input.kind === 'image' ? 'base64' : 'utf8');\n let spooledPath: string | undefined;\n let data: string | undefined = input.data;\n if (this.spoolDir && bytes >= this.spoolThreshold) {\n await fsp.mkdir(this.spoolDir, { recursive: true });\n spooledPath = path.join(this.spoolDir, `${id}.bin`);\n // atomicWrite: torn spool would silently corrupt the attachment;\n // the user would see garbled output the next time it's expanded.\n await atomicWrite(spooledPath, input.data, {\n encoding: input.kind === 'image' ? 'base64' : 'utf8',\n });\n data = undefined;\n }\n const att: Attachment = {\n id,\n kind: input.kind,\n meta: input.meta ?? {},\n data,\n path: spooledPath,\n bytes,\n createdAt: new Date().toISOString(),\n };\n this.items.set(id, att);\n const ref: AttachmentRef = { id, kind: input.kind, seq, meta: att.meta };\n this.refs.push(ref);\n return ref;\n }\n\n async get(id: string): Promise<Attachment | undefined> {\n return this.items.get(id);\n }\n\n list(): AttachmentRef[] {\n return [...this.refs];\n }\n\n async expand(text: string): Promise<ContentBlock[]> {\n const matches = [...text.matchAll(PLACEHOLDER_RE)];\n if (matches.length === 0) return text ? [{ type: 'text', text }] : [];\n const blocks: ContentBlock[] = [];\n let lastIndex = 0;\n for (const m of matches) {\n const idx = m.index ?? 0;\n const before = text.slice(lastIndex, idx);\n if (before) blocks.push({ type: 'text', text: before });\n let ref: AttachmentRef | undefined;\n if (m[3] !== undefined) {\n // Path-keyed `[file:<path>]` — most recent matching file ref wins.\n const wantPath = m[3];\n ref = findLast(this.refs, (r) => r.kind === 'file' && refPath(r) === wantPath);\n } else {\n const kind = prefixToKind(m[1] as string);\n const seq = Number(m[2]);\n ref = this.refs.find((r) => r.kind === kind && r.seq === seq);\n }\n const att = ref ? this.items.get(ref.id) : undefined;\n if (!att) {\n blocks.push({ type: 'text', text: m[0] });\n } else {\n blocks.push(await this.toBlock(att));\n }\n lastIndex = idx + m[0].length;\n }\n const tail = text.slice(lastIndex);\n if (tail) blocks.push({ type: 'text', text: tail });\n return mergeAdjacentText(blocks);\n }\n\n async clear(): Promise<void> {\n // Unlink any spooled files so we don't leak disk space.\n if (this.spoolDir) {\n const toDelete: string[] = [];\n for (const att of this.items.values()) {\n if (att.path) toDelete.push(att.path);\n }\n /* v8 ignore next -- best-effort: unlink of a just-spooled file does not reject */\n await Promise.all(toDelete.map((p) => fsp.unlink(p).catch(() => undefined)));\n }\n this.items.clear();\n this.refs.length = 0;\n this.nextSeq = { text: 0, image: 0, file: 0 };\n }\n\n private async toBlock(att: Attachment): Promise<ContentBlock> {\n if (att.kind === 'image') {\n const data =\n att.data ?? (att.path ? await fsp.readFile(att.path, { encoding: 'base64' }) : '');\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: att.meta.mediaType ?? 'image/png',\n data,\n },\n };\n }\n const raw = att.data ?? (att.path ? await fsp.readFile(att.path, 'utf8') : '');\n const label = att.meta.filename ? `<file path=\"${att.meta.filename}\">` : '<pasted>';\n const close = att.meta.filename ? '</file>' : '</pasted>';\n return { type: 'text', text: `${label}\\n${raw}\\n${close}` };\n }\n}\n\nfunction kindPrefix(kind: AttachmentKind): string {\n return kind === 'text' ? 'pasted' : kind;\n}\n\nfunction prefixToKind(prefix: string): AttachmentKind {\n if (prefix === 'pasted') return 'text';\n if (prefix === 'image') return 'image';\n return 'file';\n}\n\n/** Path a file ref was registered under, for `[file:<path>]` lookup. */\nfunction refPath(ref: AttachmentRef): string | undefined {\n return ref.meta.filename ?? ref.meta.label;\n}\n\n/** Last element matching the predicate (Node < 20 lacks Array.findLast). */\nfunction findLast<T>(arr: readonly T[], pred: (v: T) => boolean): T | undefined {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (pred(arr[i] as T)) return arr[i];\n }\n return undefined;\n}\n\nfunction mergeAdjacentText(blocks: ContentBlock[]): ContentBlock[] {\n const out: ContentBlock[] = [];\n for (const b of blocks) {\n const prev = out[out.length - 1];\n if (b.type === 'text' && prev && prev.type === 'text') {\n prev.text += b.text;\n } else {\n out.push(b);\n }\n }\n return out;\n}\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n /**\n * Attach a trace ID to this store so that all subsequent `storage.*`\n * events include it for observability correlation. Mutates the store\n * in place and returns the same instance (convenience chaining).\n */\n withTraceId(traceId: string): MemoryStore;\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { MEMORY_TYPE_LABELS, type MemoryPriority, type MemoryType } from '../types/memory.js';\nimport { atomicWrite, ensureDir, withFileLock } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\n// ── Backend interface ──────────────────────────────────────────────────\n\nexport interface MemoryBackend {\n readonly kind: string;\n remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void>;\n forget(scope: MemoryScope, query: string, filePath: string): Promise<number>;\n readAll(scope: MemoryScope, filePath: string): Promise<string>;\n list(scope: MemoryScope, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n search(scope: MemoryScope, query: string, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n /** Find memories related to the given text via graph traversal. Optional — falls back to search. */\n findRelated?(scope: MemoryScope, filePath: string, text: string, limit: number): Promise<MemoryEntry[]>;\n clear(scope: MemoryScope, filePath: string): Promise<void>;\n consolidate(scope: MemoryScope, filePath: string): Promise<number>;\n}\n\n// ── Entry serialization format ─────────────────────────────────────────\n//\n// Full format:\n// - [ISO] [TYPE|PRIORITY] mem_<id> text content #tag1 #tag2\n//\n// Examples:\n// - [2026-06-07T...] mem_1234_abcd Project uses pnpm #pnpm #build\n// - [2026-06-07T...] [convention|high] mem_5678_ef01 Use conventional commits #git #commit\n//\n// Old format (backward compatible):\n// - [ISO] mem_<id> text content\n\nconst TYPE_PRIORITY_RE = /^\\[(\\w+)\\|(\\w+)\\]\\s+/;\nconst TAG_RE = /#([\\w-]+)/g;\n\nfunction formatMetadata(entry: MemoryEntry): string {\n const parts: string[] = [];\n if (entry.type && entry.priority) {\n parts.push(`[${entry.type}|${entry.priority}]`);\n } else if (entry.type) {\n parts.push(`[${entry.type}]`);\n } else if (entry.priority) {\n parts.push(`[${entry.priority}]`);\n }\n if (entry.tags && entry.tags.length > 0) {\n parts.push(entry.tags.map((t) => `#${t}`).join(' '));\n }\n return parts.length > 0 ? ` ${parts.join(' ')}` : '';\n}\n\nfunction lineToEntry(line: string, scope: MemoryScope): MemoryEntry | null {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- [')) return null;\n\n // Parse timestamp: `- [ISO] ...`\n const tsMatch = trimmed.match(/^-\\s*\\[([^\\]]+)\\]/);\n if (!tsMatch) return null;\n const ts = tsMatch[1] ?? '';\n\n let rest = trimmed.slice(tsMatch[0].length).trim();\n\n // Parse optional type|priority: `[convention|high]` or `[fact]`\n let type: MemoryType | undefined;\n let priority: MemoryPriority | undefined;\n const tpMatch = rest.match(TYPE_PRIORITY_RE);\n if (tpMatch) {\n const a = tpMatch[1] ?? '';\n const b = tpMatch[2] ?? '';\n if (isMemoryType(a)) {\n type = a;\n priority = isPriority(b) ? b : undefined;\n } else if (isPriority(a)) {\n priority = a;\n }\n rest = rest.slice(tpMatch[0].length).trim();\n }\n\n // Parse optional entry ID: `mem_<ts>_<rand>`\n const idMatch = rest.match(/^mem_\\d+_\\w+\\s+/);\n let text: string;\n if (idMatch) {\n text = rest.slice(idMatch[0].length).trim();\n } else {\n text = rest.trim();\n }\n\n // Extract #tags from text\n const tags: string[] = [];\n let tagMatch: RegExpExecArray | null;\n TAG_RE.lastIndex = 0;\n // biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop\n while ((tagMatch = TAG_RE.exec(text)) !== null) {\n tags.push(tagMatch[1] ?? '');\n }\n // Remove tags from display text\n const cleanText = text.replace(TAG_RE, '').replace(/\\s{2,}/g, ' ').trim();\n\n if (!cleanText) return null;\n\n return {\n scope,\n text: cleanText,\n ts,\n type,\n priority,\n tags: tags.length > 0 ? tags : undefined,\n };\n}\n\nfunction isMemoryType(s: string): s is MemoryType {\n return s in MEMORY_TYPE_LABELS;\n}\n\nfunction isPriority(s: string): s is MemoryPriority {\n return s === 'critical' || s === 'high' || s === 'medium' || s === 'low';\n}\n\n// ── File-based backend ─────────────────────────────────────────────────\n\nexport interface FileMemoryBackendOptions {\n paths: WstackPaths;\n}\n\nexport class FileMemoryBackend implements MemoryBackend {\n readonly kind = 'file';\n private readonly files: Record<MemoryScope, string>;\n\n constructor(opts: FileMemoryBackendOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n }\n\n private resolveFile(filePath: string, scope: MemoryScope): string {\n return filePath || this.files[scope];\n }\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await ensureDir(path.dirname(file));\n let existing = '';\n try { existing = await fs.readFile(file, 'utf8'); } catch { /* new file */ }\n\n const id = `mem_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const meta = formatMetadata(entry);\n const line = `\\n- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\\n/g, ' ')}\\n`;\n const next = existing.trim()\n ? existing.replace(/\\n+$/, '') + line\n : `# Agent Memory\\n${line}`;\n await atomicWrite(file, next);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n return withFileLock(file, async () => {\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const needle = query.toLowerCase();\n const idMatcher = /mem_\\d+_\\w+/;\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n if (idMatcher.test(query)) {\n const entryIdMatch = /mem_\\d+_\\w+/.exec(trimmed);\n if (entryIdMatch && entryIdMatch[0] === query) { removed++; return false; }\n }\n if (trimmed.toLowerCase().includes(needle)) { removed++; return false; }\n return true;\n });\n if (removed > 0) {\n if (lines.length === 0 || (lines.length === 1 && !lines[0]?.trim())) {\n await atomicWrite(file, '');\n } else {\n await atomicWrite(file, lines.join('\\n'));\n }\n }\n return removed;\n });\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n const file = this.resolveFile(filePath, scope);\n try { return await fs.readFile(file, 'utf8'); } catch { return ''; /* best-effort */ }\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const raw = await this.readAll(scope, filePath);\n if (!raw.trim()) return [];\n const entries = parseEntries(raw, scope);\n return limit ? entries.slice(0, limit) : entries;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const entries = await this.list(scope, filePath);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Score by word overlap + tag match\n const scored = entries.map((e) => {\n const words = e.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n // Tag matches are weighted higher\n if (e.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n return { entry: e, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await atomicWrite(file, '');\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const seen = new Set<string>();\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n // Normalize: strip timestamp, ID, type|priority, tags\n const norm = trimmed\n .replace(/\\[[^\\]]+\\]/g, '')\n .replace(/\\bmem_\\d+_\\w+\\s*/, '')\n .replace(/#[\\w-]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .toLowerCase();\n if (seen.has(norm)) { removed++; return false; }\n seen.add(norm);\n return true;\n });\n\n const next = lines.join('\\n');\n const backup = `${file}.bak.${Date.now()}`;\n try { await fs.copyFile(file, backup); } catch { /* best-effort */ }\n /* v8 ignore next -- best-effort: atomicWrite failure during consolidate is non-fatal */\n try { await atomicWrite(file, next); } catch { return 0; /* best-effort */ }\n return removed;\n }\n}\n\n// ── Entry parsing ──────────────────────────────────────────────────────\n\nexport function parseEntries(raw: string, scope: MemoryScope = 'project-memory'): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n for (const line of raw.split('\\n')) {\n const entry = lineToEntry(line, scope);\n if (entry) entries.push(entry);\n }\n return entries.reverse(); // newest first\n}\n","import type {\n MemoryClearedPayload,\n MemoryConsolidatedPayload,\n MemoryEntry,\n MemoryForgottenPayload,\n MemoryRelevanceContext,\n MemoryRememberedPayload,\n MemoryScope,\n MemoryStore,\n ScoredEntry,\n} from '../types/memory.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { type MemoryBackend, FileMemoryBackend } from './memory-backend.js';\n\nconst MAX_BYTES_TOTAL = 32_000; // ~8K tokens\n\nexport interface MemoryStoreOptions {\n paths: WstackPaths;\n /**\n * Optional event bus — when provided, mutations emit events so plugins\n * and other subsystems can react to memory changes.\n */\n events?: EventBus | undefined;\n /**\n * Storage backend. Defaults to FileMemoryBackend when omitted.\n * Plugins can register a custom backend (graph, semantic, vector)\n * via the DI container to override storage behavior.\n */\n backend?: MemoryBackend | undefined;\n}\n\n/**\n * Three scopes:\n * project-agents → <project>/.wrongstack/AGENTS.md (committed)\n * project-memory → ~/.wrongstack/projects/<hash>/memory.md (per-project agent notes)\n * user-memory → ~/.wrongstack/memory.md (global personal memory)\n */\nexport class DefaultMemoryStore implements MemoryStore {\n private readonly files: Record<MemoryScope, string>;\n private readonly events?: EventBus | undefined;\n private traceId?: string | undefined;\n private readonly backend: MemoryBackend;\n\n /**\n * Per-scope serialization queue. `remember` / `forget` / `consolidate` /\n * `clear` are read-modify-write against a single file; without a lock,\n * two concurrent calls on the same scope can read the same baseline and\n * the later write silently drops the earlier entry. We chain each\n * mutation onto the prior promise for the same scope so they run in\n * issue order. Different scopes still proceed in parallel.\n *\n * The chain tracks only the last pending write. If a write fails, its\n * error is caught and swallowed so the chain stays alive for subsequent\n * calls. The error is stored in `writeErrors` so callers can learn about\n * it on the next read operation.\n */\n private readonly writeChain = new Map<MemoryScope, Promise<unknown>>();\n /** Last write error per scope — surfaced as warnings on the next readAll(). */\n private readonly writeErrors = new Map<MemoryScope, Error>();\n\n /**\n * When the global root is a temporary directory (opencode, CI sandboxes),\n * memory files are also mirrored to the project tree so they survive\n * session cleanup. The primary path stays in the temp root for isolation;\n * this backup ensures memory is never lost.\n */\n private readonly persistBackup: boolean;\n private readonly backupDir: string;\n\n constructor(opts: MemoryStoreOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n this.events = opts.events;\n this.backend = opts.backend ?? new FileMemoryBackend({ paths: opts.paths });\n\n // Detect temporary global roots: opencode, CI, test sandboxes.\n // When detected, mirror writes to the project's .wrongstack/ dir.\n const root = opts.paths.globalRoot.toLowerCase();\n this.persistBackup = /[/\\\\](tmp|temp|cache)[/\\\\]/.test(root);\n this.backupDir = this.persistBackup\n ? opts.paths.inProjectAgentsFile.replace(/AGENTS\\.md$/, 'memory-persist')\n : '';\n }\n\n /** Expose the backend for plugin introspection and advanced queries. */\n getBackend(): MemoryBackend {\n return this.backend;\n }\n\n private async runSerialized<T>(scope: MemoryScope, work: () => Promise<T>): Promise<T> {\n const prior = this.writeChain.get(scope) ?? Promise.resolve();\n // Chain: catch errors from the prior write, then run the next work item.\n const next = prior\n .catch((err) => {\n this.writeErrors.set(scope, err as Error);\n })\n .then(() => work());\n this.writeChain.set(scope, next as Promise<unknown>);\n try {\n return await next;\n } catch (err) {\n this.writeErrors.set(scope, err as Error);\n throw err;\n } finally {\n if (this.writeChain.get(scope) === next) {\n this.writeChain.delete(scope);\n }\n }\n }\n\n async readAll(): Promise<string> {\n const parts: string[] = [];\n for (const scope of ['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]) {\n const writeErr = this.writeErrors.get(scope);\n if (writeErr) {\n parts.push(`> ⚠️ Memory write error (${labelOf(scope)}): ${writeErr.message}`);\n }\n const t0 = Date.now();\n const filePath = this.files[scope];\n try {\n const body = await this.backend.readAll(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'readAll',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n if (body.trim()) parts.push(`## ${labelOf(scope)}\\n\\n${body.trim()}`);\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'readAll',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n }\n return parts.join('\\n\\n');\n }\n\n async read(scope: MemoryScope): Promise<string> {\n const t0 = Date.now();\n const filePath = this.files[scope];\n try {\n const body = await this.backend.readAll(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'read',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return body;\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'read',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n }\n\n /**\n * List entries from a scope, newest first. Delegates to the backend\n * so graph/semantic backends can return enriched or filtered results.\n */\n async list(scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.list(scope, this.files[scope], limit);\n }\n\n /**\n * Find memories related to the given text via graph traversal.\n * Falls back to content search when no graph backend is available.\n */\n async findRelated(text: string, scope: MemoryScope = 'project-memory', limit = 5): Promise<MemoryEntry[]> {\n if (this.backend.findRelated) {\n return this.backend.findRelated(scope, this.files[scope], text, limit);\n }\n return this.search(text, scope, limit);\n }\n\n async search(query: string, scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.search(scope, query, this.files[scope], limit);\n }\n\n async remember(\n text: string,\n scope: MemoryScope = 'project-memory',\n metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>,\n ): Promise<void> {\n const ts = new Date().toISOString();\n return this.runSerialized(scope, async () => {\n const entry: MemoryEntry = { scope, text, ts, ...metadata };\n const filePath = this.files[scope];\n const t0 = Date.now();\n try {\n await this.backend.remember(scope, entry, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'remember',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'remember',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n\n // Size check — consolidate if the file exceeds the cap.\n const raw = await this.backend.readAll(scope, this.files[scope]);\n if (Buffer.byteLength(raw, 'utf8') > MAX_BYTES_TOTAL) {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n }\n }\n\n // Mirror to persistent backup when running in a temp sandbox.\n await this.mirrorBackup(scope);\n\n this.events?.emit('memory.remembered', {\n scope,\n text,\n ts,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n } satisfies MemoryRememberedPayload);\n });\n }\n\n /**\n * Score and rank memories by relevance to the current context.\n * Returns entries with score >= MIN_RELEVANCE_SCORE, sorted highest first.\n */\n async scoreRelevant(\n ctx: MemoryRelevanceContext,\n scope: MemoryScope = 'project-memory',\n limit = 8,\n ): Promise<ScoredEntry[]> {\n const all = await this.list(scope);\n if (all.length === 0) return [];\n\n const taskWords = ctx.currentTask.toLowerCase().split(/\\s+/).filter((w) => w.length > 2);\n const skillWords = (ctx.activeSkills ?? []).flatMap((s) => s.split('-'));\n const toolWords = (ctx.toolNames ?? []).flatMap((t) => t.toLowerCase().split('_'));\n const now = Date.now();\n\n const scored: ScoredEntry[] = [];\n\n for (const entry of all) {\n let score = 0;\n const reasons: string[] = [];\n const textLower = entry.text.toLowerCase();\n const tagsLower = (entry.tags ?? []).map((t) => t.toLowerCase());\n\n // Word overlap with current task (primary signal)\n let taskHits = 0;\n for (const w of taskWords) {\n if (textLower.includes(w)) { taskHits++; score += 2; }\n if (tagsLower.some((t) => t.includes(w))) { taskHits++; score += 3; }\n }\n if (taskHits > 0) reasons.push(`task match (${taskHits})`);\n\n // Skill/tool relevance\n let skillHits = 0;\n for (const w of skillWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n skillHits++;\n }\n }\n score += skillHits;\n if (skillHits > 0) reasons.push(`skill match (${skillHits})`);\n\n for (const w of toolWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n score += 1;\n reasons.push(`tool mention: ${w}`);\n }\n }\n\n // Priority boost\n switch (entry.priority) {\n case 'critical': score += 5; reasons.push('critical'); break;\n case 'high': score += 3; reasons.push('high priority'); break;\n case 'medium': score += 1; break;\n case 'low': score -= 2; reasons.push('low priority'); break;\n }\n\n // Type boost — decisions, conventions, anti-patterns are high-value\n switch (entry.type) {\n case 'decision': score += 2; reasons.push('decision'); break;\n case 'convention': score += 2; reasons.push('convention'); break;\n case 'anti_pattern': score += 3; reasons.push('anti-pattern'); break;\n case 'preference': score += 1; reasons.push('preference'); break;\n case 'reference': break;\n case 'fact': break;\n }\n\n // Recency boost — newer entries get +1, very old get 0\n const ageDays = (now - new Date(entry.ts).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays < 1) score += 1;\n else if (ageDays > 30) score -= 1;\n\n // Confidence penalty\n if (entry.confidence !== undefined && entry.confidence < 0.5) {\n score -= 2;\n reasons.push('low confidence');\n }\n\n // Repetition avoidance — recently accessed entries get slight penalty\n if (entry.lastAccessed) {\n const hoursSinceAccess = (now - new Date(entry.lastAccessed).getTime()) / (1000 * 60 * 60);\n if (hoursSinceAccess < 1) score -= 1;\n }\n\n if (score > 0) {\n scored.push({\n ...entry,\n score,\n matchReason: reasons.join(', ') || 'keyword match',\n });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n\n // Filter to entries that meet the minimum relevance threshold.\n // Critical or high-priority entries always pass.\n const threshold = 2;\n const relevant = scored.filter(\n (s) => s.score >= threshold || s.priority === 'critical' || s.priority === 'high',\n );\n\n return relevant.slice(0, Math.min(limit, 15));\n }\n\n async forget(query: string, scope: MemoryScope = 'project-memory'): Promise<number> {\n return this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n let removed = 0;\n try {\n removed = await this.backend.forget(scope, query, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'forget',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'forget',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n if (removed > 0) {\n this.events?.emit('memory.forgotten', {\n scope,\n query,\n removed,\n } satisfies MemoryForgottenPayload);\n await this.mirrorBackup(scope);\n }\n return removed;\n });\n }\n\n async consolidate(scope: MemoryScope): Promise<void> {\n return this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n let removed = 0;\n try {\n removed = await this.backend.consolidate(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'consolidate',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'consolidate',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n await this.mirrorBackup(scope);\n }\n });\n }\n\n async clear(scope?: MemoryScope): Promise<void> {\n if (scope) {\n await this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n try {\n await this.backend.clear(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n this.events?.emit('memory.cleared', { scope } satisfies MemoryClearedPayload);\n await this.mirrorBackup(scope);\n });\n return;\n }\n await Promise.all(\n (['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]).map(async (s) =>\n this.runSerialized(s, async () => {\n const filePath = this.files[s];\n const t0 = Date.now();\n try {\n await this.backend.clear(s, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n this.events?.emit('memory.cleared', { scope: s } satisfies MemoryClearedPayload);\n await this.mirrorBackup(s);\n }),\n ),\n );\n }\n\n /**\n * Return a new MemoryStore proxy that carries `traceId` on every storage\n * event. The original store is left unchanged — callers that need a\n * trace-decorated view (e.g. session-run tools) receive the proxy while\n * the singleton remains trace-free for boot-time use.\n *\n * The proxy implements the full `MemoryStore` interface; all other\n * properties (backend, etc.) are delegated to the original store.\n */\n withTraceId(traceId: string): MemoryStore {\n // Mutate the singleton's traceId so that all subsequent I/O (including\n // calls from tools that captured the original store reference) emits\n // storage events with the correct session trace ID.\n this.traceId = traceId;\n return this;\n }\n private async mirrorBackup(scope: MemoryScope): Promise<void> {\n if (!this.persistBackup || scope === 'project-agents') return;\n try {\n const content = await this.backend.readAll(scope, this.files[scope]);\n const { writeFile, mkdir } = await import('node:fs/promises');\n await mkdir(this.backupDir, { recursive: true });\n await writeFile(`${this.backupDir}/${scope}.md`, content, 'utf8');\n } catch {\n // best-effort\n }\n }\n}\n\nfunction labelOf(scope: MemoryScope): string {\n switch (scope) {\n case 'project-agents':\n return 'Project AGENTS.md';\n case 'project-memory':\n return 'Project memory';\n case 'user-memory':\n return 'User memory';\n }\n}\n","import * as fs from 'node:fs/promises';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { type FileMemoryBackendOptions, FileMemoryBackend } from './memory-backend.js';\nimport type { MemoryBackend } from './memory-backend.js';\n\n// ── Graph node and edge types ──────────────────────────────────────────\n\ninterface GraphNode {\n id: string;\n entry: MemoryEntry;\n firstSeen: string;\n count: number;\n /** Extracted metadata for fast lookup. */\n type?: MemoryEntry['type'] | undefined;\n tags?: string[] | undefined;\n priority?: MemoryEntry['priority'] | undefined;\n}\n\ninterface GraphEdge {\n from: string;\n to: string;\n /** Why these nodes are related. */\n relation: 'co_occurring' | 'similar' | 'same_turn' | 'explicit';\n weight: number;\n ts: string;\n}\n\n// ── Backend ────────────────────────────────────────────────────────────\n\nexport interface GraphMemoryBackendOptions extends FileMemoryBackendOptions {\n /**\n * Path to the graph metadata file (edges + node metadata).\n * Defaults to `<projectDir>/memory-graph.json`.\n */\n graphPath?: string | undefined;\n}\n\n/**\n * Graph-based memory backend that tracks relationships between entries.\n * Builds on top of FileMemoryBackend — entries are still persisted as\n * markdown bullets, but the graph layer adds:\n *\n * - Co-occurrence edges (entries from the same remember() batch)\n * - Content similarity edges (simple Jaccard on word overlap)\n * - Turn-based edges (entries created in the same LLM turn)\n * - Graph traversal queries (find related memories)\n *\n * The graph metadata persists to `<projectDir>/memory-graph.json`.\n */\nexport class GraphMemoryBackend implements MemoryBackend {\n readonly kind = 'graph';\n\n private readonly file: FileMemoryBackend;\n private readonly graphFile: string;\n\n // In-memory graph state — lazily loaded, saved on mutation.\n private nodes = new Map<string, GraphNode>();\n private edges: GraphEdge[] = [];\n private loadedScope: MemoryScope | null = null;\n private loaded = false;\n\n constructor(opts: GraphMemoryBackendOptions) {\n this.file = new FileMemoryBackend({ paths: opts.paths });\n this.graphFile = opts.graphPath ?? `${opts.paths.projectDir}/memory-graph.json`;\n }\n\n // ── Backend interface ──────────────────────────────────────────────\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n await this.file.remember(scope, entry, filePath);\n await this.loadGraph(scope);\n\n const nodeId = this.nodeId(entry);\n const existing = this.nodes.get(nodeId);\n if (existing) {\n existing.count++;\n existing.entry = entry;\n existing.type = entry.type;\n existing.tags = entry.tags;\n existing.priority = entry.priority;\n } else {\n this.nodes.set(nodeId, {\n id: nodeId,\n entry,\n firstSeen: entry.ts,\n count: 1,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n });\n\n // Create similarity edges with existing nodes\n for (const [, other] of this.nodes) {\n if (other.id === nodeId) continue;\n const sim = wordOverlap(entry.text, other.entry.text);\n // Also create edges for shared tags\n const tagSim = sharedTags(entry.tags ?? [], other.tags ?? []);\n const weight = Math.max(sim, tagSim * 0.5);\n if (weight > 0.15) {\n this.edges.push({\n from: nodeId,\n to: other.id,\n relation: sim >= tagSim ? 'similar' : 'same_turn',\n weight,\n ts: entry.ts,\n });\n }\n }\n }\n\n await this.saveGraph(scope);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const removed = await this.file.forget(scope, query, filePath);\n if (removed > 0) {\n await this.loadGraph(scope);\n // Remove nodes whose entry text matches the query\n const n = query.toLowerCase();\n const toRemove: string[] = [];\n for (const [id, node] of this.nodes) {\n if (node.entry.text.toLowerCase().includes(n)) {\n toRemove.push(id);\n }\n }\n for (const id of toRemove) this.nodes.delete(id);\n this.edges = this.edges.filter((e) => !toRemove.includes(e.from) && !toRemove.includes(e.to));\n await this.saveGraph(scope);\n }\n return removed;\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n return this.file.readAll(scope, filePath);\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n // Merge: file entries are canonical, graph adds metadata and dedup\n const fileEntries = await this.file.list(scope, filePath);\n const nodeMap = new Map(this.nodes.entries());\n\n // Enrich file entries with graph metadata\n const enriched = fileEntries.map((fe) => {\n const nodeId = this.nodeId(fe);\n const node = nodeMap.get(nodeId);\n if (node) {\n return {\n ...fe,\n type: node.type ?? fe.type,\n tags: node.tags ?? fe.tags,\n priority: node.priority ?? fe.priority,\n };\n }\n return fe;\n });\n\n // Add graph-only nodes not in file (shouldn't happen normally, but safety)\n const fileIds = new Set(fileEntries.map((e) => this.nodeId(e)));\n for (const [id, node] of this.nodes) {\n if (!fileIds.has(id)) {\n enriched.push(node.entry);\n }\n }\n\n enriched.sort((a, b) => b.ts.localeCompare(a.ts));\n return limit ? enriched.slice(0, limit) : enriched;\n }\n\n async search(scope: MemoryScope, query: string, _filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Use in-memory nodes directly instead of re-reading the file.\n // loadGraph() already keeps nodes/edges synchronized incrementally.\n const scored: { entry: MemoryEntry; score: number }[] = [];\n for (const node of this.nodes.values()) {\n // Skip nodes from other scopes\n if (node.entry.scope !== scope) continue;\n\n const words = node.entry.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n if (node.entry.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n if (node.priority === 'critical') score += 3;\n else if (node.priority === 'high') score += 2;\n score += node.count * 0.5;\n if (score > 0) scored.push({ entry: node.entry, score });\n }\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n await this.file.clear(scope, filePath);\n this.nodes.clear();\n this.edges = [];\n this.loadedScope = scope;\n this.loaded = true;\n // Write empty graph\n try { await fs.unlink(this.graphFile); } catch { /* ok */ }\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n return this.file.consolidate(scope, filePath);\n }\n\n // ── Graph-specific queries ─────────────────────────────────────────\n\n /**\n * Find memories related to the given entry, ordered by edge weight.\n */\n async findRelated(scope: MemoryScope, _filePath: string, entryText: string, limit = 5): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const targetId = this.nodeId({ scope, text: entryText, ts: '' });\n const related = this.edges\n .filter((e) => e.from === targetId || e.to === targetId)\n .sort((a, b) => b.weight - a.weight)\n .slice(0, limit);\n\n const result: MemoryEntry[] = [];\n for (const edge of related) {\n const otherId = edge.from === targetId ? edge.to : edge.from;\n const node = this.nodes.get(otherId);\n if (node) result.push(node.entry);\n }\n return result;\n }\n\n /**\n * Get all edges for visualization or traversal.\n */\n getGraph(): { nodes: GraphNode[]; edges: GraphEdge[] } {\n return {\n nodes: [...this.nodes.values()],\n edges: [...this.edges],\n };\n }\n\n // ── Persistence ────────────────────────────────────────────────────\n\n private nodeId(entry: MemoryEntry): string {\n // Stable ID from scope + normalized text\n const norm = entry.text.toLowerCase().trim().replace(/\\s+/g, ' ');\n return `${entry.scope ?? 'mem'}::${simpleHash(norm)}`;\n }\n\n private async loadGraph(scope: MemoryScope): Promise<void> {\n if (this.loaded && this.loadedScope === scope) return;\n try {\n const raw = await fs.readFile(this.graphFile, 'utf8');\n const data: { nodes: Array<[string, GraphNode]>; edges: GraphEdge[] } = JSON.parse(raw);\n this.nodes = new Map(data.nodes);\n this.edges = data.edges;\n } catch {\n this.nodes = new Map();\n this.edges = [];\n }\n this.loadedScope = scope;\n this.loaded = true;\n }\n\n private async saveGraph(scope: MemoryScope): Promise<void> {\n this.loadedScope = scope;\n this.loaded = true;\n try {\n const data = {\n nodes: [...this.nodes.entries()],\n edges: this.edges,\n };\n await fs.mkdir(\n this.graphFile.substring(0, this.graphFile.lastIndexOf('/')),\n { recursive: true },\n );\n // Atomic write via temp file\n const tmp = `${this.graphFile}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(data));\n await fs.rename(tmp, this.graphFile);\n } catch {\n // best-effort — graph is an enhancement, not critical\n }\n }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────\n\n/** Jaccard-style word overlap between two strings. 0.0 = no overlap, 1.0 = identical. */\nfunction wordOverlap(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n if (wordsA.size === 0 || wordsB.size === 0) return 0;\n let intersection = 0;\n for (const w of wordsA) {\n if (wordsB.has(w)) intersection++;\n }\n return intersection / Math.max(wordsA.size, wordsB.size);\n}\n\n/** Tag overlap ratio — how many tags two nodes share. */\nfunction sharedTags(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const setB = new Set(b);\n let shared = 0;\n for (const t of a) if (setB.has(t)) shared++;\n return shared / Math.max(a.length, b.length);\n}\n\n/** Fast non-crypto hash for stable node IDs. */\nfunction simpleHash(s: string): string {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h).toString(36);\n}\n","import type { RunResult } from '../core/agent-types.js';\nimport type { Context } from '../core/context.js';\nimport type { AfterRunHook, AgentExtension } from '../extension/extension-points.js';\nimport type { MemoryEntry, MemoryStore } from '../types/memory.js';\nimport type { Provider } from '../types/provider.js';\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport interface ConsolidationOp {\n action: 'add' | 'edit' | 'delete';\n /** For add: the fact to remember. For edit: the new text replacing the old. */\n text?: string | undefined;\n /** For edit/delete: the query to match existing entries. */\n query?: string | undefined;\n /** Memory type for categorization. */\n type?: string | undefined;\n /** Tags for grouping. */\n tags?: string[] | undefined;\n /** Priority level. */\n priority?: string | undefined;\n}\n\ninterface ConsolidationResponse {\n operations: ConsolidationOp[];\n summary?: string | undefined;\n}\n\nexport interface MemoryConsolidatorOptions {\n memoryStore: MemoryStore;\n /**\n * Provider used for the consolidation LLM call. Uses the session's\n * provider by default.\n */\n provider?: Provider | undefined;\n /**\n * Model override for the consolidation call. Uses the session's model\n * by default. A smaller/faster model is recommended (e.g. haiku, flash).\n */\n model?: string | undefined;\n /**\n * Minimum session iterations before consolidation fires.\n * Sessions shorter than this are skipped (default 2).\n */\n minIterations?: number | undefined;\n /**\n * Maximum memory entries to include in the prompt as context.\n */\n maxExistingEntries?: number | undefined;\n}\n\n// ── Prompt ──────────────────────────────────────────────────────────────\n\nfunction buildConsolidationPrompt(\n finalText: string,\n iterations: number,\n existingEntries: MemoryEntry[],\n): string {\n const existingBlock =\n existingEntries.length > 0\n ? `\\n\\nExisting memory entries:\\n${existingEntries\n .map((e) => `- [${e.ts.slice(0, 10)}] ${e.text}`)\n .join('\\n')}`\n : '';\n\n return `You are a memory consolidator. Review the following session summary and decide what key facts, conventions, decisions, or learnings should be persisted to long-term memory.\n\nSession summary (${iterations} iterations):\n${finalText.slice(0, 3000)}${existingBlock}\n\nReturn a JSON object with an \"operations\" array. Each operation must have an \"action\" field:\n- \"add\": create a new memory entry. Include \"text\", and optionally \"type\", \"tags\", \"priority\".\n- \"edit\": replace an existing entry. Include \"query\" (to match) and \"text\" (replacement).\n- \"delete\": remove an entry. Include \"query\" (to match).\n\nMemory types:\n- \"fact\": Objective truth about the project (e.g. \"uses pnpm workspaces\")\n- \"decision\": A choice that was made (e.g. \"decided to use biome over eslint\")\n- \"convention\": A recurring pattern or standard (e.g. \"commit messages use conventional format\")\n- \"preference\": User or team preference (e.g. \"prefers short variable names\")\n- \"reference\": Pointer to a file or location (e.g. \"auth logic in packages/core/src/auth/\")\n- \"anti_pattern\": Something to avoid (e.g. \"never use any in TypeScript\")\n\nPriority levels:\n- \"critical\": Must always be known (e.g. security constraints)\n- \"high\": Important for most tasks\n- \"medium\": Useful context\n- \"low\": Nice to know\n\nRules:\n- Only persist facts likely useful across multiple future sessions.\n- Do NOT persist task progress, temporary state, or one-off observations.\n- Prefer \"add\" over \"edit\" unless the existing entry is clearly outdated.\n- Assign a type and priority to every \"add\" operation.\n- Use 1-3 hashtag tags for each entry (e.g. #typescript #build).\n- Be concise — each memory entry should be one clear sentence.\n\nReturn ONLY valid JSON, no markdown, no explanation:\n{\n \"operations\": [\n { \n \"action\": \"add\", \n \"text\": \"Project uses pnpm workspaces with TypeScript strict mode\",\n \"type\": \"convention\",\n \"priority\": \"high\",\n \"tags\": [\"pnpm\", \"typescript\", \"build\"]\n },\n { \n \"action\": \"edit\", \n \"query\": \"pnpm\", \n \"text\": \"Project uses pnpm v9+ with ESM-only modules\",\n \"type\": \"fact\",\n \"priority\": \"medium\"\n },\n { \"action\": \"delete\", \"query\": \"outdated convention\" }\n ]\n}`;\n}\n\n// ── Consolidator ────────────────────────────────────────────────────────\n\nexport class SessionMemoryConsolidator implements AgentExtension {\n name = 'session-memory-consolidator';\n owner = 'core';\n\n private readonly memoryStore: MemoryStore;\n private readonly provider?: Provider | undefined;\n private readonly model?: string | undefined;\n private readonly minIterations: number;\n private readonly maxExistingEntries: number;\n\n constructor(opts: MemoryConsolidatorOptions) {\n this.memoryStore = opts.memoryStore;\n this.provider = opts.provider;\n this.model = opts.model;\n this.minIterations = opts.minIterations ?? 2;\n this.maxExistingEntries = opts.maxExistingEntries ?? 15;\n }\n\n afterRun: AfterRunHook = async (ctx: Context, result: RunResult) => {\n // Only consolidate successful sessions with meaningful output\n if (result.status !== 'done') return;\n if (!result.finalText || result.finalText.trim().length < 20) return;\n if (result.iterations < this.minIterations) return;\n\n const provider = this.provider ?? ctx.provider;\n if (!provider || !provider.complete) return;\n\n try {\n // Load existing memory for dedup context\n const existingEntries = await this.memoryStore.list('project-memory', this.maxExistingEntries);\n const prompt = buildConsolidationPrompt(\n result.finalText,\n result.iterations,\n existingEntries,\n );\n\n // Call the LLM with a focused, one-shot prompt\n const signal = AbortSignal.timeout(15_000);\n const response = await provider.complete(\n {\n model: this.model ?? ctx.model,\n system: [{ type: 'text', text: prompt }],\n messages: [\n { role: 'user', content: 'Review the session and return memory operations as JSON.' },\n ],\n maxTokens: 500,\n },\n { signal },\n );\n\n const text = response.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n .trim();\n if (!text) return;\n\n // Extract JSON from possible markdown wrapper\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) return;\n\n const parsed: ConsolidationResponse = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(parsed.operations) || parsed.operations.length === 0) return;\n\n // Apply operations\n let added = 0;\n let edited = 0;\n let deleted = 0;\n\n for (const op of parsed.operations) {\n switch (op.action) {\n case 'add': {\n if (op.text?.trim()) {\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n added++;\n }\n break;\n }\n case 'edit': {\n if (op.query && op.text && op.text.trim()) {\n await this.memoryStore.forget(op.query);\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n edited++;\n }\n break;\n }\n case 'delete': {\n if (op.query) {\n const n = await this.memoryStore.forget(op.query);\n deleted += n;\n }\n break;\n }\n }\n }\n\n if (added > 0 || edited > 0 || deleted > 0) {\n const parts: string[] = [];\n if (added) parts.push(`${added} added`);\n if (edited) parts.push(`${edited} edited`);\n if (deleted) parts.push(`${deleted} deleted`);\n // Log to stderr so it surfaces in the terminal\n process.stderr.write(`[memory] Session consolidation: ${parts.join(', ')}\\n`);\n }\n } catch {\n // Silent — memory consolidation is best-effort, never blocks session cleanup\n }\n };\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { Config, ConfigStore } from '../types/config.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n\n/**\n * Strip fields that originated from environment variables so they are never\n * persisted back to disk. This prevents an env-sourced secret (e.g.\n * WRONGSTACK_API_KEY) from being accidentally written to ~/.wrongstack/config.json.\n */\nfunction stripEphemeralFields(cfg: Partial<Config>): Partial<Config> {\n const env = (cfg as Partial<Config & { _envSource?: Set<string> | undefined}>)._envSource;\n if (!env?.size) return cfg;\n const out: Partial<Config> = { ...cfg };\n for (const field of env) {\n delete (out as Record<string, unknown>)[field];\n }\n delete (out as Record<string, unknown>)._envSource;\n return out;\n}\n\n/**\n * Reference implementation of `ConfigStore`. Stores a single frozen Config\n * and notifies watchers synchronously on every update. Updates use a deep\n * clone so callers can mutate their `partial` argument freely without\n * tainting state.\n *\n * For the CLI: instantiate once at boot, pass the store (not the Config)\n * to subsystems that care about runtime changes (provider switching,\n * extension reload).\n */\nexport class DefaultConfigStore implements ConfigStore {\n private current: Readonly<Config>;\n private watchers = new Set<(next: Readonly<Config>, prev: Readonly<Config>) => void>();\n\n constructor(initial: Config) {\n this.current = deepFreeze(structuredClone(initial));\n }\n\n get(): Readonly<Config> {\n return this.current;\n }\n\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]> {\n return this.current[key] as Readonly<Config[K]>;\n }\n\n getExtension(pluginName: string): Readonly<Record<string, unknown>> {\n const ext = this.current.extensions?.[pluginName];\n return ext ? (ext as Readonly<Record<string, unknown>>) : FROZEN_EMPTY;\n }\n\n update(partial: Partial<Config>): Readonly<Config> {\n // Strip env-sourced fields before persisting to prevent secrets leaking\n // from in-memory env-derived config values into the on-disk config file.\n const scrubbed = stripEphemeralFields(partial);\n // Shallow merge — top-level fields replace, nested objects do too unless\n // the caller passes a fully-formed sub-object. That matches the JSON\n // config user mental model (replace `tools.maxIterations` by passing\n // the whole `tools` block, or by patching `extensions.<name>`).\n const next = deepFreeze(structuredClone({ ...this.current, ...scrubbed })) as Readonly<Config>;\n\n if (next.version !== 1) {\n throw new ConfigError({\n message: `ConfigStore.update: version must remain 1, got ${String(next.version)}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: next.version },\n });\n }\n\n const prev = this.current;\n this.current = next;\n // Notify watchers AFTER mutating `current` so re-entrant watcher reads\n // see the new state. Watcher exceptions are caught individually so one\n // misbehaving subscriber can't block the others.\n for (const w of this.watchers) {\n try {\n w(next, prev);\n } catch (err) {\n // A plugin watcher that crashes on /model switch or similar would\n // otherwise leave the system in a quietly-inconsistent state. We\n // still don't propagate (one bad subscriber must not break the\n // others), but we surface the error so it's discoverable.\n console.error(JSON.stringify({\n level: 'error',\n event: 'config_store.watcher_threw',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n return next;\n }\n\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void {\n this.watchers.add(cb);\n return () => this.watchers.delete(cb);\n }\n}\n\nconst FROZEN_EMPTY: Readonly<Record<string, unknown>> = Object.freeze({});\n\nfunction deepFreeze<T>(obj: T): T {\n /* v8 ignore start -- defensive: callers (and the recursion guard below) only pass unfrozen objects */\n if (obj === null || typeof obj !== 'object') return obj;\n if (Object.isFrozen(obj)) return obj;\n /* v8 ignore stop */\n for (const key of Object.keys(obj as object)) {\n const v = (obj as Record<string, unknown>)[key];\n if (v !== null && typeof v === 'object' && !Object.isFrozen(v)) {\n deepFreeze(v);\n }\n }\n return Object.freeze(obj);\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { RotatableSecretVault, SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport {\n ENCRYPTED_PREFIX_PATTERN,\n encryptedPrefixForVersion,\n} from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Key file format v2+: 4-byte magic + 1-byte version + 32-byte key = 37 bytes.\n * The magic header distinguishes versioned key files from legacy 32-byte raw keys.\n */\nconst KEY_FILE_MAGIC = Buffer.from('WSKV', 'ascii');\nconst VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES; // 37 bytes\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n *\n * Key file format:\n * - Legacy (v1): exactly 32 raw bytes\n * - Versioned (v2+): 4-byte magic `WSKV` + 1-byte version + 32-byte key (37 bytes)\n *\n * Encrypted value format: `enc:v<N>:<iv>:<tag>:<ciphertext>` where N is the\n * key version. After rotation, encrypt() emits the new version prefix.\n */\nexport class DefaultSecretVault implements RotatableSecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n private _keyVersion: number = 1;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n /** Current key version. Starts at 1; incremented by rotateKey(). */\n get keyVersion(): number {\n // Ensure key is loaded so version is accurate\n if (!this.key) this.loadOrCreateKey();\n return this._keyVersion;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && ENCRYPTED_PREFIX_PATTERN.test(value);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n const prefix = encryptedPrefixForVersion(this._keyVersion);\n return `${prefix}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n // Strip the versioned prefix (enc:v1:, enc:v2:, etc.)\n const prefixMatch = value.match(ENCRYPTED_PREFIX_PATTERN);\n if (!prefixMatch) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const rest = value.slice(prefixMatch[0].length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n /**\n * Generate a new encryption key, write it to disk, and increment the key version.\n * After rotation, encrypt() emits the new version prefix (e.g. enc:v2:).\n * The caller must re-encrypt existing config values (see rotateConfigKeys()).\n */\n rotateKey(): { oldVersion: number; newVersion: number } {\n const oldVersion = this._keyVersion;\n const newKey = randomBytes(KEY_BYTES);\n const newVersion = oldVersion + 1;\n\n // Write versioned key file: WSKV + version byte + key\n const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);\n KEY_FILE_MAGIC.copy(keyFileBuf, 0);\n keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;\n newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);\n\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n fs.writeFileSync(this.keyFile, keyFileBuf, { mode: 0o600 });\n checkKeyFilePermissions(this.keyFile);\n\n this.key = newKey;\n this._keyVersion = newVersion;\n return { oldVersion, newVersion };\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n\n // Detect key file format:\n if (buf.length === KEY_BYTES) {\n // Legacy v1: raw 32-byte key\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned v2+: WSKV magic + version byte + 32-byte key\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const key = buf.subarray(KEY_FILE_MAGIC.length + 1);\n if (key.length !== KEY_BYTES) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has wrong key size (${key.length} bytes, expected ${KEY_BYTES})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: key.length },\n });\n }\n this.key = Buffer.from(key);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n // Wrong size — neither legacy nor versioned format\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length === KEY_BYTES) {\n // Legacy v1 format\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned format\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const winnerKey = buf.subarray(KEY_FILE_MAGIC.length + 1);\n this.key = Buffer.from(winnerKey);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = key;\n this._keyVersion = 1;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Rotate the vault's encryption key and re-encrypt all secret-bearing\n * fields in a config file. This is the atomic key rotation operation:\n *\n * 1. Read the config file\n * 2. Decrypt all encrypted values with the old key\n * 3. Generate a new key (vault.rotateKey())\n * 4. Re-encrypt all values with the new key (new version prefix)\n * 5. Write the config file atomically\n *\n * Returns the number of fields re-encrypted and the version transition.\n * If the config file doesn't exist or has no encrypted fields, returns\n * { rotated: 0 } without modifying the key.\n */\nexport async function rotateConfigKeys(\n configPath: string,\n vault: RotatableSecretVault,\n logger?: Pick<Logger, 'warn' | 'info'>,\n): Promise<{ rotated: number; oldVersion: number; newVersion: number; file: string }> {\n const log = logger?.info ?? (() => {});\n const warn = logger?.warn ?? ((msg: string) => console.warn(msg));\n\n // Read the config file\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n // No config file — just rotate the key without re-encrypting anything\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no config file to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n warn(`[secret-vault] Config file ${configPath} is not valid JSON — skipping rotation`);\n return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };\n }\n\n // Count encrypted fields and decrypt them\n const counter = { n: 0, failed: [] as string[] };\n const decrypted = walkDecryptCount(parsed, vault, counter);\n\n // Abort BEFORE rotating if any encrypted field could not be decrypted with\n // the current key. Rotation would discard the old key while these fields\n // still hold old-key ciphertext, and walkReencrypt skips already-encrypted\n // values — so they would become permanently undecryptable. Surface the\n // corruption and leave the key intact for the operator to investigate.\n if (counter.failed.length > 0) {\n throw new Error(\n `[secret-vault] Aborting key rotation: ${counter.failed.length} field(s) could not be decrypted ` +\n `with the current key and would be permanently lost on rotation: ${counter.failed.join(', ')}. ` +\n `Restore or remove these fields before rotating.`,\n );\n }\n\n if (counter.n === 0) {\n // No encrypted fields — just rotate the key\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no encrypted fields to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n // Rotate the key (generates new key, increments version)\n const { oldVersion, newVersion } = vault.rotateKey();\n\n // Re-encrypt all secret fields with the new key\n const reencrypted = walkReencrypt(decrypted, vault);\n\n // Write the config file atomically\n await atomicWrite(configPath, JSON.stringify(reencrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath, { warn });\n\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — re-encrypted ${counter.n} field(s)`);\n return { rotated: counter.n, oldVersion, newVersion, file: configPath };\n}\n\n/**\n * Walk a config object, decrypt all encrypted values, and count them.\n * Returns a new object with decrypted values.\n *\n * `counter.failed` collects the key paths of any field that is encrypted but\n * could NOT be decrypted with the current key. These are left as-is (old\n * ciphertext). The caller MUST treat a non-empty `failed` list as a hard stop\n * before rotating: rotation discards the old key, and `walkReencrypt` skips\n * already-encrypted values, so a retained old-key ciphertext would become\n * permanently undecryptable. Surfacing it is strictly safer than entombing it.\n */\nfunction walkDecryptCount<T>(\n node: T,\n vault: SecretVault,\n counter: { n: number; failed: string[] },\n pathPrefix = '',\n): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item, i) =>\n walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`),\n ) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;\n if (typeof v === 'string' && vault.isEncrypted(v)) {\n try {\n out[k] = vault.decrypt(v);\n counter.n++;\n } catch {\n // Decryption failed — record the path and keep the old ciphertext.\n // The caller aborts rotation when counter.failed is non-empty, so\n // the old key is never discarded while this value still depends on it.\n counter.failed.push(keyPath);\n out[k] = v;\n }\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkDecryptCount(v, vault, counter, keyPath);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Walk a config object and re-encrypt all secret-bearing fields.\n * Unlike encryptConfigSecrets, this encrypts ALL string values that\n * were previously decrypted (they're now plaintext), not just those\n * matching the secret field pattern. This ensures we re-encrypt values\n * that were successfully decrypted in walkDecryptCount.\n */\nfunction walkReencrypt<T>(node: T, vault: SecretVault): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkReencrypt(item, vault)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && v.length > 0 && !vault.isEncrypted(v)) {\n // This was a decrypted secret — re-encrypt it\n out[k] = vault.encrypt(v);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkReencrypt(v, vault);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as unknown as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n autoExtendLimit: true,\n restrictToProjectRoot: false,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/**\n * Default process circuit-breaker config. Protection is OFF by default — the\n * breaker only gates `bash`/`exec` once the user opts in via `/settings breaker on`.\n * The auto kill/reset delay is only consulted when protection is enabled.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({\n enabled: false,\n autoKillResetMs: 60_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","import * as fs from 'node:fs/promises';\nimport { decryptConfigSecrets } from '../security/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport {\n DEFAULT_CONTEXT_WINDOW_MODE_ID,\n isContextWindowModeId,\n listContextWindowModes,\n} from '../types/context-window.js';\nimport type { Config, ConfigLoader, SyncConfig } from '../types/config.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { deepMerge as deepMergeCore, type DeepMergeOptions } from '../utils/deep-merge.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport {\n DEFAULT_TOOLS_CONFIG,\n DEFAULT_CONTEXT_CONFIG,\n DEFAULT_SESSION_LOGGING_CONFIG,\n} from '../types/default-config.js';\nimport type { EventBus } from '../kernel/events.js';\n\n/**\n * Surface the OS error code (EACCES, ENOSPC, …) alongside the message in\n * storage.* event payloads. Codes are stable and locale-independent, so\n * they are what dashboards and alerts key on; the message is supplementary.\n */\nfunction storageErrorString(err: unknown): string {\n if (err instanceof Error) {\n const code = (err as NodeJS.ErrnoException).code;\n return code ? `${code}: ${err.message}` : err.message;\n }\n /* v8 ignore next -- defensive: callers only pass fs Error instances */\n return String(err);\n}\n\n/**\n * Defaults express *behavior*, not identity. Provider and model are NOT\n * hardcoded — they must be resolved at runtime from config + env + the\n * ModelsRegistry. A bare Config returned by this loader will throw when\n * the agent tries to construct a provider, with a message that points\n * users at `wstack init`.\n */\nconst BEHAVIOR_DEFAULTS: Omit<Config, 'provider' | 'model'> = {\n version: 1,\n context: {\n mode: DEFAULT_CONTEXT_WINDOW_MODE_ID,\n warnThreshold: 0.6,\n softThreshold: 0.75,\n hardThreshold: 0.9,\n autoCompact: true,\n preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,\n eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold,\n },\n tools: {\n defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,\n maxIterations: DEFAULT_TOOLS_CONFIG.maxIterations,\n iterationTimeoutMs: DEFAULT_TOOLS_CONFIG.iterationTimeoutMs,\n sessionTimeoutMs: DEFAULT_TOOLS_CONFIG.sessionTimeoutMs,\n perIterationOutputCapBytes: DEFAULT_TOOLS_CONFIG.perIterationOutputCapBytes,\n autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit,\n restrictToProjectRoot: DEFAULT_TOOLS_CONFIG.restrictToProjectRoot,\n },\n log: { level: 'info' },\n features: {\n mcp: true,\n plugins: true,\n memory: true,\n modelsRegistry: true,\n skills: true,\n },\n mcpServers: {},\n indexing: {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n },\n session: { ...DEFAULT_SESSION_LOGGING_CONFIG },\n};\n\n/** Parse a boolean-ish env var: \"0\"/\"false\"/\"no\"/\"off\" → false, anything else → true. */\nfunction envBool(v: string): boolean {\n return !/^(0|false|no|off)$/i.test(v.trim());\n}\n\nfunction envBoolOptional(v: string | undefined): boolean {\n return v !== undefined && envBool(v);\n}\n\nconst LOG_LEVELS = new Set<Config['log']['level']>(['error', 'warn', 'info', 'debug', 'trace']);\n\nfunction envLogLevel(v: string): Config['log']['level'] {\n return LOG_LEVELS.has(v as Config['log']['level']) ? (v as Config['log']['level']) : 'info';\n}\n\nconst ENV_MAP: Record<string, (cfg: PartialConfig, val: string) => void> = {\n WRONGSTACK_PROVIDER: (c, v) => {\n c.provider = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('provider');\n },\n WRONGSTACK_MODEL: (c, v) => {\n c.model = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('model');\n },\n WRONGSTACK_API_KEY: (c, v) => {\n c.apiKey = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('apiKey');\n },\n WRONGSTACK_BASE_URL: (c, v) => {\n c.baseUrl = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('baseUrl');\n },\n WRONGSTACK_LOG_LEVEL: (c, v) => {\n /* v8 ignore next -- defensive: config defaults always seed c.log before env handlers run */\n if (!c.log) c.log = { level: 'info' };\n c.log.level = envLogLevel(v);\n },\n WRONGSTACK_INDEX_ON_START: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onSessionStart: envBool(v) };\n },\n WRONGSTACK_INDEX_ON_EDIT: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onEdit: envBool(v) };\n },\n WRONGSTACK_INDEX_WATCH: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, watchExternal: envBool(v) };\n },\n};\n\nconst defaultIndexing = {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n} as const;\n\ntype PartialConfig = Partial<Config> & {\n providers?: Record<\n string,\n { apiKey?: string | undefined; baseUrl?: string | undefined; type?: string | undefined }\n >;\n /** Fields that came from environment variables — must not be persisted. */\n _envSource?: Set<string> | undefined;\n};\n\n/**\n * Config-layer deep merge — delegates to the shared utility with\n * `arrayMode: 'concat-primitives'` and optional debug logging for\n * non-primitive array replacements.\n */\nfunction deepMerge<T>(base: T, patch: Partial<T>): T {\n const opts: DeepMergeOptions = { arrayMode: 'concat-primitives' };\n if (envBoolOptional(process.env.WRONGSTACK_DEBUG_CONFIG)) {\n opts.onNonPrimitiveArrayReplace = (key, existingLen, patchLen) => {\n console.warn(\n `[config] Non-primitive array for \"${key}\" replaced (global + local config merge). ` +\n `Global entries: ${existingLen}, local entries: ${patchLen}.`,\n );\n };\n }\n return deepMergeCore(base as Record<string, unknown>, patch as Record<string, unknown>, opts) as T;\n}\n\n/**\n * A single config source. Higher priority wins in merges.\n * Sources are applied in priority order (lowest first), so a source\n * with priority=10 overrides one with priority=1.\n */\nexport interface ConfigSource {\n /** Unique name for debugging and error messages. */\n name: string;\n /** Lower numbers merge first, higher numbers override lower. Default: 50. */\n priority?: number | undefined;\n /**\n * Read the raw config patch. Return an empty object if unavailable.\n * Errors are surfaced but do not abort loading — the source is skipped.\n */\n read(): Promise<Partial<Config>>;\n}\n\nexport interface ConfigLoaderOptions {\n paths: WstackPaths;\n strict?: boolean | undefined;\n vault?: SecretVault | undefined;\n /** Extra sources merged after the built-in layers. */\n sources?: ConfigSource[] | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class DefaultConfigLoader implements ConfigLoader {\n private readonly paths: WstackPaths;\n private readonly strict: boolean;\n private readonly vault: SecretVault | undefined;\n private readonly extraSources: ConfigSource[];\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n\n constructor(opts: ConfigLoaderOptions) {\n this.paths = opts.paths;\n this.strict = opts.strict ?? false;\n this.vault = opts.vault;\n this.extraSources = opts.sources ?? [];\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n async load(\n opts: { cliFlags?: Partial<Config> | undefined; cwd?: string | undefined } = {},\n ): Promise<Config> {\n let cfg: PartialConfig = { ...BEHAVIOR_DEFAULTS } as PartialConfig;\n\n // Layer 2, 3 & 3b: global + project-local + in-project config — read in parallel.\n // inProjectConfig (<project>/.wrongstack/config.json) merges AFTER\n // projectLocalConfig so it takes priority (user-intended > auto-cached).\n const [global, local, inProject] = await Promise.all([\n this.readJson(this.paths.globalConfig),\n this.readJson(this.paths.projectLocalConfig),\n this.readJson(this.paths.inProjectConfig),\n ]);\n cfg = deepMerge(cfg, global);\n cfg = deepMerge(cfg, local);\n cfg = deepMerge(cfg, inProject);\n\n // Layer 4: env vars\n for (const [key, fn] of Object.entries(ENV_MAP)) {\n const v = process.env[key];\n if (v) fn(cfg, v);\n }\n\n // Layer 5: extra sources — sorted by priority (lowest first).\n // When priorities tie, sort by name for deterministic order.\n const sorted = [...this.extraSources].sort((a, b) => {\n const pd = (a.priority ?? 50) - (b.priority ?? 50);\n if (pd !== 0) return pd;\n return a.name.localeCompare(b.name);\n });\n for (const src of sorted) {\n try {\n const patch = await src.read();\n if (patch && Object.keys(patch).length > 0) {\n cfg = deepMerge(cfg, patch);\n }\n } catch (err) {\n // Best-effort: skip failing sources so one bad source doesn't block boot.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.source_load_failed',\n source: src.name,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n // Layer 6: CLI flags\n if (opts.cliFlags) {\n cfg = deepMerge(cfg, opts.cliFlags);\n }\n\n // Decrypt apiKey-like fields if a vault is configured.\n if (this.vault) {\n cfg = decryptConfigSecrets(cfg, this.vault);\n }\n\n // Multi-key resolution: when a provider has `apiKeys[]` configured,\n // mirror the active entry into `apiKey` so downstream construction\n // code (provider registry, wire adapters) needs no changes. Honors\n // `activeKey` (by label), else falls back to the first entry. A\n // pre-existing `apiKey` set by env/CLI flags wins so an explicit\n // override still beats the saved list.\n if (cfg.providers) {\n for (const pcfg of Object.values(cfg.providers)) {\n if (!pcfg || typeof pcfg !== 'object') continue;\n const rawKeys = (pcfg as { apiKeys?: unknown | undefined }).apiKeys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) continue;\n // Each apiKeys entry came from arbitrary JSON. Filter to entries\n // that actually have a string apiKey + label so a malformed array\n // (null entry, missing field) doesn't crash the .find / chosen.apiKey\n // path below.\n const keys = rawKeys.filter(\n (k): k is { label: string; apiKey: string } =>\n !!k &&\n typeof k === 'object' &&\n typeof (k as { label?: unknown | undefined }).label === 'string' &&\n typeof (k as { apiKey?: unknown | undefined }).apiKey === 'string',\n );\n if (keys.length === 0) continue;\n const existing = (pcfg as { apiKey?: string | undefined }).apiKey;\n if (existing && existing.length > 0) continue;\n const activeLabel = (pcfg as { activeKey?: string | undefined }).activeKey;\n const chosen = activeLabel\n ? (keys.find((k) => k.label === activeLabel) ?? keys[0])\n : keys[0];\n if (chosen?.apiKey) {\n (pcfg as { apiKey?: string | undefined }).apiKey = chosen.apiKey;\n }\n }\n }\n\n this.validateBehavior(cfg);\n if (this.strict) {\n this.validateIdentity(cfg);\n }\n // In strict mode, validateIdentity has confirmed provider/model are set;\n // it's safe to assert the full Config contract. In non-strict mode the\n // caller (e.g. early-boot wizard) accepts a Partial and constructs the\n // provider later, so we deliberately return without the cast.\n return Object.freeze(cfg) as Config;\n }\n\n /**\n * Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted\n * by the vault (if provided). The file is isolated from the main config\n * hierarchy to prevent accidental commits.\n */\n async persistSyncConfig(cfg: SyncConfig): Promise<void> {\n let toWrite = { ...cfg };\n if (this.vault && toWrite.githubToken && !toWrite.githubToken.startsWith('enc:')) {\n // Re-encrypt if plaintext (e.g. came from in-memory configStore update\n // rather than direct /sync enable call). Idempotent for already-encrypted.\n toWrite = { ...toWrite, githubToken: this.vault.encrypt(toWrite.githubToken) };\n }\n const fp = this.paths.syncConfig;\n const t0 = Date.now();\n try {\n await atomicWrite(fp, JSON.stringify(toWrite, null, 2), { mode: 0o600 });\n this.events?.emit('storage.write', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'persist_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'persist_sync',\n outcome: 'failure',\n error: storageErrorString(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Read ~/.wrongstack/sync.json (encrypted GitHub token storage) and decrypt\n * the token if a vault is available. Returns null if the file doesn't exist.\n * This is separate from main config loading because sync.json is intentionally\n * isolated — it should never be part of project-local or env-driven config.\n */\n async loadSyncConfig(): Promise<SyncConfig | null> {\n const fp = this.paths.syncConfig;\n const t0 = Date.now();\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const parsed = safeParse<SyncConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse error or empty file',\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return null;\n }\n\n // Decrypt the token if vault is available (field name matches secret pattern)\n if (this.vault) {\n const decrypted = decryptConfigSecrets({ sync: parsed.value } as PartialConfig, this.vault);\n const result = (decrypted as { sync: SyncConfig }).sync ?? null;\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return result;\n }\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return parsed.value;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Non-ENOENT failures (EACCES, ENOSPC, etc.) — emit storage.read failure, then return null\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.sync_load_failed',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n }\n\n private async readJson(file: string): Promise<PartialConfig> {\n let raw: string;\n const t0 = Date.now();\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n // Missing file is the common case (per-project local config rarely\n // exists at start). Surface anything else (EACCES, EISDIR) so a\n // mis-permissioned config doesn't silently fall back to defaults.\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: file,\n operation: 'read_json',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.read_failed',\n path: file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return {};\n }\n const parsed = safeParse<PartialConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n // The file exists but isn't valid JSON. Don't silently reset to\n // defaults — that's hours of debug timesink for users who'd typo'd\n // their config. Warn loudly and keep the in-memory defaults.\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: file,\n operation: 'read_json',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse error or empty file',\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.parse_failed',\n path: file,\n message: 'invalid JSON — falling back to defaults for this layer',\n timestamp: new Date().toISOString(),\n }));\n return {};\n }\n return parsed.value;\n }\n\n private validateBehavior(cfg: PartialConfig): void {\n /* v8 ignore start -- defensive: config defaults always seed version:1 before validation */\n if (cfg.version === undefined) throw new ConfigError({\n message: 'Config: missing version field',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version' },\n });\n /* v8 ignore stop */\n if (cfg.version !== 1) throw new ConfigError({\n message: `Config: unsupported version ${cfg.version}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: cfg.version },\n });\n const c = cfg.context;\n if (!c) throw new ConfigError({\n message: 'Config: missing context section',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'context' },\n });\n // A user-edited config.json can land strings here (\"0.6\") and slip past\n // truthiness checks; the `>=` comparison then coerces silently and the\n // threshold ordering check passes for nonsense values. Validate types\n // explicitly so misconfigs surface here, not as confusing failures deep\n // in the auto-compaction logic.\n const fields: Array<keyof typeof c> = ['warnThreshold', 'softThreshold', 'hardThreshold'];\n for (const f of fields) {\n const v = c[f];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n throw new ConfigError({\n message: `Config: context.${String(f)} must be a finite number (got ${typeof v})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: `context.${String(f)}`, actualType: typeof v },\n });\n }\n }\n if (c.warnThreshold >= c.softThreshold || c.softThreshold >= c.hardThreshold) {\n throw new ConfigError({\n message: 'Config: context thresholds must satisfy warn < soft < hard',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { warn: c.warnThreshold, soft: c.softThreshold, hard: c.hardThreshold },\n });\n }\n if (c.mode !== undefined && !isContextWindowModeId(c.mode)) {\n // An unknown mode (typo or value from an older/renamed scheme) should not\n // brick the CLI — unlike the numeric thresholds above there is a safe\n // default. Warn and fall back rather than throwing.\n const known = listContextWindowModes()\n .map((m) => m.id)\n .join(', ');\n console.warn(\n `[config] Ignoring unknown context.mode \"${c.mode}\" (expected one of: ${known}); ` +\n `falling back to \"${DEFAULT_CONTEXT_WINDOW_MODE_ID}\".`,\n );\n c.mode = DEFAULT_CONTEXT_WINDOW_MODE_ID;\n }\n }\n\n private validateIdentity(cfg: PartialConfig): void {\n if (!cfg.provider) {\n throw new ConfigError({\n message: 'Config: no provider configured. Run `wstack init` or set WRONGSTACK_PROVIDER.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'provider' },\n });\n }\n if (!cfg.model) {\n throw new ConfigError({\n message: 'Config: no model configured. Run `wstack init` or set WRONGSTACK_MODEL.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'model' },\n });\n }\n }\n}\n","/**\n * L2-D: Config version migration framework. Pure functions, decoupled\n * from disk/CLI — caller passes a parsed JSON object and gets back the\n * up-to-date `Config` shape (or a structured error explaining why\n * migration failed).\n *\n * Migrations are registered as `{ from, to, migrate }` triples and run\n * sequentially. Each migration is independently testable. Adding a new\n * version means appending one migration; existing user configs are\n * upgraded in place at load time.\n */\n\nexport interface MigrationContext {\n /**\n * Original on-disk version of the input. Migrations may use this to\n * decide between in-place patches and rewrites.\n */\n fromVersion: number;\n /**\n * Set when the migration writes back to disk. Callers persist the\n * migrated config when this is true so the user doesn't see the same\n * migration banner on every boot.\n */\n shouldPersist: boolean;\n}\n\nexport interface ConfigMigration {\n /** Version of the input this migration accepts. */\n from: number;\n /** Version of the output it produces. */\n to: number;\n /** Pure transform — no I/O. */\n migrate(input: Record<string, unknown>, ctx: MigrationContext): Record<string, unknown>;\n /** Optional human-readable description for migration logs / banners. */\n describe?: string | undefined;\n}\n\nexport interface MigrationResult {\n /** Final config (still typed as `unknown`-keyed — caller validates). */\n config: Record<string, unknown>;\n /** Ordered list of `from→to` versions that ran. */\n applied: string[];\n /** True when at least one migration produced changes worth persisting. */\n shouldPersist: boolean;\n}\n\nexport class ConfigMigrationError extends Error {\n readonly fromVersion: number;\n readonly targetVersion: number;\n readonly missingStep: number | null;\n\n constructor(opts: {\n message: string;\n fromVersion: number;\n targetVersion: number;\n missingStep: number | null;\n }) {\n super(opts.message);\n this.name = 'ConfigMigrationError';\n this.fromVersion = opts.fromVersion;\n this.targetVersion = opts.targetVersion;\n this.missingStep = opts.missingStep;\n }\n}\n\n/**\n * Run registered migrations until the input reaches `targetVersion`.\n *\n * Resolution rules:\n * 1. If `input.version === targetVersion`, no migrations run; `shouldPersist`\n * is false.\n * 2. Otherwise walk the migration chain from `input.version` upward,\n * picking the migration whose `from` matches the current version.\n * 3. Stop when `current.version === targetVersion`.\n * 4. If no migration matches at some point, throw `ConfigMigrationError`\n * with the missing step recorded for diagnostics.\n *\n * Migrations may be downward (e.g. for staged rollouts), but `targetVersion`\n * must be reachable strictly via the registered chain — there's no implicit\n * \"skip\" or transitive resolution.\n */\nexport function runConfigMigrations(\n input: Record<string, unknown>,\n targetVersion: number,\n migrations: readonly ConfigMigration[],\n): MigrationResult {\n const initial = typeof input['version'] === 'number' ? (input['version'] as number) : 1;\n let current: Record<string, unknown> = { ...input };\n let currentVersion = initial;\n const applied: string[] = [];\n let shouldPersist = false;\n\n let guard = 0;\n while (currentVersion !== targetVersion) {\n if (++guard > 100) {\n throw new ConfigMigrationError({\n message: `Config migration looped past 100 steps (from v${initial} toward v${targetVersion})`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const step = migrations.find((m) => m.from === currentVersion);\n if (!step) {\n throw new ConfigMigrationError({\n message: `No migration registered from config v${currentVersion} (target v${targetVersion}). Update the framework or revert the config file.`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const ctx: MigrationContext = { fromVersion: currentVersion, shouldPersist: false };\n const next = step.migrate(current, ctx);\n // Ensure the migration set the new version. Be tolerant: if it didn't,\n // patch it in so the chain doesn't infinite-loop on author oversight.\n if (typeof next['version'] !== 'number' || next['version'] !== step.to) {\n next['version'] = step.to;\n }\n current = next;\n currentVersion = step.to;\n applied.push(`v${step.from}→v${step.to}`);\n shouldPersist = shouldPersist || ctx.shouldPersist || step.from < step.to;\n }\n return { config: current, applied, shouldPersist };\n}\n\n/**\n * Default empty migration registry. Real migrations are appended as new\n * Config versions are introduced. Example (when v2 lands):\n *\n * export const CONFIG_MIGRATIONS: readonly ConfigMigration[] = [\n * {\n * from: 1, to: 2, describe: 'rename `apiKey` → `auth.apiKey`',\n * migrate(cfg) {\n * const apiKey = cfg.apiKey;\n * delete cfg.apiKey;\n * return { ...cfg, auth: { ...(cfg.auth ?? {}), apiKey } };\n * },\n * },\n * ];\n */\nexport const DEFAULT_CONFIG_MIGRATIONS: readonly ConfigMigration[] = [];\n","import * as fsp from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SessionStore } from '../types/session.js';\nimport { ensureDir } from '../utils/atomic-write.js';\n\n/**\n * Per-project lockfile used for crash detection. The CLI writes one of\n * these alongside the session JSONLs (`<projectSessions>/active.json`)\n * when an interactive run starts, and deletes it on clean exit. If we\n * find one on the next launch whose owning PID is dead (or whose host\n * doesn't match), we know the previous run was killed mid-flight and\n * the session it was writing to is a recovery candidate.\n *\n * The lockfile is intentionally per-project (already isolated by\n * `wpaths.projectSessions`), so two TUIs in two different repos do not\n * fight each other.\n */\nexport interface RecoveryLockOptions {\n /** Directory the lockfile lives in. Usually `wpaths.projectSessions`. */\n dir: string;\n /** This process's PID. Default: `process.pid`. */\n pid?: number | undefined;\n /** Hostname recorded for the lock. Default: `os.hostname()`. */\n hostname?: string | undefined;\n /** Locks older than this are considered orphaned (disk wiped, etc.). Default 24h. */\n maxAgeMs?: number | undefined;\n /** Used to check whether the abandoned session was actually closed cleanly. */\n sessionStore?: SessionStore | undefined;\n /**\n * Override the PID-liveness probe. Default: `process.kill(pid, 0)` —\n * succeeds (or throws EPERM) when the PID is alive, throws ESRCH when\n * it is gone. Tests inject a deterministic stub.\n */\n isPidAlive?: (((pid: number) => boolean)) | undefined;\n}\n\nexport interface AbandonedSession {\n sessionId: string;\n pid: number;\n startedAt: string;\n /** Lockfile age in ms at the time of the check. */\n ageMs: number;\n /** Number of messages already on disk for this session. */\n messageCount: number;\n}\n\ninterface LockFile {\n v: 1;\n sessionId: string;\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\nconst LOCK_FILE = 'active.json';\nconst DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport class RecoveryLock {\n private readonly file: string;\n private readonly pid: number;\n private readonly hostname: string;\n private readonly maxAgeMs: number;\n private readonly sessionStore?: SessionStore | undefined;\n private readonly probe: (pid: number) => boolean;\n\n constructor(opts: RecoveryLockOptions) {\n this.file = path.join(opts.dir, LOCK_FILE);\n this.pid = opts.pid ?? process.pid;\n this.hostname = opts.hostname ?? os.hostname();\n this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n this.sessionStore = opts.sessionStore;\n this.probe = opts.isPidAlive ?? defaultIsPidAlive;\n }\n\n /**\n * Examine the lockfile and decide whether it represents an abandoned\n * session. Returns `null` if the file is missing, points to a live\n * instance, references a clean-closed session, is too old, or is\n * malformed. Otherwise returns enough detail to prompt the user.\n *\n * Important: this is a read-only check. We never delete an active\n * lock from here — if another wstack instance is alive, the caller\n * should bail or run with a fresh session instead.\n */\n async checkAbandoned(): Promise<AbandonedSession | null> {\n const lock = await this.readLock();\n if (!lock) return null;\n\n const ageMs = Date.now() - new Date(lock.startedAt).getTime();\n if (Number.isNaN(ageMs) || ageMs < 0) {\n // Clock skew or corrupted timestamp — treat as orphan.\n return null;\n }\n if (ageMs > this.maxAgeMs) return null;\n\n // PID liveness only meaningful on the same host. Different host\n // means we can't probe — assume abandoned (the other machine's\n // wstack can't be holding *our* sessions dir unless it was\n // shared via network mount, in which case the user is on their\n // own).\n if (lock.hostname === this.hostname && this.probe(lock.pid)) {\n // Another wstack on this box is actively writing here.\n return null;\n }\n\n let messageCount = 0;\n if (this.sessionStore) {\n try {\n const data = await this.sessionStore.load(lock.sessionId);\n // Closed means the LAST session_end is not followed by further\n // conversation activity. Legacy /save wrote mid-stream session_end\n // markers — `some()` would treat a session that crashed AFTER such a\n // marker as cleanly closed and silently skip recovery.\n const lastEnd = data.events.findLastIndex((e) => e.type === 'session_end');\n const closed =\n lastEnd >= 0 &&\n !data.events\n .slice(lastEnd + 1)\n .some(\n (e) =>\n e.type === 'user_input' ||\n e.type === 'llm_response' ||\n e.type === 'in_flight_start',\n );\n if (closed) return null;\n messageCount = data.messages.length;\n } catch {\n // Lock points to a session that doesn't exist on disk (deleted\n // out from under us). Nothing to recover.\n return null;\n }\n }\n\n return {\n sessionId: lock.sessionId,\n pid: lock.pid,\n startedAt: lock.startedAt,\n ageMs,\n messageCount,\n };\n }\n\n /**\n * Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)\n * to detect whether another process acquired the lock between our\n * `checkAbandoned()` call and now. If the file already exists, it means\n * another process won the race and we throw instead of silently\n * overwriting their recovery record.\n *\n * The caller MUST have already called `checkAbandoned()` and handled its\n * null return before calling this.\n */\n async write(sessionId: string): Promise<void> {\n await ensureDir(path.dirname(this.file));\n const lock: LockFile = {\n v: 1,\n sessionId,\n pid: this.pid,\n hostname: this.hostname,\n startedAt: new Date().toISOString(),\n };\n // O_EXCL: atomic create — fails with EEXIST if another process wrote\n // the file between our checkAbandoned() and this write. This prevents\n // two processes that scanned the same stale lock from both believing\n // they hold it. The atomicWrite approach (temp+rename) would silently\n // replace on POSIX, hiding the race.\n try {\n await fsp.writeFile(this.file, JSON.stringify(lock), { flag: 'wx', mode: 0o600 });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') {\n throw new Error(`Recovery lock already held by another process`);\n }\n /* v8 ignore next -- defensive: an unexpected (non-EEXIST) write failure is rethrown */\n throw err;\n }\n }\n\n /**\n * Release the lock. Idempotent — silently succeeds if the file is\n * already gone (e.g. someone else cleared it, or the directory was\n * wiped).\n */\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n /* v8 ignore next -- defensive: an unexpected (non-ENOENT) unlink failure is rethrown */\n throw err;\n }\n }\n\n private async readLock(): Promise<LockFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null;\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isLockFile(parsed)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n}\n\nfunction isLockFile(v: unknown): v is LockFile {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return (\n o['v'] === 1 &&\n typeof o['sessionId'] === 'string' &&\n typeof o['pid'] === 'number' &&\n typeof o['hostname'] === 'string' &&\n typeof o['startedAt'] === 'string'\n );\n}\n\n/**\n * Probe whether a process is alive without sending it a real signal.\n *\n * Unix: `process.kill(pid, 0)` succeeds for our own processes, throws\n * EPERM for others (still alive, just not ours), and throws ESRCH\n * when the PID is gone.\n * Windows (Node 22+): same call returns true if the process exists,\n * throws otherwise.\n */\nfunction defaultIsPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n /* v8 ignore next -- platform/permission-specific: EPERM means alive but owned by another user */\n if (code === 'EPERM') return true; // alive, but owned by someone else\n return false;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport type { ContentBlock } from '../types/blocks.js';\r\nimport type {\r\n DefaultSessionReaderOptions,\r\n SessionExportOptions,\r\n SessionQuery,\r\n SessionReader,\r\n SessionSearchHit,\r\n SessionSearchQuery,\r\n SessionSummaryLite,\r\n} from '../types/session-reader.js';\r\nimport { compileUserRegex } from '../utils/regex-guard.js';\r\nimport type { SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\r\n\r\n/**\r\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\r\n * and export helpers. Implemented on top of the public `SessionStore`\r\n * surface so any concrete store can be inspected without re-implementation.\r\n *\r\n * The heavy operations re-parse the JSONL stream on every call — fine for\r\n * /resume and one-off analytics. Wrap with a memoizing decorator if needed.\r\n */\r\nexport class DefaultSessionReader implements SessionReader {\r\n private readonly store: SessionStore;\r\n\r\n constructor(opts: DefaultSessionReaderOptions) {\r\n this.store = opts.store;\r\n }\r\n\r\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\r\n // Fetch only what's needed; in-process filters are cheap relative to store I/O.\r\n // If a caller needs pagination, it should pass `q.limit` and page through results.\r\n const raw = await this.store.list(q.limit ? Math.max(q.limit, 100) : 1000);\r\n const titleNeedle = q.titleContains?.toLowerCase();\r\n const filtered = raw.filter((s) => {\r\n if (q.since && s.startedAt < q.since) return false;\r\n if (q.until && s.startedAt > q.until) return false;\r\n if (q.provider && s.provider !== q.provider) return false;\r\n if (q.model && s.model !== q.model) return false;\r\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n const out: SessionSummaryLite[] = filtered.map((s) => ({\r\n id: s.id,\r\n title: s.title,\r\n startedAt: s.startedAt,\r\n provider: s.provider,\r\n model: s.model,\r\n tokenTotal: s.tokenTotal,\r\n }));\r\n return q.limit ? out.slice(0, q.limit) : out;\r\n }\r\n\r\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\r\n const data = await this.store.load(sessionId);\r\n for (const e of data.events) yield e;\r\n }\r\n\r\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\r\n const limit = q.limit ?? 100;\r\n const matcher = buildMatcher(q);\r\n const allowedTypes = q.types ? new Set(q.types) : null;\r\n\r\n // Filter sessions BEFORE loading events — avoids loading thousands of events\r\n // from sessions that don't match the time/provider/model criteria.\r\n let ids: string[];\r\n if (sessionId) {\r\n ids = [sessionId];\r\n } else {\r\n const sessions = await this.store.list(1000);\r\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\r\n const filtered = sessions.filter((s) => {\r\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\r\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\r\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\r\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\r\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n ids = filtered.map((s) => s.id);\r\n }\r\n\r\n const hits: SessionSearchHit[] = [];\r\n for (const id of ids) {\r\n let data;\r\n try {\r\n data = await this.store.load(id);\r\n } catch {\r\n continue;\r\n }\r\n for (let i = 0; i < data.events.length; i++) {\r\n const ev = expectDefined(data.events[i]);\r\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\r\n const text = eventText(ev);\r\n if (text === null) continue;\r\n const hit = matcher(text);\r\n if (!hit) continue;\r\n hits.push({\r\n sessionId: id,\r\n eventIndex: i,\r\n ts: ev.ts,\r\n type: ev.type,\r\n snippet: snippetOf(text, hit.start, hit.end),\r\n });\r\n if (hits.length >= limit) return hits;\r\n }\r\n }\r\n return hits;\r\n }\r\n\r\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\r\n const data = await this.store.load(sessionId);\r\n const includeTools = opts.includeTools ?? true;\r\n const includeDiagnostics = opts.includeDiagnostics ?? true;\r\n\r\n const filtered = data.events.filter((e) => {\r\n if (\r\n !includeTools &&\r\n (e.type === 'tool_use' ||\r\n e.type === 'tool_result' ||\r\n e.type === 'tool_call_start' ||\r\n e.type === 'tool_call_end')\r\n ) {\r\n return false;\r\n }\r\n if (\r\n !includeDiagnostics &&\r\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\r\n ) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n if (opts.format === 'json') {\r\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\r\n }\r\n if (opts.format === 'text') {\r\n return renderPlainText(data.metadata, filtered);\r\n }\r\n return renderMarkdown(data.metadata, filtered);\r\n }\r\n\r\n async metadata(sessionId: string): Promise<SessionMetadata> {\r\n const data = await this.store.load(sessionId);\r\n return data.metadata;\r\n }\r\n}\r\n\r\nfunction buildMatcher(\r\n q: SessionSearchQuery,\r\n): (text: string) => { start: number; end: number } | null {\r\n const ci = q.caseInsensitive ?? true;\r\n if (q.regex) {\r\n const flags = ci ? 'i' : '';\r\n const compiled = compileUserRegex(q.query, flags);\r\n if (!compiled.ok) {\r\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\r\n }\r\n const re = compiled.regex;\r\n return (text) => {\r\n const m = re.exec(text);\r\n return m ? { start: m.index, end: m.index + m[0].length } : null;\r\n };\r\n }\r\n const needle = ci ? q.query.toLowerCase() : q.query;\r\n return (text) => {\r\n const hay = ci ? text.toLowerCase() : text;\r\n const idx = hay.indexOf(needle);\r\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\r\n };\r\n}\r\n\r\nfunction eventText(e: SessionEvent): string | null {\r\n switch (e.type) {\r\n case 'user_input':\r\n return contentToString(e.content);\r\n case 'llm_response':\r\n return contentToString(e.content);\r\n case 'tool_use':\r\n return `${e.name} ${JSON.stringify(e.input)}`;\r\n case 'tool_result':\r\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\r\n case 'error':\r\n return `${e.phase}: ${e.message}`;\r\n case 'session_start':\r\n case 'session_resumed':\r\n return `${e.model}/${e.provider}`;\r\n case 'task_created':\r\n case 'task_completed':\r\n return e.title;\r\n case 'task_failed':\r\n return `${e.title}: ${e.error}`;\r\n case 'skill_activated':\r\n case 'skill_deactivated':\r\n return e.skillName;\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\nfunction contentToString(content: string | ContentBlock[]): string {\r\n if (typeof content === 'string') return content;\r\n return content\r\n .map((b) => {\r\n switch (b.type) {\r\n case 'text':\r\n return b.text;\r\n case 'tool_use':\r\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\r\n case 'tool_result':\r\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\r\n default:\r\n return '';\r\n }\r\n })\r\n .join('\\n');\r\n}\r\n\r\nconst SNIPPET_RADIUS = 60;\r\n\r\nfunction snippetOf(text: string, start: number, end: number): string {\r\n const from = Math.max(0, start - SNIPPET_RADIUS);\r\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\r\n const prefix = from > 0 ? '…' : '';\r\n const suffix = to < text.length ? '…' : '';\r\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\r\n}\r\n\r\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(`# Session ${meta.id}`);\r\n lines.push('');\r\n if (meta.model || meta.provider) {\r\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\r\n }\r\n lines.push(`- **Started:** ${meta.startedAt}`);\r\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input': {\r\n lines.push(`## User — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n }\r\n case 'llm_response': {\r\n lines.push(`## Assistant — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n if (e.stopReason && e.stopReason !== 'end_turn') {\r\n lines.push('');\r\n lines.push(`*stop: ${e.stopReason}*`);\r\n }\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_use': {\r\n lines.push(`### Tool call: \\`${e.name}\\``);\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify(e.input, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_result': {\r\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\r\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(body);\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'error': {\r\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\r\n lines.push('');\r\n break;\r\n }\r\n case 'compaction': {\r\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\r\n lines.push('');\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(\r\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\r\n );\r\n lines.push(''.padEnd(72, '-'));\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input':\r\n lines.push(`[${e.ts}] USER`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'llm_response':\r\n lines.push(`[${e.ts}] ASSISTANT`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'tool_use':\r\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\r\n break;\r\n case 'tool_result':\r\n lines.push(\r\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\r\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\r\n }`,\r\n );\r\n break;\r\n case 'error':\r\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/12-30-45Z_model_ab12\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\nimport type { EventBus } from '../kernel/events.js';\n/**\n * L2-B: AnnotationsStore — sidecar storage for collaboration annotations\n * (Phase 2 of idea #13 from IDEAS.md).\n *\n * Why a sidecar file, not the session JSONL?\n *\n * The session log is an event-sourced append-only journal\n * (`packages/core/src/types/session.ts` invariant: events are\n * append-only, with `truncateToCheckpoint` only as an explicit\n * rewind). Mixing in human-typed annotations would break that\n * invariant — the user's note about \"this rm looks dangerous\"\n * is not part of the agent's event history; it is meta-commentary\n * on the history.\n *\n * So we keep annotations in a sibling file: one JSON document per\n * session, at `<sessionDir>/<sessionId>.annotations.json`. The\n * shape is a simple versioned array, written atomically.\n *\n * Concurrency model:\n *\n * The store uses a per-session Promise chain to serialize writes.\n * Multiple annotators adding notes at the same time will queue,\n * not race. The atomic write itself is the second line of\n * defense (in case the chain is bypassed — e.g. two processes\n * pointing at the same dir).\n */\n\n/** Wire/storage shape for one annotation. */\nexport interface Annotation {\n /** Stable id (UUIDv4-ish). Referenced by resolve/delete. */\n id: string;\n /** Session this annotation belongs to. */\n sessionId: string;\n /** Index into the session event log the annotation refers to. */\n atEventIndex: number;\n /** Participant id of the annotator (matches WSCollabParticipantJoined.participantId). */\n authorId: string;\n /** Human-readable role label snapshot for display (e.g. \"annotator\"). */\n authorRole: 'annotator';\n /** The note itself. Trimmed, capped at `MAX_TEXT_LENGTH` on add. */\n text: string;\n /** ISO timestamp of creation. */\n createdAt: string;\n /** Resolved state. Annotations start unresolved. */\n resolved: boolean;\n /** ISO timestamp when resolved (if resolved). */\n resolvedAt?: string | undefined;\n /** Participant id of the resolver (if resolved). */\n resolvedBy?: string | undefined;\n}\n\ninterface AnnotationsFile {\n /** Bumped when the on-disk shape changes. v1 = initial release. */\n version: 1;\n annotations: Annotation[];\n}\n\n/** Bumped when the on-disk shape changes. Bump + migration on change. */\nconst FILE_VERSION = 1;\n/** Hard cap to keep a runaway annotator from writing megabytes. */\nconst MAX_TEXT_LENGTH = 2000;\n/** Hard cap on total annotations per session (oldest are evicted beyond this). */\nconst MAX_ANNOTATIONS = 1000;\n\nexport interface AnnotationsStoreOptions {\n /** Directory where `<sessionId>.annotations.json` files live. */\n dir: string;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class AnnotationsStore {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n /** Per-session write queue. Created lazily on first add. */\n private readonly writeChains = new Map<string, Promise<void>>();\n\n constructor(opts: AnnotationsStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n // ── Reads ──────────────────────────────────────────────────────────────\n\n /**\n * Return all annotations for `sessionId` in insertion order\n * (oldest first). Returns an empty array when no file exists\n * yet (the normal case for a fresh session) and also degrades\n * gracefully to `[]` on a read error (permissions, corruption) —\n * the failure is still surfaced via a `storage.read` event so it\n * never silently hides I/O problems from observers.\n */\n async list(sessionId: string): Promise<Annotation[]> {\n const t0 = Date.now();\n const fp = this.filePath(sessionId);\n try {\n const file = await this.readFile(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'list',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return file ? file.annotations : [];\n } catch (err) {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'list',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return [];\n }\n }\n\n /**\n * Convenience: only unresolved annotations, newest first — the\n * common UI rendering for \"what still needs attention?\".\n */\n async listOpen(sessionId: string): Promise<Annotation[]> {\n const all = await this.list(sessionId);\n return all.filter((a) => !a.resolved).reverse();\n }\n\n // ── Writes ─────────────────────────────────────────────────────────────\n\n /**\n * Add a new annotation. Returns the persisted record (with id\n * and timestamps filled in). Throws when `text` is empty or\n * exceeds `MAX_TEXT_LENGTH`.\n */\n async add(input: {\n sessionId: string;\n atEventIndex: number;\n authorId: string;\n text: string;\n }): Promise<Annotation> {\n const text = input.text.trim();\n if (text.length === 0) {\n throw new WrongStackError({\n message: 'Annotation text must be non-empty',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', sessionId: input.sessionId },\n });\n }\n if (text.length > MAX_TEXT_LENGTH) {\n throw new WrongStackError({\n message: `Annotation text exceeds ${MAX_TEXT_LENGTH} chars (got ${text.length})`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', maxLength: MAX_TEXT_LENGTH, actualLength: text.length },\n });\n }\n if (!Number.isInteger(input.atEventIndex) || input.atEventIndex < 0) {\n throw new WrongStackError({\n message: 'atEventIndex must be a non-negative integer',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'atEventIndex', value: input.atEventIndex },\n });\n }\n const annotation: Annotation = {\n id: randomUUID(),\n sessionId: input.sessionId,\n atEventIndex: input.atEventIndex,\n authorId: input.authorId,\n authorRole: 'annotator',\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n };\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n const all = await this.list(input.sessionId);\n all.push(annotation);\n // Evict oldest if we crossed the cap. Resolved first, then oldest.\n if (all.length > MAX_ANNOTATIONS) {\n const sorted = all\n .map((a, i) => ({ a, i }))\n .sort((x, y) => {\n // resolved=false wins (keep unresolved); among same resolved state, oldest first.\n /* v8 ignore next -- scale+tiebreak: needs >1000 annotations with mixed resolved states */\n if (x.a.resolved !== y.a.resolved) return x.a.resolved ? 1 : -1;\n return x.a.createdAt.localeCompare(y.a.createdAt);\n });\n const evictCount = all.length - MAX_ANNOTATIONS;\n const toEvict = new Set(sorted.slice(0, evictCount).map((s) => s.a.id));\n const kept = all.filter((a) => !toEvict.has(a.id));\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: kept });\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'evict',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n } else {\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'add',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n });\n });\n return annotation;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'add',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Mark an annotation as resolved. Returns the updated record, or\n * `null` if no annotation with that id exists in this session.\n * Idempotent: resolving an already-resolved annotation refreshes\n * `resolvedAt` / `resolvedBy` to the latest call.\n */\n async resolve(input: {\n sessionId: string;\n annotationId: string;\n resolvedBy: string;\n }): Promise<Annotation | null> {\n let updated: Annotation | null = null;\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n const all = await this.list(input.sessionId);\n const idx = all.findIndex((a) => a.id === input.annotationId);\n if (idx === -1) {\n updated = null;\n return;\n }\n const next: Annotation = {\n ...expectDefined(all[idx]),\n resolved: true,\n resolvedAt: new Date().toISOString(),\n resolvedBy: input.resolvedBy,\n };\n all[idx] = next;\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n updated = next;\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'resolve',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n });\n });\n return updated;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'resolve',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban here used to\n // throw for every modern session id, breaking annotations entirely.\n return sessionScopedPath(this.dir, sessionId, '.annotations.json');\n }\n\n private async readFile(sessionId: string): Promise<AnnotationsFile | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Non-ENOENT I/O errors (EACCES, ENOSPC): re-throw so callers emit\n // storage.error.\n throw err;\n }\n try {\n const parsed = JSON.parse(raw) as AnnotationsFile;\n if (parsed.version !== FILE_VERSION) {\n return { version: FILE_VERSION, annotations: [] };\n }\n return parsed;\n } catch {\n // JSON parse error (SyntaxError): treat as empty store — not an I/O failure.\n return null;\n }\n }\n\n private async writeFile(sessionId: string, file: AnnotationsFile): Promise<void> {\n const fp = this.filePath(sessionId);\n await atomicWrite(fp, JSON.stringify(file, null, 2));\n }\n\n /**\n * Serialize writes per-sessionId. We chain promises instead of\n * using a Mutex class so the contract is obvious from the\n * call-site: `enqueue(sid, fn)` runs `fn` after every prior\n * enqueue for `sid` has settled.\n */\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Keep the chain intact even when `fn` throws; failures\n // shouldn't break subsequent writes.\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { createHash } from 'node:crypto';\nimport type { Request } from '../types/provider.js';\n\n/**\n * Idea #2 from IDEAS.md — Deterministic Replay.\n *\n * The hash function is the foundation of replay: given a `Request`,\n * produce a stable identifier so a recorded `Response` can be looked\n * up later when we want to \"re-run\" the same agent loop without\n * burning API credits.\n *\n * Stability rules:\n *\n * - All object keys are sorted recursively before stringification.\n * Without this, two semantically identical requests that differ\n * only in key insertion order would produce different hashes.\n * - We hash ONLY the fields that affect the response: `model`,\n * `system`, `messages`, `tools`, `maxTokens`, and the four\n * sampling knobs (`temperature`, `topP`, `stopSequences`,\n * `toolChoice`). Anything else on the `Request` (metadata,\n * future extensions) is ignored so replay stays forward-compat.\n * - We serialize to JSON. The `ContentBlock` and `Message` shapes\n * are pure data; this works as long as no `undefined` values\n * sneak in (those get dropped by `JSON.stringify`, which is\n * fine — the structural diff is what matters).\n *\n * The SHA-256 output is hex-encoded and prefixed with the algorithm\n * tag so a future migration to a different hash (e.g. blake3) is\n * trivial to detect.\n */\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function hashRequest(request: Request): string {\n // Pick only the fields that affect the response. See stability rules.\n const payload = {\n model: request.model,\n system: request.system,\n messages: request.messages,\n tools: request.tools,\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n topP: request.topP,\n stopSequences: request.stopSequences,\n toolChoice: request.toolChoice,\n };\n const json = stableStringify(payload);\n const digest = createHash('sha256').update(json, 'utf8').digest('hex');\n return `sha256:${digest}`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { hashRequest } from '../replay/hash.js';\nimport type { Request, Response } from '../types/provider.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport type { EventBus } from '../kernel/events.js';\n\n/**\n * Surface the OS error code (EACCES, ENOSPC, …) alongside the message in\n * storage.* event payloads. Codes are stable and locale-independent, so\n * they are what dashboards and alerts key on; the message is supplementary.\n */\nfunction storageErrorString(err: unknown): string {\n if (err instanceof Error) {\n const code = (err as NodeJS.ErrnoException).code;\n return code ? `${code}: ${err.message}` : err.message;\n }\n /* v8 ignore next -- defensive: fs/lock failures are always Error instances */\n return String(err);\n}\n\n/**\n * ReplayLogStore — sidecar store for deterministic-replay support\n * (idea #2 from IDEAS.md). One JSONL file per session, recording\n * every provider request/response pair so the same agent loop can\n * be re-run later with frozen API responses.\n *\n * Why a sidecar (not the session JSONL)?\n *\n * Same reason as `AnnotationsStore` — the session log is\n * event-sourced and append-only; a provider request payload can be\n * tens of kilobytes (especially with long conversation history),\n * and we want replay to be opt-in (recorded only when the user\n * runs with `--replay` or a future equivalent). Mixing it into\n * the event log would inflate every read for replay-irrelevant\n * paths.\n *\n * File layout: `<dir>/<sessionId>.replay.jsonl`, one entry per line.\n * Each entry: `{ hash, ts, request, response }`. The `hash` is\n * computed via `hashRequest` so lookups are O(1) by hash.\n *\n * Concurrency: per-session write queue (same pattern as\n * `AnnotationsStore`). Reads are lock-free; the write chain makes\n * the append + rehash sequence atomic.\n */\nexport interface ReplayEntry {\n hash: string;\n ts: string;\n request: Request;\n response: Response;\n}\n\nconst FILE_VERSION = 1;\n\n/** Default cap on the number of entries per session. */\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport interface ReplayLogStoreOptions {\n /** Directory where `<sessionId>.replay.jsonl` files live. */\n dir: string;\n /**\n * Cap on the number of entries per session. When a `record` would\n * push the file beyond this, the oldest entries are evicted (LRU\n * by insertion order). Set to `Infinity` to disable rotation.\n * Defaults to 1000 — a single LLM call averages ~5KB serialized\n * (messages + tools + response), so 1000 entries is ~5MB per\n * session which is a reasonable upper bound.\n */\n maxEntries?: number | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class ReplayLogStore {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n private readonly writeChains = new Map<string, Promise<void>>();\n /** Per-session hash → entry index, kept in memory after the first load. */\n private readonly cache = new Map<string, Map<string, ReplayEntry>>();\n /** Per-session entry count on disk, to detect when compaction is needed. */\n private readonly diskCount = new Map<string, number>();\n private readonly maxEntries: number;\n\n constructor(opts: ReplayLogStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n // ── Writes ──────────────────────────────────────────────────────────────\n\n /**\n * Record a request/response pair. Idempotent on hash: a second\n * `record` for the same hash is a no-op (the existing entry wins).\n * Returns the hash.\n */\n async record(input: {\n sessionId: string;\n request: Request;\n response: Response;\n }): Promise<string> {\n const hash = hashRequest(input.request);\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n // Dedup via the in-memory hash map — O(1) instead of re-reading\n // and re-parsing the whole JSONL just to run `entries.some(...)`.\n // `ensureCache` populates both the cache and `diskCount` from a\n // single read on first contact; subsequent records reuse it.\n const cache = await this.ensureCache(input.sessionId);\n if (cache.has(hash)) return; // already recorded\n\n const entry: ReplayEntry = {\n hash,\n ts: new Date().toISOString(),\n request: input.request,\n response: input.response,\n };\n\n const currentCount = this.diskCount.get(input.sessionId) ?? 0;\n const willEvict = currentCount + 1 > this.maxEntries;\n\n if (!willEvict) {\n // Common path (the first `maxEntries` writes per session, plus\n // any session that never hits the cap): a single O(1) append.\n // The previous implementation did a full readAll + full rewrite\n // (atomicWrite of the entire file) on every single record, which\n // was quadratic in session length — a 1000-call session rewrote\n // a multi-MB file 1000 times.\n await fs.appendFile(fp, JSON.stringify(entry) + '\\n', 'utf8');\n cache.set(hash, entry);\n this.diskCount.set(input.sessionId, currentCount + 1);\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'record',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return;\n }\n\n // Eviction path: we're at capacity, drop the oldest entry to make\n // room. This does require a full read + rewrite, but it fires at\n // most once per `maxEntries` writes (default 1000), not per write.\n const all = await this.readAll(input.sessionId);\n all.push(entry);\n const keep = all.slice(-this.maxEntries);\n const refreshed = new Map<string, ReplayEntry>();\n for (const e of keep) refreshed.set(e.hash, e);\n this.cache.set(input.sessionId, refreshed);\n this.diskCount.set(input.sessionId, keep.length);\n await this.writeAll(input.sessionId, keep, 'compact');\n });\n });\n return hash;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'record',\n outcome: 'failure',\n error: storageErrorString(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Reads ───────────────────────────────────────────────────────────────\n\n /**\n * Look up an entry by hash. Returns `null` when the request has\n * not been recorded for this session. O(1) after the first call\n * per session (in-memory cache).\n */\n async lookup(sessionId: string, hash: string): Promise<ReplayEntry | null> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const cache = await this.ensureCache(sessionId);\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'lookup',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return cache.get(hash) ?? null;\n } catch (err) {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'lookup',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /** All recorded entries for a session, in insertion order. */\n async load(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const cache = await this.ensureCache(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'load',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return [...cache.values()];\n } catch (err) {\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'load',\n outcome: 'failure',\n durationMs,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * List every session id that has a replay log in the store dir.\n * Returns an array of `{ sessionId, entryCount, path }` sorted\n * by sessionId for stable output. Used by `wstack replay --list`.\n */\n async list(): Promise<Array<{ sessionId: string; entryCount: number; path: string }>> {\n const out: Array<{ sessionId: string; entryCount: number; path: string }> = [];\n // Replay logs sit next to their session JSONL — flat at the root for\n // legacy/`record-<ts>` ids, inside a date-shard dir for modern ids.\n // Scan both levels; a root-only scan misses every sharded session.\n const scan = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if (depth === 0 && (err as NodeJS.ErrnoException).code !== 'ENOENT') {\n // EACCES, ENOTDIR, etc. — log the real error so the operator can\n // diagnose a misconfiguration, but still return empty list so the\n // caller (slash command display) doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'replay_log_store.list_readdir_failed',\n dir,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n if (depth === 0) await scan(path.join(dir, entry.name), entry.name, depth + 1);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.replay.jsonl')) continue;\n const base = entry.name.slice(0, -'.replay.jsonl'.length);\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const fp = path.join(dir, entry.name);\n out.push({\n sessionId,\n entryCount: await this.countEntries(fp),\n path: fp,\n });\n }\n };\n await scan(this.dir, '', 0);\n return out.sort((a, b) => a.sessionId.localeCompare(b.sessionId));\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // the moment a real (sharded) session id is used for --replay.\n return sessionScopedPath(this.dir, sessionId, '.replay.jsonl');\n }\n\n private async countEntries(filePath: string): Promise<number> {\n // list() only needs a count, not provider request/response payloads. Count\n // non-empty JSONL rows in fixed-size chunks so large replay logs are not\n // parsed or materialized just to render `wstack replay --list`.\n const handle = await fs.open(filePath, 'r');\n const buffer = Buffer.allocUnsafe(64 * 1024);\n let count = 0;\n let hasNonWhitespace = false;\n try {\n while (true) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);\n if (bytesRead === 0) break;\n for (let i = 0; i < bytesRead; i++) {\n const ch = buffer[i]!;\n if (ch === 10) {\n if (hasNonWhitespace) count++;\n hasNonWhitespace = false;\n continue;\n }\n if (ch !== 13 && ch !== 32 && ch !== 9) {\n hasNonWhitespace = true;\n }\n }\n }\n } finally {\n await handle.close();\n }\n if (hasNonWhitespace) count++;\n return count;\n }\n\n private async readAll(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: ReplayEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<\n { version?: number | undefined; entry?: ReplayEntry | undefined } & ReplayEntry\n >(line);\n if (!parsed.ok || !parsed.value) continue;\n // Forward-compat: v1 stores entries one per line, no envelope.\n // A future \"v2\" could wrap with `{version, entries:[...]}`;\n // the loader would then branch on `parsed.version`.\n if ('entry' in parsed.value && parsed.value.entry) {\n out.push(parsed.value.entry);\n } else {\n out.push(parsed.value);\n }\n } catch {\n // Skip a corrupt line — annotations-store and other sidecar\n // stores take the same approach (meta-data, not fatal).\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Non-ENOENT errors (EACCES, ENOSPC, etc.) are real I/O failures —\n // re-throw so callers can emit storage.error.\n throw err;\n }\n }\n\n private async writeAll(\n sessionId: string,\n entries: ReplayEntry[],\n operation: 'record' | 'compact' = 'record',\n ): Promise<void> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n const body = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n await atomicWrite(fp, body);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation,\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n // Drop the version-stamp comment at the top — v1 has no envelope,\n // but we keep a one-line marker for human readers / future tooling.\n // (The atomicWrite just wrote pure JSONL; that's correct for v1.)\n void FILE_VERSION;\n }\n\n private async ensureCache(sessionId: string): Promise<Map<string, ReplayEntry>> {\n let cache = this.cache.get(sessionId);\n if (cache) return cache;\n const all = await this.readAll(sessionId);\n cache = new Map();\n for (const e of all) cache.set(e.hash, e);\n this.cache.set(sessionId, cache);\n this.diskCount.set(sessionId, all.length);\n return cache;\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SessionEvent } from '../types/session.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * Idea #1 from IDEAS.md — Stateful Session Recovery.\n *\n * `SessionRecovery` is the read-side companion to the in-flight\n * marker mechanism. When the agent loop is running, it writes an\n * `in_flight_start` event at the current point in the log. On\n * clean shutdown, a matching `in_flight_end` follows. If the\n * process dies (crash, OOM, machine sleep, SIGKILL) the marker\n * is the last event in the file — and `detectStale` flags the\n * session as \"incomplete, can be resumed\".\n *\n * Phase 1 of this feature is **detection only**. The actual\n * re-execution of incomplete work is a follow-up: it requires\n * tracking pending tool calls, mid-stream LLM responses, and\n * uncommitted file changes — and re-running the agent loop from\n * the last `checkpoint` event. The detection layer is independent\n * and ships first because (a) it gives the user immediate\n * visibility into what died, and (b) it's the foundation for the\n * resume command and the CLI's \"Incomplete sessions\" surface.\n *\n * Concurrency: pure read; no writes. Safe to call from multiple\n * processes simultaneously.\n */\nexport interface StaleSession {\n sessionId: string;\n /** Path to the JSONL log. */\n path: string;\n /** Last event ts (the in_flight_start timestamp). */\n lastEventTs: string;\n /** Context the agent was working on when it died. */\n context: string;\n /** Total events in the log. */\n eventCount: number;\n}\n\nexport interface RecoveryPlan {\n sessionId: string;\n /** True if the session is stale (has a dangling in_flight_start). */\n stale: boolean;\n /** The last `checkpoint` event before the un-replayed work, or null. */\n lastCheckpoint: SessionEvent | null;\n /** All events after the last checkpoint (i.e. the work that needs re-execution). */\n pendingEvents: SessionEvent[];\n /** The dangling in_flight_start event, if any. */\n inFlightStart: SessionEvent | null;\n /** Free-form context the agent was working on, if any. */\n context: string | null;\n}\n\n/**\n * Result of `SessionRecovery.recover(sessionId)`. Distinct from\n * `StaleSession`: a session is \"stale\" if the last event is an\n * open marker, but a \"recovery plan\" can also be generated for\n * clean sessions whose last checkpoint is older than the\n * conversation history (e.g. a user-initiated \"rewind to last\n * good state\" flow). Phase 2 of idea #1: this returns the plan;\n * the actual kernel re-execution is a follow-up.\n */\nexport class SessionRecovery {\n /**\n * Scan a session log and return a `StaleSession` if and only\n * if the last event is an `in_flight_start` without a matching\n * `in_flight_end`. Returns `null` when:\n * - the log does not exist;\n * - the log is empty;\n * - the last event is `in_flight_end` (clean shutdown);\n * - the last event is something else (e.g. an unannotated\n * legacy log without in-flight markers).\n */\n async detectStale(sessionId: string): Promise<StaleSession | null> {\n const fp = this.filePath(sessionId);\n // Only read the last ~8KB — enough for several large events.\n // This is O(1) I/O vs O(n) of reading the entire file.\n const TAIL_SIZE = 8192;\n let stat;\n try {\n stat = await fs.stat(fp);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n /* v8 ignore next -- defensive: any other stat failure is also non-recoverable */\n return null;\n }\n if (stat.size === 0) return null;\n const position = Math.max(0, stat.size - TAIL_SIZE);\n const buf = Buffer.alloc(TAIL_SIZE);\n let fh;\n try {\n fh = await fs.open(fp, 'r');\n const { bytesRead } = await fh.read(buf, 0, TAIL_SIZE, position);\n // Count total events for StaleSession.eventCount — requires full scan.\n // For very large files this is a trade-off; count is informational.\n let eventCount = 0;\n const raw = buf.subarray(0, bytesRead).toString('utf8');\n for (const line of raw.split('\\n')) {\n if (line.trim()) eventCount++;\n }\n // Find the last complete JSON line in the tail.\n const lines = raw.split('\\n').filter((l) => l.trim());\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const ev = JSON.parse(expectDefined(lines[i])) as SessionEvent;\n if (ev.type === 'in_flight_start') {\n return {\n sessionId,\n path: fp,\n lastEventTs: ev.ts,\n context: ev.context,\n eventCount,\n };\n }\n // Found a different last event — clean shutdown or legacy\n return null;\n } catch {\n // Incomplete line (spans the read boundary) — skip\n }\n }\n return null;\n /* v8 ignore start -- defensive: tail open/read failure after a successful stat is rare */\n } catch {\n return null;\n } finally {\n if (fh) await fh.close();\n }\n /* v8 ignore stop */\n }\n\n /**\n * Generate a recovery plan for a session. The plan describes\n * \"what would be re-executed\" if the user chose to resume —\n * everything after the last `checkpoint` event, plus the\n * dangling in-flight marker if present.\n *\n * Returns a non-null plan for ANY session that has at least\n * one event after a checkpoint (or, for legacy sessions, at\n * least one event). Pure read; no mutation.\n */\n async recover(sessionId: string): Promise<RecoveryPlan | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n /* v8 ignore next -- defensive: any other read failure is also non-recoverable */\n return null;\n }\n const events: SessionEvent[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n if (events.length === 0) return null;\n // Find the last checkpoint.\n let lastCheckpoint: SessionEvent | null = null;\n let lastCheckpointIdx = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i]?.type === 'checkpoint') {\n lastCheckpoint = expectDefined(events[i]);\n lastCheckpointIdx = i;\n }\n }\n // Events after the last checkpoint = the work that needs re-execution.\n const pendingEvents =\n lastCheckpointIdx >= 0 ? events.slice(lastCheckpointIdx + 1) : events;\n // The dangling in_flight_start, if the last event is one.\n const lastEv = expectDefined(events[events.length - 1]);\n const inFlightStart =\n lastEv.type === 'in_flight_start' ? lastEv : null;\n const context = inFlightStart && inFlightStart.type === 'in_flight_start'\n ? inFlightStart.context\n : null;\n return {\n sessionId,\n stale: inFlightStart !== null,\n lastCheckpoint,\n pendingEvents,\n inFlightStart,\n context,\n };\n }\n\n /**\n * List every stale session in a directory. Returns an array\n * (possibly empty) sorted by `lastEventTs` descending — most\n * recent crash first.\n */\n async listResumable(): Promise<StaleSession[]> {\n const out: StaleSession[] = [];\n // Modern sessions live inside date-shard subdirectories\n // (\"2026-06-11/<base>.jsonl\"); legacy/flat sessions sit at the root.\n // Scan both — a root-only scan silently misses every modern crash.\n const collect = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n /* v8 ignore start -- defensive: the sessions dir (and its shards) are readable during a scan */\n } catch {\n return;\n }\n /* v8 ignore stop */\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (\n entry.name === 'shared' ||\n entry.name === 'subagents' ||\n entry.name === 'attachments'\n )\n continue;\n if (entry.isDirectory()) {\n if (depth === 0) {\n await collect(path.join(dir, entry.name), entry.name, depth + 1);\n }\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.jsonl')) continue;\n if (entry.name === '_index.jsonl' || entry.name === '_mailbox.jsonl') continue;\n const base = entry.name.slice(0, -'.jsonl'.length);\n if (base.includes('.replay') || base.includes('.annotations') || base.includes('.audit'))\n continue;\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const stale = await this.detectStale(sessionId);\n if (stale) out.push(stale);\n }\n };\n await collect(this.dir, '', 0);\n return out.sort((a, b) => b.lastEventTs.localeCompare(a.lastEventTs));\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. Shared with the other per-session\n // sidecar stores so the contract can't drift.\n return sessionScopedPath(this.dir, sessionId, '.jsonl');\n }\n\n constructor(private readonly dir: string) {}\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { withFileLock } from '../utils/atomic-write.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport type { EventBus } from '../kernel/events.js';\n/**\n * ToolAuditLog — idea #9 from IDEAS.md.\n *\n * Tamper-evident audit trail for tool calls. Every tool_use /\n * tool_result pair is appended to a sidecar JSONL with a chained\n * SHA-256 — each entry's `prevHash` is the prior entry's `hash`,\n * so any post-hoc modification of a single line breaks the chain\n * from that point forward.\n *\n * Why a sidecar (not the session JSONL)?\n * Same reason as `AnnotationsStore` and `ReplayLogStore`: the\n * session log is an event-sourced journal. Mixing in a hash\n * chain would inflate every read and tightly couple the\n * integrity check to the event format. Sidecar keeps both\n * concerns orthogonal.\n *\n * What \"tamper-evident\" means here:\n * - The hash covers the full serialized entry: tool name, id,\n * input, output, timestamp, author. Changing any byte\n * changes the hash.\n * - The chain is sequential — a verifier walks the file in\n * order, recomputing each hash, and checks `prevHash`\n * matches the previous entry's `hash`.\n * - Any insertion, deletion, or modification of a single\n * entry surfaces as a \"chain broken at entry N\" verdict.\n *\n * What it does NOT defend against:\n * - An attacker who rewrites the whole file consistently.\n * For that you'd need an external anchor (signing key,\n * transparency log, etc.) — out of scope for Phase 1.\n * - The agent itself misbehaving; this is post-hoc audit, not\n * real-time enforcement. Use `PermissionPolicy` for that.\n *\n * File layout: `<dir>/<sessionId>.audit.jsonl`, one entry per\n * line. The chain starts with a `genesis` entry whose\n * `prevHash` is all zeros.\n */\nexport interface AuditEntry {\n /** Monotonic index (0-based). */\n index: number;\n /** UUID for cross-referencing with logs. */\n id: string;\n /** ISO timestamp. */\n ts: string;\n /** Hash of the previous entry (or all-zeros for the genesis entry). */\n prevHash: string;\n /** Hash of this entry's content (sha256 over the canonical JSON). */\n hash: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n}\n\nconst GENESIS_PREV = '0'.repeat(64);\n\nexport type VerifyResult =\n | { ok: true; entries: number }\n | { ok: false; brokenAt: number; reason: string };\n\nexport interface ToolAuditLogOptions {\n /** Directory where `<sessionId>.audit.jsonl` files live. */\n dir: string;\n /**\n * Flush the file system cache to disk every N writes per session.\n * Default 100. Lower values = better crash durability, more I/O overhead.\n * Set to `Infinity` to disable periodic fsync (fastest, but highest data-loss risk).\n */\n fsyncEvery?: number | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\n/** Default number of writes between fsync calls. */\nconst DEFAULT_FSYNC_EVERY = 100;\n\nexport class ToolAuditLog {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n /** In-memory cache of the last entry's hash (per session), to compute chains efficiently. */\n private readonly tailHash = new Map<string, string>();\n /** In-memory counter for entry indices — avoids re-reading the file on every write. */\n private readonly tailIndex = new Map<string, number>();\n /**\n * File mtime+size recorded after our last write, per session. Used to\n * detect cross-process writes (session handoff, recovery) that would\n * invalidate the in-memory tail cache: if the stat no longer matches\n * we re-read the file to re-establish the chain tip before appending.\n */\n private readonly tailStat = new Map<string, { mtimeMs: number; size: number }>();\n /** Tracks writes since last fsync, per session. */\n private readonly unSyncedWrites = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly fsyncEvery: number;\n\n constructor(opts: ToolAuditLogOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n this.fsyncEvery = opts.fsyncEvery ?? DEFAULT_FSYNC_EVERY;\n }\n\n /**\n * Append a tool call/result pair to the chain. Returns the\n * resulting entry. Idempotency is not guaranteed — if you\n * record the same tool_use twice you get two entries. That's\n * intentional: the audit log is a record, not a cache.\n */\n async record(input: {\n sessionId: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n }): Promise<AuditEntry> {\n let entry!: AuditEntry; // assigned inside the enqueue callback\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n // Resolve the chain tip from the in-memory cache when possible,\n // re-reading the file only on first contact or when an external\n // writer (cross-process session handoff) changed it under us.\n // The previous implementation did `readAll` on every single\n // record just to find `entries.at(-1)` — a full parse of the\n // audit file per tool call.\n const tip = await this._resolveChainTip(input.sessionId, fp);\n const prevHash = tip.prevHash;\n const index = tip.nextIndex;\n\n const id = randomUUID();\n const ts = new Date().toISOString();\n const content = {\n id,\n ts,\n prevHash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n const hash = createHash('sha256').update(stableStringify(content), 'utf8').digest('hex');\n entry = {\n id,\n ts,\n prevHash,\n hash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n\n // True O(1) append — one line, no full-file rewrite. The previous\n // `writeAll(entries)` path re-serialized every entry on every\n // record; a 1000-call session rewrote a multi-MB audit file 1000\n // times (quadratic in session length). `withFileLock` above\n // guarantees no concurrent writer interleaves with our append.\n await fs.appendFile(fp, JSON.stringify(entry) + '\\n', 'utf8');\n\n // Refresh caches + fsync bookkeeping. We stat post-write so the\n // mtime+size tracker reflects the just-appended line — the next\n // record can trust the cache without re-reading.\n try {\n const st = await fs.stat(fp);\n this.tailStat.set(input.sessionId, { mtimeMs: st.mtimeMs, size: st.size });\n } catch {\n /* best-effort; next record will just re-read */\n }\n this.tailHash.set(input.sessionId, hash);\n this.tailIndex.set(input.sessionId, index + 1);\n await this._trackUnsynced(input.sessionId, fp);\n\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'record',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n });\n });\n return entry;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'record',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Resolve the chain tip (previous hash + next index) for an append.\n * Uses the in-memory `tailHash`/`tailIndex` cache when the file's\n * stat matches our last known write; falls back to a full read on\n * cache miss or when an external writer has extended the file.\n */\n private async _resolveChainTip(\n sessionId: string,\n fp: string,\n ): Promise<{ prevHash: string; nextIndex: number }> {\n const cachedHash = this.tailHash.get(sessionId);\n const cachedIndex = this.tailIndex.get(sessionId);\n const cachedStat = this.tailStat.get(sessionId);\n\n if (cachedHash !== undefined && cachedIndex !== undefined && cachedStat) {\n // Verify no other process appended since our last write. Stat is a\n // single inode lookup; the common case (same-process sequential\n // writes) returns immediately and we skip the full read.\n try {\n const st = await fs.stat(fp);\n if (st.mtimeMs === cachedStat.mtimeMs && st.size === cachedStat.size) {\n return { prevHash: cachedHash, nextIndex: cachedIndex };\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n // File was removed out from under us — reset and start a new chain.\n this.tailHash.delete(sessionId);\n this.tailIndex.delete(sessionId);\n this.tailStat.delete(sessionId);\n return { prevHash: GENESIS_PREV, nextIndex: 0 };\n }\n /* v8 ignore next -- defensive: a non-ENOENT stat failure during cache-hit is rare */\n throw err;\n }\n }\n\n // Cache miss or external write detected — read the true tail.\n const entries = await this.readAll(sessionId);\n const prev = entries.at(-1);\n const prevHash = prev?.hash ?? GENESIS_PREV;\n const nextIndex = prev ? prev.index + 1 : 0;\n this.tailHash.set(sessionId, prevHash);\n this.tailIndex.set(sessionId, nextIndex);\n try {\n const st = await fs.stat(fp);\n this.tailStat.set(sessionId, { mtimeMs: st.mtimeMs, size: st.size });\n } catch {\n /* leave cache empty; next record re-reads */\n }\n return { prevHash, nextIndex };\n }\n\n /**\n * Walk the chain and verify every entry's hash and prevHash.\n * Returns a structured verdict — never throws.\n */\n async verify(sessionId: string): Promise<VerifyResult> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n let entries: AuditEntry[];\n try {\n entries = await this.readAll(sessionId);\n } catch (err) {\n // The file exists but can't be read (permissions, corruption). We\n // can't verify it, so emit a read failure for observability and\n // degrade gracefully — this method's contract is \"never throws\".\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'verify',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return { ok: true, entries: 0 };\n }\n\n // Walk the chain into a verdict, then emit a single storage.read whose\n // outcome reflects the verification result (a broken chain is a failure).\n const verdict = ((): VerifyResult => {\n if (entries.length === 0) return { ok: true, entries: 0 };\n // The first entry's prevHash must be the all-zeros genesis marker.\n if (entries[0]?.prevHash !== GENESIS_PREV) {\n return {\n ok: false,\n brokenAt: 0,\n reason: 'first entry is not the genesis (prevHash != 0…0)',\n };\n }\n let prevHash = GENESIS_PREV;\n for (let i = 0; i < entries.length; i++) {\n const e = expectDefined(entries[i]);\n if (e.prevHash !== prevHash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `prevHash mismatch at entry ${i} (expected ${prevHash.slice(0, 8)}…, got ${e.prevHash.slice(0, 8)}…)`,\n };\n }\n // Recompute the hash from the entry's content (without the\n // `hash` field itself, which is what we are verifying).\n const content = {\n id: e.id,\n ts: e.ts,\n prevHash: e.prevHash,\n toolName: e.toolName,\n toolUseId: e.toolUseId,\n input: e.input,\n output: e.output,\n isError: e.isError,\n index: e.index,\n };\n const expectedHash = createHash('sha256')\n .update(stableStringify(content), 'utf8')\n .digest('hex');\n if (expectedHash !== e.hash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `hash mismatch at entry ${i} (entry content was modified)`,\n };\n }\n prevHash = e.hash;\n }\n return { ok: true, entries: entries.length };\n })();\n\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'verify',\n outcome: verdict.ok ? 'success' : 'failure',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return verdict;\n }\n\n /** All entries for a session, in insertion order. */\n async load(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const entries = await this.readAll(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'load',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return entries;\n } catch (err) {\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'load',\n outcome: 'failure',\n durationMs,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // for every modern session id the moment record() gets wired in.\n return sessionScopedPath(this.dir, sessionId, '.audit.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: AuditEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<AuditEntry>(line);\n if (parsed.ok && parsed.value) out.push(parsed.value);\n } catch {\n // Skip corrupt lines — audit data is meta, not fatal.\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Non-ENOENT errors (EACCES, ENOSPC, etc.) are real I/O failures —\n // re-throw so callers (verify, load) can emit storage.error.\n throw err;\n }\n }\n\n /**\n * Tracks writes since last fsync and triggers periodic fsync.\n * Called after each O(1) append to maintain the same durability\n * guarantees as the old writeAll approach.\n */\n private async _trackUnsynced(sessionId: string, fp: string): Promise<void> {\n const count = (this.unSyncedWrites.get(sessionId) ?? 0) + 1;\n this.unSyncedWrites.set(sessionId, count);\n if (this.fsyncEvery !== Number.POSITIVE_INFINITY && count % this.fsyncEvery === 0) {\n await this.sync(sessionId, fp);\n }\n }\n\n /**\n * Explicitly sync the file to disk. Called automatically every\n * `fsyncEvery` writes, and available for callers who want to\n * force a sync before closing or during graceful shutdown.\n */\n async flush(sessionId: string): Promise<void> {\n await this.sync(sessionId, this.filePath(sessionId));\n }\n\n private async sync(sessionId: string, fp: string): Promise<void> {\n try {\n const fh = await fs.open(fp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync is best-effort; a failure here does not corrupt the chain.\n } finally {\n this.unSyncedWrites.set(sessionId, 0);\n }\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n","import type { SessionEvent } from '../types/session.js';\n\nexport interface QueryFilter {\n eventTypes?: string[] | undefined;\n toolNames?: string[] | undefined;\n timeRange?: { start: string; end: string } | undefined;\n}\n\nexport interface ToolInvocation {\n ts: string;\n name: string;\n input: unknown;\n output?: unknown | undefined;\n error?: string | undefined;\n durationMs: number;\n}\n\nexport interface SessionError {\n ts: string;\n phase: string;\n message: string;\n}\n\nexport interface ModeChange {\n ts: string;\n from: string;\n to: string;\n}\n\nexport interface TaskSummary {\n taskId: string;\n title: string;\n status: string;\n createdAt: string;\n completedAt?: string | undefined;\n}\n\nexport interface SessionAnalysis {\n sessionId: string;\n totalDuration: number;\n toolUsageCount: Record<string, number>;\n errorCount: number;\n modeChanges: ModeChange[];\n tasks: TaskSummary[];\n}\n\nexport class SessionAnalyzer {\n analyze(events: SessionEvent[]): SessionAnalysis {\n const toolUsageCount: Record<string, number> = {};\n const errors: SessionError[] = [];\n const modeChanges: ModeChange[] = [];\n const tasksById = new Map<string, TaskSummary>();\n let sessionId = '';\n\n for (const event of events) {\n // sessionId comes from session_start / session_resumed.\n if (event.type === 'session_start' || event.type === 'session_resumed') {\n if (!sessionId) sessionId = event.id;\n }\n if (event.type === 'tool_use') {\n toolUsageCount[event.name] = (toolUsageCount[event.name] ?? 0) + 1;\n }\n if (event.type === 'error') {\n errors.push({ ts: event.ts, phase: event.phase, message: event.message });\n }\n if (event.type === 'mode_changed') {\n modeChanges.push({ ts: event.ts, from: event.from, to: event.to });\n }\n if (event.type === 'task_created') {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'created',\n createdAt: event.ts,\n });\n }\n if (event.type === 'task_updated') {\n const t = tasksById.get(event.taskId);\n if (t) t.status = event.status;\n }\n if (event.type === 'task_completed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'completed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'completed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n if (event.type === 'task_failed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'failed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'failed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n }\n\n return {\n sessionId,\n totalDuration: this.calcDuration(events),\n toolUsageCount,\n errorCount: errors.length,\n modeChanges,\n tasks: Array.from(tasksById.values()),\n };\n }\n\n query(events: SessionEvent[], filter: QueryFilter): SessionEvent[] {\n return events.filter((e) => {\n if (filter.eventTypes?.length && !filter.eventTypes.includes(e.type)) return false;\n if (filter.toolNames?.length && e.type === 'tool_use') {\n const toolEvent = e as { type: 'tool_use'; name: string };\n if (!filter.toolNames.includes(toolEvent.name)) return false;\n }\n if (filter.timeRange) {\n const ts = new Date(e.ts).getTime();\n const start = new Date(filter.timeRange.start).getTime();\n const end = new Date(filter.timeRange.end).getTime();\n if (ts < start || ts > end) return false;\n }\n return true;\n });\n }\n\n private calcDuration(events: SessionEvent[]): number {\n if (events.length < 2) return 0;\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n /* v8 ignore next -- defensive: length>=2 guard above guarantees both ends exist */\n if (!firstEvent || !lastEvent) return 0;\n const first = new Date(firstEvent.ts).getTime();\n const last = new Date(lastEvent.ts).getTime();\n return last - first;\n }\n}\n","/**\n * SessionRegistry — cross-process session and agent tracker.\n *\n * Each WrongStack process registers its session on start and updates its\n * status periodically. The registry is a single JSON file at\n * `~/.wrongstack/session-registry.json`. Entries are keyed by session ID.\n *\n * Because multiple processes may write concurrently, every write is an\n * atomic read-modify-write protected by a per-file advisory lock (flock on\n * Unix, exclusive open on Windows). Stale entries (process no longer alive)\n * are pruned on every read.\n *\n * @module session-registry\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\n/** Live status of a single agent within a session. */\nexport type AgentLiveStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user' // brain.ask_human, confirm prompt\n | 'error';\n\nexport interface AgentEntry {\n /** Unique agent id (ULID or UUID). */\n id: string;\n /** Human-readable label (e.g. \"leader\", \"bug-hunter #1\"). */\n name: string;\n status: AgentLiveStatus;\n /** Current tool name if running, undefined otherwise. */\n currentTool?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** Cumulative cost in USD for this agent, when known. */\n costUsd?: number | undefined;\n /** Cumulative input tokens, when known. */\n tokensIn?: number | undefined;\n /** Cumulative output tokens, when known. */\n tokensOut?: number | undefined;\n /** Context window fill 0–100 (may exceed 100 when over limit), when known. */\n ctxPct?: number | undefined;\n /** Model id this agent is running on, when known. */\n model?: string | undefined;\n /**\n * Tail of the assistant text currently being streamed (capped, throttled).\n * Lets a cross-process watcher see the response form in near-real-time\n * instead of waiting for the completed turn to land in the session log.\n */\n partialText?: string | undefined;\n /** UTC ISO timestamp of last activity. */\n lastActivityAt: string;\n}\n\nexport type SessionLiveStatus =\n | 'active' // process running, agents may be idle or busy\n | 'idle' // process running, no agent activity\n | 'closing' // session_end written, process shutting down\n | 'stale'; // process no longer alive (pruned on next read)\n\nexport interface SessionRegistryEntry {\n sessionId: string;\n projectSlug: string;\n projectRoot: string;\n projectName: string;\n workingDir: string;\n /**\n * Which surface owns this session — `'tui'` / `'webui'` / `'cli'` (one-shot or\n * REPL). Lets cross-process consumers (e.g. the WebUI Fleet HQ office map) label\n * each live session by client kind. Optional for back-compat with older entries.\n */\n clientType?: 'tui' | 'webui' | 'cli' | 'repl' | string | undefined;\n /** Current git branch, if the project is a git repo. Detected at registration. */\n gitBranch?: string | undefined;\n status: SessionLiveStatus;\n pid: number;\n /** UTC ISO */\n startedAt: string;\n /** UTC ISO — updated on every heartbeat */\n lastHeartbeatAt: string;\n /** Count of tracked agents */\n agentCount: number;\n agents: AgentEntry[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\nconst REGISTRY_FILE = 'session-registry.json';\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst STALE_TIMEOUT_MS = 30_000; // entry considered stale after 30s without heartbeat\n// A session that announced `closing` (heartbeat stopped) is dropped this long\n// after its last heartbeat, so the fleet view doesn't keep a dead client around.\nconst CLOSING_GRACE_MS = 15_000;\n// A held lock is released within milliseconds; anything older is a crashed\n// owner's leftover and is safe to break so writes never wedge permanently.\nconst STALE_LOCK_MS = 10_000;\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Registry class ────────────────────────────────────────────────────────\n\nexport class SessionRegistry {\n private readonly filePath: string;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private currentSessionId: string | null = null;\n /**\n * Last full entry this process registered. Kept so the heartbeat can\n * re-create our entry if it ever goes missing — e.g. our initial register()\n * write was dropped (a wedged lock), the file was reset, or we were pruned.\n */\n private lastEntry: SessionRegistryEntry | null = null;\n\n constructor(globalRoot: string) {\n this.filePath = path.join(globalRoot, REGISTRY_FILE);\n }\n\n // ── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Register the current session. Call once on session start.\n * Starts the heartbeat timer.\n */\n async register(\n entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {\n agents?: AgentEntry[] | undefined;\n },\n ): Promise<void> {\n // Safe to call again on a project switch: the WebUI re-roots in place and\n // creates a fresh session id pointing at the new project. Clear the prior\n // heartbeat timer (otherwise each switch leaks a timer that keeps writing).\n // A process owns exactly one entry, so the same-pid dedup below drops our\n // own previous entry — the registry never carries a phantom session still\n // pointing at the old project's root/workingDir.\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n this.currentSessionId = entry.sessionId;\n const full: SessionRegistryEntry = {\n ...entry,\n status: 'active',\n lastHeartbeatAt: new Date().toISOString(),\n agentCount: entry.agents?.length ?? 0,\n agents: entry.agents ?? [],\n };\n this.lastEntry = full;\n await this.atomicUpdate((registry) => {\n // Prune dead entries that haven't heartbeated recently.\n // A just-created entry has no heartbeat yet — don't prune it.\n const now = Date.now();\n for (const [id, existing] of Object.entries(registry)) {\n if (existing.pid === entry.pid) {\n // Our own process owns exactly one entry. When re-registering under\n // a new session id (project switch re-roots in place), drop the\n // stale same-pid entry so it doesn't linger pointing at the old\n // project's root/workingDir.\n if (id !== entry.sessionId) delete registry[id];\n continue;\n }\n const heartbeatAge = now - new Date(existing.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(existing.pid)) {\n delete registry[id];\n }\n }\n registry[entry.sessionId] = full;\n });\n\n // Start heartbeat\n this.heartbeatTimer = setInterval(() => {\n void this.heartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n if (this.heartbeatTimer.unref) this.heartbeatTimer.unref();\n }\n\n /**\n * Update agent status for the current session. Call on every\n * significant status change (agent start, tool start, user wait, error).\n */\n async updateAgents(agents: AgentEntry[]): Promise<void> {\n if (!this.currentSessionId) return;\n // Derive session status from the agent collective.\n const hasRunning = agents.some((a) => a.status === 'running' || a.status === 'streaming');\n const hasWaiting = agents.some((a) => a.status === 'waiting_user');\n const hasError = agents.some((a) => a.status === 'error');\n const status: SessionLiveStatus = hasRunning || hasWaiting || hasError ? 'active' : 'idle';\n const nowIso = new Date().toISOString();\n\n // Keep the cached entry current so a heartbeat re-insert carries live agents.\n if (this.lastEntry) {\n this.lastEntry.agents = agents;\n this.lastEntry.agentCount = agents.length;\n this.lastEntry.status = status;\n this.lastEntry.lastHeartbeatAt = nowIso;\n }\n\n await this.atomicUpdate((registry) => {\n let entry = registry[this.currentSessionId!];\n if (!entry) {\n // Our entry vanished (dropped write / reset / pruned) — re-create it.\n if (!this.lastEntry) return;\n entry = { ...this.lastEntry };\n registry[this.currentSessionId!] = entry;\n }\n entry.agents = agents;\n entry.agentCount = agents.length;\n entry.status = status;\n entry.lastHeartbeatAt = nowIso;\n });\n }\n\n /**\n * Mark the session as closing. Called during shutdown.\n * Stops the heartbeat timer.\n */\n async markClosing(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.status = 'closing';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Remove the current session from the registry. Call on clean exit.\n */\n async unregister(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n const sid = this.currentSessionId;\n this.currentSessionId = null;\n await this.atomicUpdate((registry) => {\n delete registry[sid];\n });\n }\n\n /**\n * List all non-stale sessions. Prunes stale entries automatically.\n */\n async list(): Promise<SessionRegistryEntry[]> {\n const registry = await this.readAndPrune();\n return Object.values(registry);\n }\n\n /**\n * Get a single session entry by ID. Returns undefined if not found or stale.\n */\n async get(sessionId: string): Promise<SessionRegistryEntry | undefined> {\n const registry = await this.readAndPrune();\n return registry[sessionId];\n }\n\n /**\n * List all sessions for a specific project (by slug).\n */\n async listByProject(projectSlug: string): Promise<SessionRegistryEntry[]> {\n const all = await this.list();\n return all.filter((e) => e.projectSlug === projectSlug);\n }\n\n /**\n * Return the registry file path. Useful for WebUI to watch/read.\n */\n get registryPath(): string {\n return this.filePath;\n }\n\n // ── Internal ────────────────────────────────────────────────────────────\n\n private async heartbeat(): Promise<void> {\n if (!this.currentSessionId) return;\n try {\n const sessionId = this.currentSessionId;\n const nowIso = new Date().toISOString();\n await this.atomicUpdate((registry) => {\n const entry = registry[sessionId];\n if (entry) {\n entry.lastHeartbeatAt = nowIso;\n // Status bound: if closing, don't revert\n if (entry.status !== 'closing') {\n const hasRunning = (entry.agents ?? []).some(\n (a) => a.status === 'running' || a.status === 'streaming',\n );\n entry.status = hasRunning ? 'active' : 'idle';\n }\n return;\n }\n if (this.lastEntry) {\n // Our entry is gone (initial register() dropped on a wedged lock, file\n // reset, or pruned). Re-create it through the locked path so a process\n // that booted into a broken registry still shows up once it heals.\n registry[sessionId] = { ...this.lastEntry, lastHeartbeatAt: nowIso };\n }\n });\n } catch {\n // Best-effort heartbeat — never throw\n }\n }\n\n private async readAndPrune(): Promise<Record<string, SessionRegistryEntry>> {\n try {\n const raw = await fs.readFile(this.filePath, 'utf8');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const now = Date.now();\n let pruned = false;\n\n for (const [id, entry] of Object.entries(registry)) {\n const heartbeatAge = now - new Date(entry.lastHeartbeatAt).getTime();\n // Cleanly-closed session: drop after a short grace (handles both a fully\n // exited process and one still alive but done) so no dead client lingers.\n if (entry.status === 'closing' && heartbeatAge > CLOSING_GRACE_MS) {\n delete registry[id];\n pruned = true;\n continue;\n }\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(entry.pid)) {\n entry.status = 'stale';\n // Keep stale entries for 5 minutes so UIs can show \"recently closed\"\n const startedAge = now - new Date(entry.startedAt).getTime();\n if (startedAge > 5 * 60_000) {\n delete registry[id];\n pruned = true;\n }\n }\n }\n\n if (pruned) {\n await this.writeAtomic(registry).catch(() => undefined);\n }\n\n return registry;\n } catch {\n return {};\n }\n }\n\n private async atomicUpdate(\n fn: (registry: Record<string, SessionRegistryEntry>) => void,\n ): Promise<void> {\n const lockPath = `${this.filePath}.lock`;\n const maxRetries = 8;\n const retryDelayMs = 20;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n // Acquire exclusive lock via O_CREAT | O_EXCL\n let lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n if (!lockHandle) {\n // Lock contended. A crashed process can leave its lock file behind\n // forever (the `finally` unlink never ran), which would wedge EVERY\n // future write — the registry silently stops updating. Break the lock\n // when its owner pid is dead or it has been held implausibly long\n // (legit holds are sub-millisecond), then retry the open once.\n if (await this.breakStaleLock(lockPath)) {\n lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n }\n if (!lockHandle) {\n await new Promise((r) => setTimeout(r, retryDelayMs * (attempt + 1)));\n continue;\n }\n }\n\n try {\n // Stamp the owner pid so other processes can detect a stale lock.\n await lockHandle.writeFile(String(process.pid)).catch(() => undefined);\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n fn(registry);\n await this.writeAtomicLocked(registry);\n return; // success\n } finally {\n await lockHandle.close();\n await fs.unlink(lockPath).catch(() => undefined);\n }\n } catch {\n // Best-effort — never throw from registry writes\n return;\n }\n }\n // All retries exhausted — registry update dropped (non-critical)\n }\n\n /**\n * Break a contended lock if it is stale: the recorded owner pid is no longer\n * alive, or the lock is older than {@link STALE_LOCK_MS}. Returns true when the\n * lock was removed (caller should retry acquisition). Best-effort and\n * race-tolerant — a fresh lock (age ~0, live owner) is never broken, so the\n * common concurrent case self-heals on the next heartbeat.\n */\n private async breakStaleLock(lockPath: string): Promise<boolean> {\n try {\n const [stat, content] = await Promise.all([\n fs.stat(lockPath),\n fs.readFile(lockPath, 'utf8').catch(() => ''),\n ]);\n const ageMs = Date.now() - stat.mtimeMs;\n const ownerPid = Number.parseInt(content.trim(), 10);\n const ownerDead =\n Number.isInteger(ownerPid) && ownerPid > 0 && ownerPid !== process.pid && !pidAlive(ownerPid);\n if (ownerDead || ageMs > STALE_LOCK_MS) {\n await fs.unlink(lockPath).catch(() => undefined);\n return true;\n }\n return false;\n } catch {\n // stat failed → the lock vanished underneath us; let the caller retry.\n return true;\n }\n }\n\n private async writeAtomicLocked(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n\n /** Legacy write without lock — used by heartbeat for performance. */\n private async writeAtomic(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n }\n}\n\n/** Singleton — created once per process. */\nlet _instance: SessionRegistry | null = null;\n\nexport function getSessionRegistry(globalRoot?: string): SessionRegistry {\n if (!_instance && globalRoot) {\n _instance = new SessionRegistry(globalRoot);\n }\n if (!_instance) {\n throw new Error('SessionRegistry not initialized. Call getSessionRegistry(globalRoot) first.');\n }\n return _instance;\n}\n\nexport function hasSessionRegistry(): boolean {\n return _instance !== null;\n}\n","/**\n * AgentStatusTracker — subscribes to EventBus events and keeps the\n * SessionRegistry updated with live agent status.\n *\n * Created once per process during boot. Listens for:\n * - agent.run.started / agent.run.completed → agent status changes\n * - tool.started / tool.executed → current tool tracking\n * - brain.ask_human → waiting_user status\n * - fleet events (subagent spawn/start/done) → agent entries\n *\n * @module agent-status-tracker\n */\nimport type { EventBus } from './kernel/events.js';\nimport type {\n AgentEntry,\n AgentLiveStatus,\n SessionRegistry,\n} from './session-registry.js';\n\n/** A finished (idle/error) subagent older than this is reaped from the fleet view. */\nconst AGENT_REAP_MS = 30_000;\n/** How often the reaper sweeps for finished subagents. */\nconst AGENT_SWEEP_INTERVAL_MS = 10_000;\n/** Max chars of streamed assistant text kept in the registry (the live tail). */\nconst PARTIAL_TEXT_CAP = 1200;\n/** Min gap between registry flushes triggered purely by streamed text. */\nconst PARTIAL_FLUSH_THROTTLE_MS = 300;\n\nexport interface AgentStatusTrackerOptions {\n events: EventBus;\n registry: SessionRegistry;\n /** Leader agent name shown in the registry. Default: \"leader\". */\n leaderName?: string | undefined;\n /**\n * Best-effort callback fired after each registry write settles. Used to nudge\n * local WebUI servers (FleetNotifier) so cross-process status reaches the map\n * without waiting on their file-watch/poll. Never block or throw.\n */\n onUpdate?: (() => void) | undefined;\n}\n\nexport class AgentStatusTracker {\n private readonly events: EventBus;\n private readonly registry: SessionRegistry;\n private readonly leaderName: string;\n\n // Live agent map: agentId → AgentEntry\n private agents = new Map<string, AgentEntry>();\n\n // Leader tracking\n private leaderStatus: AgentLiveStatus = 'idle';\n private leaderCurrentTool: string | undefined;\n private leaderIterations = 0;\n private leaderToolCalls = 0;\n private leaderCostUsd = 0;\n private leaderTokensIn = 0;\n private leaderTokensOut = 0;\n private leaderCtxPct: number | undefined;\n private leaderModel: string | undefined;\n private leaderPartialText = '';\n\n private unsubscribers: Array<() => void> = [];\n private readonly onUpdate: (() => void) | undefined;\n private sweepTimer: ReturnType<typeof setInterval> | null = null;\n private partialTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(opts: AgentStatusTrackerOptions) {\n this.events = opts.events;\n this.registry = opts.registry;\n this.leaderName = opts.leaderName ?? 'leader';\n this.onUpdate = opts.onUpdate;\n }\n\n start(): void {\n // Leader events\n this.unsubscribers.push(\n this.events.onPattern('agent.run.started', () => {\n this.leaderStatus = 'running';\n this.leaderIterations++;\n this.flush();\n }),\n );\n\n // Capture the leader's model + context fill from each iteration's context.\n this.unsubscribers.push(\n this.events.onPattern('iteration.started', (_e, payload) => {\n const ctx = (payload as { ctx?: { model?: string; tokenCount?: number; maxContext?: number } } | undefined)?.ctx;\n if (!ctx) return;\n if (ctx.model) this.leaderModel = ctx.model;\n if (typeof ctx.tokenCount === 'number' && typeof ctx.maxContext === 'number' && ctx.maxContext > 0) {\n this.leaderCtxPct = Math.round((ctx.tokenCount / ctx.maxContext) * 100);\n }\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.completed', () => {\n this.leaderStatus = 'idle';\n this.leaderCurrentTool = undefined;\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.error', () => {\n this.leaderStatus = 'error';\n this.leaderCurrentTool = undefined;\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n // Tool events — track current tool\n this.unsubscribers.push(\n this.events.onPattern('tool.started', (_event, payload) => {\n const p = payload as { name?: string } | undefined;\n if (p?.name) {\n this.leaderCurrentTool = p.name;\n this.leaderToolCalls++;\n }\n this.leaderStatus = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('tool.executed', () => {\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Brain ask_human → waiting for user input\n this.unsubscribers.push(\n this.events.onPattern('brain.ask_human', () => {\n this.leaderStatus = 'waiting_user';\n this.flush();\n }),\n );\n\n // Streaming events\n this.unsubscribers.push(\n this.events.onPattern('llm.stream_started', () => {\n this.leaderStatus = 'streaming';\n // A new response is starting — drop the previous turn's live tail.\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n // Live assistant text — accumulate the streamed tail so a cross-process\n // watcher sees the response form. Flushed on a throttle, NOT per token\n // (text_delta fires once per chunk → would thrash the shared registry).\n this.unsubscribers.push(\n this.events.onPattern('provider.text_delta', (_e, payload) => {\n const text = (payload as { text?: string } | undefined)?.text;\n if (!text) return;\n this.leaderStatus = 'streaming';\n const next = this.leaderPartialText + text;\n this.leaderPartialText =\n next.length > PARTIAL_TEXT_CAP ? next.slice(next.length - PARTIAL_TEXT_CAP) : next;\n this.schedulePartialFlush();\n }),\n );\n\n // Leader token + cost accounting (per provider call — accumulate).\n this.unsubscribers.push(\n this.events.onPattern('token.accounted', (_e, payload) => {\n const p = payload as\n | { usage?: { input?: number; output?: number }; cost?: { total?: number } }\n | undefined;\n if (!p) return;\n this.leaderTokensIn += p.usage?.input ?? 0;\n this.leaderTokensOut += p.usage?.output ?? 0;\n this.leaderCostUsd += p.cost?.total ?? 0;\n this.flush();\n }),\n );\n\n // ── Subagent tracking ──────────────────────────────────────────────\n // These are the real fleet lifecycle events (emitted by MultiAgentHost /\n // the subagent runner / director). The previous code listened to a\n // `fleet.subagent.*` namespace that nothing emits, so subagents never\n // reached the registry — only the leader showed up.\n const touch = (id: string): AgentEntry => {\n let entry = this.agents.get(id);\n if (!entry) {\n entry = { id, name: id, status: 'idle', iterations: 0, toolCalls: 0, lastActivityAt: new Date().toISOString() };\n this.agents.set(id, entry);\n }\n entry.lastActivityAt = new Date().toISOString();\n return entry;\n };\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.spawned', (_e, payload) => {\n const p = payload as { subagentId?: string; name?: string; model?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.name = p.name?.trim() || entry.name;\n if (p.model) entry.model = p.model;\n entry.status = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.ctx_pct', (_e, payload) => {\n const p = payload as { subagentId?: string; load?: number } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n if (typeof p.load === 'number') entry.ctxPct = Math.round(p.load * 100);\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.task_started', (_e, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n entry.iterations++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.tool_executed', (_e, payload) => {\n const p = payload as { subagentId?: string; name?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n entry.currentTool = p.name;\n entry.toolCalls++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.iteration_summary', (_e, payload) => {\n const p = payload as\n | {\n subagentId?: string;\n iteration?: number;\n toolCalls?: number;\n currentTool?: string;\n costUsd?: number;\n partialText?: string;\n }\n | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n if (typeof p.iteration === 'number') entry.iterations = p.iteration;\n if (typeof p.toolCalls === 'number') entry.toolCalls = p.toolCalls;\n if (typeof p.costUsd === 'number') entry.costUsd = p.costUsd;\n if (p.currentTool) entry.currentTool = p.currentTool;\n // Live streamed tail of THIS subagent's current response (the runner\n // already accumulates it) — capped to the same budget as the leader.\n if (typeof p.partialText === 'string') {\n entry.partialText =\n p.partialText.length > PARTIAL_TEXT_CAP\n ? p.partialText.slice(p.partialText.length - PARTIAL_TEXT_CAP)\n : p.partialText;\n }\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.task_completed', (_e, payload) => {\n const p = payload as\n | { subagentId?: string; status?: string; iterations?: number; toolCalls?: number }\n | undefined;\n if (!p?.subagentId) return;\n // Only update an agent we already know — a completion for an unseen\n // agent isn't worth materialising.\n const entry = this.agents.get(p.subagentId);\n if (!entry) return;\n entry.status = p.status === 'failed' || p.status === 'timeout' ? 'error' : 'idle';\n entry.currentTool = undefined;\n entry.partialText = undefined;\n if (typeof p.iterations === 'number') entry.iterations = p.iterations;\n if (typeof p.toolCalls === 'number') entry.toolCalls = p.toolCalls;\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.stopped', (_e, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (!p?.subagentId) return;\n if (this.agents.delete(p.subagentId)) this.flush();\n }),\n );\n\n // Reap finished subagents so the fleet view doesn't fill with dead/idle\n // desks. The leader is synthesised in flush() (never in `this.agents`), so\n // it is never reaped — it represents the live session.\n this.sweepTimer = setInterval(() => this.sweep(), AGENT_SWEEP_INTERVAL_MS);\n if (typeof this.sweepTimer.unref === 'function') this.sweepTimer.unref();\n }\n\n stop(): void {\n for (const unsub of this.unsubscribers) {\n try { unsub(); } catch { /* ignore */ }\n }\n this.unsubscribers = [];\n if (this.sweepTimer) {\n clearInterval(this.sweepTimer);\n this.sweepTimer = null;\n }\n if (this.partialTimer) {\n clearTimeout(this.partialTimer);\n this.partialTimer = null;\n }\n }\n\n /**\n * Coalesce streamed-text flushes: at most one registry write per\n * {@link PARTIAL_FLUSH_THROTTLE_MS} while text streams in, so per-token\n * deltas never thrash the cross-process registry file.\n */\n private schedulePartialFlush(): void {\n if (this.partialTimer) return;\n this.partialTimer = setTimeout(() => {\n this.partialTimer = null;\n this.flush();\n }, PARTIAL_FLUSH_THROTTLE_MS);\n if (typeof this.partialTimer.unref === 'function') this.partialTimer.unref();\n }\n\n /**\n * Remove subagents that have been finished (idle/error) for longer than\n * {@link AGENT_REAP_MS}. Running / streaming / waiting_user agents are kept\n * regardless of age — only *not-working* agents are reaped.\n */\n private sweep(): void {\n const now = Date.now();\n let removed = false;\n for (const [id, a] of this.agents) {\n const finished = a.status !== 'running' && a.status !== 'streaming' && a.status !== 'waiting_user';\n const age = now - Date.parse(a.lastActivityAt);\n if (finished && Number.isFinite(age) && age > AGENT_REAP_MS) {\n this.agents.delete(id);\n removed = true;\n }\n }\n if (removed) this.flush();\n }\n\n private flush(): void {\n const leaderEntry: AgentEntry = {\n id: 'leader',\n name: this.leaderName,\n status: this.leaderStatus,\n currentTool: this.leaderCurrentTool,\n iterations: this.leaderIterations,\n toolCalls: this.leaderToolCalls,\n costUsd: this.leaderCostUsd,\n tokensIn: this.leaderTokensIn,\n tokensOut: this.leaderTokensOut,\n ctxPct: this.leaderCtxPct,\n model: this.leaderModel,\n partialText: this.leaderPartialText || undefined,\n lastActivityAt: new Date().toISOString(),\n };\n\n const allAgents = [leaderEntry, ...this.agents.values()];\n // Nudge local WebUIs only AFTER the write settles, so they re-read fresh\n // data. Best-effort — never let a notifier failure surface here.\n this.registry\n .updateAgents(allAgents)\n .then(() => {\n try {\n this.onUpdate?.();\n } catch {\n /* best-effort */\n }\n })\n .catch(() => undefined);\n }\n}\n","/**\n * FleetNotifier — push-on-write nudge to local WebUI servers.\n *\n * The cross-process source of truth is the file-based SessionRegistry, which\n * every WebUI server already watches (`fs.watch`, ~150ms) and polls (5s). This\n * notifier is a best-effort *latency* optimisation on top: after a process\n * writes its session/agent status to the registry, it sends a tiny\n * fire-and-forget `POST /api/fleet/ping` to every WebUI running against the\n * same project (discovered from `~/.wrongstack/webui-instances.json`). The\n * WebUI responds by re-broadcasting the (already-fresh) registry immediately —\n * so a TUI/REPL agent's activity reaches the Fleet HQ map in ~milliseconds\n * instead of waiting on the watch/poll.\n *\n * Design notes:\n * - **Never the source of truth.** If no WebUI is running, the file system +\n * watch/poll still carry everything. Every failure here is swallowed.\n * - **Coalesced.** Bursts of events (tool calls, deltas) collapse into one POST\n * per ~50ms so we never hammer the WebUI per token.\n * - **Discovery cached** for a couple seconds to avoid a disk read per event.\n * - **Loopback only / self-excluded.** Targets the local instances file; a\n * `0.0.0.0`/`::` bind is dialled on `127.0.0.1`, and the caller's own pid is\n * skipped so a WebUI never pings itself.\n *\n * @module fleet-notifier\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nconst INSTANCES_FILE = 'webui-instances.json';\nconst DISCOVERY_TTL_MS = 2_500;\nconst COALESCE_MS = 50;\nconst POST_TIMEOUT_MS = 500;\n\ninterface InstanceRecordLike {\n pid: number;\n httpPort: number;\n host: string;\n projectRoot: string;\n}\n\nfunction pidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n/** Normalise a project root for cross-process comparison (case-insensitive on Windows). */\nfunction normRoot(root: string): string {\n const resolved = path.resolve(root);\n return process.platform === 'win32' ? resolved.toLowerCase() : resolved;\n}\n\nexport interface FleetNotifierOptions {\n /** WrongStack global dir (`~/.wrongstack`) holding `webui-instances.json`. */\n baseDir: string;\n /** This process's project root — only WebUIs on the same project are pinged. */\n projectRoot: string;\n /** This process's pid, so a WebUI never pings itself. */\n selfPid?: number | undefined;\n /** Injectable POST for tests. Defaults to a timed `fetch`. */\n post?: ((url: string) => Promise<void>) | undefined;\n}\n\nexport class FleetNotifier {\n private readonly baseDir: string;\n private readonly projectRoot: string;\n private readonly selfPid: number;\n private readonly doPost: (url: string) => Promise<void>;\n\n private cache: { at: number; urls: string[] } | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n constructor(opts: FleetNotifierOptions) {\n this.baseDir = opts.baseDir;\n this.projectRoot = normRoot(opts.projectRoot);\n this.selfPid = opts.selfPid ?? process.pid;\n this.doPost = opts.post ?? defaultPost;\n }\n\n /** Coalesced, best-effort nudge. Safe to call on every status change. */\n notify(): void {\n if (this.disposed || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, COALESCE_MS);\n if (typeof this.timer.unref === 'function') this.timer.unref();\n }\n\n /** Resolve same-project WebUI ping URLs (cached briefly). Exposed for tests. */\n async endpoints(): Promise<string[]> {\n const now = Date.now();\n if (this.cache && now - this.cache.at < DISCOVERY_TTL_MS) return this.cache.urls;\n const urls = await this.discover();\n this.cache = { at: now, urls };\n return urls;\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async flush(): Promise<void> {\n const urls = await this.endpoints();\n await Promise.all(urls.map((u) => this.doPost(u).catch(() => undefined)));\n }\n\n private async discover(): Promise<string[]> {\n try {\n const raw = await fs.readFile(path.join(this.baseDir, INSTANCES_FILE), 'utf8');\n const data = JSON.parse(raw) as { instances?: InstanceRecordLike[] };\n const list = Array.isArray(data?.instances) ? data.instances : [];\n return list\n .filter((i) => i && typeof i.httpPort === 'number')\n .filter((i) => i.pid !== this.selfPid)\n .filter((i) => normRoot(i.projectRoot) === this.projectRoot)\n .filter((i) => pidAlive(i.pid))\n .map((i) => {\n const host = i.host === '0.0.0.0' || i.host === '::' || !i.host ? '127.0.0.1' : i.host;\n return `http://${host}:${i.httpPort}/api/fleet/ping`;\n });\n } catch {\n // Missing/corrupt instances file → no WebUIs to notify.\n return [];\n }\n }\n}\n\nasync function defaultPost(url: string): Promise<void> {\n await fetch(url, {\n method: 'POST',\n signal: AbortSignal.timeout(POST_TIMEOUT_MS),\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport { toErrorMessage } from '../utils/error.js';\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { CheckpointInfo, RewindResult, RewindResultExtended, SessionRewinder } from '../types/session-rewinder.js';\r\nimport type { SessionEvent, FileSnapshot } from '../types/session.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\nimport { SessionError, ERROR_CODES } from '../types/errors.js';\r\n\r\nexport interface SessionRewinderOptions {\r\n sessionsDir: string;\r\n /** The project root directory; used to validate rewind targets stay inside it. */\r\n projectRoot: string;\r\n}\r\n\r\n/**\r\n * Rewind engine that reads session JSONL files and reverts file system\r\n * changes to any previous checkpoint.\r\n */\r\nexport class DefaultSessionRewinder implements SessionRewinder {\r\n constructor(private readonly sessionsDir: string, private readonly projectRoot: string) {}\r\n\r\n async listCheckpoints(sessionId: string): Promise<CheckpointInfo[]> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n // Build a map of promptIndex -> file snapshot count\r\n const fileCountMap = new Map<number, number>();\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n const e = event as { promptIndex: number; files: FileSnapshot[] };\r\n fileCountMap.set(e.promptIndex, (fileCountMap.get(e.promptIndex) ?? 0) + e.files.length);\r\n }\r\n }\r\n\r\n const checkpoints: CheckpointInfo[] = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n const e = event as { promptIndex: number; promptPreview: string; ts: string };\r\n checkpoints.push({\r\n promptIndex: e.promptIndex,\r\n promptPreview: e.promptPreview,\r\n ts: e.ts,\r\n fileCount: fileCountMap.get(e.promptIndex) ?? 0,\r\n });\r\n }\r\n }\r\n\r\n return checkpoints;\r\n }\r\n\r\n async rewindToCheckpoint(\r\n sessionId: string,\r\n checkpointIndex: number,\r\n ): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n let targetIdx = -1;\r\n for (let i = 0; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n const checkpointEvent = event as { promptIndex: number };\r\n if (checkpointEvent.promptIndex === checkpointIndex) {\r\n targetIdx = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (targetIdx === -1) {\r\n throw new SessionError({\r\n message: `Checkpoint ${checkpointIndex} not found`,\r\n code: ERROR_CODES.SESSION_NOT_FOUND,\r\n context: { checkpointIndex },\r\n });\r\n }\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (let i = targetIdx + 1; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n break;\r\n }\r\n if (event.type === 'file_snapshot') {\r\n const snapshotEvent = event as { promptIndex: number; files: FileSnapshot[] };\r\n if (snapshotEvent.promptIndex >= checkpointIndex) {\r\n snapshotsToRevert.push({ promptIndex: snapshotEvent.promptIndex, files: snapshotEvent.files });\r\n }\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert, this.projectRoot);\r\n const removedEvents = events.length - targetIdx - 1;\r\n return { ...result, toPromptIndex: checkpointIndex, removedEvents };\r\n }\r\n\r\n async rewindLastN(sessionId: string, n: number): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const checkpoints: Array<{ promptIndex: number; ts: string }> = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n checkpoints.push({ promptIndex: event.promptIndex, ts: event.ts });\r\n }\r\n }\r\n\r\n if (checkpoints.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n checkpoints.sort((a, b) => b.promptIndex - a.promptIndex);\r\n const targetIndex = checkpoints[n]?.promptIndex ?? 0;\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n let shouldRevert = false;\r\n\r\n for (const event of events) {\r\n if (event.type === 'checkpoint' && event.promptIndex === targetIndex) {\r\n shouldRevert = true;\r\n continue;\r\n }\r\n if (shouldRevert && event.type === 'file_snapshot') {\r\n snapshotsToRevert.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: targetIndex, removedEvents: snapshotsToRevert.length };\r\n }\r\n\r\n async rewindToStart(sessionId: string): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const allSnapshots: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n allSnapshots.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n if (allSnapshots.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n const result = await revertSnapshots(allSnapshots.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: 0, removedEvents: allSnapshots.length };\r\n }\r\n}\r\n\r\nfunction parseEvents(raw: string): SessionEvent[] {\r\n const lines = raw.split('\\n').filter((l) => l.trim());\r\n const events: SessionEvent[] = [];\r\n\r\n for (const line of lines) {\r\n try {\r\n const parsed = JSON.parse(line);\r\n if (\r\n parsed !== null &&\r\n typeof parsed === 'object' &&\r\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\r\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\r\n ) {\r\n events.push(parsed as SessionEvent);\r\n }\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n\r\n return events;\r\n}\r\n\r\nasync function revertSnapshots(\r\n snapshots: Array<{ promptIndex: number; files: FileSnapshot[] }>,\r\n projectRoot: string,\r\n): Promise<RewindResult> {\r\n const revertedFiles: string[] = [];\r\n const errors: string[] = [];\r\n\r\n for (const snapshot of snapshots) {\r\n for (const file of snapshot.files) {\r\n try {\r\n // Guard: ensure the target path resolves inside the project root.\r\n // Without this, a maliciously recorded path (e.g., via path traversal\r\n // in a tool call that wasn't caught) could cause rewind to write\r\n // to arbitrary locations.\r\n const absPath = path.resolve(file.path);\r\n const root = path.resolve(projectRoot);\r\n const rel = path.relative(root, absPath);\r\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\r\n errors.push(`${file.path}: path resolves outside project root — skipping`);\r\n continue;\r\n }\r\n\r\n if (file.action === 'deleted') {\r\n // File was deleted — restore it from before\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n } else if (file.action === 'created') {\r\n // File was created — delete it\r\n await fsp.unlink(file.path);\r\n revertedFiles.push(file.path);\r\n } else if (file.action === 'modified') {\r\n // File was modified — restore before content\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n }\r\n } catch (err) {\r\n errors.push(`${file.path}: ${toErrorMessage(err)}`);\r\n }\r\n }\r\n }\r\n\r\n return { revertedFiles, errors };\r\n}","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport type { TodoItem } from '../core/context.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * On-disk checkpoint for `ctx.todos`. Written atomically every time the\n * todo list changes, read once on session resume. This is the missing\n * piece that lets `wstack resume <id>` rehydrate where the previous run\n * stopped instead of starting with an empty board.\n *\n * Schema is intentionally small — a single JSON object so a future\n * format bump is easy. The `version` field is the only contract; the\n * shape under `todos` mirrors `TodoItem` so reading is a straight assign.\n */\nexport interface TodosCheckpointFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n todos: TodoItem[];\n}\n\nexport type TodosCheckpointDetach = () => Promise<void>;\n\n/** Read a checkpoint from disk. Returns null when the file doesn't\n * exist or is corrupt — callers treat both cases as \"no prior state\".\n */\nexport async function loadTodosCheckpoint(\n filePath: string,\n events?: EventBus,\n traceId?: string,\n): Promise<TodoItem[] | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TodosCheckpointFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.todos)) {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return parsed.todos.filter(\n (t): t is TodoItem =>\n !!t &&\n typeof t.id === 'string' &&\n typeof t.content === 'string' &&\n typeof t.status === 'string' &&\n (t.activeForm === undefined || typeof t.activeForm === 'string'),\n );\n } catch {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n}\n\n/** Write the checkpoint atomically. Best-effort: a write failure is\n * logged but does not throw — losing one checkpoint shouldn't bring\n * down the agent run.\n */\nexport async function saveTodosCheckpoint(\n filePath: string,\n sessionId: string,\n todos: readonly TodoItem[],\n events?: EventBus,\n traceId?: string,\n): Promise<void> {\n const t0 = Date.now();\n const payload: TodosCheckpointFile = {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n todos: [...todos],\n };\n try {\n await atomicWrite(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: traceId ?? sessionId,\n store: 'todos',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? sessionId,\n store: 'todos',\n filePath,\n operation: 'save',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'todos_checkpoint.save_failed',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n}\n\n/**\n * Subscribe a `ConversationState` so every `todos_replaced` mutation\n * triggers an atomic write to disk. Returns the unsubscribe function.\n *\n * Writes are debounced by 150ms so a flurry of edits (e.g. the LLM\n * marking three items done in the same tool call) coalesces into one\n * disk hit.\n */\nexport function attachTodosCheckpoint(\n state: ConversationState,\n filePath: string,\n sessionId: string,\n events?: EventBus,\n traceId?: string,\n): TodosCheckpointDetach {\n let timer: NodeJS.Timeout | null = null;\n let pending: readonly TodoItem[] | null = null;\n let writeChain: Promise<void> = Promise.resolve();\n\n const enqueueWrite = (todos: readonly TodoItem[]) => {\n writeChain = writeChain\n .then(() => saveTodosCheckpoint(filePath, sessionId, todos, events, traceId))\n /* v8 ignore start -- defensive: saveTodosCheckpoint swallows its own errors and never rejects */\n .catch((err) => {\n // Log and keep the chain alive — a failed write must not\n // poison the chain and silently stop all subsequent writes.\n const msg = toErrorMessage(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'todos_checkpoint.write_chain_failed',\n sessionId,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n /* v8 ignore stop */\n return writeChain;\n };\n\n const flush = () => {\n timer = null;\n if (pending) {\n const todos = pending;\n pending = null;\n return enqueueWrite(todos);\n }\n /* v8 ignore next -- defensive: flush is only invoked when a change is pending */\n return writeChain;\n };\n\n const unsubscribe = state.onChange((change) => {\n if (change.kind !== 'todos_replaced') return;\n pending = change.todos;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n void flush();\n }, 150);\n });\n return async () => {\n unsubscribe();\n if (timer) {\n clearTimeout(timer);\n // Flush any pending write before detach so callers can safely\n // unsubscribe at shutdown without losing the last update.\n await flush();\n } else {\n await writeChain;\n }\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Plan items are the strategic counterpart to todos. Where `ctx.todos`\n * is the moment-to-moment task board the LLM mutates per-turn, a plan\n * captures the higher-level approach — the steps the user (or LLM)\n * laid out before any work began.\n *\n * Plans persist by default (per session) so a resumed session can show\n * \"you were on step 3 of 5\". Todos are derived/transient. Both can\n * coexist: think roadmap (plan) vs. sprint board (todos).\n */\nexport interface PlanItem {\n id: string;\n title: string;\n /** Optional longer-form context or rationale. */\n details?: string | undefined;\n status: 'open' | 'in_progress' | 'done';\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PlanFile {\n version: 1;\n sessionId: string;\n title?: string | undefined;\n updatedAt: string;\n items: PlanItem[];\n}\n\nexport async function loadPlan(filePath: string, events?: EventBus): Promise<PlanFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as PlanFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.items)) {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return parsed;\n } catch {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n });\n return null;\n }\n}\n\n/**\n * Persist a plan. Returns `true` on success, `false` if the write failed\n * (still emits `storage.error` + warns — it does NOT throw, so callers that\n * treat a lost plan-save as non-fatal keep working). `mutatePlan` inspects the\n * result and throws so the plan TOOL can report `ok:false` instead of falsely\n * claiming the plan was persisted.\n */\nexport async function savePlan(filePath: string, plan: PlanFile, events?: EventBus): Promise<boolean> {\n const t0 = Date.now();\n try {\n await atomicWrite(filePath, JSON.stringify(plan, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return true;\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'save',\n error: toErrorMessage(err),\n recoverable: false,\n });\n console.warn(\n '[plan-store] save failed:',\n toErrorMessage(err),\n );\n return false;\n }\n}\n\n/** Create a new PlanFile when none exists on disk. */\nexport function emptyPlan(sessionId: string, title?: string): PlanFile {\n return {\n version: 1,\n sessionId,\n title,\n updatedAt: new Date().toISOString(),\n items: [],\n };\n}\n\nexport function addPlanItem(\n plan: PlanFile,\n title: string,\n details?: string | undefined,\n): { plan: PlanFile; item: PlanItem } {\n const now = new Date().toISOString();\n const item: PlanItem = {\n id: `plan_${Date.now()}_${randomUUID().slice(0, 6)}`,\n title,\n details,\n status: 'open',\n createdAt: now,\n updatedAt: now,\n };\n return {\n plan: { ...plan, items: [...plan.items, item], updatedAt: now },\n item,\n };\n}\n\nexport function removePlanItem(plan: PlanFile, idOrIndex: string): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n return {\n ...plan,\n items: plan.items.filter((_, i) => i !== idx),\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function setPlanItemStatus(\n plan: PlanFile,\n idOrIndex: string,\n status: PlanItem['status'],\n): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n const now = new Date().toISOString();\n const items = plan.items.map((it, i) =>\n i === idx ? { ...it, status, updatedAt: now } : it,\n );\n return { ...plan, items, updatedAt: now };\n}\n\nexport function clearPlan(plan: PlanFile): PlanFile {\n return { ...plan, items: [], updatedAt: new Date().toISOString() };\n}\n\n/** Render the plan as a short markdown-ish string suitable for slash output. */\nexport function formatPlan(plan: PlanFile): string {\n if (plan.items.length === 0) return 'Plan is empty.';\n const lines: string[] = [];\n if (plan.title) lines.push(`# ${plan.title}`);\n plan.items.forEach((it, i) => {\n const mark = it.status === 'done' ? '[x]' : it.status === 'in_progress' ? '[~]' : '[ ]';\n lines.push(`${i + 1}. ${mark} ${it.title}`);\n if (it.details) {\n for (const line of it.details.split('\\n')) lines.push(` ${line}`);\n }\n });\n return lines.join('\\n');\n}\n\nfunction matchIndex(plan: PlanFile, idOrIndex: string): number {\n const asNum = Number.parseInt(idOrIndex, 10);\n if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= plan.items.length) return asNum - 1;\n const byId = plan.items.findIndex((it) => it.id === idOrIndex);\n if (byId !== -1) return byId;\n const lower = idOrIndex.toLowerCase();\n return plan.items.findIndex((it) => it.title.toLowerCase().includes(lower));\n}\n\n/**\n * Promote a plan item to a set of todo items.\n * The plan item is marked 'in_progress' (if not already done) and its\n * title + details become the first todo; additional subtasks are appended.\n * Returns the derived todo list so the caller can pass it to `todoTool`\n * or `ctx.state.replaceTodos()`.\n */\nexport function deriveTodosFromPlanItem(\n plan: PlanFile,\n idOrIndex: string,\n subtasks?: string[] | undefined,\n): { plan: PlanFile; todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> } | null {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return null;\n\n const item = plan.items[idx];\n /* v8 ignore next -- defensive: matchIndex returns a valid in-range index or -1 (handled above) */\n if (!item) return null;\n\n // Mark the plan item in_progress if it wasn't already done\n let updatedPlan = plan;\n if (item.status !== 'done') {\n updatedPlan = setPlanItemStatus(plan, idOrIndex, 'in_progress');\n }\n\n const todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> = [];\n\n // First todo from the plan item itself\n todos.push({\n id: `todo_${Date.now()}_plan`,\n content: item.title,\n status: 'in_progress',\n activeForm: item.title,\n promotedFromPlan: item.id,\n });\n\n // Optional subtasks\n if (subtasks && subtasks.length > 0) {\n for (const st of subtasks) {\n todos.push({\n id: `todo_${Date.now()}_${randomUUID().slice(0, 6)}`,\n content: st,\n status: 'pending',\n promotedFromPlan: item.id,\n });\n }\n }\n\n return { plan: updatedPlan, todos };\n}\n\n/**\n * Load, modify, and save the plan file under a file-level lock.\n * Prevents races from parallel tool invocations (e.g. batch_tool_use).\n */\nexport async function mutatePlan(\n filePath: string,\n sessionId: string,\n fn: (plan: PlanFile) => PlanFile | Promise<PlanFile>,\n): Promise<PlanFile> {\n return withFileLock(filePath, async () => {\n const plan = (await loadPlan(filePath)) ?? emptyPlan(sessionId);\n const updated = await fn(plan);\n const persisted = await savePlan(filePath, updated);\n if (!persisted) {\n throw new Error(`Failed to persist plan to ${filePath} — the change was NOT saved.`);\n }\n return updated;\n });\n}\n\n/**\n * Optional: attach a state-listener so meta operations (storing a plan\n * id on ctx.meta) trigger a save. Currently a stub — plans don't live\n * on Context, but this keeps the API surface symmetric with the todos\n * checkpoint so future refactors can flip plans into Context if needed.\n */\nexport function attachPlanCheckpoint(\n _state: ConversationState,\n _filePath: string,\n _sessionId: string,\n): () => void {\n return () => undefined;\n}\n","/**\n * Plan templates — pre-defined plan skeletons for common workflows.\n *\n * Templates are stored in-memory (no disk I/O). Users instantiate them\n * via `/plan template use <name>` or `planTool(action: 'template_use')`.\n * Each template is a function that returns an array of item titles, so\n * dynamic content (dates, project names) can be injected later.\n */\n\nexport interface PlanTemplate {\n name: string;\n description: string;\n category: 'development' | 'release' | 'maintenance' | 'infrastructure';\n items: Array<{\n title: string;\n details?: string | undefined;\n }>;\n}\n\nconst templates: Record<string, PlanTemplate> = {\n 'new-feature': {\n name: 'new-feature',\n description: 'Standard workflow for adding a new feature',\n category: 'development',\n items: [\n { title: 'Write specification / design doc', details: 'Define scope, acceptance criteria, edge cases' },\n { title: 'Set up feature branch', details: 'git checkout -b feature/...' },\n { title: 'Implement core logic', details: 'TDD preferred — write tests first' },\n { title: 'Add unit tests', details: '>= 80% coverage for new code' },\n { title: 'Add integration tests', details: 'End-to-end happy path + error paths' },\n { title: 'Update documentation', details: 'README, API docs, changelog' },\n { title: 'Code review', details: 'Self-review before requesting review' },\n { title: 'Merge and deploy', details: 'CI green, tag release' },\n ],\n },\n 'bug-fix': {\n name: 'bug-fix',\n description: 'Systematic approach to fixing bugs',\n category: 'maintenance',\n items: [\n { title: 'Reproduce the bug', details: 'Minimal reproduction case' },\n { title: 'Root cause analysis', details: 'Trace through logs, debugger' },\n { title: 'Write failing test', details: 'Test must fail before fix' },\n { title: 'Implement fix', details: 'Smallest possible change' },\n { title: 'Verify fix', details: 'Test passes, reproduction no longer fails' },\n { title: 'Regression test', details: 'Ensure no related tests broken' },\n { title: 'Document in changelog', details: 'Brief description + issue link' },\n ],\n },\n 'refactor': {\n name: 'refactor',\n description: 'Safe refactoring workflow',\n category: 'maintenance',\n items: [\n { title: 'Identify refactoring target', details: 'Code smell, performance bottleneck, or tech debt' },\n { title: 'Ensure test coverage', details: 'Existing tests must pass before and after' },\n { title: 'Write characterization tests', details: 'Capture current behavior if tests weak' },\n { title: 'Apply refactoring', details: 'Small steps, frequent commits' },\n { title: 'Run full test suite', details: 'All tests must pass' },\n { title: 'Performance check', details: 'Ensure no regression' },\n { title: 'Code review', details: 'Explain the why, not just the what' },\n ],\n },\n 'release': {\n name: 'release',\n description: 'Preparing a new release',\n category: 'release',\n items: [\n { title: 'Version bump', details: 'package.json, lockfiles, tags' },\n { title: 'Update changelog', details: 'All changes since last release' },\n { title: 'Run full test suite', details: 'Unit + integration + e2e' },\n { title: 'Build artifacts', details: 'Docker images, bundles, binaries' },\n { title: 'Staging smoke tests', details: 'Deploy to staging, verify' },\n { title: 'Production deploy', details: 'Blue-green or canary' },\n { title: 'Post-deploy verification', details: 'Health checks, error rates' },\n { title: 'Announce release', details: 'Slack, email, GitHub release notes' },\n ],\n },\n 'security-audit': {\n name: 'security-audit',\n description: 'Security review and hardening',\n category: 'infrastructure',\n items: [\n { title: 'Dependency audit', details: 'npm audit, Snyk, Dependabot alerts' },\n { title: 'Secret scan', details: 'git-secrets, truffleHog, manual review' },\n { title: 'Access control review', details: 'IAM, roles, least privilege' },\n { title: 'Input validation audit', details: 'SQL injection, XSS, path traversal' },\n { title: 'Authentication review', details: 'Session management, MFA, password policy' },\n { title: 'Logging and monitoring', details: 'PII in logs, audit trails' },\n { title: 'Incident response plan', details: 'Runbooks, contacts, escalation' },\n ],\n },\n 'onboarding': {\n name: 'onboarding',\n description: 'New developer onboarding checklist',\n category: 'infrastructure',\n items: [\n { title: 'Repository access', details: 'GitHub/GitLab permissions' },\n { title: 'Local environment setup', details: 'Docker, dependencies, env files' },\n { title: 'Run tests locally', details: 'Verify green suite' },\n { title: 'Read architecture docs', details: 'ADR, README, onboarding guide' },\n { title: 'First commit', details: 'Docs fix or small improvement' },\n { title: 'Pair programming session', details: 'Walk through codebase with buddy' },\n { title: 'Deploy to staging', details: 'Verify CI/CD access' },\n ],\n },\n};\n\nexport function listPlanTemplates(): PlanTemplate[] {\n return Object.values(templates);\n}\n\nexport function getPlanTemplate(name: string): PlanTemplate | undefined {\n return templates[name];\n}\n\nexport function formatPlanTemplates(): string {\n const cats = new Map<PlanTemplate['category'], PlanTemplate[]>();\n for (const t of Object.values(templates)) {\n const arr = cats.get(t.category) ?? [];\n arr.push(t);\n cats.set(t.category, arr);\n }\n\n const lines: string[] = ['Available plan templates:'];\n for (const [cat, items] of cats) {\n lines.push(`\\n${cat}:`);\n for (const t of items) {\n lines.push(` ${t.name.padEnd(18)} — ${t.description}`);\n }\n }\n return lines.join('\\n');\n}\n","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport type { TaskItem } from '../utils/task-format.js';\n\n// ---------------------------------------------------------------------------\n// Task file persistence — one JSON file per session in\n// `<projectSessions>/<sessionId>.tasks.json`.\n//\n// Low-level load/save are exported for read-only consumers. Mutating callers\n// should use `mutateTasks` which wraps the entire read-modify-write cycle\n// under a file-level lock, preventing races from parallel tool invocations.\n// ---------------------------------------------------------------------------\n\nexport interface TaskFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n tasks: TaskItem[];\n}\n\nexport function emptyTaskFile(sessionId: string): TaskFile {\n return {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n tasks: [],\n };\n}\n\n/** Read the task file. Returns null when the file doesn't exist. */\nexport async function loadTasks(\n filePath: string,\n events?: EventBus,\n traceId?: string,\n): Promise<TaskFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TaskFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.tasks)) {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return parsed;\n } catch {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n}\n\n/**\n * Write the task file atomically. Prefer `mutateTasks` for read-modify-write\n * cycles — this low-level function does NOT acquire a lock.\n */\n/**\n * Persist the task file. Returns `true` on success, `false` if the write\n * failed (still emits `storage.error` + warns — does NOT throw). `mutateTasks`\n * inspects the result and throws so the task TOOL can report `ok:false`\n * instead of falsely claiming the tasks were saved.\n */\nexport async function saveTasks(\n filePath: string,\n tasks: TaskFile,\n events?: EventBus,\n traceId?: string,\n): Promise<boolean> {\n const t0 = Date.now();\n try {\n tasks.updatedAt = new Date().toISOString();\n await atomicWrite(filePath, JSON.stringify(tasks, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return true;\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'save',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n ...(traceId !== undefined && { traceId }),\n });\n console.warn(\n '[task-store] save failed:',\n toErrorMessage(err),\n );\n return false;\n }\n}\n\n/**\n * Load, modify, and save the task file under a file-level lock.\n * `fn` receives the current TaskFile (or a fresh empty one) and must\n * return the mutated TaskFile (mutating in-place is fine — the returned\n * reference is what gets saved).\n *\n * This is the primary API for any code path that reads *and then writes*\n * the task file — it prevents races from parallel `batch_tool_use` calls.\n */\nexport async function mutateTasks(\n filePath: string,\n sessionId: string,\n fn: (file: TaskFile) => TaskFile | Promise<TaskFile>,\n events?: EventBus,\n traceId?: string,\n): Promise<TaskFile> {\n return withFileLock(filePath, async () => {\n const file = (await loadTasks(filePath, events, traceId)) ?? emptyTaskFile(sessionId);\n const updated = await fn(file);\n const persisted = await saveTasks(filePath, updated, events, traceId);\n if (!persisted) {\n throw new Error(`Failed to persist tasks to ${filePath} — the change was NOT saved.`);\n }\n return updated;\n });\n}\n","import * as fsp from 'node:fs/promises';\nimport { hostname } from 'node:os';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Director state checkpoint — written incrementally throughout a fleet\n * run so a crashed director can be inspected (and eventually resumed)\n * instead of leaving only a final `fleet.json` manifest after `shutdown()`.\n *\n * Schema is JSON-friendly and deliberately denormalized. Each mutation\n * triggers an atomic-write of the whole file — small payloads (typically\n * < 10 KB even with dozens of subagents) make this cheap.\n */\nexport interface DirectorSubagentState {\n id: string;\n name?: string | undefined;\n role?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n spawnedAt: string;\n}\n\nexport interface DirectorTaskState {\n taskId: string;\n subagentId?: string | undefined;\n description?: string | undefined;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout';\n assignedAt?: string | undefined;\n completedAt?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n durationMs?: number | undefined;\n error?: string | undefined;\n}\n\nexport interface DirectorStateSnapshot {\n version: 1;\n directorRunId: string;\n updatedAt: string;\n spawnCount: number;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n subagents: DirectorSubagentState[];\n tasks: DirectorTaskState[];\n /** Aggregated usage snapshot. Optional — populated by the Director on save when available. */\n usage?: unknown | undefined;\n}\n\nexport async function loadDirectorState(filePath: string): Promise<DirectorStateSnapshot | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as DirectorStateSnapshot;\n if (parsed?.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Lock file entry written when a director starts. Prevents two directors\n * from resuming the same run — the second one sees the lock and refuses\n * rather than corrupting the checkpoint by writing concurrently.\n */\nexport interface DirectorStateLock {\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\n/**\n * Write a lock file to claim this checkpoint. Returns false if the lock\n * is already held by a live process; returns true if the lock was acquired\n * (either the file didn't exist, or the previous holder is dead).\n */\nexport async function acquireDirectorStateLock(\n lockPath: string,\n processId = process.pid,\n): Promise<boolean> {\n let existing: string | undefined;\n try {\n existing = await fsp.readFile(lockPath, 'utf8');\n } catch {\n // No lock file — we're safe to claim\n }\n\n if (existing) {\n try {\n const lock = JSON.parse(existing) as DirectorStateLock;\n // Check if the process is still alive\n try {\n process.kill(lock.pid, 0);\n // Signal success means the process is alive — another director\n // owns this checkpoint. Refuse.\n return false;\n } catch {\n // ESRCH means the process is dead — stale lock. We'll overwrite.\n }\n } catch {\n // Malformed lock — treat as stale.\n }\n }\n\n const lock: DirectorStateLock = {\n pid: processId,\n hostname: hostname(),\n startedAt: new Date().toISOString(),\n };\n await atomicWrite(lockPath, JSON.stringify(lock), { mode: 0o600 });\n return true;\n}\n\n/**\n * Remove the lock file. Call this on graceful Director.shutdown() so the\n * next director run can claim the checkpoint without stale-lock checks.\n */\nexport async function releaseDirectorStateLock(lockPath: string): Promise<void> {\n try {\n await fsp.unlink(lockPath);\n } catch {\n // ignore\n }\n}\n\n/**\n * In-memory accumulator with atomic-write checkpoint. The Director keeps\n * an instance, mutates it on every spawn/assign/complete/fail event, and\n * the instance debounces writes so a burst of activity collapses into a\n * single disk hit.\n *\n * Supports crash recovery: use `loadDirectorState()` to read an existing\n * checkpoint, then call `DirectorStateCheckpoint.resume(snapshot)` to\n * re-attach to a fleet mid-flight. The lock mechanism ensures no two\n * directors can claim the same checkpoint.\n */\nexport class DirectorStateCheckpoint {\n private snapshot: DirectorStateSnapshot;\n private readonly filePath: string;\n private readonly lockPath: string;\n private timer: NodeJS.Timeout | null = null;\n private readonly debounceMs: number;\n private writing = false;\n private rewriteRequested = false;\n\n constructor(\n filePath: string,\n init: {\n directorRunId: string;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n },\n debounceMs = 250,\n ) {\n this.filePath = filePath;\n // Lock file lives alongside the checkpoint — `<path>.lock`\n this.lockPath = `${filePath}.lock`;\n this.debounceMs = debounceMs;\n this.snapshot = {\n version: 1,\n directorRunId: init.directorRunId,\n updatedAt: new Date().toISOString(),\n spawnCount: 0,\n maxSpawns: init.maxSpawns,\n spawnDepth: init.spawnDepth,\n maxSpawnDepth: init.maxSpawnDepth,\n directorBudget: init.directorBudget,\n subagents: [],\n tasks: [],\n };\n }\n\n /**\n * Attempt to acquire the lock for this checkpoint. Call this before\n * resuming a crashed director run. If it returns false, another\n * director process is still running this fleet — do not resume.\n */\n async acquireLock(): Promise<boolean> {\n return acquireDirectorStateLock(this.lockPath);\n }\n\n /**\n * Release the lock on graceful shutdown. Call `flush()` first to ensure\n * the final checkpoint state is on disk before removing the lock.\n * Without this, the next resume will see a stale-lock and refuse.\n */\n async releaseLock(): Promise<void> {\n return releaseDirectorStateLock(this.lockPath);\n }\n\n /**\n * Resume from a snapshot previously loaded via `loadDirectorState()`.\n * Use this when `--resume <runId>` is triggered — the snapshot has\n * the full fleet state (subagents, tasks) from before the crash; the\n * checkpoint continues from there.\n */\n resume(snapshot: DirectorStateSnapshot): void {\n this.snapshot = snapshot;\n }\n\n current(): DirectorStateSnapshot {\n return this.snapshot;\n }\n\n recordSpawn(sub: DirectorSubagentState, spawnCount: number): void {\n this.snapshot = {\n ...this.snapshot,\n spawnCount,\n subagents: [...this.snapshot.subagents.filter((s) => s.id !== sub.id), sub],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskAssigned(task: DirectorTaskState): void {\n const exists = this.snapshot.tasks.some((t) => t.taskId === task.taskId);\n this.snapshot = {\n ...this.snapshot,\n tasks: exists\n ? this.snapshot.tasks.map((t) => (t.taskId === task.taskId ? { ...t, ...task } : t))\n : [...this.snapshot.tasks, task],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskStatus(\n taskId: string,\n patch: Partial<DirectorTaskState> & { status: DirectorTaskState['status'] },\n ): void {\n this.snapshot = {\n ...this.snapshot,\n tasks: this.snapshot.tasks.map((t) =>\n t.taskId === taskId ? { ...t, ...patch } : t,\n ),\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n setUsage(usage: unknown): void {\n this.snapshot = { ...this.snapshot, usage };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n /** Force a synchronous flush — used by Director.shutdown(). */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n await this.persist();\n // If a rewrite was requested while we waited, persist() scheduled\n // a follow-up write. Loop until no more rewrites are requested so\n // shutdown doesn't return before the most recent state lands on disk.\n /* v8 ignore start -- concurrency-defensive: persist()'s finally clears the flag in single-threaded flow */\n while (this.rewriteRequested) {\n this.rewriteRequested = false;\n await this.persist();\n }\n /* v8 ignore stop */\n }\n\n private bumpUpdatedAt(): void {\n this.snapshot = { ...this.snapshot, updatedAt: new Date().toISOString() };\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.persist();\n }, this.debounceMs);\n }\n\n private async persist(): Promise<void> {\n if (this.writing) {\n // A write is already in flight — defer to a follow-up flush so the\n // most recent state still lands. Without this guard, simultaneous\n // burst mutations can drop the latest snapshot if rename races.\n this.rewriteRequested = true;\n return;\n }\n this.writing = true;\n try {\n await atomicWrite(this.filePath, JSON.stringify(this.snapshot, null, 2), {\n mode: 0o600,\n });\n } catch (err) {\n console.warn(\n '[director-state] checkpoint write failed:',\n toErrorMessage(err),\n );\n } finally {\n this.writing = false;\n /* v8 ignore start -- concurrency-defensive: rewriteRequested is only set by an overlapping persist() */\n if (this.rewriteRequested) {\n this.rewriteRequested = false;\n this.schedule();\n }\n /* v8 ignore stop */\n }\n }\n}\n","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { color } from '../utils/color.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport { FsError, ERROR_CODES } from '../types/errors.js';\n\n/**\n * Long-running autonomous mission. A goal survives across sessions and\n * drives the EternalAutonomyEngine — every iteration of the engine\n * consults the goal to choose what to do next.\n *\n * Storage: `~/.wrongstack/projects/<hash>/goal.json`. Persistent and\n * project-scoped on purpose: the goal belongs to the codebase, not the\n * REPL session.\n */\n\nexport interface JournalEntry {\n /** ISO timestamp of the iteration. */\n at: string;\n /** Sequential iteration counter (1-based, monotonically increasing). */\n iteration: number;\n /** Source that produced the action ('todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel'). */\n source: 'todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel';\n /** Short one-line description of what the iteration set out to do. */\n task: string;\n /** Outcome status. */\n status: 'success' | 'failure' | 'aborted' | 'skipped';\n /** Optional free-form note (error message, summary, etc.). */\n note?: string | undefined;\n /** Optional token usage delta for this iteration. */\n tokens?: { input: number; output: number } | undefined;\n /** Optional USD cost delta for this iteration (provider-estimated). */\n costUsd?: number | undefined;\n}\n\nexport interface GoalFile {\n version: 1;\n /** The raw mission statement as entered by the user. */\n goal: string;\n /**\n * LLM-refined version of the goal — unambiguous, with concrete\n * deliverables and acceptance criteria.\n */\n refinedGoal?: string | undefined;\n /**\n * Concrete, verifiable deliverables extracted from the refined goal.\n */\n deliverables?: string[] | undefined;\n /**\n * Estimated completion 0-100. Updated by the engine after each\n * iteration. Null means \"not yet assessed\".\n */\n progress?: number | undefined;\n /** Human-readable note explaining the current progress estimate. */\n progressNote?: string | undefined;\n /**\n * Time-series of progress measurements for trend analysis.\n * Last 200 entries retained. Use `recordProgress()` to append.\n */\n progressHistory?: ProgressSnapshot[] | undefined;\n /**\n * Computed trend from recent progress measurements.\n * 'accelerating' | 'steady' | 'stalling' | undefined.\n */\n progressTrend?: 'accelerating' | 'steady' | 'stalling' | undefined;\n /** When the goal was first set or last replaced. */\n setAt: string;\n /** Updated on every iteration completion. */\n lastActivityAt: string;\n /** Total iterations the engine has run against this goal (cumulative). */\n iterations: number;\n /** Engine lifecycle state — 'running' means another process owns this goal. */\n engineState: 'idle' | 'running' | 'stopped';\n /**\n * Mission-level lifecycle.\n */\n goalState?: 'active' | 'paused' | 'completed' | 'abandoned' | undefined;\n /**\n * Per-todo attempt counter.\n */\n todoAttempts?: Record<string, number>;\n /** Bounded ring buffer of recent iterations (newest last). */\n journal: JournalEntry[];\n}\n\n/** Cap on persisted journal entries — older entries are evicted FIFO. */\nexport const MAX_JOURNAL_ENTRIES = 500;\n\n/**\n * Resolve the goal file path for a given project root.\n *\n * SINGLE canonical location: the per-project directory that\n * `resolveWstackPaths()` uses for everything else (sessions, memory, specs) —\n * `~/.wrongstack/projects/<slug>/goal.json`. This is the same path the `/goal`\n * slash command writes via `opts.paths.projectGoal`, so every reader/writer\n * (the eternal/parallel autonomy engines, the CLI autonomy commands, the TUI\n * F9 panel, and `/goal` itself) now agree on one file.\n *\n * Previously this returned a SEPARATE hash-based dir (`projects/<hash>/`), which\n * disagreed with `/goal` and littered the home dir with thousands of stray\n * `<hash>/goal.json` directories that held nothing else.\n */\nexport function goalFilePath(projectRoot: string): string {\n return resolveWstackPaths({ projectRoot }).projectGoal;\n}\n\nexport async function loadGoal(filePath: string, events?: EventBus): Promise<GoalFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return null; // file doesn't exist — not an error\n }\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n error: toErrorMessage(err),\n recoverable: false,\n });\n throw err; // permission errors etc. should surface\n }\n try {\n const parsed = JSON.parse(raw) as GoalFile;\n if (parsed?.version !== 1 || typeof parsed.goal !== 'string' || !Array.isArray(parsed.journal)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.invalid_schema',\n path: filePath,\n message: 'invalid schema — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return parsed;\n } catch {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.parse_failed',\n path: filePath,\n message: 'JSON parse failed — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n });\n return null;\n }\n}\n\nexport async function saveGoal(filePath: string, goal: GoalFile, events?: EventBus): Promise<void> {\n const t0 = Date.now();\n try {\n await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'save',\n error: toErrorMessage(err),\n recoverable: false,\n });\n throw new FsError({\n message: toErrorMessage(err),\n code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,\n path: filePath,\n cause: err,\n });\n }\n}\n\n/**\n * Atomically load, modify, and save a goal file under a file lock.\n * Prevents lost-update races when the autonomy engine and CLI /goal commands\n * write concurrently (both eternal and parallel engines may run simultaneously).\n *\n * `fn` receives the current GoalFile (or `null` if no goal exists yet)\n * and must return the updated GoalFile (or `null` to delete).\n */\nexport async function updateGoal(\n filePath: string,\n fn: (current: GoalFile | null) => GoalFile | null,\n events?: EventBus,\n): Promise<void> {\n const t0 = Date.now();\n await withFileLock(filePath, async () => {\n const current = await loadGoal(filePath, events);\n const next = fn(current);\n if (next) {\n await saveGoal(filePath, next, events);\n } else {\n try {\n await fsp.unlink(filePath);\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'delete',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'delete',\n error: toErrorMessage(err),\n recoverable: true,\n });\n // best-effort — file may not exist\n }\n }\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'update',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n });\n}\n\nexport function emptyGoal(goal: string): GoalFile {\n const now = new Date().toISOString();\n return {\n version: 1,\n goal,\n setAt: now,\n lastActivityAt: now,\n iterations: 0,\n engineState: 'idle',\n goalState: 'active',\n todoAttempts: {},\n journal: [],\n };\n}\n\n/**\n * Set progress estimate on a goal. Returns a new GoalFile.\n * Clamps progress to 0-100.\n */\nexport function setProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? clamped + '% complete',\n };\n}\n\n/**\n * Append a journal entry, bumping iteration counters and trimming the\n * ring buffer. Returns a new GoalFile — does not mutate the argument.\n */\nexport function appendJournal(goal: GoalFile, entry: Omit<JournalEntry, 'iteration' | 'at'>): GoalFile {\n const iteration = goal.iterations + 1;\n const at = new Date().toISOString();\n const full: JournalEntry = { ...entry, iteration, at };\n const journal = [...goal.journal, full];\n const trimmed = journal.length > MAX_JOURNAL_ENTRIES\n ? journal.slice(journal.length - MAX_JOURNAL_ENTRIES)\n : journal;\n return {\n ...goal,\n iterations: iteration,\n lastActivityAt: at,\n journal: trimmed,\n };\n}\n\n/**\n * Aggregate cumulative cost + tokens across all journal entries.\n */\nexport function summarizeUsage(goal: GoalFile): {\n totalCostUsd: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n iterationsWithUsage: number;\n} {\n let totalCostUsd = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let iterationsWithUsage = 0;\n for (const e of goal.journal) {\n if (typeof e.costUsd === 'number') totalCostUsd += e.costUsd;\n if (e.tokens) {\n totalInputTokens += e.tokens.input;\n totalOutputTokens += e.tokens.output;\n }\n if (typeof e.costUsd === 'number' || e.tokens) iterationsWithUsage++;\n }\n return { totalCostUsd, totalInputTokens, totalOutputTokens, iterationsWithUsage };\n}\n\nconst DOLLAR = '\\u0024';\n\n/** Format the goal + recent journal as a human-readable status block. */\nexport function formatGoal(goal: GoalFile, journalLimit = 10): string {\n const lines: string[] = [];\n\n // Header — show refined goal, with original as annotation if different\n const displayGoal = goal.refinedGoal || goal.goal;\n lines.push(color.bold('Goal') + ': ' + displayGoal);\n if (goal.refinedGoal && goal.refinedGoal !== goal.goal) {\n const snippet = goal.goal.length > 60 ? goal.goal.slice(0, 60) + '…' : goal.goal;\n lines.push(color.dim(' (original: \"' + snippet + '\")'));\n }\n\n // Progress bar (20-segment)\n if (typeof goal.progress === 'number') {\n const pct = Math.min(100, Math.max(0, Math.round(goal.progress)));\n const filled = Math.round(pct / 5);\n const empty = 20 - filled;\n const bar = color.green('█'.repeat(filled)) + color.dim('░'.repeat(empty));\n lines.push('Progress: ' + bar + ' ' + color.bold(pct + '%'));\n if (goal.progressNote) {\n lines.push(' ' + color.dim(goal.progressNote));\n }\n // Trend indicator\n if (goal.progressTrend) {\n const trendIcon = goal.progressTrend === 'accelerating' ? '🚀'\n : goal.progressTrend === 'stalling' ? '⚠️'\n : '➡️';\n lines.push(' Trend: ' + trendIcon + ' ' + goal.progressTrend);\n }\n }\n\n // Deliverables checklist\n if (goal.deliverables && goal.deliverables.length > 0) {\n lines.push('');\n lines.push(color.bold('Deliverables:'));\n for (const d of goal.deliverables) {\n const done = /^\\[[x✓]\\]|✅|\\(done\\)/i.test(d);\n const marker = done ? color.green('✓') : color.dim('○');\n lines.push(' ' + marker + ' ' + d);\n }\n }\n\n lines.push('');\n lines.push('Set: ' + goal.setAt);\n lines.push('Last activity: ' + goal.lastActivityAt);\n lines.push('Iterations: ' + goal.iterations);\n const stateLabel = goal.goalState ?? 'active';\n lines.push('State: ' + stateLabel + (goal.iterations > 0 ? ' (iteration #' + goal.iterations + ')' : ''));\n lines.push('Engine: ' + goal.engineState);\n const usage = summarizeUsage(goal);\n if (usage.iterationsWithUsage > 0) {\n const spent = 'Spent: ' + DOLLAR + usage.totalCostUsd.toFixed(4)\n + ' (in ' + usage.totalInputTokens + ' / out ' + usage.totalOutputTokens\n + ' tokens across ' + usage.iterationsWithUsage + ' iterations)';\n lines.push(spent);\n }\n if (goal.journal.length > 0) {\n lines.push('');\n lines.push('Recent journal (last ' + Math.min(journalLimit, goal.journal.length) + '):');\n const tail = goal.journal.slice(-journalLimit);\n for (const e of tail) {\n const mark = e.status === 'success' ? '✓' : e.status === 'failure' ? '✗' : e.status === 'aborted' ? '⊘' : '·';\n const note = e.note ? ' — ' + e.note : '';\n const cost = typeof e.costUsd === 'number' ? ' (' + DOLLAR + e.costUsd.toFixed(4) + ')' : '';\n lines.push(' #' + e.iteration + ' ' + mark + ' [' + e.source + '] ' + e.task + cost + note);\n }\n }\n return lines.join('\\n');\n}\n\n/** A single progress measurement at a point in time. */\nexport interface ProgressSnapshot {\n at: string;\n progress: number;\n note?: string | undefined;\n}\n\n/**\n * Parse [PROGRESS: N%] from agent final text.\n * Supports formats:\n * [PROGRESS: 45%]\n * [PROGRESS: 45%] — 3/5 deliverables done\n * [progress: 100%]\n * Returns null if no match.\n */\nexport function parseProgressFromText(text: string): { progress: number; note?: string } | null {\n const re = /\\[progress:\\s*(\\d{1,3})%\\]\\s*(?:[—-]\\s*(.+))?/i;\n const m = text.match(re);\n if (!m) return null;\n // Regex match guarantees capture group 1 exists, but use ?? fallback to\n // satisfy noUncheckedIndexedAccess without a non-null assertion.\n const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? '0', 10)));\n const note = m[2]?.trim() || undefined;\n return note === undefined ? { progress } : { progress, note };\n}\n\n/**\n * Record a progress measurement. Returns a new GoalFile with:\n * - progress + progressNote updated\n * - progressHistory appended (last 200 entries kept)\n * - progress trend computed (accelerating/steady/stalling)\n */\nexport function recordProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n const history = [...(goal.progressHistory ?? []), { at: new Date().toISOString(), progress: clamped, note }];\n // Keep last 200 snapshots\n const trimmed = history.length > 200 ? history.slice(-200) : history;\n\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? `${clamped}% complete`,\n progressHistory: trimmed,\n progressTrend: computeTrend(trimmed),\n };\n}\n\n/** Max progress history entries to retain. */\nexport const MAX_PROGRESS_HISTORY = 200;\n\nfunction computeTrend(history: ProgressSnapshot[]): 'accelerating' | 'steady' | 'stalling' | undefined {\n if (history.length < 3) return undefined;\n const recent = history.slice(-5);\n const deltas: number[] = [];\n for (let i = 1; i < recent.length; i++) {\n deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));\n }\n /* v8 ignore next -- unreachable: history.length>=3 guard above guarantees >=2 deltas */\n if (deltas.length < 2) return undefined;\n const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n if (avgDelta > 2) return 'accelerating';\n if (avgDelta < -1) return 'stalling';\n return 'steady';\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\nexport interface PromptEntry {\n id: string;\n title: string;\n content: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PromptStore {\n list(): Promise<PromptEntry[]>;\n get(id: string): Promise<PromptEntry | null>;\n save(entry: PromptEntry): Promise<void>;\n delete(id: string): Promise<boolean>;\n find(query: string): Promise<PromptEntry[]>;\n}\n\ninterface RawPromptFile {\n version: 1;\n entry: PromptEntry;\n}\n\nexport class DefaultPromptStore implements PromptStore {\n private readonly dir: string;\n\n constructor(paths: WstackPaths) {\n this.dir = paths.globalPrompts;\n }\n\n async list(): Promise<PromptEntry[]> {\n await ensureDir(this.dir);\n const entries: PromptEntry[] = [];\n try {\n const files = await fs.readdir(this.dir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const raw: RawPromptFile = JSON.parse(\n await fs.readFile(path.join(this.dir, file), 'utf8'),\n );\n entries.push(raw.entry);\n } catch {\n // skip corrupt files\n }\n }\n } catch {\n // dir doesn't exist yet\n }\n return entries.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n async get(id: string): Promise<PromptEntry | null> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n const raw: RawPromptFile = JSON.parse(await fs.readFile(file, 'utf8'));\n return raw.entry;\n } catch {\n return null;\n }\n }\n\n async save(entry: PromptEntry): Promise<void> {\n await ensureDir(this.dir);\n const file = path.join(this.dir, `${entry.id}.json`);\n const raw: RawPromptFile = { version: 1, entry };\n await atomicWrite(file, JSON.stringify(raw, null, 2));\n }\n\n async delete(id: string): Promise<boolean> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n await fs.unlink(file);\n return true;\n } catch {\n return false;\n }\n }\n\n async find(query: string): Promise<PromptEntry[]> {\n const all = await this.list();\n const lower = query.toLowerCase();\n return all.filter(\n (e) =>\n e.title.toLowerCase().includes(lower) ||\n e.content.toLowerCase().includes(lower) ||\n e.tags.some((t) => t.toLowerCase().includes(lower)),\n );\n }\n\n /** Create a new entry and return it. Does NOT persist — call save() afterwards. */\n createNew(title: string, content: string, tags: string[] = []): PromptEntry {\n const now = new Date().toISOString();\n return {\n id: randomUUID().slice(0, 8),\n title,\n content,\n tags,\n createdAt: now,\n updatedAt: now,\n };\n }\n}","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport type { SyncCategory, SyncConfig } from '../types/config.js';\nimport { FsError, WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport const ALL_SYNC_CATEGORIES: SyncCategory[] = ['settings', 'skills', 'prompts', 'memory', 'history'];\n\nexport interface SyncResult {\n ok: boolean;\n action: 'push' | 'pull';\n categories: SyncCategory[];\n committedAt?: string | undefined;\n message: string;\n}\n\ninterface SyncStateFile {\n version: 1;\n sha: string;\n lastSyncedAt: string;\n localRev: string;\n}\n\n/**\n * CloudSync — push/pull user-selected ~/.wrongstack categories to a\n * private GitHub repo. No git CLI needed; uses GitHub REST API via fetch.\n * The token is stored encrypted via SecretVault (field named `githubToken`\n * so the vault walker picks it up automatically).\n */\nexport class CloudSync {\n private readonly statePath: string;\n private state: SyncStateFile | null = null;\n\n constructor(\n private readonly paths: WstackPaths,\n private readonly getConfig: () => SyncConfig | null,\n private readonly setConfig: (c: SyncConfig) => Promise<void>,\n ) {\n this.statePath = path.join(paths.globalRoot, 'sync-state.json');\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n async status(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) {\n return 'CloudSync: disabled. Run `/sync enable` to activate.';\n }\n const last = this.state?.lastSyncedAt;\n const since = last ? timeAgo(last) : 'never';\n return [\n `CloudSync: enabled`,\n ` repo: ${cfg.repo}`,\n ` categories: ${cfg.categories.join(', ')}`,\n ` last sync: ${since}`,\n ].join('\\n');\n }\n\n async enable(_repo: string, _categories: SyncCategory[]): Promise<string> {\n // Persisted by the slash command via configStore.update.\n return 'Enable via /sync enable.';\n }\n\n async disable(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg) return 'CloudSync is not configured.';\n const next = { ...cfg, enabled: false };\n await this.setConfig(next);\n return 'CloudSync disabled. Local data kept.';\n }\n\n async push(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'push', categories: [], message: 'Not enabled.' };\n\n const parts = cfg.repo.split('/');\n const owner = expectDefined(parts[0]);\n const repoName = expectDefined(parts[1]);\n const branch = 'main';\n const baseTreeSha = this.state?.sha;\n\n const { treeEntries, rev } = await this.buildLocalTree(cfg.categories);\n const newTreeSha = await this.createGitTree(token, owner, repoName, treeEntries, baseTreeSha);\n\n const commitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n baseTreeSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n\n try {\n await this.updateRef(token, owner, repoName, branch, commitSha);\n } catch (err) {\n // 422 = not a fast forward — remote branch moved. Fetch latest SHA and retry.\n if (err instanceof Error && err.message.includes('422')) {\n const remote = await this.getRef(token, owner, repoName, branch);\n const currentSha = remote.object.sha;\n const rebasedCommitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n currentSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n await this.updateRef(token, owner, repoName, branch, rebasedCommitSha);\n } else {\n throw err;\n }\n }\n\n const syncState: SyncStateFile = {\n version: 1,\n sha: commitSha,\n lastSyncedAt: new Date().toISOString(),\n localRev: rev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'push',\n categories: cfg.categories,\n committedAt: commitSha,\n message: `Pushed ${cfg.categories.join(', ')} to ${cfg.repo}. Commit: ${commitSha.slice(0, 7)}`,\n };\n }\n\n async pull(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'pull', categories: [], message: 'Not enabled.' };\n\n const pullParts = cfg.repo.split('/');\n const owner = expectDefined(pullParts[0]);\n const repoName = expectDefined(pullParts[1]);\n\n const branchData = await this.getRef(token, owner, repoName, 'main');\n const currentSha = branchData.object.sha;\n\n const commitData = await this.getCommit(token, owner, repoName, currentSha);\n const treeSha = commitData.tree.sha;\n\n const treeEntries = await this.getTreeEntries(token, owner, repoName, treeSha);\n\n for (const entry of treeEntries) {\n if (entry.type !== 'blob') continue;\n\n // Paths look like \"data/{category}/...\" — extract the category\n const segments = entry.path.split('/');\n if (segments[0] !== 'data' || !segments[1]) continue;\n const cat = segments[1] as SyncCategory;\n if (!['settings', 'skills', 'prompts', 'memory', 'history'].includes(cat)) continue;\n\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n\n // Reconstruct relative path under the category dir. Remote trees are\n // untrusted input: a compromised sync repo could contain paths like\n // data/skills/../../config.json. Keep every write inside the selected\n // category root, and only allow subpaths for directory-backed categories.\n const rel = segments.slice(2).join('/');\n const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);\n\n const blobData = await this.getBlob(token, owner, repoName, entry.sha);\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.writeFile(destPath, Buffer.from(blobData, 'base64'));\n }\n\n const localRev = await this.hashLocalCategories(cfg.categories);\n const syncState: SyncStateFile = {\n version: 1,\n sha: currentSha,\n lastSyncedAt: new Date().toISOString(),\n localRev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'pull',\n categories: cfg.categories,\n committedAt: currentSha,\n message: `Pulled ${cfg.categories.join(', ')} from ${cfg.repo}. Commit: ${currentSha.slice(0, 7)}`,\n };\n }\n\n async hasLocalChanges(): Promise<boolean> {\n if (!this.state) return true;\n const cfg = this.getConfig();\n if (!cfg) return true;\n const current = await this.hashLocalCategories(cfg.categories);\n return current !== this.state.localRev;\n }\n\n async loadState(): Promise<void> {\n try {\n const raw = await fs.readFile(this.statePath, 'utf8');\n this.state = JSON.parse(raw) as SyncStateFile;\n } catch {\n this.state = null;\n }\n }\n\n // ── GitHub API helpers ──────────────────────────────────────────────\n\n private async githubFetch(\n token: string,\n owner: string,\n repo: string,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH',\n pathSegment: string,\n body?: unknown | undefined,\n ): Promise<unknown> {\n const url = `https://api.github.com/repos/${owner}/${repo}${pathSegment}`;\n const init: RequestInit = {\n signal: AbortSignal.timeout(15_000),\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Content-Type': 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new WrongStackError({\n message: `GitHub API ${method} ${pathSegment} failed (${res.status}): ${errText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { method, pathSegment, status: res.status, repo: `${owner}/${repo}` },\n });\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : {};\n }\n\n private async getRef(token: string, owner: string, repo: string, ref: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/refs/heads/${ref}`)) as {\n object: { sha: string };\n };\n }\n\n private async updateRef(token: string, owner: string, repo: string, ref: string, sha: string) {\n await this.githubFetch(token, owner, repo, 'PATCH', `/git/refs/heads/${ref}`, {\n sha,\n force: false,\n });\n }\n\n private async getCommit(token: string, owner: string, repo: string, sha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/commits/${sha}`)) as {\n tree: { sha: string };\n message: string;\n };\n }\n\n private async getTreeEntries(token: string, owner: string, repo: string, treeSha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/trees/${treeSha}?recursive=1`)) as Array<{\n path: string;\n sha: string;\n type: 'blob' | 'tree';\n }>;\n }\n\n private async createCommit(\n token: string, owner: string, repo: string,\n treeSha: string, parentSha?: string | undefined, message = 'sync',\n ) {\n const body: Record<string, unknown> = { message, tree: treeSha };\n if (parentSha) body.parents = [parentSha];\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/commits', body)) as { sha: string };\n return result.sha;\n }\n\n private async createGitTree(\n token: string, owner: string, repo: string,\n entries: Array<{ path: string; content: string; mode: string }>,\n baseTreeSha?: string | undefined,\n ): Promise<string> {\n const tree = entries.map((e) => ({\n path: e.path,\n mode: e.mode,\n type: 'blob',\n content: e.content,\n }));\n const body: Record<string, unknown> = { tree };\n if (baseTreeSha) body.base_tree = baseTreeSha;\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/trees', body)) as { sha: string };\n return result.sha;\n }\n\n private async getBlob(token: string, owner: string, repo: string, sha: string): Promise<string> {\n const result = (await this.githubFetch(token, owner, repo, 'GET', `/git/blobs/${sha}`)) as { content: string };\n return result.content;\n }\n\n // ── Local file helpers ──────────────────────────────────────────────\n\n private async buildLocalTree(categories: SyncCategory[]): Promise<{\n treeEntries: Array<{ path: string; content: string; mode: string }>;\n rev: string;\n }> {\n const entries: Array<{ path: string; content: string; mode: string }> = [];\n const hashes: string[] = [];\n\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file, 'utf8');\n const rel = path.relative(localPath, file).replace(/\\\\/g, '/');\n entries.push({ path: `data/${cat}/${rel}`, content, mode: '100644' });\n hashes.push(content);\n }\n } else {\n const content = await fs.readFile(localPath, 'utf8');\n entries.push({ path: `data/${cat}`, content, mode: '100644' });\n hashes.push(content);\n }\n } catch {\n // skip missing files/dirs\n }\n }\n\n const rev = createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n return { treeEntries: entries, rev };\n }\n\n private async hashLocalCategories(categories: SyncCategory[]): Promise<string> {\n const hashes: string[] = [];\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file);\n hashes.push(content.toString('base64') + file);\n }\n } else {\n const content = await fs.readFile(localPath);\n hashes.push(content.toString('base64') + localPath);\n }\n } catch {\n // skip\n }\n }\n return createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n }\n\n private categoryToPath(cat: SyncCategory): string | null {\n switch (cat) {\n case 'settings': return this.paths.globalConfig;\n case 'skills': return this.paths.globalSkills;\n case 'prompts': return this.paths.globalPrompts;\n case 'memory': return this.paths.globalMemory;\n case 'history': return this.paths.historyFile;\n /* v8 ignore next -- unreachable: SyncCategory is exhaustively matched above */\n default: return null;\n }\n }\n\n private async walkDir(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await this.walkDir(full, base)));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n\nfunction resolvePulledCategoryPath(\n cat: SyncCategory,\n localPath: string,\n rel: string,\n remotePath: string,\n): string {\n const directoryBacked = cat === 'skills' || cat === 'prompts';\n if (!directoryBacked) {\n if (rel) throw new FsError({\n message: `Refusing nested CloudSync path for file category: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'nested_file_category', category: cat },\n });\n return localPath;\n }\n\n if (!rel) return localPath;\n const normalizedRel = path.normalize(rel);\n const traversesUp = normalizedRel === '..' || normalizedRel.startsWith(`..${path.sep}`);\n if (path.isAbsolute(normalizedRel) || traversesUp) {\n throw new FsError({\n message: `Refusing CloudSync path traversal: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'path_traversal', normalizedRel },\n });\n }\n\n const dest = path.resolve(localPath, normalizedRel);\n const root = path.resolve(localPath);\n const relative = path.relative(root, dest);\n /* v8 ignore start -- unreachable: the normalizedRel '..' guard above already rejects traversal */\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new FsError({\n message: `Refusing CloudSync path outside category root: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'outside_category_root', category: cat },\n });\n }\n /* v8 ignore stop */\n return dest;\n}\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n","import type { SessionEvent, SessionWriter } from '../types/session.js';\n\nexport type AuditLevel = 'minimal' | 'standard' | 'full';\n\n/**\n * Configuration for sampling high-volume events inside the bridge.\n * This allows callers (CLI, TUI, WebUI, plugins) to tune how aggressively\n * noisy events like tool progress are persisted.\n */\nexport interface ToolProgressSamplingOptions {\n /**\n * How often to persist 'log' and 'partial_output' progress events.\n * - 1 = every message (no sampling)\n * - 8 = keep the first message + every 8th after that (default)\n */\n sampleRate?: number | undefined;\n}\n\nexport interface SessionSamplingOptions {\n /** Controls sampling behavior for `tool_progress` events (only relevant at auditLevel 'full'). */\n toolProgress?: ToolProgressSamplingOptions | undefined;\n}\n\nexport interface SessionEventBridgeOptions {\n /** Sampling rules for high-volume audit events. */\n sampling?: SessionSamplingOptions | undefined;\n}\n\n/**\n * Small, safe helper that wraps a SessionWriter and enforces the\n * configured auditLevel.\n *\n * All appends are best-effort. Failures are swallowed (with optional\n * diagnostics) so they never crash the agent loop.\n */\nexport interface SessionEventBridge {\n /** Append an event if allowed by the current audit level. */\n append(event: SessionEvent): Promise<void>;\n /** Batch-append events allowed by the current audit level. */\n appendBatch(events: SessionEvent[]): Promise<void>;\n\n /** Current audit level. Reflects the latest {@link setAuditLevel} value. */\n readonly level: AuditLevel;\n\n /**\n * Change the audit level on a live bridge. Subsequent appends are filtered\n * by the new level — used by the TUI `/settings` picker to apply an\n * `auditLevel` change to the running session without a restart.\n */\n setAuditLevel(level: AuditLevel): void;\n\n /** Returns true if an event of this type should be written at the current level. */\n allows(type: SessionEvent['type']): boolean;\n}\n\n/** Core events that are always written regardless of auditLevel. */\nconst CORE_RECONSTRUCT_EVENTS = new Set<SessionEvent['type']>([\n 'session_start',\n 'session_resumed',\n 'user_input',\n 'llm_response',\n 'tool_result',\n 'checkpoint',\n 'file_snapshot',\n 'rewound',\n 'in_flight_start',\n 'in_flight_end',\n 'session_end',\n]);\n\n/**\n * Events that are considered \"standard\" audit detail.\n * These are lightweight and high-value for forensics.\n */\nconst STANDARD_AUDIT_EVENTS = new Set<SessionEvent['type']>([\n 'llm_request',\n 'tool_use',\n 'tool_call_start',\n 'tool_call_end',\n 'compaction',\n 'error',\n 'message_truncated',\n 'provider_retry',\n 'provider_error',\n]);\n\n/**\n * Events that are only allowed at 'full' audit level because they can be\n * very high volume (e.g. streaming tool output).\n */\nconst FULL_ONLY_EVENTS = new Set<SessionEvent['type']>([\n 'tool_progress',\n]);\n\n/**\n * \"full\" level allows everything (including potentially heavy events\n * that plugins or future code may emit).\n */\nfunction isAllowed(type: SessionEvent['type'], level: AuditLevel): boolean {\n if (CORE_RECONSTRUCT_EVENTS.has(type)) return true;\n if (level === 'minimal') return false;\n\n if (STANDARD_AUDIT_EVENTS.has(type)) return true;\n if (level === 'standard') return false;\n\n // 'full' level events (high volume)\n if (FULL_ONLY_EVENTS.has(type)) {\n return level === 'full';\n }\n\n // 'full' — allow everything else\n return true;\n}\n\n/**\n * Create a safe, audit-level-aware bridge around a SessionWriter.\n *\n * The bridge can also apply sampling for high-volume events (e.g. `tool_progress`)\n * when `auditLevel` is set to `'full'`.\n *\n * @example\n * const bridge = createSessionEventBridge(sessionWriter, 'full', {\n * sampling: {\n * toolProgress: { sampleRate: 5 } // more aggressive sampling\n * }\n * });\n */\nexport function createSessionEventBridge(\n writer:\n | SessionWriter\n | (() => SessionWriter | undefined | null)\n | undefined\n | null,\n level: AuditLevel = 'standard',\n options: SessionEventBridgeOptions = {},\n): SessionEventBridge {\n // Mutable so setAuditLevel() can re-tune a live bridge in place.\n let currentLevel: AuditLevel = level ?? 'standard';\n\n // Accept either a writer instance or a getter. A getter lets long-lived\n // hosts (CLI/TUI/WebUI) resolve the CURRENT writer on every append — when\n // the user resumes another session mid-run, audit events follow the swap\n // instead of being silently dropped into the old, closed writer.\n const resolveWriter: () => SessionWriter | undefined | null =\n typeof writer === 'function' ? writer : () => writer;\n\n // Internal sampling state for high-volume events (e.g. tool_progress).\n // Keyed by tool call id (or name as fallback) to keep sampling per-call.\n const progressCounters = new Map<string, number>();\n\n const toolProgressConfig = options.sampling?.toolProgress ?? {};\n const TOOL_PROGRESS_SAMPLE_RATE = toolProgressConfig.sampleRate ?? 8;\n\n /**\n * Decide whether a high-volume event should be sampled in.\n * Currently only implements sampling for 'tool_progress'.\n */\n function shouldSample(event: SessionEvent): boolean {\n if (event.type !== 'tool_progress') return true;\n\n const progEvent = event as Extract<SessionEvent, { type: 'tool_progress' }>;\n const innerType = progEvent.event?.type;\n\n // Always let through high-signal structured events\n if (innerType === 'warning' || innerType === 'metric' || innerType === 'file_changed') {\n return true;\n }\n\n // Sample noisy text streams (log / partial_output)\n if (innerType === 'log' || innerType === 'partial_output') {\n const key = progEvent.id || progEvent.name;\n const count = (progressCounters.get(key) || 0) + 1;\n progressCounters.set(key, count);\n\n // Always keep the first message + every Nth after that\n return count === 1 || (count % TOOL_PROGRESS_SAMPLE_RATE === 0);\n }\n\n return true;\n }\n\n return {\n get level() {\n return currentLevel;\n },\n\n setAuditLevel(next) {\n currentLevel = next ?? 'standard';\n },\n\n allows(type) {\n return isAllowed(type, currentLevel);\n },\n\n async append(event) {\n const target = resolveWriter();\n if (!target) return;\n if (!isAllowed(event.type, currentLevel)) return;\n\n // Apply sampling for high-volume events (only at 'full' level)\n if (!shouldSample(event)) return;\n\n try {\n await target.append(event);\n } catch (err) {\n // Best-effort: never let session logging break the agent.\n // The existing FileSessionWriter already does throttled warnings,\n // but we keep this wrapper silent by default to avoid log spam.\n // Callers that care can listen to EventBus 'session.damaged' etc.\n }\n },\n\n async appendBatch(events) {\n const target = resolveWriter();\n if (!target || events.length === 0) return;\n const allowed = events.filter(\n (e) => isAllowed(e.type, currentLevel) && shouldSample(e),\n );\n if (allowed.length === 0) return;\n try {\n await target.appendBatch(allowed);\n } catch {\n // best-effort — same contract as append()\n }\n },\n };\n}\n\n/** Convenience re-export of the allowed core set for tests/docs. */\nexport { CORE_RECONSTRUCT_EVENTS, STANDARD_AUDIT_EVENTS };\n\n/**\n * Safely extract the auditLevel from a (possibly partial) Config object.\n * Falls back to 'standard' if not present or invalid.\n */\nexport function resolveAuditLevel(\n cfg?: { session?: { auditLevel?: AuditLevel | undefined } | undefined } | null,\n): AuditLevel {\n const raw = cfg?.session?.auditLevel;\n if (raw === 'minimal' || raw === 'standard' || raw === 'full') {\n return raw;\n }\n return 'standard';\n}\n\n/**\n * Fully resolves the session logging configuration with sensible defaults.\n * This is the recommended way for the CLI / TUI / WebUI to read session config.\n */\nexport function resolveSessionLoggingConfig(\n cfg?: {\n session?: {\n auditLevel?: AuditLevel | undefined;\n sampling?: {\n toolProgress?: { sampleRate?: number | undefined };\n };\n };\n } | null,\n): {\n auditLevel: AuditLevel;\n sampling: {\n toolProgress: { sampleRate: number };\n };\n} {\n const session = cfg?.session ?? {};\n\n const auditLevel = resolveAuditLevel(cfg);\n\n const toolProgressSampleRate =\n session.sampling?.toolProgress?.sampleRate ?? 8;\n\n return {\n auditLevel,\n sampling: {\n toolProgress: {\n sampleRate: Math.max(1, Math.floor(toolProgressSampleRate)),\n },\n },\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/atomic-write.ts","../../src/utils/expect-defined.ts","../../src/utils/message-invariants.ts","../../src/utils/term.ts","../../src/utils/color.ts","../../src/utils/deep-merge.ts","../../src/utils/error.ts","../../src/utils/regex-guard.ts","../../src/utils/safe-json.ts","../../src/utils/wstack-paths.ts","../../src/storage/session-store.ts","../../src/storage/queue-store.ts","../../src/storage/attachment-store.ts","../../src/types/memory.ts","../../src/storage/memory-backend.ts","../../src/storage/memory-store.ts","../../src/storage/memory-graph-backend.ts","../../src/storage/memory-consolidator.ts","../../src/types/errors.ts","../../src/storage/config-store.ts","../../src/security/secret-vault.ts","../../src/types/context-window.ts","../../src/types/default-config.ts","../../src/storage/config-loader.ts","../../src/storage/config-migration.ts","../../src/storage/recovery-lock.ts","../../src/storage/session-reader.ts","../../src/utils/session-scoped-path.ts","../../src/storage/annotations-store.ts","../../src/replay/hash.ts","../../src/storage/replay-log-store.ts","../../src/storage/session-recovery.ts","../../src/storage/tool-audit-log.ts","../../src/storage/session-analyzer.ts","../../src/session-registry.ts","../../src/agent-status-tracker.ts","../../src/fleet-notifier.ts","../../src/storage/session-rewinder.ts","../../src/storage/todos-checkpoint.ts","../../src/storage/plan-store.ts","../../src/storage/plan-templates.ts","../../src/storage/task-store.ts","../../src/storage/director-state.ts","../../src/storage/goal-store.ts","../../src/storage/prompt-store.ts","../../src/storage/cloud-sync.ts","../../src/storage/session-event-bridge.ts"],"names":["path","fs","stat","resolve","open","projectHash","randomBytes","path3","path4","fsp2","fsp3","path5","path6","fs2","writeFile","mkdir","fs3","deepMerge","fs5","path8","os2","fsp5","path9","randomUUID","fs6","createHash","storageErrorString","fs7","path10","fs8","path11","stableStringify","fs9","sortKeys","path12","projectSlug","fs10","pidAlive","path13","fs11","path14","fsp6","fsp7","fsp8","fsp9","fsp10","lock","hostname","fsp11","fs12","path15","path16","fs13","relative"],"mappings":";;;;;;;;AAcA,eAAsB,WAAA,CACpB,UAAA,EACA,OAAA,EACA,IAAA,GAA2B,EAAC,EACb;AACf,EAAA,MAAM,GAAA,GAAWA,cAAQ,UAAU,CAAA;AACnC,EAAA,MAASC,GAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,EAAA,MAAM,GAAA,GAAWD,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAASA,eAAS,UAAU,CAAC,CAAA,CAAA,EAAI,WAAA,CAAY,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,IAAA,CAAM,CAAA;AAIhG,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,MAAA,MAASC,GAAA,CAAA,SAAA,CAAU,GAAA,EAAK,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,QAAA,EAAU,IAAA,CAAK,QAAA,IAAY,MAAA,EAAQ,CAAA;AAAA,IACpF,CAAA,MAAO;AACL,MAAA,MAASA,cAAU,GAAA,EAAK,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,MAASA,GAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAClC,MAAA,IAAI;AACF,QAAA,MAAM,GAAG,IAAA,EAAK;AAAA,MAChB,CAAA,SAAE;AACA,QAAA,MAAM,GAAG,KAAA,EAAM;AAAA,MACjB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAGA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAMC,KAAAA,GAAO,MAASD,GAAA,CAAA,IAAA,CAAK,UAAU,CAAA;AACrC,MAAA,IAAA,GAAOC,MAAK,IAAA,GAAO,GAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,GAAO,IAAA,CAAK,IAAA;AAAA,IACd;AACA,IAAA,IAAI,SAAS,KAAA,CAAA,EAAW;AACtB,MAAA,MAASD,GAAA,CAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IAC1B;AACA,IAAA,MAAM,eAAA,CAAgB,KAAK,UAAU,CAAA;AAAA,EACvC,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI;AACF,MAAA,MAASA,WAAO,GAAG,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAEA,eAAsB,UAAU,GAAA,EAA4B;AAC1D,EAAA,MAASA,GAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACzC;AAEA,eAAsB,YAAA,CACpB,UAAA,EACA,EAAA,EACA,IAAA,GAAwB,EAAC,EACb;AACZ,EAAA,MAAM,GAAA,GAAWD,cAAQ,UAAU,CAAA;AACnC,EAAA,MAASC,GAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,EAAA,MAAM,WAAgBD,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAASA,KAAA,CAAA,QAAA,CAAS,UAAU,CAAC,CAAA,KAAA,CAAO,CAAA;AACpE,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,GAAA;AACpC,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,GAAA;AAChC,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,EAAA,IAAI,MAAA;AAEJ,EAAA,WAAS;AACP,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAASC,GAAA,CAAA,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AACrC,MAAA,MAAM,MAAA,CAAO,UAAU,CAAA,EAAG,OAAA,CAAQ,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,EAAK,CAAA,CAAE,CAAA;AACrD,MAAA;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAG5C,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,MAASA,GAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,KAAS,UAAU,MAAM,GAAA;AAC7B,MAAA,IAAI;AACF,QAAA,MAAMC,KAAAA,GAAO,MAASD,GAAA,CAAA,IAAA,CAAK,QAAQ,CAAA;AACnC,QAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAIC,KAAAA,CAAK,UAAU,OAAA,EAAS;AACvC,UAAA,MAASD,WAAO,QAAQ,CAAA;AACxB,UAAA;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA,IAAW,SAAA,EAAW;AACrC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,UAAU,CAAA,CAAE,CAAA;AAAA,MAClE;AACA,MAAA,MAAM,IAAI,OAAA,CAAQ,CAACE,aAAY,UAAA,CAAWA,QAAAA,EAAS,EAAE,CAAC,CAAA;AAAA,IACxD;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,EAAA,EAAG;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,KAAA,EAAM;AAAA,IACtB,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAI;AACF,MAAA,MAASF,WAAO,QAAQ,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAMA,IAAM,sBAAA,uBAA6B,GAAA,CAAI,CAAC,SAAS,OAAA,EAAS,QAAA,EAAU,WAAW,CAAC,CAAA;AAEhF,eAAe,eAAA,CAAgB,MAAc,EAAA,EAA2B;AACtE,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,MAASA,GAAA,CAAA,MAAA,CAAO,MAAM,EAAE,CAAA;AACxB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,SAAS,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,KAAK,GAAG,CAAA;AACpC,EAAA,IAAI,OAAA;AACJ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,IAAI;AACF,MAAA,MAASA,GAAA,CAAA,MAAA,CAAO,MAAM,EAAE,CAAA;AACxB,MAAA;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,GAAU,GAAA;AACV,MAAA,MAAM,OAAQ,GAAA,EAA+B,IAAA;AAC7C,MAAA,IAAI,CAAC,QAAQ,CAAC,sBAAA,CAAuB,IAAI,IAAI,CAAA,IAAK,CAAA,KAAM,MAAA,CAAO,MAAA,EAAQ;AACrE,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,MAAM,IAAI,QAAQ,CAACE,QAAAA,KAAY,WAAWA,QAAAA,EAAS,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,IAC/D;AAAA,EACF;AACA,EAAA,MAAM,OAAA;AACR;;;ACtJO,SAAS,aAAA,CAAiB,OAA6B,KAAA,EAAmB;AAC/E,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,MAAM,MAAM,IAAI,KAAA,CAAkD,8BAA8B,CAAA;AAChG,IAAA,GAAA,CAAI,IAAA,GAAO,oBAAA;AACX,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,OAAO,KAAA;AACT;;;ACaO,SAAS,uBAAuB,QAAA,EAA0C;AAC/E,EAAA,MAAM,kBAA4B,EAAC;AACnC,EAAA,MAAM,qBAA+B,EAAC;AACtC,EAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,MAAM,MAAiB,EAAC;AAExB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,QAAA,CAAS,CAAC,CAAC,CAAA;AAC1C,IAAA,IAAI,GAAA,GAAM,QAAA;AAEV,IAAA,IAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACnB,MAAA,MAAM,OAAA,GAAU,aAAA,CAAc,QAAA,CAAS,CAAA,GAAI,CAAC,CAAC,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAA,EAAK,CAAC,MAAA,KAAW;AAC3C,QAAA,MAAM,OAAuB,EAAC;AAC9B,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,UAAA,IAAI,KAAA,CAAM,SAAS,UAAA,IAAc,CAAC,QAAQ,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AACvD,YAAA,eAAA,CAAgB,IAAA,CAAK,MAAM,EAAE,CAAA;AAC7B,YAAA,OAAA,GAAU,IAAA;AACV,YAAA;AAAA,UACF;AACA,UAAA,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,QACjB;AACA,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AACD,MAAA,GAAA,GAAM,QAAA,IAAY,GAAA;AAAA,IACpB;AAEA,IAAA,IAAI,aAAA,CAAc,GAAG,CAAA,EAAG;AACtB,MAAA,MAAM,UAAU,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,CAAC,CAAC,CAAA;AAC9C,MAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAA,EAAK,CAAC,MAAA,KAAW;AAC3C,QAAA,MAAM,OAAuB,EAAC;AAC9B,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,UAAA,IAAI,KAAA,CAAM,SAAS,aAAA,IAAiB,CAAC,QAAQ,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACnE,YAAA,kBAAA,CAAmB,IAAA,CAAK,MAAM,WAAW,CAAA;AACzC,YAAA,OAAA,GAAU,IAAA;AACV,YAAA;AAAA,UACF;AACA,UAAA,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,QACjB;AACA,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AACD,MAAA,GAAA,GAAM,QAAA,IAAY,GAAA;AAAA,IACpB;AAEA,IAAA,IAAI,cAAA,CAAe,GAAG,CAAA,EAAG;AACvB,MAAA,eAAA,EAAA;AACA,MAAA,OAAA,GAAU,IAAA;AACV,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACd;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,UAAU,GAAA,GAAM,QAAA;AAAA,IAC1B,MAAA,EAAQ,EAAE,OAAA,EAAS,eAAA,EAAiB,oBAAoB,eAAA;AAAgB,GAC1E;AACF;AAEA,SAAS,WAAW,GAAA,EAAmC;AACrD,EAAA,OAAO,aAAA,CAAc,GAAG,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAyB,CAAA,CAAE,SAAS,UAAU,CAAA;AAChF;AAEA,SAAS,cAAc,GAAA,EAAmC;AACxD,EAAA,OAAO,aAAA,CAAc,GAAG,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAA4B,CAAA,CAAE,SAAS,aAAa,CAAA;AACtF;AAEA,SAAS,WAAW,GAAA,EAAuC;AACzD,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,IAAI,GAAA,EAAK,IAAA,KAAS,WAAA,EAAa,OAAO,GAAA;AACtC,EAAA,KAAA,MAAW,KAAA,IAAS,aAAA,CAAc,GAAG,CAAA,EAAG;AACtC,IAAA,IAAI,MAAM,IAAA,KAAS,UAAA,EAAY,GAAA,CAAI,GAAA,CAAI,MAAM,EAAE,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,cAAc,GAAA,EAAuC;AAC5D,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,IAAI,GAAA,EAAK,IAAA,KAAS,MAAA,EAAQ,OAAO,GAAA;AACjC,EAAA,KAAA,MAAW,KAAA,IAAS,aAAA,CAAc,GAAG,CAAA,EAAG;AACtC,IAAA,IAAI,MAAM,IAAA,KAAS,aAAA,EAAe,GAAA,CAAI,GAAA,CAAI,MAAM,WAAW,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,cAAc,GAAA,EAA0C;AAC/D,EAAA,OAAO,GAAA,IAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GAAI,GAAA,CAAI,UAAU,EAAC;AAC5D;AAEA,SAAS,UAAA,CACP,KACA,EAAA,EACgB;AAChB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,GAAG,OAAO,GAAA;AACxC,EAAA,MAAM,IAAA,GAAO,EAAA,CAAG,GAAA,CAAI,OAAO,CAAA;AAC3B,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,GAAA,CAAI,OAAA,CAAQ,UAAU,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,QAAQ,CAAA,KAAM,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAC,CAAA,EAAG;AACxF,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAE,GAAG,GAAA,EAAK,OAAA,EAAS,IAAA,EAAK;AACjC;AAEA,SAAS,eAAe,GAAA,EAAuB;AAC7C,EAAA,IAAI,OAAO,IAAI,OAAA,KAAY,QAAA,SAAiB,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA;AAC1E,EAAA,OAAO,GAAA,CAAI,QAAQ,MAAA,KAAW,CAAA;AAChC;;;AC5GA,IAAM,YAAY,MAAe,OAAO,YAAY,WAAA,IAAe,CAAC,CAAC,OAAA,CAAQ,MAAA;AAItE,SAAS,WAAA,GAAuB;AACrC,EAAA,OAAO,SAAA,EAAU,IAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,KAAK,CAAA;AACpD;;;ACxBA,IAAM,aAAa,MAAe;AAChC,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,GAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,WAAW,GAAG,OAAO,IAAA;AAC7C,EAAA,OAAO,WAAA,EAAY;AACrB,CAAA;AAEA,SAAS,QAAQ,KAAA,EAAoC;AACnD,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAChC,EAAA,IAAI,KAAA,CAAM,IAAA,EAAK,KAAM,EAAA,EAAI,OAAO,KAAA;AAChC,EAAA,OAAO,CAAC,qBAAA,CAAsB,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AACjD;AAEA,IAAM,QAAQ,UAAA,EAAW;AAEzB,IAAM,IAAA,GACJ,CAACC,KAAAA,EAAc,KAAA,KACf,CAAC,CAAA,KACC,KAAA,GAAQ,CAAA,KAAA,EAAQA,KAAI,CAAA,CAAA,EAAI,CAAC,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA,CAAA,GAAM,CAAA;AAEzC,IAAM,KAAA,GAAQ;AAAA,EACnB,KAAA,EAAO,IAAA,CAAK,GAAA,EAAK,GAAG,CAAA;AAAA,EACpB,IAAA,EAAM,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EACpB,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EACnB,MAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EACtB,SAAA,EAAW,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EACzB,GAAA,EAAK,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACpB,KAAA,EAAO,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACvB,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACrB,OAAA,EAAS,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACxB,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACrB,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACrB,KAAA,EAAO,IAAA,CAAK,UAAA,EAAY,IAAI,CAAA;AAAA,EAC5B,IAAA,EAAM,IAAA,CAAK,UAAA,EAAY,IAAI,CAAA;AAAA,EAC3B,KAAA,EAAO,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,OAAA,EAAS,IAAA,CAAK,IAAA,EAAM,IAAI;AAC1B,CAAA;;;ACtBO,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EAC1C,WAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAOM,SAAS,iBAAiB,CAAA,EAAuB;AACtD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,KAAM,IAAA,IAAS,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,UAAW,CAAA;AACxF;AA6EO,SAAS,SAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,GAA4B,EAAC,EACpB;AACT,EAAA,MAAM;AAAA,IACJ,kBAAA,GAAqB,cAAA;AAAA,IACrB,SAAA,GAAY,SAAA;AAAA,IACZ,YAAA,GAAe,IAAA;AAAA,IACf;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAIA,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,KAAK,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/C,IAAA,IACE,cAAc,mBAAA,IACd,gBAAA,CAAiB,IAAI,CAAA,IACrB,gBAAA,CAAiB,KAAK,CAAA,EACtB;AACA,MAAA,OAAO,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,EAAM,GAAG,KAAK,CAAC,CAAC,CAAA;AAAA,IACzC;AACA,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAGA,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,KAAK,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/C,IAAA,OAAO,kBAAA,KAAuB,iBAAiB,KAAA,GAAQ,IAAA;AAAA,EACzD;AAGA,EAAA,MAAM,OAAA,GAAU,IAAA;AAChB,EAAA,MAAM,QAAA,GAAW,KAAA;AACjB,EAAA,MAAM,GAAA,GAA+B,EAAE,GAAG,OAAA,EAAQ;AAElD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC7C,IAAA,IAAI,YAAA,IAAgB,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,EAAG;AAEjD,IAAA,MAAM,QAAA,GAAW,IAAI,CAAC,CAAA;AACtB,IAAA,IACE,MAAM,IAAA,IACN,OAAO,MAAM,QAAA,IACb,CAAC,MAAM,OAAA,CAAQ,CAAC,KAChB,QAAA,KAAa,IAAA,IACb,OAAO,QAAA,KAAa,QAAA,IACpB,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EACvB;AAEA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,QAAA,EAAU,GAAG,OAAO,CAAA;AAAA,IACzC,CAAA,MAAA,IAAW,MAAM,OAAA,CAAQ,CAAC,KAAK,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAMtD,MAAA,IAAI,0BAAA,IAA8B,CAAC,gBAAA,CAAiB,CAAC,CAAA,EAAG;AACtD,QAAA,0BAAA,CAA2B,CAAA,EAAG,QAAA,CAAS,MAAA,EAAQ,CAAA,CAAE,MAAM,CAAA;AAAA,MACzD;AACA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,QAAA,EAAU,GAAG,OAAO,CAAA;AAAA,IACzC,CAAA,MAAA,IAAW,MAAM,MAAA,EAAW;AAG1B,MAAA,IACE,0BAAA,IACA,MAAM,OAAA,CAAQ,CAAC,KACf,CAAC,gBAAA,CAAiB,CAAC,CAAA,EACnB;AACA,QAAA,MAAM,cAAc,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,SAAS,MAAA,GAAS,CAAA;AAChE,QAAA,0BAAA,CAA2B,CAAA,EAAG,WAAA,EAAa,CAAA,CAAE,MAAM,CAAA;AAAA,MACrD;AACA,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EAIF;AAEA,EAAA,OAAO,GAAA;AACT;;;AChMO,SAAS,eAAe,GAAA,EAAsB;AACnD,EAAA,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AACxD;;;ACMA,IAAM,eAAA,GAAkB,GAAA;AAGxB,IAAM,kBAAA,GAA4C;AAAA,EAChD,0BAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAYO,SAAS,gBAAA,CAAiB,SAAiB,KAAA,EAA4C;AAC5F,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,0BAAA,EAA2B;AAAA,EACzD;AACA,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,kBAAA,EAAmB;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,SAAS,eAAA,EAAiB;AACpC,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,CAAA,gBAAA,EAAmB,eAAe,CAAA,WAAA,CAAA,EAAc;AAAA,EAC9E;AACA,EAAA,KAAA,MAAW,MAAM,kBAAA,EAAoB;AACnC,IAAA,IAAI,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA,EAAG;AACpB,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,MAAA,EACE;AAAA,OACJ;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,OAAO,EAAE,IAAI,IAAA,EAAM,KAAA,EAAO,IAAI,MAAA,CAAO,OAAA,EAAS,KAAK,CAAA,EAAE;AAAA,EACvD,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EAAQ,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU;AAAA,KAC/C;AAAA,EACF;AACF;;;ACjDO,SAAS,SAAA,CAAuB,KAAA,EAAe,QAAA,GAAW,GAAA,EAA+B;AAC9F,EAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,CAAA,qBAAA,EAAwB,QAAQ,CAAA,OAAA,CAAA,EAAU;AAAA,EACvE;AACA,EAAA,IAAI;AACF,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,EAAO;AAAA,EACnD,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO,eAAe,GAAG;AAAA,KAC3B;AAAA,EACF;AACF;ACwEO,SAAS,YAAY,OAAA,EAAyB;AACnD,EAAA,OAAO,UAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAY,KAAA,CAAA,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AACrF;AAMO,SAAS,YAAY,OAAA,EAAyB;AACnD,EAAA,MAAM,IAAA,GAAO,OAAA,CAAa,KAAA,CAAA,QAAA,CAAS,OAAO,CAAC,CAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,UAAA,CAAW,QAAQ,CAAA,CAAE,OAAY,KAAA,CAAA,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACxF,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACxB;AAGA,SAAS,QAAQ,IAAA,EAAsB;AACrC,EAAA,OACE,IAAA,CACG,WAAA,EAAY,CAEZ,OAAA,CAAQ,eAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,IAAK,SAAA;AAEvB;AAqBO,SAAS,gBAAA,GAA2B;AACzC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,iBAAiB,CAAA;AAC7C,EAAA,IAAI,OAAA,IAAW,QAAQ,IAAA,EAAK,CAAE,SAAS,CAAA,EAAG,OAAY,cAAQ,OAAO,CAAA;AACrE,EAAA,OAAY,KAAA,CAAA,IAAA,CAAQ,EAAA,CAAA,OAAA,EAAQ,EAAG,aAAa,CAAA;AAC9C;AAEO,SAAS,mBAAmB,IAAA,EAAsC;AAGvE,EAAA,MAAM,UAAA,GACJ,IAAA,CAAK,UAAA,KAAe,IAAA,CAAK,QAAA,GAAgB,WAAK,IAAA,CAAK,QAAA,EAAU,aAAa,CAAA,GAAI,gBAAA,EAAiB,CAAA;AACjG,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,IAAA,CAAK,WAAW,CAAA;AACzC,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,IAAA,CAAK,WAAW,CAAA;AACzC,EAAA,MAAM,UAAA,GAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,UAAA,EAAY,IAAI,CAAA;AACzD,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,SAAA,EAAW,UAAA;AAAA,IACX,YAAA,EAAmB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,aAAa,CAAA;AAAA,IACjD,UAAA,EAAiB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,MAAM,CAAA;AAAA,IACxC,YAAA,EAAmB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAC/C,YAAA,EAAmB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,QAAQ,CAAA;AAAA,IAC5C,aAAA,EAAoB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,SAAS,CAAA;AAAA,IAC9C,QAAA,EAAe,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA;AAAA,IACvC,WAAA,EAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,OAAA,EAAS,iBAAiB,CAAA;AAAA,IAC7D,kBAAA,EAAyB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,OAAA,EAAS,qBAAqB,CAAA;AAAA,IACxE,WAAA,EAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,SAAS,CAAA;AAAA,IAC5C,OAAA,EAAc,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,MAAA,EAAQ,gBAAgB,CAAA;AAAA,IACvD,UAAA;AAAA,IACA,oBAAA,EAA2B,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,gBAAgB,CAAA;AAAA,IAC5D,aAAA,EAAoB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAChD,eAAA,EAAsB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,UAAU,CAAA;AAAA,IACjD,YAAA,EAAmB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,YAAY,CAAA;AAAA,IAChD,WAAA,EAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAC9C,kBAAA,EAAyB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,mBAAmB,CAAA;AAAA,IAC7D,eAAA,EAAsB,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,eAAe,aAAa,CAAA;AAAA,IACzE,mBAAA,EAA0B,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,eAAe,WAAW,CAAA;AAAA,IAC3E,eAAA,EAAsB,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,eAAe,QAAQ,CAAA;AAAA,IACpE,kBAAA,EAAyB,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,eAAe,WAAW,CAAA;AAAA,IAC1E,WAAA,EAAa,IAAA;AAAA,IACb,WAAA,EAAa,IAAA;AAAA,IACb,WAAA,EAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAC9C,YAAA,EAAmB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA;AAAA,IAC3C,iBAAA,EAAwB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,aAAa,CAAA;AAAA,IACtD,iBAAA,EAAwB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,kBAAkB,CAAA;AAAA,IAC3D,WAAA,EAAkB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAC9C,gBAAA,EAAuB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IACnD,UAAA,EAAiB,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,IAC7C,eAAe,CAACC,YAAAA,KAA6B,WAAK,UAAA,EAAY,UAAA,EAAYA,cAAa,aAAa;AAAA,GACtG;AACF;;;ACnKA,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,iBAAA,EAAmB,GAAG,EAC9B,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,QAAA,EAAU,EAAE,CAAA,CACpB,KAAA,CAAM,GAAG,EAAE,CAAA;AAChB;AAeA,SAAS,iBAAA,CAAkB,WAAmB,KAAA,EAAwB;AACpE,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAClC,EAAA,MAAM,IAAA,GAAO,UAAU,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AACtD,EAAA,MAAM,MAAA,GAASC,WAAAA,CAAY,CAAC,CAAA,CAAE,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,YAAY,KAAA,GAAQ,CAAA,CAAA,EAAI,aAAA,CAAc,KAAK,CAAC,CAAA,CAAA,GAAK,EAAA;AACvD,EAAA,OAAO,GAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,SAAS,IAAI,MAAM,CAAA,CAAA;AAC/C;AAmCO,IAAM,mBAAA,GAAN,MAAM,oBAAA,CAA4C;AAAA,EACtC,GAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,UAAA,uBAAiB,GAAA,EAA4B;AAAA,EACtD,WAAA,GAAsC,IAAA;AAAA,EAC9C,OAAwB,sBAAA,GAAyB,EAAA;AAAA,EAEjD,YAAY,IAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,iBAAiB,IAAA,CAAK,cAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,SAAA,EAA0B;AACvC,IAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,SAAS,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAIQ,SACN,SAAA,EACA,QAAA,EACA,SAAA,EACA,OAAA,EACA,YACA,KAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAChC,SAAA;AAAA,MACA,KAAA,EAAO,SAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU;AAAC,KACxC,CAAA;AAAA,EACH;AAAA,EAEQ,UACN,SAAA,EACA,QAAA,EACA,WACA,OAAA,EACA,UAAA,EACA,YACA,KAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MACjC,SAAA;AAAA,MACA,KAAA,EAAO,SAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,MACjD,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU;AAAC,KACxC,CAAA;AAAA,EACH;AAAA,EAEQ,SAAA,CACN,SAAA,EACA,QAAA,EACA,SAAA,EACA,OACA,WAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MACjC,SAAA;AAAA,MACA,KAAA,EAAO,SAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,IAAY,SAAA,GAAoB;AAC9B,IAAA,OAAYC,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,cAAc,CAAA;AAAA,EAC3C;AAAA;AAAA,EAGQ,WAAA,CAAY,IAAY,GAAA,EAAyC;AACvE,IAAA,OAAYA,WAAK,IAAA,CAAK,GAAA,EAAK,GAAG,EAAE,CAAA,EAAG,GAAG,CAAA,CAAE,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,eAAe,EAAA,EAA6B;AACxD,IAAA,MAAM,UAAeA,KAAA,CAAA,OAAA,CAAaA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,EAAE,CAAC,CAAA;AACpD,IAAA,MAAM,UAAU,OAAO,CAAA;AACvB,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,IAAA,EAAkE;AAC7E,IAAA,MAAM,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACzC,IAAA,MAAM,EAAA,GACJ,IAAA,CAAK,EAAA,IAAM,IAAA,CAAK,GAAG,MAAA,GAAS,CAAA,GACxB,IAAA,CAAK,EAAA,GACL,iBAAA,CAAkB,SAAA,EAAW,IAAA,CAAK,KAAA,IAAS,KAAK,QAAQ,CAAA;AAC9D,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA,CAAe,EAAE,CAAA;AAC7C,IAAA,MAAM,OAAYA,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,GAAQA,KAAA,CAAA,QAAA,CAAS,EAAE,CAAC,CAAA,MAAA,CAAQ,CAAA;AAC7D,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,EAAM,GAAA,EAAK,GAAK,CAAA;AAAA,IAC1C,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,UAAU,EAAA,EAAI,IAAA,EAAM,UAAU,cAAA,CAAe,GAAG,GAAG,KAAK,CAAA;AAC7D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,6BAAA,EAAgC,cAAA,CAAe,GAAG,CAAC,CAAA,CAAA;AAAA,QACnD,EAAE,OAAO,GAAA;AAAI,OACf;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAI,iBAAA,CAAkB,EAAA,EAAI,QAAQ,SAAA,EAAW,IAAA,EAAM,KAAK,MAAA,EAAQ;AAAA,QAC7E,GAAA,EAAK,QAAA;AAAA,QACL,QAAA,EAAU,IAAA;AAAA,QACV,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,OAAA,EAAS,CAAC,CAAA,KAAM,IAAA,CAAK,cAAc,CAAC;AAAA,OACrC,CAAA;AACD,MAAA,IAAA,CAAK,SAAA,CAAU,IAAI,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,CAAK,GAAA,KAAQ,EAAE,CAAA;AAC7D,MAAA,OAAO,MAAA;AAAA,IAET,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,MAAA,CAAO,OAAM,CAAE,KAAA,CAAM,CAAC,CAAA,KAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU;AAAA,QAC5D,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,mCAAA;AAAA,QACP,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AAAA,QAClD,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAC,CAAA;AACH,MAAA,IAAA,CAAK,UAAU,EAAA,EAAI,IAAA,EAAM,UAAU,cAAA,CAAe,GAAG,GAAG,IAAI,CAAA;AAC5D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EAEF;AAAA,EAEA,MAAM,OAAO,EAAA,EAAqC;AAChD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA;AAC/B,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,EAAM,GAAA,EAAK,GAAK,CAAA;AAAA,IAE1C,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,UAAU,EAAA,EAAI,IAAA,EAAM,UAAU,cAAA,CAAe,GAAG,GAAG,KAAK,CAAA;AAC7D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,wBAAA,EAA2B,EAAE,CAAA,cAAA,EAAiB,cAAA,CAAe,GAAG,CAAC,CAAA,CAAA;AAAA,QACjE,EAAE,OAAO,GAAA;AAAI,OACf;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,IAAI,iBAAA;AAAA,QACjB,EAAA;AAAA,QACA,MAAA;AAAA,QAAA,iBACA,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QACvB;AAAA,UACE,EAAA;AAAA,UACA,KAAA,EAAO,KAAK,QAAA,CAAS,KAAA;AAAA,UACrB,QAAA,EAAU,KAAK,QAAA,CAAS;AAAA,SAC1B;AAAA,QACA,IAAA,CAAK,MAAA;AAAA,QACL;AAAA,UACE,OAAA,EAAS,IAAA;AAAA;AAAA;AAAA;AAAA,UAIT,GAAA,EAAUA,cAAQ,IAAI,CAAA;AAAA,UACtB,QAAA,EAAU,IAAA;AAAA,UACV,gBAAgB,IAAA,CAAK,cAAA;AAAA,UACrB,OAAA,EAAS,CAAC,CAAA,KAAM,IAAA,CAAK,cAAc,CAAC;AAAA;AACtC,OACF;AACA,MAAA,IAAA,CAAK,SAAA,CAAU,IAAI,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,CAAK,GAAA,KAAQ,EAAE,CAAA;AAC7D,MAAA,OAAO,EAAE,QAAQ,IAAA,EAAK;AAAA,IAExB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,MAAA,CAAO,OAAM,CAAE,KAAA,CAAM,CAAC,CAAA,KAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU;AAAA,QAC5D,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,mCAAA;AAAA,QACP,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AAAA,QAClD,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAC,CAAA;AACH,MAAA,IAAA,CAAK,UAAU,EAAA,EAAI,IAAA,EAAM,UAAU,cAAA,CAAe,GAAG,GAAG,IAAI,CAAA;AAC5D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EAEF;AAAA,EAEA,MAAM,KAAK,EAAA,EAAkC;AAC3C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,OAAA,GAAiC,SAAA;AACrC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,QAAA,GAAW,KAAA;AACf,IAAA,IAAI;AAIF,MAAA,MAAM,CAAA,GAAI,MAAU,GAAA,CAAA,IAAA,CAAK,IAAI,CAAA;AAC7B,MAAA,MAAML,QAA0C,EAAE,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,EAAM,EAAE,IAAA,EAAK;AAGnF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA;AACrC,MAAA,IAAI,MAAA,IAAU,OAAO,OAAA,KAAYA,KAAAA,CAAK,WAAW,MAAA,CAAO,IAAA,KAASA,MAAK,IAAA,EAAM;AAC1E,QAAA,QAAA,GAAW,IAAA;AAGX,QAAA,IAAA,CAAK,UAAA,CAAW,OAAO,EAAE,CAAA;AACzB,QAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,EAAA,EAAI,MAAM,CAAA;AAC9B,QAAA,OAAO,MAAA,CAAO,IAAA;AAAA,MAChB;AAGA,MAAA,MAAM,GAAA,GAAM,MAAU,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC3C,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA;AACpD,MAAA,MAAM,SAAyB,EAAC;AAChC,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AACvC,UAAA,IACE,MAAA,KAAW,IAAA,IACX,OAAO,MAAA,KAAW,QAAA,IAClB,OAAQ,MAAA,CAA0C,IAAA,KAAS,QAAA,IAC3D,OAAQ,MAAA,CAAwC,EAAA,KAAO,QAAA,EACvD;AACA,YAAA,MAAA,CAAO,KAAK,MAAsB,CAAA;AAAA,UACpC;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AACA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,cAAA,CAAe,EAAA,EAAI,MAAM,CAAA;AAC3C,MAAA,MAAM,EAAE,QAAA,EAAU,KAAA,KAAU,IAAA,CAAK,MAAA,CAAO,QAAQ,EAAE,CAAA;AAElD,MAAA,MAAM,YAAA,GAAe,oBAAoB,MAAM,CAAA;AAC/C,MAAA,MAAM,OAAoB,EAAE,QAAA,EAAU,MAAM,MAAA,EAAQ,QAAA,EAAU,OAAO,YAAA,EAAa;AAGlF,MAAA,IAAI,IAAA,CAAK,UAAA,CAAW,IAAA,IAAQ,oBAAA,CAAoB,sBAAA,EAAwB;AAEtE,QAAA,MAAM,SAAS,IAAA,CAAK,UAAA,CAAW,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAC7C,QAAA,IAAI,WAAW,KAAA,CAAA,EAAW;AACxB,UAAA,IAAA,CAAK,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA,QAC/B;AAAA,MACF;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,EAAA,EAAI,EAAE,OAAA,EAASA,KAAAA,CAAK,OAAA,EAAS,IAAA,EAAMA,KAAAA,CAAK,IAAA,EAAM,IAAA,EAAM,CAAA;AAExE,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,GAAU,SAAA;AACV,MAAA,QAAA,GAAW,eAAe,GAAG,CAAA;AAC7B,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAA,CAAS,IAAI,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA,EAAI,QAAQ,CAAA;AAClE,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,mBAAA,EAAqB;AAAA,UACrC,SAAA,EAAW,EAAA;AAAA,UACX,KAAA,EAAO,SAAA;AAAA,UACP,QAAA,EAAU,IAAA;AAAA,UACV,SAAA,EAAW,MAAA;AAAA,UACX,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,SAC1B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,KAAA,GAAQ,EAAA,EAA+B;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AAGxB,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,EAAU;AACrC,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACrB,UAAA,IAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAA,EAAW,OAAO,CAAA;AACtC,UAAA,IAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAA,EAAW,OAAO,CAAA,CAAA;AACtC,UAAA,OAAO,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAA;AAAA,QAChC,CAAC,CAAA;AACD,QAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAAA,MAC/B;AAEA,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,iBAAA,CAAkB,KAAK,GAAG,CAAA;AAEjD,MAAA,MAAM,WAAW,MAAM,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAI,CAAC,EAAA,KAAO,IAAA,CAAK,UAAA,CAAW,EAAE,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAC,CAAC,CAAA;AACzF,MAAA,MAAM,MAAM,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAA2B,MAAM,IAAI,CAAA;AAClE,MAAA,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACjB,QAAA,IAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAA,EAAW,OAAO,CAAA;AACtC,QAAA,IAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAA,EAAW,OAAO,CAAA,CAAA;AACtC,QAAA,OAAO,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAA;AAAA,MAChC,CAAC,CAAA;AACD,MAAA,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,gBAAA,GAAmB,CAAA;AAAA,EAC3B,OAAwB,aAAA,GAAgB,EAAA;AAAA;AAAA,EAGxC,MAAc,cAAc,OAAA,EAAwC;AAGlE,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AACxB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,GAAI,IAAA;AACvC,MAAA,MAAU,GAAA,CAAA,UAAA,CAAW,IAAA,CAAK,SAAA,EAAW,IAAA,EAAM,MAAM,CAAA;AACjD,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,IAAA,CAAK,gBAAA,EAAA;AAEL,MAAA,IAAI,IAAA,CAAK,gBAAA,IAAoB,oBAAA,CAAoB,aAAA,EAAe;AAC9D,QAAA,MAAM,KAAK,YAAA,EAAa;AACxB,QAAA,IAAA,CAAK,gBAAA,GAAmB,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,eAAe,EAAA,EAA2B;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AACxB,MAAA,MAAM,IAAA,GAAO,KAAK,SAAA,CAAU,EAAE,QAAQ,QAAA,EAAU,EAAA,EAAI,CAAA,GAAI,IAAA;AACxD,MAAA,MAAU,GAAA,CAAA,UAAA,CAAW,IAAA,CAAK,SAAA,EAAW,IAAA,EAAM,MAAM,CAAA;AACjD,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,IAAA,CAAK,gBAAA,EAAA;AAAA,IACP,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAA,GAA8B;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,OAAA,GAAiC,SAAA;AACrC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,EAAU;AACrC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC1B,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,YAAA,CAAA;AAC7B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AACjE,MAAA,MAAU,GAAA,CAAA,SAAA,CAAU,GAAA,EAAK,KAAA,EAAO,MAAM,CAAA;AACtC,MAAA,MAAU,GAAA,CAAA,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,SAAS,CAAA;AACpC,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,GAAU,SAAA;AACV,MAAA,QAAA,GAAW,eAAe,GAAG,CAAA;AAAA,IAC/B,CAAA,SAAE;AAEA,MAAA,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,CAAK,SAAA,EAAW,SAAA,EAAW,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA,EAAI,MAAA,EAAW,QAAQ,CAAA;AAAA,IACtG;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,SAAA,GAAuC;AACnD,IAAA,IAAIA,KAAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AACvC,MAAAA,QAAO,EAAE,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,EAAM,EAAE,IAAA,EAAK;AAAA,IAC5C,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,IACE,IAAA,CAAK,WAAA,KAAgB,IAAA,IACrB,IAAA,CAAK,WAAA,CAAY,OAAA,KAAYA,KAAAA,CAAK,OAAA,IAClC,IAAA,CAAK,WAAA,CAAY,IAAA,KAASA,KAAAA,CAAK,IAAA,EAC/B;AACA,MAAA,OAAO,CAAC,GAAG,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA;AAAA,IACvC;AAEA,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAU,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,SAAA,EAAW,MAAM,CAAA;AAAA,IACjD,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,IAAA,MAAM,IAAA,uBAAW,GAAA,EAA4B;AAC7C,IAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,QAAA,IAAY,KAAA,CAAM,EAAA,EAAI;AACzC,UAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,EAAE,CAAA;AACpB,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,EAAE,CAAA;AACpB,UAAA;AAAA,QACF;AACA,QAAA,IAAI,MAAM,EAAA,IAAM,CAAC,QAAQ,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AAEtC,UAAA,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAuB,CAAA;AAAA,QAC5C;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAC1C,IAAA,IAAA,CAAK,WAAA,GAAc,EAAE,GAAGA,KAAAA,EAAM,SAAA,EAAU;AACxC,IAAA,OAAO,CAAC,GAAG,SAAS,CAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAA,GAAgC;AACpC,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,iBAAA,CAAkB,KAAK,GAAG,CAAA;AAEjD,IAAA,MAAM,YAAY,MAAM,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAI,CAAC,EAAA,KAAO,IAAA,CAAK,UAAA,CAAW,EAAE,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAC,CAAC,CAAA;AAC1F,IAAA,MAAM,QAAQ,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAA2B,MAAM,IAAI,CAAA;AAErE,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,IAAA,CAAA;AAC7B,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAC/D,IAAA,MAAU,GAAA,CAAA,SAAA,CAAU,GAAA,EAAK,KAAA,EAAO,MAAM,CAAA;AACtC,IAAA,MAAU,GAAA,CAAA,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,SAAS,CAAA;AACpC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,OAAO,KAAA,CAAM,MAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iBAAA,CACZ,GAAA,EACA,MAAA,GAAS,EAAA,EACT,QAAQ,CAAA,EACW;AACnB,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAU,GAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,IAC1D,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,GAAA;AAAA,IACT;AACA,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,MAAA,IAAI,MAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,KAAA,CAAM,SAAS,aAAA,EAAe;AAChE,MAAA,IAAI,MAAM,IAAA,KAAS,QAAA,IAAY,MAAM,IAAA,KAAS,WAAA,IAAe,MAAM,IAAA,KAAS,aAAA;AAC1E,QAAA;AACF,MAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AAEvB,QAAA,MAAM,WAAA,GAAc,UAAU,CAAA,GAAI,KAAA,CAAM,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA;AACtE,QAAA,GAAA,CAAI,IAAA,CAAK,GAAI,MAAM,IAAA,CAAK,iBAAA,CAAuBK,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA,EAAG,WAAA,EAAa,KAAA,GAAQ,CAAC,CAAE,CAAA;AAAA,MAChG,CAAA,MAAA,IAAW,MAAM,MAAA,EAAO,IAAK,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG;AAI1D,QAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACnC,QAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,YAAY,EAAE,CAAA;AAE9C,QAAA,GAAA,CAAI,KAAK,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,KAAK,IAAI,CAAA;AAAA,MAC9C;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAc,WAAW,EAAA,EAAqC;AAC5D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,eAAe,CAAA;AACrD,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,OAAA,GAAiC,SAAA;AACrC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAU,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAC/C,MAAA,IAAA,CAAK,QAAA,CAAS,IAAI,QAAA,EAAU,SAAA,EAAW,WAAW,IAAA,CAAK,GAAA,KAAQ,EAAE,CAAA;AACjE,MAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACvB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AAC1C,MAAA,MAAML,KAAAA,GAAO,MAAU,GAAA,CAAA,IAAA,CAAK,IAAI,CAAA;AAChC,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,IAAIA,KAAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AACjE,MAAA,MAAM,WAAA,CAAY,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AACnF,QAAA,MAAM,GAAA,GAAM,eAAe,GAAG,CAAA;AAC9B,QAAA,IAAA,CAAK,SAAA,CAAU,EAAA,EAAI,QAAA,EAAU,kBAAA,EAAoB,KAAK,IAAI,CAAA;AAC1D,QAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,UAC1B,KAAA,EAAO,MAAA;AAAA,UACP,KAAA,EAAO,qCAAA;AAAA,UACP,SAAA,EAAW,EAAA;AAAA,UACX,OAAA,EAAS,GAAA;AAAA,UACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,SACnC,CAAC,CAAA;AAAA,MACJ,CAAC,CAAA;AACD,MAAA,OAAA,GAAU,SAAA;AACV,MAAA,QAAA,GAAW,0CAAA;AACX,MAAA,IAAA,CAAK,QAAA,CAAS,IAAI,QAAA,EAAU,SAAA,EAAW,SAAS,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA,EAAI,QAAQ,CAAA;AACzE,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,cAAc,EAAA,EAA2B;AACrD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AAC/C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,eAAe,CAAA;AACxD,IAAA,MAAM,WAAgBK,KAAA,CAAA,OAAA,CAAaA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,EAAE,CAAC,CAAA;AACrD,IAAA,MAAM,IAAA,GAAYA,eAAS,EAAE,CAAA;AAC7B,IAAA,MAAM,OAAA,GAAeA,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AAExC,IAAA,MAAM,SAAA,GAAkC;AAAA,MAClC,WAAO,SAAS,CAAA;AAAA,MAChB,WAAO,WAAW,CAAA;AAAA,MAClB,WAAYA,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,CAAA,EAAG,IAAI,YAAY,CAAC,CAAA;AAAA,MAC/C,WAAYA,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,CAAA,EAAG,IAAI,aAAa,CAAC;AAAA,KACtD;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,CAAW,SAAS,CAAA;AAClD,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,IAAI,CAAA,CAAE,WAAW,UAAA,EAAY;AAC3B,QAAA,MAAM,GAAA,GAAM,EAAE,MAAA,YAAkB,KAAA,GAAQ,EAAE,MAAA,CAAO,OAAA,GAAU,MAAA,CAAO,CAAA,CAAE,MAAM,CAAA;AAE1E,QAAA,IAAK,CAAA,CAAE,MAAA,EAAkC,IAAA,KAAS,QAAA,EAAU;AAC1D,UAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,YAC1B,KAAA,EAAO,MAAA;AAAA,YACP,KAAA,EAAO,6BAAA;AAAA,YACP,SAAA,EAAW,EAAA;AAAA,YACX,OAAA,EAAS,GAAA;AAAA,YACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WACnC,CAAC,CAAA;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAIA,IAAA,MAAU,GAAA,CAAA,EAAA,CAAG,OAAA,EAAS,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AACrE,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,4BAAA;AAAA,QACP,SAAA,EAAW,EAAA;AAAA,QACX,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,QAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AAAA,IACJ,CAAC,CAAA;AAID,IAAA,MAAM,IAAA,CAAK,eAAe,EAAE,CAAA;AAAA,EAC9B;AAAA,EAEA,MAAM,OAAO,EAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,CAAK,cAAc,EAAE,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAM,KAAA,CAAM,UAAA,GAAa,EAAA,EAAqB;AAC5C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,EAAI,GAAI,UAAA,GAAa,KAAA;AACzC,IAAA,IAAI,OAAA,GAAU,CAAA;AAGd,IAAA,IAAI,eAAA,GAAiC,IAAA;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAU,GAAA,CAAA,QAAA,CAAcA,KAAA,CAAA,IAAA,CAAK,KAAK,GAAA,EAAK,aAAa,GAAG,MAAM,CAAA;AACzE,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,eAAA,GAAkB,OAAO,SAAA,IAAa,IAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,kBAAkB,CAAC,IAAA,KACvB,KAAK,QAAA,CAAS,QAAQ,KACtB,IAAA,KAAS,cAAA,IACT,SAAS,gBAAA,IACT,CAAC,KAAK,QAAA,CAAS,eAAe,KAC9B,CAAC,IAAA,CAAK,SAAS,cAAc,CAAA;AAE/B,IAAA,MAAM,SAAA,GAAY,OAAO,GAAA,EAAa,IAAA,EAAc,MAAA,KAAkC;AACpF,MAAA,MAAM,SAAA,GAAiBA,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA;AACrC,MAAA,IAAI;AACF,QAAA,MAAML,KAAAA,GAAO,MAAU,GAAA,CAAA,IAAA,CAAK,SAAS,CAAA;AACrC,QAAA,IAAIA,KAAAA,CAAK,WAAW,MAAA,EAAQ;AAAA,MAE9B,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AACxC,MAAA,MAAM,KAAK,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,IAAA;AAE1C,MAAA,IAAI,eAAA,IAAmB,OAAO,eAAA,EAAiB;AAC/C,MAAA,MAAM,IAAA,CAAK,cAAc,EAAE,CAAA;AAC3B,MAAA,OAAA,EAAA;AAAA,IACF,CAAA;AAGA,IAAA,MAAM,OAAA,GAAU,MAAU,GAAA,CAAA,OAAA,CAAQ,IAAA,CAAK,GAAA,EAAK,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACnF,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,KAAA,CAAM,QAAO,EAAG;AAGlB,QAAA,IAAI,eAAA,CAAgB,KAAA,CAAM,IAAI,CAAA,EAAG,MAAM,UAAU,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAA,EAAM,EAAE,CAAA;AACzE,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAY,EAAG;AAE1B,MAAA,MAAM,OAAA,GAAeK,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AAE9C,MAAA,MAAM,KAAA,GAAQ,MAAU,GAAA,CAAA,OAAA,CAAQ,OAAA,EAAS,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAChF,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,CAAC,KAAK,MAAA,EAAO,IAAK,CAAC,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG;AACnD,QAAA,MAAM,SAAA,CAAU,OAAA,EAAS,IAAA,CAAK,IAAA,EAAM,MAAM,IAAI,CAAA;AAAA,MAChD;AAAA,IACF;AACA,IAAA,IAAI,UAAU,CAAA,EAAG;AAGf,MAAA,MAAM,IAAA,CAAK,YAAA,EAAa,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,IACjD;AAEA,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAY,EAAG;AAC1B,MAAA,MAAM,OAAA,GAAeA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AAC9C,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,MAAU,GAAA,CAAA,OAAA,CAAQ,OAAO,CAAA;AAC3C,QAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAE1B,UAAA,MAAU,GAAA,CAAA,KAAA,CAAM,OAAO,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,QAChD;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,EAAA,EAA2B;AAC5C,IAAA,MAAM,IAAA,CAAK,eAAe,EAAE,CAAA;AAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,eAAe,CAAA;AACjD,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU;AAAA,MAC/B,IAAA,EAAM,eAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B,EAAA;AAAA,MACA,KAAA,EAAO,SAAA;AAAA,MACP,QAAA,EAAU;AAAA,KACX,CAAC;AAAA,CAAA;AACF,IAAA,MAAU,GAAA,CAAA,SAAA,CAAU,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAA;AACxC,IAAA,MAAU,GAAA,CAAA,MAAA,CAAO,IAAI,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAc,SAAA,CAAU,EAAA,EAAY,KAAA,EAAwC;AAC1E,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA;AAC/B,MAAA,MAAM,SAAA,GAAY,KAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,YAAY,CAAA;AACjE,MAAA,MAAM,KAAA,GACJ,aAAa,SAAA,CAAU,IAAA,KAAS,eAC5B,cAAA,CAAe,SAAA,CAAU,OAAO,CAAA,GAChC,iBAAA;AAGN,MAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,MAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,MAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,MAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,MAAA,MAAM,gBAAwC,EAAC;AAC/C,MAAA,IAAI,OAAA;AACJ,MAAA,MAAM,YAAY,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,SAAS,CAAC,CAAA;AAEpD,MAAA,KAAA,MAAW,CAAA,IAAK,KAAK,MAAA,EAAQ;AAC3B,QAAA,IAAI,CAAA,CAAE,SAAS,iBAAA,EAAmB,cAAA,EAAA;AAAA,aAAA,IACzB,CAAA,CAAE,SAAS,iBAAA,EAAmB;AACrC,UAAA,aAAA,EAAA;AACA,UAAA,aAAA,CAAc,EAAE,IAAI,CAAA,GAAA,CAAK,cAAc,CAAA,CAAE,IAAI,KAAK,CAAA,IAAK,CAAA;AAAA,QACzD,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,aAAA,IAAiB,EAAE,OAAA,EAAS,cAAA,EAAA;AAAA,aAAA,IACzC,CAAA,CAAE,IAAA,KAAS,eAAA,EAAiB,eAAA,IAAmB,EAAE,KAAA,CAAM,MAAA;AAAA,MAClE;AAGA,MAAA,IAAI,SAAA,EAAW,SAAS,aAAA,EAAe;AACrC,QAAA,OAAA,GAAU,WAAA;AAAA,MACZ,CAAA,MAAA,IAAW,SAAA,EAAW,IAAA,KAAS,iBAAA,EAAmB;AAChD,QAAA,OAAA,GAAU,SAAA;AAAA,MACZ,CAAA,MAAA,IAAW,KAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA,EAAG;AACtD,QAAA,OAAA,GAAU,OAAA;AAAA,MACZ;AAEA,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA,EAAW,KAAK,QAAA,CAAS,SAAA;AAAA,QACzB,OAAA,EAAS,KAAK,QAAA,CAAS,OAAA;AAAA,QACvB,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,KAAA,IAAS,SAAA;AAAA,QAC9B,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,QAAA,IAAY,SAAA;AAAA,QACpC,UAAA,EAAY,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,MAAA;AAAA,QAC1C,cAAA,EAAgB,cAAA,GAAiB,CAAA,GAAI,cAAA,GAAiB,KAAA,CAAA;AAAA,QACtD,aAAA,EAAe,aAAA,GAAgB,CAAA,GAAI,aAAA,GAAgB,KAAA,CAAA;AAAA,QACnD,cAAA,EAAgB,cAAA,GAAiB,CAAA,GAAI,cAAA,GAAiB,KAAA,CAAA;AAAA,QACtD,eAAA,EAAiB,eAAA,GAAkB,CAAA,GAAI,eAAA,GAAkB,KAAA,CAAA;AAAA,QACzD,aAAA,EAAe,OAAO,IAAA,CAAK,aAAa,EAAE,MAAA,GAAS,CAAA,GAAI,gBAAgB,EAAC;AAAA,QACxE;AAAA,OACF;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA,KAAA,EAAO,WAAA;AAAA,QACP,SAAA,EAAW,KAAA;AAAA,QACX,KAAA,EAAO,SAAA;AAAA,QACP,QAAA,EAAU,SAAA;AAAA,QACV,UAAA,EAAY;AAAA,OACd;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,cAAA,CAAe,IAAY,MAAA,EAAyC;AAC1E,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,eAAe,CAAA;AAG3D,IAAA,MAAM,MAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,aAAa,CAAA;AAC3D,IAAA,OAAO;AAAA,MACL,EAAA;AAAA,MACA,WAAW,KAAA,EAAO,EAAA,IAAA,qBAAU,IAAA,CAAK,CAAC,GAAE,WAAA,EAAY;AAAA,MAChD,SAAS,GAAA,EAAK,EAAA;AAAA,MACd,OAAO,KAAA,EAAO,KAAA;AAAA,MACd,UAAU,KAAA,EAAO,QAAA;AAAA,MACjB,iBAAiB,GAAA,EAAK;AAAA,KACxB;AAAA,EACF;AAAA,EAEQ,MAAA,CACN,MAAA,EACA,SAAA,GAAY,SAAA,EAC0C;AACtD,IAAA,MAAM,WAAsB,EAAC;AAC7B,IAAA,IAAI,KAAA,GAAQ,EAAE,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,UAAA,EAAY,CAAA,EAAE;AAC/D,IAAA,MAAM,YAAA,uBAAmB,GAAA,EAAY;AACrC,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI,CAAA,CAAE,SAAS,YAAA,EAAc;AAC3B,QAAA,YAAA,CAAa,KAAA,EAAM;AACnB,QAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,EAAE,OAAA,EAAS,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,CAAA;AAAA,MAC9D,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,cAAA,EAAgB;AACpC,QAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,EAAE,OAAA,EAAS,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,CAAA;AACjE,QAAA,KAAA,MAAW,CAAA,IAAK,EAAE,OAAA,EAAS;AACzB,UAAA,IAAI,EAAE,IAAA,KAAS,UAAA,EAAY,YAAA,CAAa,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,QAClD;AACA,QAAA,KAAA,GAAQ;AAAA,UACN,KAAA,EAAO,KAAA,CAAM,KAAA,IAAS,CAAA,CAAE,MAAM,KAAA,IAAS,CAAA,CAAA;AAAA,UACvC,MAAA,EAAQ,KAAA,CAAM,MAAA,IAAU,CAAA,CAAE,MAAM,MAAA,IAAU,CAAA,CAAA;AAAA,UAC1C,YAAY,KAAA,CAAM,SAAA,IAAa,CAAA,KAAM,CAAA,CAAE,MAAM,SAAA,IAAa,CAAA,CAAA;AAAA,UAC1D,aAAa,KAAA,CAAM,UAAA,IAAc,CAAA,KAAM,CAAA,CAAE,MAAM,UAAA,IAAc,CAAA;AAAA,SAC/D;AAAA,MACF,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,aAAA,EAAe;AACnC,QAAA,IAAI,CAAC,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,EAAG;AAC3B,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,iBAAA,EAAmB;AAAA,YACnC,SAAA;AAAA,YACA,MAAA,EAAQ,CAAA,oBAAA,EAAuB,CAAA,CAAE,EAAE,CAAA,0BAAA;AAAA,WACpC,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,YAAA,CAAa,MAAA,CAAO,EAAE,EAAE,CAAA;AAOxB,QAAA,MAAM,WAAA,GAA4B;AAAA,UAChC,IAAA,EAAM,aAAA;AAAA,UACN,aAAa,CAAA,CAAE,EAAA;AAAA,UACf,OAAA,EAAS,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,UAC7E,UAAU,CAAA,CAAE;AAAA,SACd;AACA,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AACzC,QAAA,MAAM,uBACJ,IAAA,EAAM,IAAA,KAAS,MAAA,IACf,KAAA,CAAM,QAAQ,IAAA,CAAK,OAAO,CAAA,IAC1B,IAAA,CAAK,QAAQ,KAAA,CAAM,CAAC,CAAA,KAAO,CAAA,CAAmB,SAAS,aAAa,CAAA;AACtE,QAAA,IAAI,oBAAA,IAAwB,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AACvD,UAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,WAAW,CAAA;AAAA,QAC/B,CAAA,MAAO;AACL,UAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,CAAC,WAAW,CAAA,EAAG,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,CAAA;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,YAAA,CAAa,OAAO,CAAA,EAAG;AACzB,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,iBAAA,EAAmB;AAAA,QACnC,SAAA;AAAA,QACA,MAAA,EAAQ,CAAA,EAAG,YAAA,CAAa,IAAI,CAAA,2DAAA;AAAA,OAC7B,CAAA;AAAA,IACH;AACA,IAAA,MAAM,QAAA,GAAW,uBAAuB,QAAQ,CAAA;AAChD,IAAA,IAAI,QAAA,CAAS,OAAO,OAAA,EAAS;AAC3B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,iBAAA,EAAmB;AAAA,QACnC,SAAA;AAAA,QACA,MAAA,EACE,CAAA,mCAAA,EAAsC,QAAA,CAAS,MAAA,CAAO,gBAAgB,MAAM,CAAA,WAAA,EACzE,QAAA,CAAS,MAAA,CAAO,kBAAA,CAAmB,MAAM,CAAA,cAAA,EACzC,QAAA,CAAS,OAAO,eAAe,CAAA,eAAA;AAAA,OACrC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,EAAE,QAAA,EAAU,QAAA,CAAS,QAAA,EAAU,KAAA,EAAM;AAAA,EAC9C;AACF;AAQA,SAAS,oBAAoB,MAAA,EAAqD;AAChF,EAAA,MAAM,SAAsC,EAAC;AAC7C,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAA,CAAE,SAAS,eAAA,EAAiB;AAC9B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,IAAI,CAAA,CAAE,EAAA;AAAA,QACN,YAAY,CAAA,CAAE,UAAA;AAAA,QACd,EAAA,EAAI,EAAE,EAAA,IAAM,KAAA;AAAA,QACZ,aAAa,CAAA,CAAE,WAAA;AAAA,QACf,cAAc,CAAA,CAAE,YAAA;AAAA,QAChB,aAAa,CAAA,CAAE;AAAA,OAChB,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,IAAM,iBAAA,GAAN,MAAM,kBAAA,CAA2C;AAAA,EAiH/C,WAAA,CACkB,IACR,MAAA,EACS,SAAA,EACA,MACA,MAAA,EACjB,IAAA,GAOI,EAAC,EACL,OAAA,EACA;AAdgB,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AACR,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACS,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAWjB,IAAA,IAAA,CAAK,OAAA,GAAU,KAAK,OAAA,IAAW,KAAA;AAI/B,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,GAAA,GAAWA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,CAAA,EAAQA,KAAA,CAAA,QAAA,CAAS,EAAE,CAAC,CAAA,aAAA,CAAe,CAAA,GAAI,EAAA;AAC1F,IAAA,IAAA,CAAK,QAAA,GAAW,KAAK,QAAA,IAAY,EAAA;AACjC,IAAA,IAAA,CAAK,iBAAiB,IAAA,CAAK,cAAA;AAC3B,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,OAAA;AACtB,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,EAAA;AAAA,MACA,KAAA,EAAO,iBAAA;AAAA,MACP,SAAA;AAAA,MACA,KAAA,EAAO,KAAK,KAAA,IAAS,SAAA;AAAA,MACrB,QAAA,EAAU,KAAK,QAAA,IAAY,SAAA;AAAA,MAC3B,UAAA,EAAY;AAAA,KACd;AAIA,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAnCkB,EAAA;AAAA,EACR,MAAA;AAAA,EACS,SAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EArHX,MAAA,GAAS,KAAA;AAAA,EACT,YAAA,GAAqC,IAAA;AAAA,EACrC,YAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA,GAAU,CAAA;AAAA,EACV,QAAA,GAAW,CAAA;AAAA,EACF,QAAA;AAAA,EACjB,IAAI,cAAA,GAAqC;AACvC,IAAA,OAAO,KAAK,QAAA,IAAY,MAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,WAAA,GAAoC,IAAA;AAAA,EACpC,UAAA,GAA4B;AAClC,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,WAAA,GAAc,KAAK,qBAAA,EAAsB;AACrE,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EACiB,OAAA;AAAA,EACT,eAAA,GAAkB,CAAA;AAAA,EAClB,gBAAA,GAAmB,CAAA;AAAA,EACV,cAAA;AAAA,EACA,SAAA;AAAA;AAAA,EAEjB,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cAA8B,EAAC;AAAA,EAC/B,UAAA,GAAmD,IAAA;AAAA,EAC3D,OAAwB,iBAAA,GAAoB,GAAA;AAAA,EAC5C,OAAwB,UAAA,GAAa,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7B,UAAA,GAA4B,QAAQ,OAAA,EAAQ;AAAA;AAAA,EAG5C,aAAa,IAAA,EAA6B;AAChD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,MAAM,KAAK,MAAA,CAAO,UAAA,CAAW,IAAA,EAAM,MAAM,CAAC,CAAA;AAC7E,IAAA,IAAA,CAAK,aAAa,KAAA,CAAM,IAAA;AAAA,MACtB,MAAM,MAAA;AAAA,MACN,MAAM;AAAA,KACR;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGQ,cAAA,GAAiB,CAAA;AAAA,EACjB,aAAA,GAAgB,CAAA;AAAA,EAChB,cAAA,GAAiB,CAAA;AAAA,EACjB,gBAAwC,EAAC;AAAA,EACzC,eAAA,GAAkB,CAAA;AAAA,EAClB,eAAA,GAAkB,CAAA;AAAA,EAClB,OAAA,GAAqC,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUrC,WAAW,KAAA,EAAmC;AACpD,IAAA,MAAM,IAAI,IAAA,CAAK,cAAA;AACf,IAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,IAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,MAAA,OAAO;AAAA,QACL,GAAG,KAAA;AAAA,QACH,OAAA,EACE,OAAO,KAAA,CAAM,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA,GAAI,CAAA,CAAE,WAAA,CAAY,MAAM,OAAO;AAAA,OAC5F;AAAA,IACF;AACA,IAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,MAAA,OAAO,EAAE,GAAG,KAAA,EAAO,OAAA,EAAS,EAAE,WAAA,CAAY,KAAA,CAAM,OAAO,CAAA,EAAE;AAAA,IAC3D;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,uBAKH,EAAC;AAAA;AAAA,EAEE,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAEvC,iBAAiB,KAAA,EAKR;AACP,IAAA,IAAA,CAAK,oBAAA,CAAqB,KAAK,KAAK,CAAA;AAAA,EACtC;AAAA,EAwCA,IAAI,eAAA,GAA4B;AAC9B,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA;AAAA,EACrC;AAAA,EAEA,MAAc,qBAAA,GAAuC;AAMnD,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU;AAAA,MAC/B,IAAA,EAAM,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,eAAA;AAAA,MACzC,IAAI,IAAA,CAAK,SAAA;AAAA,MACT,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,KAAA,EAAO,IAAA,CAAK,IAAA,CAAK,KAAA,IAAS,SAAA;AAAA,MAC1B,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,QAAA,IAAY;AAAA,KACjC,CAAC;AAAA,CAAA;AACF,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,aAAa,MAAM,CAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,KAAA,EAAoC;AAC/C,IAAA,IAAI,KAAK,MAAA,EAAQ;AACjB,IAAA,MAAM,KAAK,UAAA,EAAW;AAItB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA;AAKtC,IAAA,IAAA,CAAK,kBAAkB,QAAQ,CAAA;AAC/B,IAAA,IAAA,CAAK,WAAA,CAAY,KAAK,QAAQ,CAAA;AAE9B,IAAA,IAAI,IAAA,CAAK,WAAA,CAAY,MAAA,IAAU,kBAAA,CAAkB,UAAA,EAAY;AAG3D,MAAA,IAAI,KAAK,UAAA,EAAY;AACnB,QAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,QAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,MACpB;AACA,MAAA,MAAM,KAAK,WAAA,EAAY;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,MAAA,EAAuC;AACvD,IAAA,IAAI,IAAA,CAAK,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACxC,IAAA,MAAM,KAAK,UAAA,EAAW;AACtB,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA;AACtC,MAAA,IAAA,CAAK,kBAAkB,QAAQ,CAAA;AAC/B,MAAA,IAAA,CAAK,WAAA,CAAY,KAAK,QAAQ,CAAA;AAAA,IAChC;AACA,IAAA,IAAI,IAAA,CAAK,WAAA,CAAY,MAAA,IAAU,kBAAA,CAAkB,UAAA,EAAY;AAC3D,MAAA,IAAI,KAAK,UAAA,EAAY;AACnB,QAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,QAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,MACpB;AACA,MAAA,MAAM,KAAK,WAAA,EAAY;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,MAAM,KAAK,WAAA,EAAY;AAAA,EACzB;AAAA;AAAA,EAGQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,KAAK,UAAA,EAAY;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,WAAW,MAAM;AACjC,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAElB,MAAA,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,MAAM;AAAA,MAG/B,CAAC,CAAA;AAAA,IAEH,CAAA,EAAG,mBAAkB,iBAAiB,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,WAAA,GAA6B;AACzC,IAAA,IAAI,IAAA,CAAK,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG;AACnC,IAAA,MAAM,UAAA,GAAa,KAAK,WAAA,CAAY,MAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAC1E,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,OAAA,GAAiC,SAAA;AACrC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,IAC/B,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,GAAU,SAAA;AACV,MAAA,QAAA,GAAW,eAAe,GAAG,CAAA;AAC7B,MAAA,IAAA,CAAK,eAAA,IAAmB,UAAA;AACxB,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,gBAAA,GAAmB,GAAA,EAAM;AACtC,QAAA,MAAM,UAAA,GAAa,KAAK,eAAA,GAAkB,CAAA;AAC1C,QAAA,MAAM,IAAA,GAAO,UAAA,GAAa,CAAA,GAAI,CAAA,GAAA,EAAM,UAAU,CAAA,YAAA,CAAA,GAAiB,EAAA;AAC/D,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,yBAAA;AAAA,UACA,eAAe,GAAG,CAAA;AAAA,UAClB;AAAA,SACF;AACA,QAAA,IAAA,CAAK,gBAAA,GAAmB,GAAA;AACxB,QAAA,IAAA,CAAK,eAAA,GAAkB,CAAA;AAAA,MACzB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,WAAW,IAAA,CAAK,EAAA;AAAA,QAChB,KAAA,EAAO,SAAA;AAAA,QACP,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,SAAA,EAAW,OAAA;AAAA,QACX,OAAA;AAAA,QACA,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,KAAA,EAAO,QAAA,KAAa,EAAC;AAAA,QACpD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,kBAAkB,KAAA,EAA2B;AAKnD,IAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,MAAA,KAAA,MAAW,KAAA,IAAS,MAAM,OAAA,EAAS;AACjC,QAAA,IAAI,MAAM,IAAA,KAAS,UAAA,OAAiB,YAAA,CAAa,GAAA,CAAI,MAAM,EAAE,CAAA;AAAA,MAC/D;AAAA,IACF;AACA,IAAA,IAAI,KAAA,CAAM,SAAS,UAAA,EAAY;AAC7B,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA;AAAA,IAChC,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,iBAAA,EAAmB;AAC3C,MAAA,IAAA,CAAK,aAAA,EAAA;AACL,MAAA,IAAA,CAAK,aAAA,CAAc,MAAM,IAAI,CAAA,GAAA,CAAK,KAAK,aAAA,CAAc,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA,IAAK,CAAA;AAAA,IAC3E,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,aAAA,EAAe;AACvC,MAAA,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,KAAA,CAAM,EAAE,CAAA;AACjC,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,IAAA,CAAK,cAAA,EAAA;AACL,QAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,MACjB;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,eAAA,EAAiB;AACzC,MAAA,IAAA,CAAK,eAAA,IAAmB,MAAM,KAAA,CAAM,MAAA;AAAA,IACtC,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACtC,MAAA,IAAA,CAAK,eAAA,EAAA;AAAA,IACP;AAEA,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,OAAA,IAAW,KAAA,CAAM,SAAS,gBAAA,EAAkB;AAC7D,MAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,IACjB;AACA,IAAA,IAAI,MAAM,IAAA,KAAS,YAAA,IAAgB,IAAA,CAAK,OAAA,CAAQ,UAAU,iBAAA,EAAmB;AAC3E,MAAA,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,IAAA,CAAK,SAAS,KAAA,EAAO,cAAA,CAAe,KAAA,CAAM,OAAO,CAAA,EAAE;AAAA,IACzE,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,cAAA,EAAgB;AACxC,MAAA,IAAA,CAAK,OAAA,IAAW,MAAM,KAAA,CAAM,KAAA;AAC5B,MAAA,IAAA,CAAK,QAAA,IAAY,MAAM,KAAA,CAAM,MAAA;AAC7B,MAAA,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,IAAA,CAAK,SAAS,UAAA,EAAY,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,QAAA,EAAS;AAAA,IAC7E,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,aAAA,EAAe;AACvC,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,MAAA;AAC9C,MAAA,IAAI,KAAA,GAAQ,GAAG,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,UAAA,EAAY,KAAA,EAAM;AAAA,IACrE,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,iBAAA,EAAmB;AAC3C,MAAA,IAAA,CAAK,cAAA,EAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,GAAuB;AAI3B,IAAA,IAAI,IAAA,CAAK,YAAA,EAAc,OAAO,IAAA,CAAK,YAAA;AACnC,IAAA,IAAA,CAAK,YAAA,GAAe,KAAK,OAAA,EAAQ;AACjC,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA,EAEA,MAAc,OAAA,GAAyB;AACrC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAKd,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,MAAM,KAAK,WAAA,EAAY;AAGvB,IAAA,MAAM,IAAA,CAAK,UAAA;AAEX,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,IAAA,CAAK,OAAA;AAAA,MACR,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAChC,gBAAgB,IAAA,CAAK,cAAA;AAAA,MACrB,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,gBAAgB,IAAA,CAAK,cAAA;AAAA,MACrB,iBAAiB,IAAA,CAAK,eAAA;AAAA,MACtB,eAAA,EAAiB,IAAA,CAAK,eAAA,GAAkB,CAAA,GAAI,KAAK,eAAA,GAAkB,MAAA;AAAA,MACnE,aAAA,EACE,EAAE,GAAG,IAAA,CAAK,aAAA,EAAc;AAAA,MAC1B,OAAA,EAAS,KAAK,OAAA,IAAW;AAAA,KAC3B;AAEA,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,IAAI,OAAA,GAAiC,SAAA;AACrC,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,CAAY,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAAA,MACpF,SAAS,GAAA,EAAK;AACZ,QAAA,OAAA,GAAU,SAAA;AACV,QAAA,QAAA,GAAW,eAAe,GAAG,CAAA;AAAA,MAE/B,CAAA,SAAE;AACA,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,WAAW,IAAA,CAAK,EAAA;AAAA,UAChB,KAAA,EAAO,SAAA;AAAA,UACP,UAAU,IAAA,CAAK,YAAA;AAAA,UACf,SAAA,EAAW,OAAA;AAAA,UACX,OAAA;AAAA,UACA,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,UACzB,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,KAAA,EAAO,QAAA,KAAa,EAAC;AAAA,UACpD,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,SAC/D,CAAA;AAAA,MACH;AAAA,IACF;AAOA,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,IAAA,IAAI,UAAA,GAAoC,SAAA;AACxC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,OAAO,CAAA;AAAA,IAErC,SAAS,GAAA,EAAK;AACZ,MAAA,UAAA,GAAa,SAAA;AACb,MAAA,QAAA,GAAW,eAAe,GAAG,CAAA;AAAA,IAE/B,CAAA,SAAE;AAEA,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,CAAQ,EAAA;AAAA,QACxB,KAAA,EAAO,SAAA;AAAA,QACP,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,SAAA,EAAW,cAAA;AAAA,QACX,OAAA,EAAS,UAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAAA,QACzB,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,KAAA,EAAO,QAAA,KAAa,EAAC;AAAA,QACpD,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AAAA,IACH;AACA,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAM,eAAA,CAAgB,WAAA,EAAqB,aAAA,EAAsC;AAC/E,IAAA,MAAM,SAAA,GAAY,KAAK,oBAAA,CAAqB,MAAA;AAC5C,IAAA,IAAI,YAAY,CAAA,EAAG;AACjB,MAAA,MAAM,KAAK,iBAAA,CAAkB,WAAA,EAAa,CAAC,GAAG,IAAA,CAAK,oBAAoB,CAAC,CAAA;AACxE,MAAA,IAAA,CAAK,uBAAuB,EAAC;AAAA,IAC/B;AACA,IAAA,MAAM,KAAK,MAAA,CAAO;AAAA,MAChB,IAAA,EAAM,YAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,oBAAA,EAAsB;AAAA,MACtC,WAAA;AAAA,MACA,aAAA;AAAA,MACA,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B;AAAA,KACD,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,iBAAA,CACJ,WAAA,EACA,KAAA,EACe;AACf,IAAA,MAAM,KAAK,MAAA,CAAO;AAAA,MAChB,IAAA,EAAM,eAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,qBAAqB,iBAAA,EAA4C;AAErE,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,EAAU,OAAO,CAAA;AAK3B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,MAAM,KAAK,WAAA,EAAY;AAEvB,IAAA,MAAM,IAAA,CAAK,UAAA;AAIX,IAAA,MAAM,UAAA,GAAa,KAAA;AACnB,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI,UAAA,GAAa,CAAA;AACjB,IAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,IAAA,IAAI,oBAAA,GAAuB,EAAA;AAC3B,IAAA,IAAI,YAAA,GAAe,CAAA;AACnB,IAAA,IAAI,oBAAA,GAAuB,KAAA;AAE3B,IAAA,IAAI;AACF,MAAA,EAAA,GAAK,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,KAAK,GAAK,CAAA;AAE7C,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,CAAM,UAAU,CAAA;AACnC,QAAA,MAAM,EAAE,WAAU,GAAI,MAAM,GAAG,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,UAAA,EAAY,UAAU,CAAA;AAClE,QAAA,IAAI,cAAc,CAAA,EAAG;AAErB,QAAA,IAAI,QAAA,GAAW,CAAA;AACf,QAAA,OAAO,WAAW,SAAA,EAAW;AAC3B,UAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA;AACtC,UAAA,IAAI,QAAQ,CAAA,CAAA,EAAI;AAEd,YAAA,eAAA,GAAkB,UAAA,GAAa,QAAA;AAC/B,YAAA;AAAA,UACF;AAEA,UAAA,IAAI,yBAAyB,CAAA,CAAA,EAAI;AAE/B,YAAA,YAAA,EAAA;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,QAAA,EAAU,GAAG,CAAA;AAE5C,YAAA,MAAM,IAAA,GAAO,IAAI,WAAA,CAAY,OAAA,EAAS,EAAE,OAAO,KAAA,EAAO,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA;AACxE,YAAA,IAAI,IAAA,CAAK,MAAK,EAAG;AACf,cAAA,IAAI;AACF,gBAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,gBAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,kBAAA,IAAI,KAAA,CAAM,gBAAgB,iBAAA,EAAmB;AAE3C,oBAAA,oBAAA,GAAuB,eAAA;AACvB,oBAAA,oBAAA,GAAuB,IAAA;AAAA,kBACzB,WAAW,KAAA,CAAM,WAAA,KAAgB,KAAA,CAAA,IAAa,KAAA,CAAM,cAAc,iBAAA,EAAmB;AAInF,oBAAA,oBAAA,GAAuB,eAAA;AAAA,kBACzB;AAAA,gBACF,WAAW,oBAAA,IAAwB,KAAA,CAAM,gBAAgB,KAAA,CAAA,IAAa,KAAA,CAAM,cAAc,iBAAA,EAAmB;AAE3G,kBAAA,YAAA,EAAA;AAAA,gBACF,CAAA,MAAA,IAAW,oBAAA,IAAwB,KAAA,CAAM,WAAA,KAAgB,KAAA,CAAA,EAAW;AAIlE,kBAAA,YAAA,EAAA;AAAA,gBACF,CAAA,MAAA,IAAW,CAAC,oBAAA,IAAwB,KAAA,CAAM,gBAAgB,KAAA,CAAA,EAAW;AAKnE,kBAAA,YAAA,EAAA;AAAA,gBACF,CAAA,MAAA,IAAW,CAAC,oBAAA,IAAwB,KAAA,CAAM,gBAAgB,KAAA,CAAA,IAAa,KAAA,CAAM,cAAc,iBAAA,EAAmB;AAK5G,kBAAA,YAAA,EAAA;AAAA,gBACF;AAAA,cAGF,CAAA,CAAA,MAAQ;AAAA,cAER;AAAA,YACF;AAAA,UACF;AAGA,UAAA,QAAA,GAAW,GAAA,GAAM,CAAA;AACjB,UAAA,eAAA,GAAkB,UAAA,GAAa,QAAA;AAAA,QACjC;AAEA,QAAA,UAAA,IAAc,SAAA;AACd,QAAA,IAAI,YAAY,SAAA,EAAW;AAEzB,UAAA,eAAA,GAAkB,UAAA;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,IAAI,KAAA,EAAM;AAAA,IAClB;AAEA,IAAA,IAAI,oBAAA,KAAyB,IAAI,OAAO,CAAA;AAKxC,IAAA,MAAM,IAAA,CAAK,UAAA;AACX,IAAA,MAAM,IAAA,CAAK,OAAO,KAAA,EAAM;AACxB,IAAA,MAAM,OAAA,GAAU,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,WAAA,CAAA;AAChC,IAAA,MAAM,MAAM,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,KAAK,GAAK,CAAA;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,MAAM,GAAA,CAAI,IAAA,EAAK;AAClC,MAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAM7B,MAAA,MAAM,WAAA,GAAc,oBAAA;AACpB,MAAA,IAAI,sBAAA,GAAyB,WAAA;AAE7B,MAAA,IAAI,cAAc,SAAA,EAAW;AAC3B,QAAA,MAAM,QAAA,GAAW,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,UAAA,EAAY,SAAA,GAAY,WAAW,CAAC,CAAA;AAC3E,QAAA,MAAM,EAAE,SAAA,EAAW,SAAA,EAAU,GAAI,MAAM,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,CAAA,EAAG,QAAA,CAAS,MAAA,EAAQ,WAAW,CAAA;AACzF,QAAA,IAAI,YAAY,CAAA,EAAG;AACjB,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,OAAA,CAAQ,IAAI,CAAA;AAChC,UAAA,sBAAA,GAAyB,EAAA,KAAO,CAAA,CAAA,GAAK,WAAA,GAAc,EAAA,GAAK,CAAA,GAAI,SAAA;AAAA,QAC9D;AAAA,MACF,CAAA,MAAO;AACL,QAAA,sBAAA,GAAyB,SAAA;AAAA,MAC3B;AAEA,MAAA,MAAM,OAAA,GAAU,MAAU,GAAA,CAAA,IAAA,CAAK,OAAA,EAAS,KAAK,GAAK,CAAA;AAClD,MAAA,IAAI;AACF,QAAA,IAAI,MAAA,GAAS,CAAA;AACb,QAAA,IAAI,UAAA,GAAa,CAAA;AACjB,QAAA,OAAO,aAAa,sBAAA,EAAwB;AAC1C,UAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,yBAAyB,UAAU,CAAA;AACvE,UAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA;AACnC,UAAA,MAAM,EAAE,SAAA,EAAW,CAAA,EAAE,GAAI,MAAM,IAAI,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG,MAAA,EAAQ,UAAU,CAAA;AACtE,UAAA,IAAI,MAAM,CAAA,EAAG;AACb,UAAA,MAAM,OAAA,CAAQ,KAAA,CAAM,OAAA,EAAS,CAAA,EAAG,CAAC,CAAA;AACjC,UAAA,UAAA,IAAc,CAAA;AACd,UAAA,MAAA,IAAU,CAAA;AAAA,QACZ;AAKA,QAAA,MAAM,GAAA,GAAM,MAAU,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AAC5C,QAAA,MAAM,OAAO,GAAA,CAAI,QAAA,CAAS,sBAAsB,CAAA,CAAE,SAAS,MAAM,CAAA;AACjE,QAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG;AACnC,UAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,UAAA,IAAI;AACF,YAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,UACjB,CAAA,CAAA,MAAQ;AACN,YAAA,MAAM,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,IAAI;AAAA,CAAA,EAAM,QAAW,MAAM,CAAA;AAAA,UACpD;AAAA,QACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,MAAM,QAAQ,KAAA,EAAM;AAAA,MACtB;AAEA,MAAA,MAAM,IAAI,KAAA,EAAM;AAChB,MAAA,MAAU,GAAA,CAAA,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,QAAQ,CAAA;AAEvC,MAAA,IAAA,CAAK,SAAS,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,KAAK,GAAK,CAAA;AAAA,IAExD,SAAS,GAAA,EAAK;AACZ,MAAA,MAAU,GAAA,CAAA,MAAA,CAAO,OAAO,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAC/C,MAAA,IAAA,CAAK,MAAA,GAAS,MAAU,GAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,GAAA,EAAK,GAAK,CAAA,CAAE,KAAA,CAAM,MAAM,IAAA,CAAK,MAAM,CAAA;AAC/E,MAAA,MAAM,GAAA;AAAA,IACR;AAGA,IAAA,MAAM,KAAK,MAAA,CAAO;AAAA,MAChB,IAAA,EAAM,SAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B,aAAA,EAAe,iBAAA;AAAA,MACf,eAAe;AAAC,KACjB,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,iBAAA,EAAmB;AAAA,MACnC,aAAA,EAAe,iBAAA;AAAA,MACf,eAAe,EAAC;AAAA,MAChB,aAAA,EAAe;AAAA,KAChB,CAAA;AAED,IAAA,OAAO,YAAA;AAAA,EACT;AAAA,EAEA,MAAM,YAAA,GAA8B;AAElC,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAIpB,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,IAAA,CAAK,cAAc,EAAC;AAGpB,IAAA,MAAM,IAAA,CAAK,UAAA;AACX,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU;AAAA,MAC/B,IAAA,EAAM,eAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,KAAA,EAAO,IAAA,CAAK,IAAA,CAAK,KAAA,IAAS,SAAA;AAAA,MAC1B,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,QAAA,IAAY;AAAA,KACjC,CAAC;AAAA,CAAA;AACF,IAAA,MAAU,GAAA,CAAA,SAAA,CAAU,IAAA,CAAK,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,OAAA,EAAgC;AACxD,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,GAAS,GAAA,EAAK;AACpC,MAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,IAC1D;AACA,IAAA,MAAM,KAAK,MAAA,CAAO;AAAA,MAChB,IAAA,EAAM,iBAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,mBAAA,EAAqB,EAAE,OAAA,EAAS,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,oBAAoB,MAAA,EAA0D;AAClF,IAAA,MAAM,KAAK,MAAA,CAAO;AAAA,MAChB,IAAA,EAAM,eAAA;AAAA,MACN,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAC3B;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,iBAAA,EAAmB,EAAE,MAAA,EAAQ,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AAAA,EAC/E;AACF,CAAA;AAEA,SAAS,eAAe,OAAA,EAA0C;AAChE,EAAA,MAAM,IAAA,GACJ,OAAO,OAAA,KAAY,QAAA,GACf,UACA,OAAA,CACG,MAAA,CAAO,CAAC,CAAA,KAA2C,CAAA,CAAE,SAAS,MAAM,CAAA,CACpE,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA,CACjB,KAAK,GAAG,CAAA;AACjB,EAAA,OAAA,CAAQ,IAAA,IAAQ,kBAAA,EAAoB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACjD;ACnoDO,IAAM,aAAN,MAAiB;AAAA,EACL,IAAA;AAAA;AAAA;AAAA,EAGA,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,YAAY,IAAA,EAA4D;AACtE,IAAA,IAAA,CAAK,IAAA,GAAYC,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,YAAY,CAAA;AAC5C,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA,EAEA,MAAM,MAAM,KAAA,EAA4C;AACtD,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAGtB,MAAA,MAAM,KAAK,KAAA,EAAM;AACjB,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AACnE,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,KAAA;AAAA,QACb,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,0BAAA;AAAA,QACP,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,QAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,GAAsC;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,IAC5C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,UAC3B,KAAA,EAAO,OAAA;AAAA,UACP,UAAU,IAAA,CAAK,IAAA;AAAA,UACf,SAAA,EAAW,MAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,UACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,OAAO,EAAC;AAAA,MACV;AACA,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,IAAA;AAAA,QACb,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,yBAAA;AAAA,QACP,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,QAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AACF,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACzB,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,cAAA;AAAA,QACP,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,gBAAA;AAAA,QACP,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAChC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,MAC3B,KAAA,EAAO,OAAA;AAAA,MACP,UAAU,IAAA,CAAK,IAAA;AAAA,MACf,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,KAC3D,CAAA;AACD,IAAA,MAAM,MAA4B,EAAC;AACnC,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI,oBAAA,CAAqB,CAAC,CAAA,EAAG,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,IACzC;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAUA,GAAA,CAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,SAAS,QAAA,EAAU;AACvB,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,KAAK,OAAA,IAAW,QAAA;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,IAAA;AAAA,QACb,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AAID,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,0BAAA;AAAA,QACP,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAU,GAAA,CAAc,OAAA;AAAA,QACxB,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AAAA,IACJ;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,CAAA,EAAqC;AACjE,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,MAAM,OAAO,KAAA;AAChD,EAAA,MAAM,CAAA,GAAI,CAAA;AACV,EAAA,OAAO,OAAO,EAAE,aAAa,CAAA,KAAM,YAAY,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,QAAQ,CAAC,CAAA;AAC1E;AC3LA,IAAM,0BAA0B,GAAA,GAAM,IAAA;AAOtC,IAAM,cAAA,GAAiB,yDAAA;AAQhB,IAAM,yBAAN,MAAwD;AAAA,EAC5C,KAAA,uBAAY,GAAA,EAAwB;AAAA,EACpC,OAAwB,EAAC;AAAA,EAClC,UAA0C,EAAE,IAAA,EAAM,GAAG,KAAA,EAAO,CAAA,EAAG,MAAM,CAAA,EAAE;AAAA,EAC9D,QAAA;AAAA,EACA,cAAA;AAAA,EAEjB,WAAA,CAAY,IAAA,GAA+B,EAAC,EAAG;AAC7C,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,cAAA,GAAiB,KAAK,mBAAA,IAAuB,uBAAA;AAAA,EACpD;AAAA,EAEA,MAAM,IAAI,KAAA,EAAmD;AAC3D,IAAA,MAAM,GAAA,GAAM,EAAE,IAAA,CAAK,OAAA,CAAQ,MAAM,IAAI,CAAA;AACrC,IAAA,MAAM,EAAA,GAAK,CAAA,EAAG,UAAA,CAAW,KAAA,CAAM,IAAI,CAAC,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAIH,WAAAA,CAAY,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA;AAC7E,IAAA,MAAM,KAAA,GAAQ,OAAO,UAAA,CAAW,KAAA,CAAM,MAAM,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,QAAA,GAAW,MAAM,CAAA;AACtF,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI,OAA2B,KAAA,CAAM,IAAA;AACrC,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,KAAA,IAAS,IAAA,CAAK,cAAA,EAAgB;AACjD,MAAA,MAAUI,UAAM,IAAA,CAAK,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAClD,MAAA,WAAA,GAAmBC,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,CAAA,EAAG,EAAE,CAAA,IAAA,CAAM,CAAA;AAGlD,MAAA,MAAM,WAAA,CAAY,WAAA,EAAa,KAAA,CAAM,IAAA,EAAM;AAAA,QACzC,QAAA,EAAU,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,QAAA,GAAW;AAAA,OAC/C,CAAA;AACD,MAAA,IAAA,GAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,GAAA,GAAkB;AAAA,MACtB,EAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,IAAA,EAAM,KAAA,CAAM,IAAA,IAAQ,EAAC;AAAA,MACrB,IAAA;AAAA,MACA,IAAA,EAAM,WAAA;AAAA,MACN,KAAA;AAAA,MACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACpC;AACA,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAA,EAAI,GAAG,CAAA;AACtB,IAAA,MAAM,GAAA,GAAqB,EAAE,EAAA,EAAI,IAAA,EAAM,MAAM,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,GAAA,CAAI,IAAA,EAAK;AACvE,IAAA,IAAA,CAAK,IAAA,CAAK,KAAK,GAAG,CAAA;AAClB,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,EAAA,EAA6C;AACrD,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AAAA,EAC1B;AAAA,EAEA,IAAA,GAAwB;AACtB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,IAAI,CAAA;AAAA,EACtB;AAAA,EAEA,MAAM,OAAO,IAAA,EAAuC;AAClD,IAAA,MAAM,UAAU,CAAC,GAAG,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AACjD,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA,GAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA,GAAI,EAAC;AACpE,IAAA,MAAM,SAAyB,EAAC;AAChC,IAAA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,MAAM,GAAA,GAAM,EAAE,KAAA,IAAS,CAAA;AACvB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,SAAA,EAAW,GAAG,CAAA;AACxC,MAAA,IAAI,MAAA,SAAe,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AACtD,MAAA,IAAI,GAAA;AACJ,MAAA,IAAI,CAAA,CAAE,CAAC,CAAA,KAAM,MAAA,EAAW;AAEtB,QAAA,MAAM,QAAA,GAAW,EAAE,CAAC,CAAA;AACpB,QAAA,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,QAAQ,CAAA;AAAA,MAC/E,CAAA,MAAO;AACL,QAAA,MAAM,IAAA,GAAO,YAAA,CAAa,CAAA,CAAE,CAAC,CAAW,CAAA;AACxC,QAAA,MAAM,GAAA,GAAM,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACvB,QAAA,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,IAAA,KAAS,IAAA,IAAQ,CAAA,CAAE,GAAA,KAAQ,GAAG,CAAA;AAAA,MAC9D;AACA,MAAA,MAAM,MAAM,GAAA,GAAM,IAAA,CAAK,MAAM,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,GAAI,MAAA;AAC3C,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAA,CAAE,CAAC,GAAG,CAAA;AAAA,MAC1C,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,IAAA,CAAK,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,MACrC;AACA,MAAA,SAAA,GAAY,GAAA,GAAM,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA;AAAA,IACzB;AACA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACjC,IAAA,IAAI,IAAA,SAAa,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,MAAM,CAAA;AAClD,IAAA,OAAO,kBAAkB,MAAM,CAAA;AAAA,EACjC;AAAA,EAEA,MAAM,KAAA,GAAuB;AAE3B,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,WAAqB,EAAC;AAC5B,MAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AACrC,QAAA,IAAI,GAAA,CAAI,IAAA,EAAM,QAAA,CAAS,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MACtC;AAEA,MAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAUD,GAAA,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAC,CAAC,CAAA;AAAA,IAC7E;AACA,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,IAAA,IAAA,CAAK,KAAK,MAAA,GAAS,CAAA;AACnB,IAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,GAAG,KAAA,EAAO,CAAA,EAAG,MAAM,CAAA,EAAE;AAAA,EAC9C;AAAA,EAEA,MAAc,QAAQ,GAAA,EAAwC;AAC5D,IAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,MAAA,MAAM,IAAA,GACJ,GAAA,CAAI,IAAA,KAAS,GAAA,CAAI,IAAA,GAAO,MAAUA,GAAA,CAAA,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,EAAE,QAAA,EAAU,QAAA,EAAU,CAAA,GAAI,EAAA,CAAA;AACjF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,OAAA;AAAA,QACN,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,UAAA,EAAY,GAAA,CAAI,IAAA,CAAK,SAAA,IAAa,WAAA;AAAA,UAClC;AAAA;AACF,OACF;AAAA,IACF;AACA,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,IAAA,KAAS,GAAA,CAAI,IAAA,GAAO,MAAUA,GAAA,CAAA,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,MAAM,CAAA,GAAI,EAAA,CAAA;AAC3E,IAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,QAAA,GAAW,eAAe,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,CAAA,GAAO,UAAA;AACzE,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,CAAK,QAAA,GAAW,SAAA,GAAY,WAAA;AAC9C,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,GAAG,KAAK;AAAA,EAAK,GAAG;AAAA,EAAK,KAAK,CAAA,CAAA,EAAG;AAAA,EAC5D;AACF;AAEA,SAAS,WAAW,IAAA,EAA8B;AAChD,EAAA,OAAO,IAAA,KAAS,SAAS,QAAA,GAAW,IAAA;AACtC;AAEA,SAAS,aAAa,MAAA,EAAgC;AACpD,EAAA,IAAI,MAAA,KAAW,UAAU,OAAO,MAAA;AAChC,EAAA,IAAI,MAAA,KAAW,SAAS,OAAO,OAAA;AAC/B,EAAA,OAAO,MAAA;AACT;AAGA,SAAS,QAAQ,GAAA,EAAwC;AACvD,EAAA,OAAO,GAAA,CAAI,IAAA,CAAK,QAAA,IAAY,GAAA,CAAI,IAAA,CAAK,KAAA;AACvC;AAGA,SAAS,QAAA,CAAY,KAAmB,IAAA,EAAwC;AAC9E,EAAA,KAAA,IAAS,IAAI,GAAA,CAAI,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACxC,IAAA,IAAI,KAAK,GAAA,CAAI,CAAC,CAAM,CAAA,EAAG,OAAO,IAAI,CAAC,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,kBAAkB,MAAA,EAAwC;AACjE,EAAA,MAAM,MAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA;AAC/B,IAAA,IAAI,EAAE,IAAA,KAAS,MAAA,IAAU,IAAA,IAAQ,IAAA,CAAK,SAAS,MAAA,EAAQ;AACrD,MAAA,IAAA,CAAK,QAAQ,CAAA,CAAE,IAAA;AAAA,IACjB,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,IACZ;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;;;ACvLO,IAAM,kBAAA,GAAiD;AAAA,EAC5D,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,UAAA;AAAA,EACV,UAAA,EAAY,YAAA;AAAA,EACZ,UAAA,EAAY,YAAA;AAAA,EACZ,SAAA,EAAW,WAAA;AAAA,EACX,YAAA,EAAc;AAChB,CAAA;;;ACsBA,IAAM,gBAAA,GAAmB,sBAAA;AACzB,IAAM,MAAA,GAAS,YAAA;AACf,IAAM,8BAAA,GAAiC,CAAA;AAEvC,SAAS,eAAe,KAAA,EAA4B;AAClD,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,QAAA,EAAU;AAChC,IAAA,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EAChD,CAAA,MAAA,IAAW,MAAM,IAAA,EAAM;AACrB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EAC9B,CAAA,MAAA,IAAW,MAAM,QAAA,EAAU;AACzB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EAClC;AACA,EAAA,IAAI,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA,EAAG;AACvC,IAAA,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAAK,EAAA;AACpD;AAEA,SAAS,WAAA,CAAY,MAAc,KAAA,EAAwC;AACzE,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,KAAK,GAAG,OAAO,IAAA;AAGvC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,mBAAmB,CAAA;AACjD,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAA;AAEzB,EAAA,IAAI,IAAA,GAAO,QAAQ,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,CAAE,MAAM,EAAE,IAAA,EAAK;AAGjD,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,gBAAgB,CAAA;AAC3C,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAA;AACxB,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAA;AACxB,IAAA,IAAI,YAAA,CAAa,CAAC,CAAA,EAAG;AACnB,MAAA,IAAA,GAAO,CAAA;AACP,MAAA,QAAA,GAAW,UAAA,CAAW,CAAC,CAAA,GAAI,CAAA,GAAI,MAAA;AAAA,IACjC,CAAA,MAAA,IAAW,UAAA,CAAW,CAAC,CAAA,EAAG;AACxB,MAAA,QAAA,GAAW,CAAA;AAAA,IACb;AACA,IAAA,IAAA,GAAO,KAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,CAAE,MAAM,EAAE,IAAA,EAAK;AAAA,EAC5C;AAGA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA;AAC5C,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAA,GAAO,KAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,CAAE,MAAM,EAAE,IAAA,EAAK;AAAA,EAC5C,CAAA,MAAO;AACL,IAAA,IAAA,GAAO,KAAK,IAAA,EAAK;AAAA,EACnB;AAGA,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,IAAI,QAAA;AACJ,EAAA,MAAA,CAAO,SAAA,GAAY,CAAA;AAEnB,EAAA,OAAA,CAAQ,QAAA,GAAW,MAAA,CAAO,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAC9C,IAAA,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,IAAK,EAAE,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,EAAE,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA,CAAE,IAAA,EAAK;AAExE,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,IAAA,EAAM,SAAA;AAAA,IACN,EAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA,EAAM,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,IAAA,GAAO;AAAA,GACjC;AACF;AAEA,SAAS,aAAa,CAAA,EAA4B;AAChD,EAAA,OAAO,CAAA,IAAK,kBAAA;AACd;AAEA,SAAS,WAAW,CAAA,EAAgC;AAClD,EAAA,OAAO,MAAM,UAAA,IAAc,CAAA,KAAM,MAAA,IAAU,CAAA,KAAM,YAAY,CAAA,KAAM,KAAA;AACrE;AAQO,IAAM,oBAAN,MAAiD;AAAA,EAC7C,IAAA,GAAO,MAAA;AAAA,EACC,KAAA;AAAA,EAEjB,YAAY,IAAA,EAAgC;AAC1C,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,gBAAA,EAAkB,KAAK,KAAA,CAAM,mBAAA;AAAA,MAC7B,gBAAA,EAAkB,KAAK,KAAA,CAAM,aAAA;AAAA,MAC7B,aAAA,EAAe,KAAK,KAAA,CAAM;AAAA,KAC5B;AAAA,EACF;AAAA,EAEQ,WAAA,CAAY,UAAkB,KAAA,EAA4B;AAChE,IAAA,OAAO,QAAA,IAAY,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAAA,EACrC;AAAA,EAEA,MAAM,QAAA,CAAS,KAAA,EAAoB,KAAA,EAAoB,QAAA,EAAiC;AACtF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAC7C,IAAA,MAAM,SAAA,CAAeE,KAAA,CAAA,OAAA,CAAQ,IAAI,CAAC,CAAA;AAClC,IAAA,IAAI,QAAA,GAAW,EAAA;AACf,IAAA,IAAI;AAAE,MAAA,QAAA,GAAW,MAASC,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAiB;AAE3E,IAAA,MAAM,EAAA,GAAK,CAAA,IAAA,EAAO,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,UAAA,EAAW,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACxD,IAAA,MAAM,IAAA,GAAO,eAAe,KAAK,CAAA;AACjC,IAAA,MAAM,IAAA,GAAO;AAAA,GAAA,EAAQ,KAAA,CAAM,EAAE,CAAA,EAAA,EAAK,EAAE,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC;AAAA,CAAA;AAC7E,IAAA,MAAM,IAAA,GAAO,SAAS,IAAA,EAAK,GACvB,SAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,GAAI,IAAA,GAC/B,CAAA;AAAA,EAAmB,IAAI,CAAA,CAAA;AAC3B,IAAA,MAAM,WAAA,CAAY,MAAM,IAAI,CAAA;AAAA,EAC9B;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAoB,KAAA,EAAe,QAAA,EAAmC;AACjF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAC7C,IAAA,OAAO,YAAA,CAAa,MAAM,YAAY;AACpC,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI;AAAE,QAAA,QAAA,GAAW,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,CAAA;AAAA,MAAqB;AAExF,MAAA,MAAM,MAAA,GAAS,MAAM,WAAA,EAAY;AACjC,MAAA,MAAM,SAAA,GAAY,aAAA;AAClB,MAAA,IAAI,OAAA,GAAU,CAAA;AACd,MAAA,MAAM,QAAQ,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAS;AAClD,QAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,QAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,IAAI,GAAG,OAAO,IAAA;AACtC,QAAA,IAAI,SAAA,CAAU,IAAA,CAAK,KAAK,CAAA,EAAG;AACzB,UAAA,MAAM,YAAA,GAAe,aAAA,CAAc,IAAA,CAAK,OAAO,CAAA;AAC/C,UAAA,IAAI,YAAA,IAAgB,YAAA,CAAa,CAAC,CAAA,KAAM,KAAA,EAAO;AAAE,YAAA,OAAA,EAAA;AAAW,YAAA,OAAO,KAAA;AAAA,UAAO;AAAA,QAC5E;AACA,QAAA,IAAI,OAAA,CAAQ,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,CAAA,EAAG;AAAE,UAAA,OAAA,EAAA;AAAW,UAAA,OAAO,KAAA;AAAA,QAAO;AACvE,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AACD,MAAA,IAAI,UAAU,CAAA,EAAG;AACf,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,IAAM,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,EAAK,EAAI;AACnE,UAAA,MAAM,WAAA,CAAY,MAAM,EAAE,CAAA;AAAA,QAC5B,CAAA,MAAO;AACL,UAAA,MAAM,WAAA,CAAY,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,QAC1C;AAAA,MACF;AACA,MAAA,OAAO,OAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,OAAA,CAAQ,KAAA,EAAoB,QAAA,EAAmC;AACnE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAC7C,IAAA,IAAI;AAAE,MAAA,OAAO,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,EAAA;AAAA,IAAsB;AAAA,EACvF;AAAA,EAEA,MAAM,IAAA,CAAK,KAAA,EAAoB,QAAA,EAAkB,KAAA,EAAwC;AACvF,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAC9C,IAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,SAAU,EAAC;AACzB,IAAA,MAAM,OAAA,GAAU,YAAA,CAAa,GAAA,EAAK,KAAK,CAAA;AACvC,IAAA,OAAO,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,OAAA;AAAA,EAC3C;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAoB,KAAA,EAAe,UAAkB,KAAA,EAAwC;AACxG,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,IAAA,CAAK,OAAO,QAAQ,CAAA;AAC/C,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA;AAG9C,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAChC,MAAA,MAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA;AAC9C,MAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,MAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,QAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG,KAAA,IAAS,CAAA;AAE/C,QAAA,IAAI,CAAA,CAAE,IAAA,EAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG,KAAA,IAAS,CAAA;AAAA,MACjE;AACA,MAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,KAAA,EAAM;AAAA,IAC3B,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACvC,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AACpE,IAAA,OAAO,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,OAAA;AAAA,EAC3C;AAAA,EAEA,MAAM,KAAA,CAAM,KAAA,EAAoB,QAAA,EAAiC;AAC/D,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAC7C,IAAA,MAAM,WAAA,CAAY,MAAM,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,MAAM,WAAA,CAAY,KAAA,EAAoB,QAAA,EAAmC;AACvE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAC7C,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAAE,MAAA,QAAA,GAAW,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,CAAA;AAAA,IAAqB;AAExF,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,MAAM,QAAQ,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAS;AAClD,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,MAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,IAAI,GAAG,OAAO,IAAA;AAEtC,MAAA,MAAM,IAAA,GAAO,QACV,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA,CACzB,OAAA,CAAQ,oBAAoB,EAAE,CAAA,CAC9B,QAAQ,UAAA,EAAY,EAAE,EACtB,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,GACA,WAAA,EAAY;AACf,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAAE,QAAA,OAAA,EAAA;AAAW,QAAA,OAAO,KAAA;AAAA,MAAO;AAC/C,MAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AACb,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAC5B,IAAA,MAAM,SAAS,CAAA,EAAG,IAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAK,CAAA,CAAA;AACxC,IAAA,IAAI;AACF,MAAA,MAASA,GAAA,CAAA,QAAA,CAAS,MAAM,MAAM,CAAA;AAC9B,MAAA,MAAM,wBAAwB,IAAI,CAAA;AAAA,IACpC,CAAA,CAAA,MAAQ;AAAA,IAAoB;AAE5B,IAAA,IAAI;AAAE,MAAA,MAAM,WAAA,CAAY,MAAM,IAAI,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,CAAA;AAAA,IAAqB;AAC3E,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAEA,eAAe,wBAAwB,IAAA,EAA6B;AAClE,EAAA,MAAM,GAAA,GAAWD,cAAQ,IAAI,CAAA;AAC7B,EAAA,MAAM,IAAA,GAAYA,eAAS,IAAI,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA,KAAA,CAAA;AACtB,EAAA,MAAM,OAAA,GAAA,CAAW,MAASC,GAAA,CAAA,OAAA,CAAQ,GAAG,GAClC,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAM,CAAC,CAAA,CACxC,IAAA,GACA,OAAA,EAAQ;AAEX,EAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,IACZ,QAAQ,KAAA,CAAM,8BAA8B,CAAA,CAAE,GAAA,CAAI,OAAO,IAAA,KAAS;AAChE,MAAA,IAAI;AACF,QAAA,MAASA,GAAA,CAAA,MAAA,CAAYD,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAAI,CAAC,CAAA;AAAA,MACtC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,GACH;AACF;AAIO,SAAS,YAAA,CAAa,GAAA,EAAa,KAAA,GAAqB,gBAAA,EAAiC;AAC9F,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,EAAM,KAAK,CAAA;AACrC,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,QAAQ,OAAA,EAAQ;AACzB;;;AClRA,IAAM,eAAA,GAAkB,IAAA;AAuBjB,IAAM,qBAAN,MAAgD;AAAA,EACpC,KAAA;AAAA,EACA,MAAA;AAAA,EACT,OAAA;AAAA,EACS,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,UAAA,uBAAiB,GAAA,EAAmC;AAAA;AAAA,EAEpD,WAAA,uBAAkB,GAAA,EAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1C,aAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,IAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,gBAAA,EAAkB,KAAK,KAAA,CAAM,mBAAA;AAAA,MAC7B,gBAAA,EAAkB,KAAK,KAAA,CAAM,aAAA;AAAA,MAC7B,aAAA,EAAe,KAAK,KAAA,CAAM;AAAA,KAC5B;AACA,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,OAAA,GAAU,KAAK,OAAA,IAAW,IAAI,kBAAkB,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,CAAA;AAI1E,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,WAAA,EAAY;AAC/C,IAAA,IAAA,CAAK,aAAA,GAAgB,4BAAA,CAA6B,IAAA,CAAK,IAAI,CAAA;AAC3D,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,aAAA,GAClB,IAAA,CAAK,MAAM,mBAAA,CAAoB,OAAA,CAAQ,aAAA,EAAe,gBAAgB,CAAA,GACtE,EAAA;AAAA,EACN;AAAA;AAAA,EAGA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,MAAc,aAAA,CAAiB,KAAA,EAAoB,IAAA,EAAoC;AACrF,IAAA,MAAM,QAAQ,IAAA,CAAK,UAAA,CAAW,IAAI,KAAK,CAAA,IAAK,QAAQ,OAAA,EAAQ;AAE5D,IAAA,MAAM,IAAA,GAAO,KAAA,CACV,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAA,EAAO,GAAY,CAAA;AAAA,IAC1C,CAAC,CAAA,CACA,IAAA,CAAK,MAAM,MAAM,CAAA;AACpB,IAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,KAAA,EAAO,IAAwB,CAAA;AACnD,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA;AAAA,IACf,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAA,EAAO,GAAY,CAAA;AACxC,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,KAAK,MAAM,IAAA,EAAM;AACvC,QAAA,IAAA,CAAK,UAAA,CAAW,OAAO,KAAK,CAAA;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,GAA2B;AAC/B,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,gBAAA,EAAkB,gBAAA,EAAkB,aAAa,CAAA,EAAoB;AACxF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AAC3C,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,KAAA,CAAM,IAAA,CAAK,sCAA4B,OAAA,CAAQ,KAAK,CAAC,CAAA,GAAA,EAAM,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AAAA,MAC/E;AACA,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,MAAA,IAAI;AACF,QAAA,MAAM,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,QAAQ,CAAA;AACvD,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,SAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,IAAI,IAAA,CAAK,MAAK,EAAG,KAAA,CAAM,KAAK,CAAA,GAAA,EAAM,OAAA,CAAQ,KAAK,CAAC;;AAAA,EAAO,IAAA,CAAK,IAAA,EAAM,CAAA,CAAE,CAAA;AAAA,MACtE,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,SAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,UACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,IACF;AACA,IAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,EAC1B;AAAA,EAEA,MAAM,KAAK,KAAA,EAAqC;AAC9C,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,QAAQ,CAAA;AACvD,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,GAAA;AAAA,QACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,GAAA;AAAA,QACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,OAC3D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAA,CAAK,KAAA,GAAqB,gBAAA,EAAkB,KAAA,EAAwC;AACxF,IAAA,OAAO,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA,EAAO,KAAK,KAAA,CAAM,KAAK,GAAG,KAAK,CAAA;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAA,CAAY,IAAA,EAAc,KAAA,GAAqB,gBAAA,EAAkB,QAAQ,CAAA,EAA2B;AACxG,IAAA,IAAI,IAAA,CAAK,QAAQ,WAAA,EAAa;AAC5B,MAAA,OAAO,IAAA,CAAK,QAAQ,WAAA,CAAY,KAAA,EAAO,KAAK,KAAA,CAAM,KAAK,CAAA,EAAG,IAAA,EAAM,KAAK,CAAA;AAAA,IACvE;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AAAA,EACvC;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAe,KAAA,GAAqB,kBAAkB,KAAA,EAAwC;AACzG,IAAA,OAAO,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA,EAAO,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,EAAG,KAAK,CAAA;AAAA,EACnE;AAAA,EAEA,MAAM,QAAA,CACJ,IAAA,EACA,KAAA,GAAqB,kBACrB,QAAA,EACe;AACf,IAAA,MAAM,EAAA,GAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAClC,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,YAAY;AAC3C,MAAA,MAAM,QAAqB,EAAE,KAAA,EAAO,IAAA,EAAM,EAAA,EAAI,GAAG,QAAA,EAAS;AAC1D,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,KAAA,EAAO,OAAO,QAAQ,CAAA;AAClD,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,UAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,UAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,UACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,MAAM,GAAA;AAAA,MACR;AAGA,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAQ,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAC/D,MAAA,IAAI,MAAA,CAAO,UAAA,CAAW,GAAA,EAAK,MAAM,IAAI,eAAA,EAAiB;AACpD,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,YAAY,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AACvE,QAAA,IAAI,UAAU,CAAA,EAAG;AACf,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,qBAAA,EAAuB;AAAA,YACvC,KAAA;AAAA,YACA;AAAA,WACmC,CAAA;AAAA,QACvC;AAAA,MACF;AAGA,MAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAE7B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,mBAAA,EAAqB;AAAA,QACrC,KAAA;AAAA,QACA,IAAA;AAAA,QACA,EAAA;AAAA,QACA,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,UAAU,KAAA,CAAM;AAAA,OACiB,CAAA;AAAA,IACrC,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAA,CACJ,GAAA,EACA,KAAA,GAAqB,gBAAA,EACrB,QAAQ,CAAA,EACgB;AACxB,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA;AACjC,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAE9B,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,CAAY,WAAA,EAAY,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AACvF,IAAA,MAAM,UAAA,GAAA,CAAc,GAAA,CAAI,YAAA,IAAgB,EAAC,EAAG,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACvE,IAAA,MAAM,SAAA,GAAA,CAAa,GAAA,CAAI,SAAA,IAAa,EAAC,EAAG,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACjF,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,IAAA,MAAM,SAAwB,EAAC;AAE/B,IAAA,KAAA,MAAW,SAAS,GAAA,EAAK;AACvB,MAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,MAAA,MAAM,UAAoB,EAAC;AAC3B,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,IAAA,CAAK,WAAA,EAAY;AACzC,MAAA,MAAM,SAAA,GAAA,CAAa,KAAA,CAAM,IAAA,IAAQ,EAAC,EAAG,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAG/D,MAAA,IAAI,QAAA,GAAW,CAAA;AACf,MAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,QAAA,IAAI,SAAA,CAAU,QAAA,CAAS,CAAC,CAAA,EAAG;AAAE,UAAA,QAAA,EAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAA,QAAG;AACrD,QAAA,IAAI,SAAA,CAAU,KAAK,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG;AAAE,UAAA,QAAA,EAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAA,QAAG;AAAA,MACtE;AACA,MAAA,IAAI,WAAW,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,CAAA,YAAA,EAAe,QAAQ,CAAA,CAAA,CAAG,CAAA;AAGzD,MAAA,IAAI,SAAA,GAAY,CAAA;AAChB,MAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,QAAA,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,KAAM,SAAA,CAAU,SAAS,CAAC,CAAA,IAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA,EAAI;AACnF,UAAA,SAAA,EAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,KAAA,IAAS,SAAA;AACT,MAAA,IAAI,YAAY,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,CAAA,aAAA,EAAgB,SAAS,CAAA,CAAA,CAAG,CAAA;AAE5D,MAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,QAAA,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,KAAM,SAAA,CAAU,SAAS,CAAC,CAAA,IAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA,EAAI;AACnF,UAAA,KAAA,IAAS,CAAA;AACT,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,cAAA,EAAiB,CAAC,CAAA,CAAE,CAAA;AAAA,QACnC;AAAA,MACF;AAGA,MAAA,QAAQ,MAAM,QAAA;AAAU,QACtB,KAAK,UAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,UAAU,CAAA;AAAG,UAAA;AAAA,QACvD,KAAK,MAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,eAAe,CAAA;AAAG,UAAA;AAAA,QAC5D,KAAK,QAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA;AAAA,QAC7B,KAAK,KAAA;AAAY,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,cAAc,CAAA;AAAG,UAAA;AAAA;AAI7D,MAAA,QAAQ,MAAM,IAAA;AAAM,QAClB,KAAK,UAAA;AAAe,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,UAAU,CAAA;AAAG,UAAA;AAAA,QAC1D,KAAK,YAAA;AAAe,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,YAAY,CAAA;AAAG,UAAA;AAAA,QAC5D,KAAK,cAAA;AAAgB,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,cAAc,CAAA;AAAG,UAAA;AAAA,QAC/D,KAAK,YAAA;AAAe,UAAA,KAAA,IAAS,CAAA;AAAG,UAAA,OAAA,CAAQ,KAAK,YAAY,CAAA;AAAG,UAAA;AAExC;AAItB,MAAA,MAAM,OAAA,GAAA,CAAW,GAAA,GAAM,IAAI,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA,CAAE,OAAA,EAAQ,KAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,EAAA,CAAA;AACzE,MAAA,IAAI,OAAA,GAAU,GAAG,KAAA,IAAS,CAAA;AAAA,WAAA,IACjB,OAAA,GAAU,IAAI,KAAA,IAAS,CAAA;AAGhC,MAAA,IAAI,KAAA,CAAM,UAAA,KAAe,MAAA,IAAa,KAAA,CAAM,aAAa,GAAA,EAAK;AAC5D,QAAA,KAAA,IAAS,CAAA;AACT,QAAA,OAAA,CAAQ,KAAK,gBAAgB,CAAA;AAAA,MAC/B;AAGA,MAAA,IAAI,MAAM,YAAA,EAAc;AACtB,QAAA,MAAM,gBAAA,GAAA,CAAoB,GAAA,GAAM,IAAI,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA,CAAE,OAAA,EAAQ,KAAM,GAAA,GAAO,EAAA,GAAK,EAAA,CAAA;AACvF,QAAA,IAAI,gBAAA,GAAmB,GAAG,KAAA,IAAS,CAAA;AAAA,MACrC;AAEA,MAAA,IAAI,QAAQ,CAAA,EAAG;AACb,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,GAAG,KAAA;AAAA,UACH,KAAA;AAAA,UACA,WAAA,EAAa,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,IAAK;AAAA,SACpC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAIvC,IAAA,MAAM,SAAA,GAAY,CAAA;AAClB,IAAA,MAAM,WAAW,MAAA,CAAO,MAAA;AAAA,MACtB,CAAC,MAAM,CAAA,CAAE,KAAA,IAAS,aAAa,CAAA,CAAE,QAAA,KAAa,UAAA,IAAc,CAAA,CAAE,QAAA,KAAa;AAAA,KAC7E;AAEA,IAAA,OAAO,SAAS,KAAA,CAAM,CAAA,EAAG,KAAK,GAAA,CAAI,KAAA,EAAO,EAAE,CAAC,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAe,KAAA,GAAqB,gBAAA,EAAmC;AAClF,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,YAAY;AAC3C,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,IAAI,OAAA,GAAU,CAAA;AACd,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,KAAA,EAAO,OAAO,QAAQ,CAAA;AAC1D,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,QAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,QAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,UACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,IAAI,UAAU,CAAA,EAAG;AACf,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,kBAAA,EAAoB;AAAA,UACpC,KAAA;AAAA,UACA,KAAA;AAAA,UACA;AAAA,SACgC,CAAA;AAClC,QAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,MAC/B;AACA,MAAA,OAAO,OAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,KAAA,EAAmC;AACnD,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,YAAY;AAC3C,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,MAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,MAAA,IAAI,OAAA,GAAU,CAAA;AACd,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,OAAO,QAAQ,CAAA;AACxD,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,aAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,UACjC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA;AAAA,UACA,SAAA,EAAW,aAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,UACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,SAC3D,CAAA;AACD,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,IAAI,UAAU,CAAA,EAAG;AACf,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,qBAAA,EAAuB;AAAA,UACvC,KAAA;AAAA,UACA;AAAA,SACmC,CAAA;AACrC,QAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,MAC/B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,KAAA,EAAoC;AAC9C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,YAAY;AAC1C,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACjC,QAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,QAAQ,CAAA;AACxC,UAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,YACjC,SAAA,EAAW,UAAA;AAAA,YACX,KAAA,EAAO,QAAA;AAAA,YACP,QAAA;AAAA,YACA,SAAA,EAAW,OAAA;AAAA,YACX,OAAA,EAAS,SAAA;AAAA,YACT,UAAA,EAAY,GAAA;AAAA,YACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,WAC3D,CAAA;AAAA,QACH,SAAS,GAAA,EAAK;AACZ,UAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,YACjC,SAAA,EAAW,UAAA;AAAA,YACX,KAAA,EAAO,QAAA;AAAA,YACP,QAAA;AAAA,YACA,SAAA,EAAW,OAAA;AAAA,YACX,OAAA,EAAS,SAAA;AAAA,YACT,UAAA,EAAY,GAAA;AAAA,YACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,YACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,WAC3D,CAAA;AACD,UAAA,MAAM,GAAA;AAAA,QACR;AACA,QAAA,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,gBAAA,EAAkB,EAAE,OAAsC,CAAA;AAC5E,QAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,MAC/B,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,MACX,CAAC,gBAAA,EAAkB,gBAAA,EAAkB,aAAa,CAAA,CAAoB,GAAA;AAAA,QAAI,OAAO,CAAA,KAChF,IAAA,CAAK,aAAA,CAAc,GAAG,YAAY;AAChC,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAC7B,UAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,UAAA,IAAI;AACF,YAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA;AACpC,YAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,YAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,cACjC,SAAA,EAAW,UAAA;AAAA,cACX,KAAA,EAAO,QAAA;AAAA,cACP,QAAA;AAAA,cACA,SAAA,EAAW,OAAA;AAAA,cACX,OAAA,EAAS,SAAA;AAAA,cACT,UAAA,EAAY,GAAA;AAAA,cACZ,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,aAC3D,CAAA;AAAA,UACH,SAAS,GAAA,EAAK;AACZ,YAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AACzB,YAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,cACjC,SAAA,EAAW,UAAA;AAAA,cACX,KAAA,EAAO,QAAA;AAAA,cACP,QAAA;AAAA,cACA,SAAA,EAAW,OAAA;AAAA,cACX,OAAA,EAAS,SAAA;AAAA,cACT,UAAA,EAAY,GAAA;AAAA,cACZ,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,cACzB,GAAI,IAAA,CAAK,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,KAAK,OAAA;AAAQ,aAC3D,CAAA;AACD,YAAA,MAAM,GAAA;AAAA,UACR;AACA,UAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,gBAAA,EAAkB,EAAE,KAAA,EAAO,GAAkC,CAAA;AAC/E,UAAA,MAAM,IAAA,CAAK,aAAa,CAAC,CAAA;AAAA,QAC3B,CAAC;AAAA;AACH,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YAAY,OAAA,EAA8B;AAIxC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EACA,MAAc,aAAa,KAAA,EAAmC;AAC5D,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,IAAiB,KAAA,KAAU,gBAAA,EAAkB;AACvD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAQ,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AACnE,MAAA,MAAM,EAAE,WAAAE,UAAAA,EAAW,KAAA,EAAAC,QAAM,GAAI,MAAM,OAAO,aAAkB,CAAA;AAC5D,MAAA,MAAMA,OAAM,IAAA,CAAK,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC/C,MAAA,MAAMD,UAAAA,CAAU,GAAG,IAAA,CAAK,SAAS,IAAI,KAAK,CAAA,GAAA,CAAA,EAAO,SAAS,MAAM,CAAA;AAAA,IAClE,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,QAAQ,KAAA,EAA4B;AAC3C,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,gBAAA;AACH,MAAA,OAAO,mBAAA;AAAA,IACT,KAAK,gBAAA;AACH,MAAA,OAAO,gBAAA;AAAA,IACT,KAAK,aAAA;AACH,MAAA,OAAO,aAAA;AAAA;AAEb;AC9gBO,IAAM,qBAAN,MAAkD;AAAA,EAC9C,IAAA,GAAO,OAAA;AAAA,EAEC,IAAA;AAAA,EACA,SAAA;AAAA;AAAA,EAGT,KAAA,uBAAY,GAAA,EAAuB;AAAA,EACnC,QAAqB,EAAC;AAAA,EACtB,WAAA,GAAkC,IAAA;AAAA,EAClC,MAAA,GAAS,KAAA;AAAA,EAEjB,YAAY,IAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,OAAO,IAAI,iBAAA,CAAkB,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACvD,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA,IAAa,CAAA,EAAG,IAAA,CAAK,MAAM,UAAU,CAAA,kBAAA,CAAA;AAAA,EAC7D;AAAA;AAAA,EAIA,MAAM,QAAA,CAAS,KAAA,EAAoB,KAAA,EAAoB,QAAA,EAAiC;AACtF,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,OAAO,QAAQ,CAAA;AAC/C,IAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAE1B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA;AAChC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AACtC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,KAAA,EAAA;AACT,MAAA,QAAA,CAAS,KAAA,GAAQ,KAAA;AACjB,MAAA,QAAA,CAAS,OAAO,KAAA,CAAM,IAAA;AACtB,MAAA,QAAA,CAAS,OAAO,KAAA,CAAM,IAAA;AACtB,MAAA,QAAA,CAAS,WAAW,KAAA,CAAM,QAAA;AAAA,IAC5B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,CAAM,IAAI,MAAA,EAAQ;AAAA,QACrB,EAAA,EAAI,MAAA;AAAA,QACJ,KAAA;AAAA,QACA,WAAW,KAAA,CAAM,EAAA;AAAA,QACjB,KAAA,EAAO,CAAA;AAAA,QACP,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,UAAU,KAAA,CAAM;AAAA,OACjB,CAAA;AAGD,MAAA,KAAA,MAAW,GAAG,KAAK,CAAA,IAAK,KAAK,KAAA,EAAO;AAClC,QAAA,IAAI,KAAA,CAAM,OAAO,MAAA,EAAQ;AACzB,QAAA,MAAM,MAAM,WAAA,CAAY,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,MAAM,IAAI,CAAA;AAEpD,QAAA,MAAM,MAAA,GAAS,WAAW,KAAA,CAAM,IAAA,IAAQ,EAAC,EAAG,KAAA,CAAM,IAAA,IAAQ,EAAE,CAAA;AAC5D,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,SAAS,GAAG,CAAA;AACzC,QAAA,IAAI,SAAS,IAAA,EAAM;AACjB,UAAA,IAAA,CAAK,MAAM,IAAA,CAAK;AAAA,YACd,IAAA,EAAM,MAAA;AAAA,YACN,IAAI,KAAA,CAAM,EAAA;AAAA,YACV,QAAA,EAAU,GAAA,IAAO,MAAA,GAAS,SAAA,GAAY,WAAA;AAAA,YACtC,MAAA;AAAA,YACA,IAAI,KAAA,CAAM;AAAA,WACX,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC5B;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAoB,KAAA,EAAe,QAAA,EAAmC;AACjF,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,KAAK,MAAA,CAAO,KAAA,EAAO,OAAO,QAAQ,CAAA;AAC7D,IAAA,IAAI,UAAU,CAAA,EAAG;AACf,MAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAE1B,MAAA,MAAM,CAAA,GAAI,MAAM,WAAA,EAAY;AAC5B,MAAA,MAAM,WAAqB,EAAC;AAC5B,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,IAAI,CAAA,IAAK,KAAK,KAAA,EAAO;AACnC,QAAA,IAAI,KAAK,KAAA,CAAM,IAAA,CAAK,aAAY,CAAE,QAAA,CAAS,CAAC,CAAA,EAAG;AAC7C,UAAA,QAAA,CAAS,KAAK,EAAE,CAAA;AAAA,QAClB;AAAA,MACF;AACA,MAAA,KAAA,MAAW,EAAA,IAAM,QAAA,EAAU,IAAA,CAAK,KAAA,CAAM,OAAO,EAAE,CAAA;AAC/C,MAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,CAAC,MAAM,CAAC,QAAA,CAAS,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA,IAAK,CAAC,SAAS,QAAA,CAAS,CAAA,CAAE,EAAE,CAAC,CAAA;AAC5F,MAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,IAC5B;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,OAAA,CAAQ,KAAA,EAAoB,QAAA,EAAmC;AACnE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC1C;AAAA,EAEA,MAAM,IAAA,CAAK,KAAA,EAAoB,QAAA,EAAkB,KAAA,EAAwC;AACvF,IAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAE1B,IAAA,MAAM,cAAc,MAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,OAAO,QAAQ,CAAA;AACxD,IAAA,MAAM,UAAU,IAAI,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAG5C,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,CAAI,CAAC,EAAA,KAAO;AACvC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,EAAE,CAAA;AAC7B,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA;AAC/B,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,OAAO;AAAA,UACL,GAAG,EAAA;AAAA,UACH,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,EAAA,CAAG,IAAA;AAAA,UACtB,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,EAAA,CAAG,IAAA;AAAA,UACtB,QAAA,EAAU,IAAA,CAAK,QAAA,IAAY,EAAA,CAAG;AAAA,SAChC;AAAA,MACF;AACA,MAAA,OAAO,EAAA;AAAA,IACT,CAAC,CAAA;AAGD,IAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAC9D,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,IAAI,CAAA,IAAK,KAAK,KAAA,EAAO;AACnC,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACpB,QAAA,QAAA,CAAS,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,MAC1B;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC,CAAA;AAChD,IAAA,OAAO,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,QAAA;AAAA,EAC5C;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAoB,KAAA,EAAe,WAAmB,KAAA,EAAwC;AACzG,IAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA;AAI9C,IAAA,MAAM,SAAkD,EAAC;AACzD,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AAEtC,MAAA,IAAI,IAAA,CAAK,KAAA,CAAM,KAAA,KAAU,KAAA,EAAO;AAEhC,MAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA;AACvD,MAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,MAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,QAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG,KAAA,IAAS,CAAA;AAC/C,QAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,CAAE,QAAA,CAAS,CAAC,CAAC,GAAG,KAAA,IAAS,CAAA;AAAA,MAC1E;AACA,MAAA,IAAI,IAAA,CAAK,QAAA,KAAa,UAAA,EAAY,KAAA,IAAS,CAAA;AAAA,WAAA,IAClC,IAAA,CAAK,QAAA,KAAa,MAAA,EAAQ,KAAA,IAAS,CAAA;AAC5C,MAAA,KAAA,IAAS,KAAK,KAAA,GAAQ,GAAA;AACtB,MAAA,IAAI,KAAA,GAAQ,GAAG,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,CAAA;AAAA,IACzD;AAEA,IAAA,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACvC,IAAA,MAAM,UAAU,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AACzC,IAAA,OAAO,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,OAAA;AAAA,EAC3C;AAAA,EAEA,MAAM,KAAA,CAAM,KAAA,EAAoB,QAAA,EAAiC;AAC/D,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,IAAA,IAAA,CAAK,QAAQ,EAAC;AACd,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAEd,IAAA,IAAI;AAAE,MAAA,MAASE,GAAA,CAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAW;AAAA,EAC5D;AAAA,EAEA,MAAM,WAAA,CAAY,KAAA,EAAoB,QAAA,EAAmC;AACvE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAA,CAAY,KAAA,EAAoB,SAAA,EAAmB,SAAA,EAAmB,QAAQ,CAAA,EAA2B;AAC7G,IAAA,MAAM,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,IAAA,MAAM,QAAA,GAAW,KAAK,MAAA,CAAO,EAAE,OAAO,IAAA,EAAM,SAAA,EAAW,EAAA,EAAI,EAAA,EAAI,CAAA;AAC/D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAClB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,EAAA,KAAO,QAAQ,EACtD,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA,CAClC,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAEjB,IAAA,MAAM,SAAwB,EAAC;AAC/B,IAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,MAAA,MAAM,UAAU,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,IAAA,CAAK,KAAK,IAAA,CAAK,IAAA;AACxD,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AACnC,MAAA,IAAI,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA;AAAA,IAClC;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAuD;AACrD,IAAA,OAAO;AAAA,MACL,OAAO,CAAC,GAAG,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAAA,MAC9B,KAAA,EAAO,CAAC,GAAG,IAAA,CAAK,KAAK;AAAA,KACvB;AAAA,EACF;AAAA;AAAA,EAIQ,OAAO,KAAA,EAA4B;AAEzC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,WAAA,GAAc,IAAA,EAAK,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA;AAChE,IAAA,OAAO,GAAG,KAAA,CAAM,KAAA,IAAS,KAAK,CAAA,EAAA,EAAK,UAAA,CAAW,IAAI,CAAC,CAAA,CAAA;AAAA,EACrD;AAAA,EAEA,MAAc,UAAU,KAAA,EAAmC;AACzD,IAAA,IAAI,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,WAAA,KAAgB,KAAA,EAAO;AAC/C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AACpD,MAAA,MAAM,IAAA,GAAkE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACtF,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AAC/B,MAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAAA,IACpB,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,KAAA,uBAAY,GAAA,EAAI;AACrB,MAAA,IAAA,CAAK,QAAQ,EAAC;AAAA,IAChB;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AAAA,EAEA,MAAc,UAAU,KAAA,EAAmC;AACzD,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,OAAO,CAAC,GAAG,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAAA,QAC/B,OAAO,IAAA,CAAK;AAAA,OACd;AACA,MAAA,MAASA,GAAA,CAAA,KAAA;AAAA,QACP,IAAA,CAAK,UAAU,SAAA,CAAU,CAAA,EAAG,KAAK,SAAA,CAAU,WAAA,CAAY,GAAG,CAAC,CAAA;AAAA,QAC3D,EAAE,WAAW,IAAA;AAAK,OACpB;AAEA,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,IAAA,CAAA;AAC7B,MAAA,MAASA,GAAA,CAAA,SAAA,CAAU,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAA;AAC5C,MAAA,MAASA,GAAA,CAAA,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,SAAS,CAAA;AAAA,IACrC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAKA,SAAS,WAAA,CAAY,GAAW,CAAA,EAAmB;AACjD,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,CAAA,CAAE,aAAY,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAC,CAAA;AAC/E,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,CAAA,CAAE,aAAY,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAC,CAAA;AAC/E,EAAA,IAAI,OAAO,IAAA,KAAS,CAAA,IAAK,MAAA,CAAO,IAAA,KAAS,GAAG,OAAO,CAAA;AACnD,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,YAAA,EAAA;AAAA,EACrB;AACA,EAAA,OAAO,eAAe,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,OAAO,IAAI,CAAA;AACzD;AAGA,SAAS,UAAA,CAAW,GAAa,CAAA,EAAqB;AACpD,EAAA,IAAI,EAAE,MAAA,KAAW,CAAA,IAAK,CAAA,CAAE,MAAA,KAAW,GAAG,OAAO,CAAA;AAC7C,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,CAAC,CAAA;AACtB,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,KAAK,CAAA,EAAG,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,MAAA,EAAA;AACpC,EAAA,OAAO,SAAS,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,MAAA,EAAQ,EAAE,MAAM,CAAA;AAC7C;AAGA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,CAAA,GAAA,CAAM,KAAK,CAAA,IAAK,CAAA,GAAI,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA,GAAK,CAAA;AAAA,EACzC;AACA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,CAAE,SAAS,EAAE,CAAA;AAChC;;;AC1QA,SAAS,wBAAA,CACP,SAAA,EACA,UAAA,EACA,eAAA,EACQ;AACR,EAAA,MAAM,aAAA,GACJ,eAAA,CAAgB,MAAA,GAAS,CAAA,GACrB;;AAAA;AAAA,EAAiC,gBAC9B,GAAA,CAAI,CAAC,MAAM,CAAA,GAAA,EAAM,CAAA,CAAE,GAAG,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,CAAE,EAC/C,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACb,EAAA;AAEN,EAAA,OAAO,CAAA;;AAAA,iBAAA,EAEU,UAAU,CAAA;AAAA,EAC3B,UAAU,KAAA,CAAM,CAAA,EAAG,GAAI,CAAC,GAAG,aAAa;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAiD1C;AAIO,IAAM,4BAAN,MAA0D;AAAA,EAC/D,IAAA,GAAO,6BAAA;AAAA,EACP,KAAA,GAAQ,MAAA;AAAA,EAES,WAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA;AAAA,EACA,kBAAA;AAAA,EAEjB,YAAY,IAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AACxB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAK,aAAA,IAAiB,CAAA;AAC3C,IAAA,IAAA,CAAK,kBAAA,GAAqB,KAAK,kBAAA,IAAsB,EAAA;AAAA,EACvD;AAAA,EAEA,QAAA,GAAyB,OAAO,GAAA,EAAc,MAAA,KAAsB;AAElE,IAAA,IAAI,MAAA,CAAO,WAAW,MAAA,EAAQ;AAC9B,IAAA,IAAI,CAAC,OAAO,SAAA,IAAa,MAAA,CAAO,UAAU,IAAA,EAAK,CAAE,SAAS,EAAA,EAAI;AAC9D,IAAA,IAAI,MAAA,CAAO,UAAA,GAAa,IAAA,CAAK,aAAA,EAAe;AAE5C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,GAAA,CAAI,QAAA;AACtC,IAAA,IAAI,CAAC,UAAU,QAAA,EAAU;AAEzB,IAAA,IAAI;AAEF,MAAA,MAAM,kBAAkB,MAAM,IAAA,CAAK,YAAY,IAAA,CAAK,gBAAA,EAAkB,KAAK,kBAAkB,CAAA;AAC7F,MAAA,MAAM,MAAA,GAAS,wBAAA;AAAA,QACb,MAAA,CAAO,SAAA;AAAA,QACP,MAAA,CAAO,UAAA;AAAA,QACP;AAAA,OACF;AAGA,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,CAAQ,IAAM,CAAA;AACzC,MAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,QAAA;AAAA,QAC9B;AAAA,UACE,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,GAAA,CAAI,KAAA;AAAA,UACzB,QAAQ,CAAC,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AAAA,UACvC,QAAA,EAAU;AAAA,YACR,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,0DAAA;AAA2D,WACtF;AAAA,UACA,SAAA,EAAW;AAAA,SACb;AAAA,QACA,EAAE,MAAA;AAAO,OACX;AAEA,MAAA,MAAM,OAAO,QAAA,CAAS,OAAA,CACnB,OAAO,CAAC,CAAA,KAA2C,EAAE,IAAA,KAAS,MAAM,EACpE,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,EACjB,IAAA,CAAK,EAAE,EACP,IAAA,EAAK;AACR,MAAA,IAAI,CAAC,IAAA,EAAM;AAGX,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AAC1C,MAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,MAAA,MAAM,MAAA,GAAgC,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,CAAC,CAAC,CAAA;AAC7D,MAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,IAAK,MAAA,CAAO,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAGzE,MAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,MAAA,IAAI,MAAA,GAAS,CAAA;AACb,MAAA,IAAI,OAAA,GAAU,CAAA;AAEd,MAAA,KAAA,MAAW,EAAA,IAAM,OAAO,UAAA,EAAY;AAClC,QAAA,QAAQ,GAAG,MAAA;AAAQ,UACjB,KAAK,KAAA,EAAO;AACV,YAAA,IAAI,EAAA,CAAG,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,cAAA,MAAM,KAAK,WAAA,CAAY,QAAA,CAAS,GAAG,IAAA,CAAK,IAAA,IAAQ,KAAA,CAAA,EAAW;AAAA,gBACzD,MAAM,EAAA,CAAG,IAAA;AAAA,gBACT,MAAM,EAAA,CAAG,IAAA;AAAA,gBACT,UAAU,EAAA,CAAG;AAAA,eACd,CAAA;AACD,cAAA,KAAA,EAAA;AAAA,YACF;AACA,YAAA;AAAA,UACF;AAAA,UACA,KAAK,MAAA,EAAQ;AACX,YAAA,IAAI,EAAA,CAAG,KAAA,IAAS,EAAA,CAAG,IAAA,EAAM,MAAK,EAAG;AAC/B,cAAA,MAAM,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,EAAA,CAAG,KAAK,CAAA;AACtC,cAAA,MAAM,KAAK,WAAA,CAAY,QAAA,CAAS,GAAG,IAAA,CAAK,IAAA,IAAQ,KAAA,CAAA,EAAW;AAAA,gBACzD,MAAM,EAAA,CAAG,IAAA;AAAA,gBACT,MAAM,EAAA,CAAG,IAAA;AAAA,gBACT,UAAU,EAAA,CAAG;AAAA,eACd,CAAA;AACD,cAAA,MAAA,EAAA;AAAA,YACF;AACA,YAAA;AAAA,UACF;AAAA,UACA,KAAK,QAAA,EAAU;AACb,YAAA,IAAI,GAAG,KAAA,EAAO;AACZ,cAAA,MAAM,IAAI,MAAM,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,GAAG,KAAK,CAAA;AAChD,cAAA,OAAA,IAAW,CAAA;AAAA,YACb;AACA,YAAA;AAAA,UACF;AAAA;AACF,MACF;AAEA,MAAA,IAAI,KAAA,GAAQ,CAAA,IAAK,MAAA,GAAS,CAAA,IAAK,UAAU,CAAA,EAAG;AAC1C,QAAA,MAAM,QAAkB,EAAC;AACzB,QAAA,IAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,KAAK,CAAA,MAAA,CAAQ,CAAA;AACtC,QAAA,IAAI,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,MAAM,CAAA,OAAA,CAAS,CAAA;AACzC,QAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,OAAO,CAAA,QAAA,CAAU,CAAA;AAE5C,QAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,gCAAA,EAAmC,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,CAAI,CAAA;AAAA,MAC9E;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AACF;;;ACpNO,IAAM,WAAA,GAAc;AAAA,EAcL;AAAA,EAEpB,cAAA,EAAgB,gBAAA;AAAA,EAYE;AAAA,EAElB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,oBAAA,EAAsB,sBAAA;AAAA,EAOJ;AAAA,EAElB,cAAA,EAAgB,gBAAA;AAAA,EAGhB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,sBAAA,EAAwB,wBAAA;AAAA,EAKT;AAAA,EAEf,gBAAA,EAAkB,kBAAA;AAAA,EAClB,OAAA,EAAS;AACX,CAAA;AAwBO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAChC,IAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM,KAAK,OAAA,EAAS,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACzC,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAK,QAAA,IAAY,OAAA;AACjC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,WAAA,IAAe,KAAA;AACvC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,GAAmB;AACjB,IAAA,MAAM,GAAA,GAAM,KAAK,OAAA,GAAU,CAAA,CAAA,EAAI,cAAc,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA,GAAK,EAAA;AAC/D,IAAA,OAAO,GAAG,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,OAAO,GAAG,GAAG,CAAA,CAAA;AAAA,EAC5C;AACF,CAAA;AAEA,SAAS,cAAc,GAAA,EAAsC;AAC3D,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAC7B,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS,CAAA,CACjC,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AACtC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACrD;AAyCO,IAAM,WAAA,GAAN,cAA0B,eAAA,CAAgB;AAAA,EAC/C,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,KAAA;AAAA,MACb,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF,CAAA;AAkFO,IAAM,YAAA,GAAN,cAA2B,eAAA,CAAgB;AAAA,EACvC,SAAA;AAAA,EAET,YAAY,IAAA,EAMT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,SAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,uBAAuB,OAAA,GAAU,SAAA;AAAA,MACrE,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,iBAAA;AAAA,MACvC,SAAS,EAAE,SAAA,EAAW,KAAK,SAAA,EAAW,GAAG,KAAK,OAAA,EAAQ;AAAA,MACtD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AAAA,EACxB;AACF,CAAA;AAgCO,IAAM,OAAA,GAAN,cAAsB,eAAA,CAAgB;AAAA,EAClC,IAAA;AAAA,EAET,YAAY,IAAA,EAST;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,cAAA;AAAA,MACvC,SAAS,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,GAAG,KAAK,OAAA,EAAQ;AAAA,MAC5C,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,SAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAAA,EACnB;AACF,CAAA;;;ACpWA,SAAS,qBAAqB,GAAA,EAAuC;AACnE,EAAA,MAAM,MAAO,GAAA,CAAkE,UAAA;AAC/E,EAAA,IAAI,CAAC,GAAA,EAAK,IAAA,EAAM,OAAO,GAAA;AACvB,EAAA,MAAM,GAAA,GAAuB,EAAE,GAAG,GAAA,EAAI;AACtC,EAAA,KAAA,MAAW,SAAS,GAAA,EAAK;AACvB,IAAA,OAAQ,IAAgC,KAAK,CAAA;AAAA,EAC/C;AACA,EAAA,OAAQ,GAAA,CAAgC,UAAA;AACxC,EAAA,OAAO,GAAA;AACT;AAYO,IAAM,qBAAN,MAAgD;AAAA,EAC7C,OAAA;AAAA,EACA,QAAA,uBAAe,GAAA,EAA8D;AAAA,EAErF,YAAY,OAAA,EAAiB;AAC3B,IAAA,IAAA,CAAK,OAAA,GAAU,UAAA,CAAW,eAAA,CAAgB,OAAO,CAAC,CAAA;AAAA,EACpD;AAAA,EAEA,GAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,WAAmC,GAAA,EAA6B;AAC9D,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAG,CAAA;AAAA,EACzB;AAAA,EAEA,aAAa,UAAA,EAAuD;AAClE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,UAAA,GAAa,UAAU,CAAA;AAChD,IAAA,OAAO,MAAO,GAAA,GAA4C,YAAA;AAAA,EAC5D;AAAA,EAEA,OAAO,OAAA,EAA4C;AAGjD,IAAA,MAAM,QAAA,GAAW,qBAAqB,OAAO,CAAA;AAK7C,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,eAAA,CAAgB,EAAE,GAAG,KAAK,OAAA,EAAS,GAAG,QAAA,EAAU,CAAC,CAAA;AAEzE,IAAA,IAAI,IAAA,CAAK,YAAY,CAAA,EAAG;AACtB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,CAAA,+CAAA,EAAkD,MAAA,CAAO,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA;AAAA,QAC/E,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,SAAS,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,KAAK,OAAA;AAAQ,OACnD,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,OAAO,IAAA,CAAK,OAAA;AAClB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAIf,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,QAAA,EAAU;AAC7B,MAAA,IAAI;AACF,QAAA,CAAA,CAAE,MAAM,IAAI,CAAA;AAAA,MACd,SAAS,GAAA,EAAK;AAKZ,QAAA,OAAA,CAAQ,KAAA,CAAM,KAAK,SAAA,CAAU;AAAA,UAC3B,KAAA,EAAO,OAAA;AAAA,UACP,KAAA,EAAO,4BAAA;AAAA,UACP,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,UAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,SACnC,CAAC,CAAA;AAAA,MACJ;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,EAAA,EAA0E;AAC9E,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,EAAE,CAAA;AACpB,IAAA,OAAO,MAAM,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA;AAAA,EACtC;AACF;AAEA,IAAM,YAAA,GAAkD,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAExE,SAAS,WAAc,GAAA,EAAW;AAEhC,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,OAAO,GAAA,KAAQ,UAAU,OAAO,GAAA;AACpD,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,GAAA;AAEjC,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,GAAa,CAAA,EAAG;AAC5C,IAAA,MAAM,CAAA,GAAK,IAAgC,GAAG,CAAA;AAC9C,IAAA,IAAI,CAAA,KAAM,QAAQ,OAAO,CAAA,KAAM,YAAY,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,EAAG;AAC9D,MAAA,UAAA,CAAW,CAAC,CAAA;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;AChGA,IAAM,SAAA,GAAY,EAAA;AAWlB,IAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA;AAClB,cAAA,CAAe,MAAA,GAAS,CAAA,GAAI;AAgQrD,SAAS,oBAAA,CACd,GAAA,EACA,KAAA,EACA,IAAA,EACG;AACH,EAAA,MAAM,OAAa,CAAS,CAAC,GAAA,KAAgB,OAAA,CAAQ,KAAK,GAAG,CAAA,CAAA;AAI7D,EAAA,OAAO,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,CAAC,GAAG,GAAA,KAAQ;AAClC,IAAA,IAAI;AACF,MAAA,OAAO,KAAA,CAAM,QAAQ,CAAC,CAAA;AAAA,IACxB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA;AAAA,QACE,qCAAqC,GAAG,CAAA,GAAA,EAAM,eAAe,KAAA,GAAQ,GAAA,CAAI,UAAU,GAAG,CAAA;AAAA,OACxF;AACA,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AACH;AAUA,SAAS,IAAA,CAAQ,IAAA,EAAS,KAAA,EAAoB,SAAA,EAAkD;AAC9F,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AAChD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA,CAAK,IAAI,CAAC,IAAA,KAAS,KAAK,IAAA,EAAM,KAAA,EAAO,SAAS,CAAC,CAAA;AAAA,EACxD;AACA,EAAA,MAAM,GAAA,mBAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AACvD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,aAAA,CAAc,CAAC,CAAA,EAAG;AAC7C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AAAA,IACzB,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM;AAC9C,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,OAAO,SAAS,CAAA;AAAA,IACnC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AASA,IAAM,kBAAA,GACJ,+JAAA;AAIF,IAAM,uCAAuB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,YAAY,CAAC,CAAA;AAEzD,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,MAAM,EAAA,GAAK,KAAK,WAAA,EAAY;AAC5B,EAAA,IAAI,oBAAA,CAAqB,GAAA,CAAI,EAAE,CAAA,EAAG,OAAO,KAAA;AACzC,EAAA,OAAO,kBAAA,CAAmB,KAAK,EAAE,CAAA;AACnC;;;AC/TO,IAAM,8BAAA,GAAsD,UAAA;AAE5D,IAAM,oBAAA,GAAqD,OAAO,MAAA,CAAO;AAAA,EAC9E;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,qFAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,IAAA,EAAM,MAAM,GAAA,EAAI;AAAA,IAC/C,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,EAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,QAAA;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,qEAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,GAAA,EAAK,MAAM,IAAA,EAAK;AAAA,IAChD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,CAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,MAAA;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EAAa,4EAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAA,EAAK;AAAA,IACjD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,EAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,gFAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,GAAA,EAAK,MAAM,IAAA,EAAK;AAAA,IAChD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,CAAA;AAAA,IACX,cAAA,EAAgB,IAAA;AAAA,IAChB,UAAA,EAAY;AAAA;AAEhB,CAAC,CAAA;AAEM,SAAS,sBAAA,GAA8C;AAC5D,EAAA,OAAO,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,UAAA,EAAY,EAAE,GAAG,CAAA,CAAE,UAAA,IAAa,CAAE,CAAA;AACpF;AAQO,SAAS,sBAAsB,EAAA,EAAuC;AAC3E,EAAA,OAAO,qBAAqB,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACrD;;;ACpFO,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAChD,wBAAA,EAA0B,OAAA;AAAA,EAC1B,aAAA,EAAe,GAAA;AAAA,EACf,kBAAA,EAAoB,GAAA;AAAA,EACpB,gBAAA,EAAkB,IAAA;AAAA,EAClB,0BAAA,EAA4B,GAAA;AAAA,EAC5B,eAAA,EAAiB,IAAA;AAAA,EACjB,qBAAA,EAAuB;AACzB,CAAC,CAAA;AAGM,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAClD,SAAA,EAAW,EAAA;AAAA,EACX,cAAA,EAAgB;AAClB,CAAC,CAAA;AAGM,IAAM,uBAAA,GAA0B,OAAO,MAAA,CAAO;AAAA,EACnD,kBAAA,EAAoB;AACtB,CAAC,CAAA;AAaM,IAAM,8BAAA,GAAiC,OAAO,MAAA,CAAO;AAAA,EAC1D,UAAA,EAAY,UAAA;AAAA,EACZ,QAAA,EAAU;AAAA,IACR,YAAA,EAAc;AAAA,MACZ,UAAA,EAAY;AAAA;AACd;AAEJ,CAAC,CAAA;;;ACjBD,SAAS,mBAAmB,GAAA,EAAsB;AAChD,EAAA,IAAI,eAAe,KAAA,EAAO;AACxB,IAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,IAAA,OAAO,OAAO,CAAA,EAAG,IAAI,KAAK,GAAA,CAAI,OAAO,KAAK,GAAA,CAAI,OAAA;AAAA,EAChD;AAEA,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AASA,IAAM,iBAAA,GAAwD;AAAA,EAC5D,OAAA,EAAS,CAAA;AAAA,EACT,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,8BAAA;AAAA,IACN,aAAA,EAAe,GAAA;AAAA,IACf,aAAA,EAAe,IAAA;AAAA,IACf,aAAA,EAAe,GAAA;AAAA,IACf,WAAA,EAAa,IAAA;AAAA,IACb,WAAW,sBAAA,CAAuB,SAAA;AAAA,IAClC,gBAAgB,sBAAA,CAAuB;AAAA,GACzC;AAAA,EACA,KAAA,EAAO;AAAA,IACL,0BAA0B,oBAAA,CAAqB,wBAAA;AAAA,IAC/C,eAAe,oBAAA,CAAqB,aAAA;AAAA,IACpC,oBAAoB,oBAAA,CAAqB,kBAAA;AAAA,IACzC,kBAAkB,oBAAA,CAAqB,gBAAA;AAAA,IACvC,4BAA4B,oBAAA,CAAqB,0BAAA;AAAA,IACjD,iBAAiB,oBAAA,CAAqB,eAAA;AAAA,IACtC,uBAAuB,oBAAA,CAAqB;AAAA,GAC9C;AAAA,EACA,GAAA,EAAK,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,EACrB,QAAA,EAAU;AAAA,IACR,GAAA,EAAK,IAAA;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,MAAA,EAAQ,IAAA;AAAA,IACR,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiB,KAAA;AAAA,IACjB,uBAAA,EAAyB;AAAA,GAC3B;AAAA,EACA,YAAY,EAAC;AAAA,EACb,QAAA,EAAU;AAAA,IACR,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAA,EAAQ,IAAA;AAAA,IACR,aAAA,EAAe,IAAA;AAAA,IACf,UAAA,EAAY;AAAA,GACd;AAAA,EACA,OAAA,EAAS,EAAE,GAAG,8BAAA,EAA+B;AAAA,EAC7C,QAAA,EAAU,EAAE,kBAAA,EAAoB,uBAAA,CAAwB,kBAAA;AAC1D,CAAA;AAGA,SAAS,QAAQ,CAAA,EAAoB;AACnC,EAAA,OAAO,CAAC,qBAAA,CAAsB,IAAA,CAAK,CAAA,CAAE,MAAM,CAAA;AAC7C;AAEA,SAAS,gBAAgB,CAAA,EAAgC;AACvD,EAAA,OAAO,CAAA,KAAM,MAAA,IAAa,OAAA,CAAQ,CAAC,CAAA;AACrC;AAEA,IAAM,UAAA,uBAAiB,GAAA,CAA4B,CAAC,SAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAC,CAAA;AAE9F,SAAS,YAAY,CAAA,EAAmC;AACtD,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAA2B,CAAA,GAAK,CAAA,GAA+B,MAAA;AACvF;AAEA,IAAM,OAAA,GAAqE;AAAA,EACzE,mBAAA,EAAqB,CAAC,CAAA,EAAG,CAAA,KAAM;AAC7B,IAAA,CAAA,CAAE,QAAA,GAAW,CAAA;AACb,IAAA,IAAI,EAAE,UAAA,KAAe,MAAA,EAAW,CAAA,CAAE,UAAA,uBAAiB,GAAA,EAAI;AACvD,IAAA,CAAA,CAAE,UAAA,CAAW,IAAI,UAAU,CAAA;AAAA,EAC7B,CAAA;AAAA,EACA,gBAAA,EAAkB,CAAC,CAAA,EAAG,CAAA,KAAM;AAC1B,IAAA,CAAA,CAAE,KAAA,GAAQ,CAAA;AACV,IAAA,IAAI,EAAE,UAAA,KAAe,MAAA,EAAW,CAAA,CAAE,UAAA,uBAAiB,GAAA,EAAI;AACvD,IAAA,CAAA,CAAE,UAAA,CAAW,IAAI,OAAO,CAAA;AAAA,EAC1B,CAAA;AAAA,EACA,kBAAA,EAAoB,CAAC,CAAA,EAAG,CAAA,KAAM;AAC5B,IAAA,CAAA,CAAE,MAAA,GAAS,CAAA;AACX,IAAA,IAAI,EAAE,UAAA,KAAe,MAAA,EAAW,CAAA,CAAE,UAAA,uBAAiB,GAAA,EAAI;AACvD,IAAA,CAAA,CAAE,UAAA,CAAW,IAAI,QAAQ,CAAA;AAAA,EAC3B,CAAA;AAAA,EACA,mBAAA,EAAqB,CAAC,CAAA,EAAG,CAAA,KAAM;AAC7B,IAAA,CAAA,CAAE,OAAA,GAAU,CAAA;AACZ,IAAA,IAAI,EAAE,UAAA,KAAe,MAAA,EAAW,CAAA,CAAE,UAAA,uBAAiB,GAAA,EAAI;AACvD,IAAA,CAAA,CAAE,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,EAC5B,CAAA;AAAA,EACA,oBAAA,EAAsB,CAAC,CAAA,EAAG,CAAA,KAAM;AAE9B,IAAA,IAAI,CAAC,CAAA,CAAE,GAAA,IAAO,GAAA,GAAM,EAAE,OAAO,MAAA,EAAO;AACpC,IAAA,CAAA,CAAE,GAAA,CAAI,KAAA,GAAQ,WAAA,CAAY,CAAC,CAAA;AAAA,EAC7B,CAAA;AAAA,EACA,yBAAA,EAA2B,CAAC,CAAA,EAAG,CAAA,KAAM;AACnC,IAAA,CAAA,CAAE,QAAA,GAAW,EAAE,GAAG,eAAA,EAAiB,GAAG,EAAE,QAAA,EAAU,cAAA,EAAgB,OAAA,CAAQ,CAAC,CAAA,EAAE;AAAA,EAC/E,CAAA;AAAA,EACA,wBAAA,EAA0B,CAAC,CAAA,EAAG,CAAA,KAAM;AAClC,IAAA,CAAA,CAAE,QAAA,GAAW,EAAE,GAAG,eAAA,EAAiB,GAAG,EAAE,QAAA,EAAU,MAAA,EAAQ,OAAA,CAAQ,CAAC,CAAA,EAAE;AAAA,EACvE,CAAA;AAAA,EACA,sBAAA,EAAwB,CAAC,CAAA,EAAG,CAAA,KAAM;AAChC,IAAA,CAAA,CAAE,QAAA,GAAW,EAAE,GAAG,eAAA,EAAiB,GAAG,EAAE,QAAA,EAAU,aAAA,EAAe,OAAA,CAAQ,CAAC,CAAA,EAAE;AAAA,EAC9E;AACF,CAAA;AAEA,IAAM,eAAA,GAAkB;AAAA,EACtB,cAAA,EAAgB,IAAA;AAAA,EAChB,MAAA,EAAQ,IAAA;AAAA,EACR,aAAA,EAAe,IAAA;AAAA,EACf,UAAA,EAAY;AACd,CAAA;AAgBA,SAASC,UAAAA,CAAa,MAAS,KAAA,EAAsB;AACnD,EAAA,MAAM,IAAA,GAAyB,EAAE,SAAA,EAAW,mBAAA,EAAoB;AAChE,EAAA,IAAI,eAAA,CAAgB,OAAA,CAAQ,GAAA,CAAI,uBAAuB,CAAA,EAAG;AACxD,IAAA,IAAA,CAAK,0BAAA,GAA6B,CAAC,GAAA,EAAK,WAAA,EAAa,QAAA,KAAa;AAChE,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,kCAAA,EAAqC,GAAG,CAAA,0DAAA,EACnB,WAAW,oBAAoB,QAAQ,CAAA,CAAA;AAAA,OAC9D;AAAA,IACF,CAAA;AAAA,EACF;AACA,EAAA,OAAO,SAAA,CAAc,IAAA,EAAiC,KAAA,EAAkC,IAAI,CAAA;AAC9F;AA6BO,IAAM,sBAAN,MAAkD;AAAA,EACtC,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,YAAY,IAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,IAAU,KAAA;AAC7B,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,OAAA,IAAW,EAAC;AACrC,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA,EAEA,MAAM,IAAA,CACJ,IAAA,GAA6E,EAAC,EAC7D;AACjB,IAAA,IAAI,GAAA,GAAqB,EAAE,GAAG,iBAAA,EAAkB;AAKhD,IAAA,MAAM,CAAC,MAAA,EAAQ,KAAA,EAAO,SAAS,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,MACnD,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA;AAAA,MACrC,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA;AAAA,MAC3C,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,eAAe;AAAA,KACzC,CAAA;AACD,IAAA,GAAA,GAAMA,UAAAA,CAAU,KAAK,MAAM,CAAA;AAC3B,IAAA,GAAA,GAAMA,UAAAA,CAAU,KAAK,KAAK,CAAA;AAC1B,IAAA,GAAA,GAAMA,UAAAA,CAAU,KAAK,SAAS,CAAA;AAG9B,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,EAAE,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC/C,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACzB,MAAA,IAAI,CAAA,EAAG,EAAA,CAAG,GAAA,EAAK,CAAC,CAAA;AAAA,IAClB;AAIA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAG,IAAA,CAAK,YAAY,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACnD,MAAA,MAAM,EAAA,GAAA,CAAM,CAAA,CAAE,QAAA,IAAY,EAAA,KAAO,EAAE,QAAA,IAAY,EAAA,CAAA;AAC/C,MAAA,IAAI,EAAA,KAAO,GAAG,OAAO,EAAA;AACrB,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,KAAA,MAAW,OAAO,MAAA,EAAQ;AACxB,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,QAAA,IAAI,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1C,UAAA,GAAA,GAAMA,UAAAA,CAAU,KAAK,KAAK,CAAA;AAAA,QAC5B;AAAA,MACF,SAAS,GAAA,EAAK;AAEZ,QAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,UAC1B,KAAA,EAAO,MAAA;AAAA,UACP,KAAA,EAAO,2BAAA;AAAA,UACP,QAAQ,GAAA,CAAI,IAAA;AAAA,UACZ,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,UAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,SACnC,CAAC,CAAA;AAAA,MACJ;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,GAAA,GAAMA,UAAAA,CAAU,GAAA,EAAK,IAAA,CAAK,QAAQ,CAAA;AAAA,IACpC;AAGA,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,GAAA,GAAM,oBAAA,CAAqB,GAAA,EAAK,IAAA,CAAK,KAAK,CAAA;AAAA,IAC5C;AAQA,IAAA,IAAI,IAAI,SAAA,EAAW;AACjB,MAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA,EAAG;AAC/C,QAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACvC,QAAA,MAAM,UAAW,IAAA,CAA2C,OAAA;AAC5D,QAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,IAAK,OAAA,CAAQ,WAAW,CAAA,EAAG;AAKrD,QAAA,MAAM,OAAO,OAAA,CAAQ,MAAA;AAAA,UACnB,CAAC,CAAA,KACC,CAAC,CAAC,KACF,OAAO,CAAA,KAAM,QAAA,IACb,OAAQ,CAAA,CAAsC,KAAA,KAAU,QAAA,IACxD,OAAQ,EAAuC,MAAA,KAAW;AAAA,SAC9D;AACA,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,QAAA,MAAM,WAAY,IAAA,CAAyC,MAAA;AAC3D,QAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACrC,QAAA,MAAM,cAAe,IAAA,CAA4C,SAAA;AACjE,QAAA,MAAM,MAAA,GAAS,WAAA,GACV,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,WAAW,CAAA,IAAK,IAAA,CAAK,CAAC,CAAA,GACpD,KAAK,CAAC,CAAA;AACV,QAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,UAAC,IAAA,CAAyC,SAAS,MAAA,CAAO,MAAA;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,iBAAiB,GAAG,CAAA;AACzB,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAA,CAAK,iBAAiB,GAAG,CAAA;AAAA,IAC3B;AAKA,IAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB,GAAA,EAAgC;AACtD,IAAA,IAAI,OAAA,GAAU,EAAE,GAAG,GAAA,EAAI;AACvB,IAAA,IAAI,IAAA,CAAK,SAAS,OAAA,CAAQ,WAAA,IAAe,CAAC,OAAA,CAAQ,WAAA,CAAY,UAAA,CAAW,MAAM,CAAA,EAAG;AAGhF,MAAA,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,KAAK,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,WAAW,CAAA,EAAE;AAAA,IAC/E;AACA,IAAA,MAAM,EAAA,GAAK,KAAK,KAAA,CAAM,UAAA;AACtB,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,EAAA,EAAI,IAAA,CAAK,SAAA,CAAU,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AACvE,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,cAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,cAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,mBAAmB,GAAG,CAAA;AAAA,QAC7B,WAAA,EAAa,KAAA;AAAA,QACb,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAA,GAA6C;AACjD,IAAA,MAAM,EAAA,GAAK,KAAK,KAAA,CAAM,UAAA;AACtB,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASC,GAAA,CAAA,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AACxC,MAAA,MAAM,MAAA,GAAS,UAAsB,GAAG,CAAA;AACxC,MAAA,IAAI,CAAC,MAAA,CAAO,EAAA,IAAM,CAAC,OAAO,KAAA,EAAO;AAC/B,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA,EAAU,EAAA;AAAA,UACV,SAAA,EAAW,WAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,UACzB,KAAA,EAAO,2BAAA;AAAA,UACP,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,SAC/D,CAAA;AACD,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,KAAK,KAAA,EAAO;AACd,QAAA,MAAM,SAAA,GAAY,qBAAqB,EAAE,IAAA,EAAM,OAAO,KAAA,EAAM,EAAoB,KAAK,KAAK,CAAA;AAC1F,QAAA,MAAM,MAAA,GAAU,UAAmC,IAAA,IAAQ,IAAA;AAC3D,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA,EAAU,EAAA;AAAA,UACV,SAAA,EAAW,WAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,UACzB,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,SAC/D,CAAA;AACD,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,WAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,MAAA,CAAO,KAAA;AAAA,IAChB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAE7D,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,WAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,mBAAmB,GAAG,CAAA;AAAA,QAC7B,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,yBAAA;AAAA,QACP,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,QAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AACF,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,SAAS,IAAA,EAAsC;AAC3D,IAAA,IAAI,GAAA;AACJ,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IACtC,SAAS,GAAA,EAAK;AAIZ,MAAA,IAAK,GAAA,CAA8B,SAAS,QAAA,EAAU;AACpD,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,UAAA;AAAA,UACX,KAAA,EAAO,QAAA;AAAA,UACP,QAAA,EAAU,IAAA;AAAA,UACV,SAAA,EAAW,WAAA;AAAA,UACX,OAAA,EAAS,SAAA;AAAA,UACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,UACzB,KAAA,EAAO,mBAAmB,GAAG,CAAA;AAAA,UAC7B,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,SAC/D,CAAA;AACD,QAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,UAC1B,KAAA,EAAO,MAAA;AAAA,UACP,KAAA,EAAO,oBAAA;AAAA,UACP,IAAA,EAAM,IAAA;AAAA,UACN,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,UAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,SACnC,CAAC,CAAA;AAAA,MACJ;AACA,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,MAAM,MAAA,GAAS,UAAyB,GAAG,CAAA;AAC3C,IAAA,IAAI,CAAC,MAAA,CAAO,EAAA,IAAM,CAAC,OAAO,KAAA,EAAO;AAI/B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,IAAA;AAAA,QACV,SAAA,EAAW,WAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,2BAAA;AAAA,QACP,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,qBAAA;AAAA,QACP,IAAA,EAAM,IAAA;AAAA,QACN,OAAA,EAAS,6DAAA;AAAA,QACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AACF,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,OAAO,MAAA,CAAO,KAAA;AAAA,EAChB;AAAA,EAEQ,iBAAiB,GAAA,EAA0B;AAEjD,IAAA,IAAI,GAAA,CAAI,OAAA,KAAY,MAAA,EAAW,MAAM,IAAI,WAAA,CAAY;AAAA,MACnD,OAAA,EAAS,+BAAA;AAAA,MACT,MAAM,WAAA,CAAY,cAAA;AAAA,MAClB,OAAA,EAAS,EAAE,KAAA,EAAO,SAAA;AAAU,KAC7B,CAAA;AAED,IAAA,IAAI,GAAA,CAAI,OAAA,KAAY,CAAA,EAAG,MAAM,IAAI,WAAA,CAAY;AAAA,MAC3C,OAAA,EAAS,CAAA,4BAAA,EAA+B,GAAA,CAAI,OAAO,CAAA,CAAA;AAAA,MACnD,MAAM,WAAA,CAAY,cAAA;AAAA,MAClB,SAAS,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,IAAI,OAAA;AAAQ,KAClD,CAAA;AACD,IAAA,MAAM,IAAI,GAAA,CAAI,OAAA;AACd,IAAA,IAAI,CAAC,CAAA,EAAG,MAAM,IAAI,WAAA,CAAY;AAAA,MAC5B,OAAA,EAAS,iCAAA;AAAA,MACT,MAAM,WAAA,CAAY,cAAA;AAAA,MAClB,OAAA,EAAS,EAAE,KAAA,EAAO,SAAA;AAAU,KAC7B,CAAA;AAMD,IAAA,MAAM,MAAA,GAAgC,CAAC,eAAA,EAAiB,eAAA,EAAiB,eAAe,CAAA;AACxF,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,MAAM,CAAA,GAAI,EAAE,CAAC,CAAA;AACb,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,EAAG;AAChD,QAAA,MAAM,IAAI,WAAA,CAAY;AAAA,UACpB,SAAS,CAAA,gBAAA,EAAmB,MAAA,CAAO,CAAC,CAAC,CAAA,8BAAA,EAAiC,OAAO,CAAC,CAAA,CAAA,CAAA;AAAA,UAC9E,MAAM,WAAA,CAAY,cAAA;AAAA,UAClB,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,QAAA,EAAW,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA,EAAI,UAAA,EAAY,OAAO,CAAA;AAAE,SAChE,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,IAAI,EAAE,aAAA,IAAiB,CAAA,CAAE,iBAAiB,CAAA,CAAE,aAAA,IAAiB,EAAE,aAAA,EAAe;AAC5E,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,4DAAA;AAAA,QACT,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,OAAA,EAAS,EAAE,IAAA,EAAM,CAAA,CAAE,aAAA,EAAe,MAAM,CAAA,CAAE,aAAA,EAAe,IAAA,EAAM,CAAA,CAAE,aAAA;AAAc,OAChF,CAAA;AAAA,IACH;AACA,IAAA,IAAI,EAAE,IAAA,KAAS,MAAA,IAAa,CAAC,qBAAA,CAAsB,CAAA,CAAE,IAAI,CAAA,EAAG;AAI1D,MAAA,MAAM,KAAA,GAAQ,sBAAA,EAAuB,CAClC,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,EAAE,CAAA,CACf,IAAA,CAAK,IAAI,CAAA;AACZ,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,2CAA2C,CAAA,CAAE,IAAI,CAAA,oBAAA,EAAuB,KAAK,uBACvD,8BAA8B,CAAA,EAAA;AAAA,OACtD;AACA,MAAA,CAAA,CAAE,IAAA,GAAO,8BAAA;AAAA,IACX;AAAA,EACF;AAAA,EAEQ,iBAAiB,GAAA,EAA0B;AACjD,IAAA,IAAI,CAAC,IAAI,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,+EAAA;AAAA,QACT,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,OAAA,EAAS,EAAE,KAAA,EAAO,UAAA;AAAW,OAC9B,CAAA;AAAA,IACH;AACA,IAAA,IAAI,CAAC,IAAI,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,WAAA,CAAY;AAAA,QACpB,OAAA,EAAS,yEAAA;AAAA,QACT,MAAM,WAAA,CAAY,cAAA;AAAA,QAClB,OAAA,EAAS,EAAE,KAAA,EAAO,OAAA;AAAQ,OAC3B,CAAA;AAAA,IACH;AAAA,EACF;AACF;;;ACtgBO,IAAM,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EACrC,WAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AACxB,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,aAAA;AAC1B,IAAA,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA;AAAA,EAC1B;AACF;AAkBO,SAAS,mBAAA,CACd,KAAA,EACA,aAAA,EACA,UAAA,EACiB;AACjB,EAAA,MAAM,OAAA,GAAU,OAAO,KAAA,CAAM,SAAS,MAAM,QAAA,GAAY,KAAA,CAAM,SAAS,CAAA,GAAe,CAAA;AACtF,EAAA,IAAI,OAAA,GAAmC,EAAE,GAAG,KAAA,EAAM;AAClD,EAAA,IAAI,cAAA,GAAiB,OAAA;AACrB,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,IAAI,aAAA,GAAgB,KAAA;AAEpB,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,OAAO,mBAAmB,aAAA,EAAe;AACvC,IAAA,IAAI,EAAE,QAAQ,GAAA,EAAK;AACjB,MAAA,MAAM,IAAI,oBAAA,CAAqB;AAAA,QAC7B,OAAA,EAAS,CAAA,8CAAA,EAAiD,OAAO,CAAA,SAAA,EAAY,aAAa,CAAA,CAAA,CAAA;AAAA,QAC1F,WAAA,EAAa,OAAA;AAAA,QACb,aAAA;AAAA,QACA,WAAA,EAAa;AAAA,OACd,CAAA;AAAA,IACH;AACA,IAAA,MAAM,OAAO,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,cAAc,CAAA;AAC7D,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,oBAAA,CAAqB;AAAA,QAC7B,OAAA,EAAS,CAAA,qCAAA,EAAwC,cAAc,CAAA,UAAA,EAAa,aAAa,CAAA,kDAAA,CAAA;AAAA,QACzF,WAAA,EAAa,OAAA;AAAA,QACb,aAAA;AAAA,QACA,WAAA,EAAa;AAAA,OACd,CAAA;AAAA,IACH;AACA,IAAA,MAAM,GAAA,GAAwB,EAAE,WAAA,EAAa,cAAA,EAAgB,eAAe,KAAA,EAAM;AAClF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA;AAGtC,IAAA,IAAI,OAAO,KAAK,SAAS,CAAA,KAAM,YAAY,IAAA,CAAK,SAAS,CAAA,KAAM,IAAA,CAAK,EAAA,EAAI;AACtE,MAAA,IAAA,CAAK,SAAS,IAAI,IAAA,CAAK,EAAA;AAAA,IACzB;AACA,IAAA,OAAA,GAAU,IAAA;AACV,IAAA,cAAA,GAAiB,IAAA,CAAK,EAAA;AACtB,IAAA,OAAA,CAAQ,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA,OAAA,EAAK,IAAA,CAAK,EAAE,CAAA,CAAE,CAAA;AACxC,IAAA,aAAA,GAAgB,aAAA,IAAiB,GAAA,CAAI,aAAA,IAAiB,IAAA,CAAK,OAAO,IAAA,CAAK,EAAA;AAAA,EACzE;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,aAAA,EAAc;AACnD;AAiBO,IAAM,4BAAwD;ACtFrE,IAAM,SAAA,GAAY,aAAA;AAClB,IAAM,kBAAA,GAAqB,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAA;AAEnC,IAAM,eAAN,MAAmB;AAAA,EACP,IAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EAEjB,YAAY,IAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,IAAA,GAAYC,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,SAAS,CAAA;AACzC,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA;AAC/B,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,QAAA,IAAeC,EAAA,CAAA,QAAA,EAAS;AAC7C,IAAA,IAAA,CAAK,QAAA,GAAW,KAAK,QAAA,IAAY,kBAAA;AACjC,IAAA,IAAA,CAAK,eAAe,IAAA,CAAK,YAAA;AACzB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,UAAA,IAAc,iBAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,cAAA,GAAmD;AACvD,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,EAAS;AACjC,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI,GAAI,IAAI,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA,CAAE,OAAA,EAAQ;AAC5D,IAAA,IAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,IAAK,QAAQ,CAAA,EAAG;AAEpC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,QAAA,EAAU,OAAO,IAAA;AAOlC,IAAA,IAAI,IAAA,CAAK,aAAa,IAAA,CAAK,QAAA,IAAY,KAAK,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,EAAG;AAE3D,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,YAAA,GAAe,CAAA;AACnB,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAI;AACF,QAAA,MAAM,OAAO,MAAM,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,KAAK,SAAS,CAAA;AAKxD,QAAA,MAAM,OAAA,GAAU,KAAK,MAAA,CAAO,aAAA,CAAc,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,aAAa,CAAA;AACzE,QAAA,MAAM,MAAA,GACJ,WAAW,CAAA,IACX,CAAC,KAAK,MAAA,CACH,KAAA,CAAM,OAAA,GAAU,CAAC,CAAA,CACjB,IAAA;AAAA,UACC,CAAC,MACC,CAAA,CAAE,IAAA,KAAS,gBACX,CAAA,CAAE,IAAA,KAAS,cAAA,IACX,CAAA,CAAE,IAAA,KAAS;AAAA,SACf;AACJ,QAAA,IAAI,QAAQ,OAAO,IAAA;AACnB,QAAA,YAAA,GAAe,KAAK,QAAA,CAAS,MAAA;AAAA,MAC/B,CAAA,CAAA,MAAQ;AAGN,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,KAAK,IAAA,CAAK,GAAA;AAAA,MACV,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,KAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,MAAM,SAAA,EAAkC;AAC5C,IAAA,MAAM,SAAA,CAAeD,KAAA,CAAA,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AACvC,IAAA,MAAM,IAAA,GAAiB;AAAA,MACrB,CAAA,EAAG,CAAA;AAAA,MACH,SAAA;AAAA,MACA,KAAK,IAAA,CAAK,GAAA;AAAA,MACV,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACpC;AAMA,IAAA,IAAI;AACF,MAAA,MAAUE,GAAA,CAAA,SAAA,CAAU,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,GAAA,EAAO,CAAA;AAAA,IAClF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,MAAM,IAAI,MAAM,CAAA,6CAAA,CAA+C,CAAA;AAAA,MACjE;AAEA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI;AACF,MAAA,MAAUA,GAAA,CAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,IAC5B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,SAAS,QAAA,EAAU;AAEvB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,QAAA,GAAqC;AACjD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAUA,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,IAC5C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,IAAA;AAC9B,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAI,CAAC,UAAA,CAAW,MAAM,CAAA,EAAG,OAAO,IAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,WAAW,CAAA,EAA2B;AAC7C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,MAAM,OAAO,KAAA;AAChD,EAAA,MAAM,CAAA,GAAI,CAAA;AACV,EAAA,OACE,CAAA,CAAE,GAAG,CAAA,KAAM,CAAA,IACX,OAAO,CAAA,CAAE,WAAW,CAAA,KAAM,QAAA,IAC1B,OAAO,CAAA,CAAE,KAAK,CAAA,KAAM,QAAA,IACpB,OAAO,CAAA,CAAE,UAAU,MAAM,QAAA,IACzB,OAAO,CAAA,CAAE,WAAW,CAAA,KAAM,QAAA;AAE9B;AAWA,SAAS,kBAAkB,GAAA,EAAsB;AAC/C,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA,IAAK,GAAA,IAAO,GAAG,OAAO,KAAA;AAC/C,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAC,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAE5C,IAAA,IAAI,IAAA,KAAS,SAAS,OAAO,IAAA;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;AChOO,IAAM,uBAAN,MAAoD;AAAA,EACxC,KAAA;AAAA,EAEjB,YAAY,IAAA,EAAmC;AAC7C,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAAA,EACpB;AAAA,EAEA,MAAM,KAAA,CAAM,CAAA,GAAkB,EAAC,EAAkC;AAG/D,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,GAAG,IAAI,GAAI,CAAA;AACzE,IAAA,MAAM,WAAA,GAAc,CAAA,CAAE,aAAA,EAAe,WAAA,EAAY;AACjD,IAAA,MAAM,QAAA,GAAW,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM;AACjC,MAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,OAAO,OAAO,KAAA;AAC7C,MAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,OAAO,OAAO,KAAA;AAC7C,MAAA,IAAI,EAAE,QAAA,IAAY,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,UAAU,OAAO,KAAA;AACpD,MAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,OAAO,OAAO,KAAA;AAC3C,MAAA,IAAI,EAAE,SAAA,KAAc,MAAA,IAAa,EAAE,UAAA,GAAa,CAAA,CAAE,WAAW,OAAO,KAAA;AACpE,MAAA,IAAI,WAAA,IAAe,CAAC,CAAA,CAAE,KAAA,CAAM,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,EAAG,OAAO,KAAA;AACxE,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AACD,IAAA,MAAM,GAAA,GAA4B,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACrD,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,WAAW,CAAA,CAAE,SAAA;AAAA,MACb,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,YAAY,CAAA,CAAE;AAAA,KAChB,CAAE,CAAA;AACF,IAAA,OAAO,EAAE,KAAA,GAAQ,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,GAAI,GAAA;AAAA,EAC3C;AAAA,EAEA,OAAO,OAAO,SAAA,EAAgD;AAC5D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AAC5C,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AAAA,EACrC;AAAA,EAEA,MAAM,MAAA,CAAO,CAAA,EAAuB,SAAA,EAAgC,YAAA,EAA0D;AAC5H,IAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,GAAA;AACzB,IAAA,MAAM,OAAA,GAAU,aAAa,CAAC,CAAA;AAC9B,IAAA,MAAM,eAAe,CAAA,CAAE,KAAA,GAAQ,IAAI,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,GAAI,IAAA;AAIlD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,GAAA,GAAM,CAAC,SAAS,CAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,GAAI,CAAA;AAC3C,MAAA,MAAM,WAAA,GAAc,YAAA,EAAc,aAAA,EAAe,WAAA,EAAY;AAC7D,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAAM;AACtC,QAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,YAAA,CAAa,OAAO,OAAO,KAAA;AACpE,QAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,YAAA,CAAa,OAAO,OAAO,KAAA;AACpE,QAAA,IAAI,cAAc,QAAA,IAAY,CAAA,CAAE,QAAA,KAAa,YAAA,CAAa,UAAU,OAAO,KAAA;AAC3E,QAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,KAAA,KAAU,YAAA,CAAa,OAAO,OAAO,KAAA;AAClE,QAAA,IAAI,cAAc,SAAA,KAAc,MAAA,IAAa,EAAE,UAAA,GAAa,YAAA,CAAa,WAAW,OAAO,KAAA;AAC3F,QAAA,IAAI,WAAA,IAAe,CAAC,CAAA,CAAE,KAAA,CAAM,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,EAAG,OAAO,KAAA;AACxE,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AACD,MAAA,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,OAA2B,EAAC;AAClC,IAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AACA,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAC3C,QAAA,MAAM,EAAA,GAAK,aAAA,CAAc,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AACvC,QAAA,IAAI,gBAAgB,CAAC,YAAA,CAAa,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,EAAG;AAChD,QAAA,MAAM,IAAA,GAAO,UAAU,EAAE,CAAA;AACzB,QAAA,IAAI,SAAS,IAAA,EAAM;AACnB,QAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AACxB,QAAA,IAAI,CAAC,GAAA,EAAK;AACV,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,SAAA,EAAW,EAAA;AAAA,UACX,UAAA,EAAY,CAAA;AAAA,UACZ,IAAI,EAAA,CAAG,EAAA;AAAA,UACP,MAAM,EAAA,CAAG,IAAA;AAAA,UACT,SAAS,SAAA,CAAU,IAAA,EAAM,GAAA,CAAI,KAAA,EAAO,IAAI,GAAG;AAAA,SAC5C,CAAA;AACD,QAAA,IAAI,IAAA,CAAK,MAAA,IAAU,KAAA,EAAO,OAAO,IAAA;AAAA,MACnC;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,MAAA,CAAO,SAAA,EAAmB,IAAA,EAA6C;AAC3E,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AAC5C,IAAA,MAAM,YAAA,GAAe,KAAK,YAAA,IAAgB,IAAA;AAC1C,IAAA,MAAM,kBAAA,GAAqB,KAAK,kBAAA,IAAsB,IAAA;AAEtD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM;AACzC,MAAA,IACE,CAAC,YAAA,KACA,CAAA,CAAE,IAAA,KAAS,UAAA,IACV,CAAA,CAAE,IAAA,KAAS,aAAA,IACX,CAAA,CAAE,IAAA,KAAS,iBAAA,IACX,CAAA,CAAE,SAAS,eAAA,CAAA,EACb;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IACE,CAAC,kBAAA,KACA,CAAA,CAAE,IAAA,KAAS,OAAA,IAAW,EAAE,IAAA,KAAS,YAAA,IAAgB,CAAA,CAAE,IAAA,KAAS,mBAAA,CAAA,EAC7D;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,EAAE,QAAA,EAAU,IAAA,CAAK,UAAU,MAAA,EAAQ,QAAA,EAAS,EAAG,IAAA,EAAM,CAAC,CAAA;AAAA,IAC9E;AACA,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,MAAA,OAAO,eAAA,CAAgB,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AAAA,IAChD;AACA,IAAA,OAAO,cAAA,CAAe,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC/C;AAAA,EAEA,MAAM,SAAS,SAAA,EAA6C;AAC1D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AAC5C,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AACF;AAEA,SAAS,aACP,CAAA,EACyD;AACzD,EAAA,MAAM,EAAA,GAAK,EAAE,eAAA,IAAmB,IAAA;AAChC,EAAA,IAAI,EAAE,KAAA,EAAO;AACX,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,GAAM,EAAA;AACzB,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,CAAA,CAAE,KAAA,EAAO,KAAK,CAAA;AAChD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyB,CAAA,CAAE,KAAK,CAAA,GAAA,EAAM,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IACzE;AACA,IAAA,MAAM,KAAK,QAAA,CAAS,KAAA;AACpB,IAAA,OAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,MAAA,OAAO,CAAA,GAAI,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,GAAA,EAAK,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAO,GAAI,IAAA;AAAA,IAC9D,CAAA;AAAA,EACF;AACA,EAAA,MAAM,SAAS,EAAA,GAAK,CAAA,CAAE,KAAA,CAAM,WAAA,KAAgB,CAAA,CAAE,KAAA;AAC9C,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,MAAM,GAAA,GAAM,EAAA,GAAK,IAAA,CAAK,WAAA,EAAY,GAAI,IAAA;AACtC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AAC9B,IAAA,OAAO,GAAA,KAAQ,KAAK,IAAA,GAAO,EAAE,OAAO,GAAA,EAAK,GAAA,EAAK,GAAA,GAAM,MAAA,CAAO,MAAA,EAAO;AAAA,EACpE,CAAA;AACF;AAEA,SAAS,UAAU,CAAA,EAAgC;AACjD,EAAA,QAAQ,EAAE,IAAA;AAAM,IACd,KAAK,YAAA;AACH,MAAA,OAAO,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA,IAClC,KAAK,cAAA;AACH,MAAA,OAAO,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA,IAClC,KAAK,UAAA;AACH,MAAA,OAAO,CAAA,EAAG,EAAE,IAAI,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA;AAAA,IAC7C,KAAK,aAAA;AACH,MAAA,OAAO,OAAO,EAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,IAC7E,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,EAAE,OAAO,CAAA,CAAA;AAAA,IACjC,KAAK,eAAA;AAAA,IACL,KAAK,iBAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,CAAA,EAAI,EAAE,QAAQ,CAAA,CAAA;AAAA,IACjC,KAAK,cAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,CAAA,CAAE,KAAA;AAAA,IACX,KAAK,aAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,EAAE,KAAK,CAAA,CAAA;AAAA,IAC/B,KAAK,iBAAA;AAAA,IACL,KAAK,mBAAA;AACH,MAAA,OAAO,CAAA,CAAE,SAAA;AAAA,IACX;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,SAAS,gBAAgB,OAAA,EAA0C;AACjE,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,MAAA;AACH,QAAA,OAAO,CAAA,CAAE,IAAA;AAAA,MACX,KAAK,UAAA;AACH,QAAA,OAAO,CAAA,UAAA,EAAa,EAAE,IAAI,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,MACvD,KAAK,aAAA;AACH,QAAA,OAAO,OAAO,EAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,MAC7E;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd;AAEA,IAAM,cAAA,GAAiB,EAAA;AAEvB,SAAS,SAAA,CAAU,IAAA,EAAc,KAAA,EAAe,GAAA,EAAqB;AACnE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,cAAc,CAAA;AAC/C,EAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,MAAM,cAAc,CAAA;AACrD,EAAA,MAAM,MAAA,GAAS,IAAA,GAAO,CAAA,GAAI,QAAA,GAAM,EAAA;AAChC,EAAA,MAAM,MAAA,GAAS,EAAA,GAAK,IAAA,CAAK,MAAA,GAAS,QAAA,GAAM,EAAA;AACxC,EAAA,OAAO,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,IAAA,EAAK,GAAI,MAAA;AACrE;AAEA,SAAS,cAAA,CAAe,MAAuB,MAAA,EAAgC;AAC7E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,IAAA,CAAK,EAAE,CAAA,CAAE,CAAA;AACjC,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,QAAA,EAAU;AAC/B,IAAA,KAAA,CAAM,IAAA,CAAK,gBAAgB,IAAA,CAAK,QAAA,IAAY,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,IAAS,GAAG,CAAA,CAAE,CAAA;AAAA,EACxE;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,CAAE,CAAA;AAC7C,EAAA,IAAI,KAAK,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,IAAA,CAAK,OAAO,CAAA,CAAE,CAAA;AAC3D,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,YAAA,EAAc;AACjB,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAa,CAAA,CAAE,EAAE,CAAA,CAAE,CAAA;AAC9B,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,cAAA,EAAgB;AACnB,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,oBAAA,EAAkB,CAAA,CAAE,EAAE,CAAA,CAAE,CAAA;AACnC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,IAAI,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,UAAA,KAAe,UAAA,EAAY;AAC/C,UAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,UAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,CAAA,CAAE,UAAU,CAAA,CAAA,CAAG,CAAA;AAAA,QACtC;AACA,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,UAAA,EAAY;AACf,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,iBAAA,EAAoB,CAAA,CAAE,IAAI,CAAA,EAAA,CAAI,CAAA;AACzC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,KAAK,SAAS,CAAA;AACpB,QAAA,KAAA,CAAM,KAAK,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,aAAA,EAAe;AAClB,QAAA,MAAM,IAAA,GAAO,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA;AAC1F,QAAA,KAAA,CAAM,KAAK,CAAA,eAAA,EAAkB,CAAA,CAAE,OAAA,GAAU,UAAA,GAAa,EAAE,CAAA,CAAE,CAAA;AAC1D,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,OAAA,EAAS;AACZ,QAAA,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,CAAA,CAAE,KAAK,CAAA,GAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACnD,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,YAAA,EAAc;AACjB,QAAA,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,CAAA,CAAE,MAAM,CAAA,QAAA,EAAM,CAAA,CAAE,KAAK,CAAA,OAAA,CAAS,CAAA;AAC9D,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAEE;AACJ,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,SAAS,eAAA,CAAgB,MAAuB,MAAA,EAAgC;AAC9E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,CAAA,QAAA,EAAW,IAAA,CAAK,EAAE,CAAA,QAAA,EAAM,IAAA,CAAK,QAAA,IAAY,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,IAAS,GAAG,CAAA,gBAAA,EAAc,KAAK,SAAS,CAAA;AAAA,GAC/F;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,MAAA,CAAO,EAAA,EAAI,GAAG,CAAC,CAAA;AAC7B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,YAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,MAAA,CAAQ,CAAA;AAC3B,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,WAAA,CAAa,CAAA;AAChC,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,WAAA,EAAc,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,CAAA;AACpE,QAAA;AAAA,MACF,KAAK,aAAA;AACH,QAAA,KAAA,CAAM,IAAA;AAAA,UACJ,IAAI,CAAA,CAAE,EAAE,gBAAgB,CAAA,CAAE,OAAA,GAAU,aAAa,EAAE,CAAA,CAAA,EACjD,OAAO,CAAA,CAAE,OAAA,KAAY,WAAW,CAAA,CAAE,OAAA,GAAU,KAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CACtE,CAAA;AAAA,SACF;AACA,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,SAAA,EAAY,EAAE,KAAK,CAAA,GAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACvD,QAAA;AAEA;AACJ,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;ACjUO,SAAS,iBAAA,CAAkB,GAAA,EAAa,SAAA,EAAmB,MAAA,EAAwB;AACxF,EAAA,IAAI,CAAC,aAAa,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,IAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,EAAG;AACtE,IAAA,MAAM,QAAQ,SAAS,CAAA;AAAA,EACzB;AACA,EAAA,MAAM,WAAgBC,KAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,GAAG,SAAS,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA;AAC1D,EAAA,MAAM,GAAA,GAAWA,KAAA,CAAA,QAAA,CAAcA,KAAA,CAAA,OAAA,CAAQ,GAAG,GAAG,QAAQ,CAAA;AACrD,EAAA,IAAI,IAAI,UAAA,CAAW,IAAI,CAAA,IAAUA,KAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAG;AAChD,IAAA,MAAM,QAAQ,SAAS,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,QAAQ,SAAA,EAA4B;AAC3C,EAAA,OAAO,IAAI,OAAA,CAAQ;AAAA,IACjB,OAAA,EAAS,sBAAsB,SAAS,CAAA,CAAA;AAAA,IACxC,MAAM,WAAA,CAAY,gBAAA;AAAA,IAClB,IAAA,EAAM,SAAA;AAAA,IACN,OAAA,EAAS,EAAE,MAAA,EAAQ,gBAAA;AAAiB,GACrC,CAAA;AACH;;;ACiCA,IAAM,YAAA,GAAe,CAAA;AAErB,IAAM,eAAA,GAAkB,GAAA;AAExB,IAAM,eAAA,GAAkB,GAAA;AASjB,IAAM,mBAAN,MAAuB;AAAA,EACX,GAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAEA,WAAA,uBAAkB,GAAA,EAA2B;AAAA,EAE9D,YAAY,IAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,KAAK,SAAA,EAA0C;AACnD,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAC1C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,aAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA;AAAA,QACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,IAAA,GAAO,IAAA,CAAK,WAAA,GAAc,EAAC;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,aAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,SAAA,EAA0C;AACvD,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AACrC,IAAA,OAAO,GAAA,CAAI,OAAO,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,QAAQ,EAAE,OAAA,EAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,IAAI,KAAA,EAKc;AACtB,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,IAAA,EAAK;AAC7B,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,MAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,OAAA,EAAS,mCAAA;AAAA,QACT,MAAM,WAAA,CAAY,gBAAA;AAAA,QAClB,SAAA,EAAW,SAAA;AAAA,QACX,SAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAW,MAAM,SAAA;AAAU,OACtD,CAAA;AAAA,IACH;AACA,IAAA,IAAI,IAAA,CAAK,SAAS,eAAA,EAAiB;AACjC,MAAA,MAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,OAAA,EAAS,CAAA,wBAAA,EAA2B,eAAe,CAAA,YAAA,EAAe,KAAK,MAAM,CAAA,CAAA,CAAA;AAAA,QAC7E,MAAM,WAAA,CAAY,gBAAA;AAAA,QAClB,SAAA,EAAW,SAAA;AAAA,QACX,OAAA,EAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,WAAW,eAAA,EAAiB,YAAA,EAAc,KAAK,MAAA;AAAO,OACjF,CAAA;AAAA,IACH;AACA,IAAA,IAAI,CAAC,OAAO,SAAA,CAAU,KAAA,CAAM,YAAY,CAAA,IAAK,KAAA,CAAM,eAAe,CAAA,EAAG;AACnE,MAAA,MAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,OAAA,EAAS,6CAAA;AAAA,QACT,MAAM,WAAA,CAAY,gBAAA;AAAA,QAClB,SAAA,EAAW,SAAA;AAAA,QACX,SAAS,EAAE,KAAA,EAAO,cAAA,EAAgB,KAAA,EAAO,MAAM,YAAA;AAAa,OAC7D,CAAA;AAAA,IACH;AACA,IAAA,MAAM,UAAA,GAAyB;AAAA,MAC7B,IAAIC,UAAAA,EAAW;AAAA,MACf,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,UAAA,EAAY,WAAA;AAAA,MACZ,IAAA;AAAA,MACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,QAAA,EAAU;AAAA,KACZ;AACA,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,YAAY;AAC9C,QAAA,MAAM,YAAA,CAAa,IAAI,YAAY;AACjC,UAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,CAAK,MAAM,SAAS,CAAA;AAC3C,UAAA,GAAA,CAAI,KAAK,UAAU,CAAA;AAEnB,UAAA,IAAI,GAAA,CAAI,SAAS,eAAA,EAAiB;AAChC,YAAA,MAAM,MAAA,GAAS,GAAA,CACZ,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO,EAAE,CAAA,EAAG,CAAA,EAAE,CAAE,CAAA,CACxB,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAGd,cAAA,IAAI,CAAA,CAAE,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,UAAU,OAAO,CAAA,CAAE,CAAA,CAAE,QAAA,GAAW,CAAA,GAAI,CAAA,CAAA;AAC7D,cAAA,OAAO,EAAE,CAAA,CAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,EAAE,SAAS,CAAA;AAAA,YAClD,CAAC,CAAA;AACH,YAAA,MAAM,UAAA,GAAa,IAAI,MAAA,GAAS,eAAA;AAChC,YAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAA,CAAE,EAAE,CAAC,CAAA;AACtE,YAAA,MAAM,IAAA,GAAO,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AACjD,YAAA,MAAM,IAAA,CAAK,UAAU,KAAA,CAAM,SAAA,EAAW,EAAE,OAAA,EAAS,YAAA,EAAc,WAAA,EAAa,IAAA,EAAM,CAAA;AAClF,YAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,YAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,cACjC,WAAW,KAAA,CAAM,SAAA;AAAA,cACjB,KAAA,EAAO,aAAA;AAAA,cACP,QAAA,EAAU,EAAA;AAAA,cACV,SAAA,EAAW,OAAA;AAAA,cACX,OAAA,EAAS,SAAA;AAAA,cACT,UAAA;AAAA,cACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,aAC/D,CAAA;AAAA,UACH,CAAA,MAAO;AACL,YAAA,MAAM,IAAA,CAAK,UAAU,KAAA,CAAM,SAAA,EAAW,EAAE,OAAA,EAAS,YAAA,EAAc,WAAA,EAAa,GAAA,EAAK,CAAA;AACjF,YAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,YAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,cACjC,WAAW,KAAA,CAAM,SAAA;AAAA,cACjB,KAAA,EAAO,aAAA;AAAA,cACP,QAAA,EAAU,EAAA;AAAA,cACV,SAAA,EAAW,KAAA;AAAA,cACX,OAAA,EAAS,SAAA;AAAA,cACT,UAAA;AAAA,cACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,aAC/D,CAAA;AAAA,UACH;AAAA,QACF,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA,OAAO,UAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO,aAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,KAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,KAAA;AAAA,QACb,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAQ,KAAA,EAIiB;AAC7B,IAAA,IAAI,OAAA,GAA6B,IAAA;AACjC,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,YAAY;AAC9C,QAAA,MAAM,YAAA,CAAa,IAAI,YAAY;AACjC,UAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,CAAK,MAAM,SAAS,CAAA;AAC3C,UAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,MAAM,YAAY,CAAA;AAC5D,UAAA,IAAI,QAAQ,CAAA,CAAA,EAAI;AACd,YAAA,OAAA,GAAU,IAAA;AACV,YAAA;AAAA,UACF;AACA,UAAA,MAAM,IAAA,GAAmB;AAAA,YACvB,GAAG,aAAA,CAAc,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,YACzB,QAAA,EAAU,IAAA;AAAA,YACV,UAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,YACnC,YAAY,KAAA,CAAM;AAAA,WACpB;AACA,UAAA,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA;AACX,UAAA,MAAM,IAAA,CAAK,UAAU,KAAA,CAAM,SAAA,EAAW,EAAE,OAAA,EAAS,YAAA,EAAc,WAAA,EAAa,GAAA,EAAK,CAAA;AACjF,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,YACjC,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,KAAA,EAAO,aAAA;AAAA,YACP,QAAA,EAAU,EAAA;AAAA,YACV,SAAA,EAAW,SAAA;AAAA,YACX,OAAA,EAAS,SAAA;AAAA,YACT,UAAA;AAAA,YACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,WAC/D,CAAA;AAAA,QACH,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA,OAAO,OAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO,aAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,SAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,KAAA;AAAA,QACb,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAIQ,SAAS,SAAA,EAA2B;AAI1C,IAAA,OAAO,iBAAA,CAAkB,IAAA,CAAK,GAAA,EAAK,SAAA,EAAW,mBAAmB,CAAA;AAAA,EACnE;AAAA,EAEA,MAAc,SAAS,SAAA,EAAoD;AACzE,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAASC,GAAA,CAAA,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAG7D,MAAA,MAAM,GAAA;AAAA,IACR;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAI,MAAA,CAAO,YAAY,YAAA,EAAc;AACnC,QAAA,OAAO,EAAE,OAAA,EAAS,YAAA,EAAc,WAAA,EAAa,EAAC,EAAE;AAAA,MAClD;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,SAAA,CAAU,SAAA,EAAmB,IAAA,EAAsC;AAC/E,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,YAAY,EAAA,EAAI,IAAA,CAAK,UAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,OAAA,CAAQ,WAAmB,EAAA,EAAwC;AACzE,IAAA,MAAM,OAAO,IAAA,CAAK,WAAA,CAAY,IAAI,SAAS,CAAA,IAAK,QAAQ,OAAA,EAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA;AAG7B,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,MACf,SAAA;AAAA,MACA,IAAA,CAAK,KAAA,CAAM,MAAM,MAAS;AAAA,KAC5B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AClVO,SAAS,gBAAgB,KAAA,EAAwB;AACtD,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,KAAK,CAAC,CAAA;AACvC;AAEA,SAAS,SAAS,KAAA,EAAyB;AACzC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,QAAQ,CAAA;AACnD,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACtC,IAAA,MAAM,GAAA,GAAM,KAAA;AACZ,IAAA,MAAM,SAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAK,EAAG;AACzC,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,YAAY,OAAA,EAA0B;AAEpD,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,eAAe,OAAA,CAAQ,aAAA;AAAA,IACvB,YAAY,OAAA,CAAQ;AAAA,GACtB;AACA,EAAA,MAAM,IAAA,GAAO,gBAAgB,OAAO,CAAA;AACpC,EAAA,MAAM,MAAA,GAASC,WAAW,QAAQ,CAAA,CAAE,OAAO,IAAA,EAAM,MAAM,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AACrE,EAAA,OAAO,UAAU,MAAM,CAAA,CAAA;AACzB;;;AChDA,SAASC,oBAAmB,GAAA,EAAsB;AAChD,EAAA,IAAI,eAAe,KAAA,EAAO;AACxB,IAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,IAAA,OAAO,OAAO,CAAA,EAAG,IAAI,KAAK,GAAA,CAAI,OAAO,KAAK,GAAA,CAAI,OAAA;AAAA,EAChD;AAEA,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AAoCA,IAAM,mBAAA,GAAsB,GAAA;AAkBrB,IAAM,iBAAN,MAAqB;AAAA,EACT,GAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA,uBAAkB,GAAA,EAA2B;AAAA;AAAA,EAE7C,KAAA,uBAAY,GAAA,EAAsC;AAAA;AAAA,EAElD,SAAA,uBAAgB,GAAA,EAAoB;AAAA,EACpC,UAAA;AAAA,EAEjB,YAAY,IAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,mBAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,KAAA,EAIO;AAClB,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,KAAA,CAAM,OAAO,CAAA;AACtC,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,YAAY;AAC9C,QAAA,MAAM,YAAA,CAAa,IAAI,YAAY;AAKjC,UAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,WAAA,CAAY,MAAM,SAAS,CAAA;AACpD,UAAA,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AAErB,UAAA,MAAM,KAAA,GAAqB;AAAA,YACzB,IAAA;AAAA,YACA,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,YAC3B,SAAS,KAAA,CAAM,OAAA;AAAA,YACf,UAAU,KAAA,CAAM;AAAA,WAClB;AAEA,UAAA,MAAM,eAAe,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,SAAS,CAAA,IAAK,CAAA;AAC5D,UAAA,MAAM,SAAA,GAAY,YAAA,GAAe,CAAA,GAAI,IAAA,CAAK,UAAA;AAE1C,UAAA,IAAI,CAAC,SAAA,EAAW;AAOd,YAAA,MAASC,eAAW,EAAA,EAAI,IAAA,CAAK,UAAU,KAAK,CAAA,GAAI,MAAM,MAAM,CAAA;AAC5D,YAAA,KAAA,CAAM,GAAA,CAAI,MAAM,KAAK,CAAA;AACrB,YAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,eAAe,CAAC,CAAA;AACpD,YAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,cACjC,WAAW,KAAA,CAAM,SAAA;AAAA,cACjB,KAAA,EAAO,QAAA;AAAA,cACP,QAAA,EAAU,EAAA;AAAA,cACV,SAAA,EAAW,QAAA;AAAA,cACX,OAAA,EAAS,SAAA;AAAA,cACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,cACzB,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,aAC/D,CAAA;AACD,YAAA;AAAA,UACF;AAKA,UAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAM,SAAS,CAAA;AAC9C,UAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AACd,UAAA,MAAM,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,CAAC,KAAK,UAAU,CAAA;AACvC,UAAA,MAAM,SAAA,uBAAgB,GAAA,EAAyB;AAC/C,UAAA,KAAA,MAAW,KAAK,IAAA,EAAM,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,MAAM,CAAC,CAAA;AAC7C,UAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,SAAS,CAAA;AACzC,UAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,KAAK,MAAM,CAAA;AAC/C,UAAA,MAAM,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAA,EAAW,MAAM,SAAS,CAAA;AAAA,QACtD,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,QAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAOD,oBAAmB,GAAG,CAAA;AAAA,QAC7B,WAAA,EAAa,KAAA;AAAA,QACb,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAA,CAAO,SAAA,EAAmB,IAAA,EAA2C;AACzE,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA;AAC9C,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,QAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,IAAA;AAAA,IAC5B,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,QAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAOA,oBAAmB,GAAG,CAAA;AAAA,QAC7B,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,SAAA,EAA2C;AACpD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA;AAC9C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA;AAAA,QACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,CAAC,GAAG,KAAA,CAAM,MAAA,EAAQ,CAAA;AAAA,IAC3B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA;AAAA,QACA,KAAA,EAAOA,oBAAmB,GAAG,CAAA;AAAA,QAC7B,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IAAA,GAAgF;AACpF,IAAA,MAAM,MAAsE,EAAC;AAI7E,IAAA,MAAM,IAAA,GAAO,OAAO,GAAA,EAAa,MAAA,EAAgB,KAAA,KAAiC;AAChF,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,MAASC,GAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,MACzD,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,KAAA,KAAU,CAAA,IAAM,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU;AAInE,UAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,YAC1B,KAAA,EAAO,MAAA;AAAA,YACP,KAAA,EAAO,sCAAA;AAAA,YACP,GAAA;AAAA,YACA,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,YAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WACnC,CAAC,CAAA;AAAA,QACJ;AACA,QAAA;AAAA,MACF;AACA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,QAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,UAAA,IAAI,KAAA,KAAU,CAAA,EAAG,MAAM,IAAA,CAAUC,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA,EAAG,KAAA,CAAM,IAAA,EAAM,KAAA,GAAQ,CAAC,CAAA;AAC7E,UAAA;AAAA,QACF;AACA,QAAA,IAAI,CAAC,MAAM,MAAA,EAAO,IAAK,CAAC,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,eAAe,CAAA,EAAG;AAC9D,QAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,gBAAgB,MAAM,CAAA;AACxD,QAAA,MAAM,YAAY,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,IAAA;AACjD,QAAA,MAAM,EAAA,GAAUA,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AACpC,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,SAAA;AAAA,UACA,UAAA,EAAY,MAAM,IAAA,CAAK,YAAA,CAAa,EAAE,CAAA;AAAA,UACtC,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AACA,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,EAAA,EAAI,CAAC,CAAA;AAC1B,IAAA,OAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAAA,EAClE;AAAA;AAAA,EAIQ,SAAS,SAAA,EAA2B;AAI1C,IAAA,OAAO,iBAAA,CAAkB,IAAA,CAAK,GAAA,EAAK,SAAA,EAAW,eAAe,CAAA;AAAA,EAC/D;AAAA,EAEA,MAAc,aAAa,QAAA,EAAmC;AAI5D,IAAA,MAAM,MAAA,GAAS,MAASD,GAAA,CAAA,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,WAAA,CAAY,EAAA,GAAK,IAAI,CAAA;AAC3C,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,IAAI,gBAAA,GAAmB,KAAA;AACvB,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,MAAA,CAAO,KAAK,MAAA,EAAQ,CAAA,EAAG,MAAA,CAAO,MAAA,EAAQ,IAAI,CAAA;AACtE,QAAA,IAAI,cAAc,CAAA,EAAG;AACrB,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AAClC,UAAA,MAAM,EAAA,GAAK,OAAO,CAAC,CAAA;AACnB,UAAA,IAAI,OAAO,EAAA,EAAI;AACb,YAAA,IAAI,gBAAA,EAAkB,KAAA,EAAA;AACtB,YAAA,gBAAA,GAAmB,KAAA;AACnB,YAAA;AAAA,UACF;AACA,UAAA,IAAI,EAAA,KAAO,EAAA,IAAM,EAAA,KAAO,EAAA,IAAM,OAAO,CAAA,EAAG;AACtC,YAAA,gBAAA,GAAmB,IAAA;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,OAAO,KAAA,EAAM;AAAA,IACrB;AACA,IAAA,IAAI,gBAAA,EAAkB,KAAA,EAAA;AACtB,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAc,QAAQ,SAAA,EAA2C;AAC/D,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AACxC,MAAA,MAAM,MAAqB,EAAC;AAC5B,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,QAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,UAEb,IAAI,CAAA;AACN,UAAA,IAAI,CAAC,MAAA,CAAO,EAAA,IAAM,CAAC,OAAO,KAAA,EAAO;AAIjC,UAAA,IAAI,OAAA,IAAW,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,MAAM,KAAA,EAAO;AACjD,YAAA,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA;AAAA,UAC7B,CAAA,MAAO;AACL,YAAA,GAAA,CAAI,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,UACvB;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAGR;AAAA,MACF;AACA,MAAA,OAAO,GAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,EAAC;AAG9D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,QAAA,CACZ,SAAA,EACA,OAAA,EACA,YAAkC,QAAA,EACnB;AACf,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,EAAE,IAAA,CAAK,IAAI,CAAA,IAAK,OAAA,CAAQ,SAAS,IAAA,GAAO,EAAA,CAAA;AACzF,IAAA,MAAM,WAAA,CAAY,IAAI,IAAI,CAAA;AAC1B,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MACjC,SAAA;AAAA,MACA,KAAA,EAAO,QAAA;AAAA,MACP,QAAA,EAAU,EAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAA,EAAS,SAAA;AAAA,MACT,UAAA;AAAA,MACA,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,KAC/D,CAAA;AAII,EACP;AAAA,EAEA,MAAc,YAAY,SAAA,EAAsD;AAC9E,IAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,SAAS,CAAA;AACpC,IAAA,IAAI,OAAO,OAAO,KAAA;AAClB,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AACxC,IAAA,KAAA,uBAAY,GAAA,EAAI;AAChB,IAAA,KAAA,MAAW,KAAK,GAAA,EAAK,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,MAAM,CAAC,CAAA;AACxC,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,SAAA,EAAW,KAAK,CAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,EAAW,GAAA,CAAI,MAAM,CAAA;AACxC,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,OAAA,CAAQ,WAAmB,EAAA,EAAwC;AACzE,IAAA,MAAM,OAAO,IAAA,CAAK,WAAA,CAAY,IAAI,SAAS,CAAA,IAAK,QAAQ,OAAA,EAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA;AAC7B,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,MACf,SAAA;AAAA,MACA,IAAA,CAAK,KAAA,CAAM,MAAM,MAAS;AAAA,KAC5B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;ACrWO,IAAM,kBAAN,MAAsB;AAAA,EAuL3B,YAA6B,GAAA,EAAa;AAAb,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAc;AAAA,EAAd,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA5K7B,MAAM,YAAY,SAAA,EAAiD;AACjE,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAGlC,IAAA,MAAM,SAAA,GAAY,IAAA;AAClB,IAAA,IAAIzB,KAAAA;AACJ,IAAA,IAAI;AACF,MAAAA,KAAAA,GAAO,MAAS2B,GAAA,CAAA,IAAA,CAAK,EAAE,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAE7D,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI3B,KAAAA,CAAK,IAAA,KAAS,CAAA,EAAG,OAAO,IAAA;AAC5B,IAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAGA,KAAAA,CAAK,OAAO,SAAS,CAAA;AAClD,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA;AAClC,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI;AACF,MAAA,EAAA,GAAK,MAAS2B,GAAA,CAAA,IAAA,CAAK,EAAA,EAAI,GAAG,CAAA;AAC1B,MAAA,MAAM,EAAE,WAAU,GAAI,MAAM,GAAG,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,SAAA,EAAW,QAAQ,CAAA;AAG/D,MAAA,IAAI,UAAA,GAAa,CAAA;AACjB,MAAA,MAAM,MAAM,GAAA,CAAI,QAAA,CAAS,GAAG,SAAS,CAAA,CAAE,SAAS,MAAM,CAAA;AACtD,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,QAAA,IAAI,IAAA,CAAK,MAAK,EAAG,UAAA,EAAA;AAAA,MACnB;AAEA,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA;AACpD,MAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,QAAA,IAAI;AACF,UAAA,MAAM,KAAK,IAAA,CAAK,KAAA,CAAM,cAAc,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AAC7C,UAAA,IAAI,EAAA,CAAG,SAAS,iBAAA,EAAmB;AACjC,YAAA,OAAO;AAAA,cACL,SAAA;AAAA,cACA,IAAA,EAAM,EAAA;AAAA,cACN,aAAa,EAAA,CAAG,EAAA;AAAA,cAChB,SAAS,EAAA,CAAG,OAAA;AAAA,cACZ;AAAA,aACF;AAAA,UACF;AAEA,UAAA,OAAO,IAAA;AAAA,QACT,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IAET,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,SAAE;AACA,MAAA,IAAI,EAAA,EAAI,MAAM,EAAA,CAAG,KAAA,EAAM;AAAA,IACzB;AAAA,EAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QAAQ,SAAA,EAAiD;AAC7D,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAE7D,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAyB,EAAC;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAI,CAAiB,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAEhC,IAAA,IAAI,cAAA,GAAsC,IAAA;AAC1C,IAAA,IAAI,iBAAA,GAAoB,EAAA;AACxB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,IAAI,MAAA,CAAO,CAAC,CAAA,EAAG,IAAA,KAAS,YAAA,EAAc;AACpC,QAAA,cAAA,GAAiB,aAAA,CAAc,MAAA,CAAO,CAAC,CAAC,CAAA;AACxC,QAAA,iBAAA,GAAoB,CAAA;AAAA,MACtB;AAAA,IACF;AAEA,IAAA,MAAM,gBACJ,iBAAA,IAAqB,CAAA,GAAI,OAAO,KAAA,CAAM,iBAAA,GAAoB,CAAC,CAAA,GAAI,MAAA;AAEjE,IAAA,MAAM,SAAS,aAAA,CAAc,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAC,CAAA;AACtD,IAAA,MAAM,aAAA,GACJ,MAAA,CAAO,IAAA,KAAS,iBAAA,GAAoB,MAAA,GAAS,IAAA;AAC/C,IAAA,MAAM,UAAU,aAAA,IAAiB,aAAA,CAAc,IAAA,KAAS,iBAAA,GACpD,cAAc,OAAA,GACd,IAAA;AACJ,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,OAAO,aAAA,KAAkB,IAAA;AAAA,MACzB,cAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAA,GAAyC;AAC7C,IAAA,MAAM,MAAsB,EAAC;AAI7B,IAAA,MAAM,OAAA,GAAU,OAAO,GAAA,EAAa,MAAA,EAAgB,KAAA,KAAiC;AACnF,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,MAASA,GAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,MAEzD,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,QAAA,IACE,MAAM,IAAA,KAAS,QAAA,IACf,MAAM,IAAA,KAAS,WAAA,IACf,MAAM,IAAA,KAAS,aAAA;AAEf,UAAA;AACF,QAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,UAAA,IAAI,UAAU,CAAA,EAAG;AACf,YAAA,MAAM,OAAA,CAAaC,WAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA,EAAG,KAAA,CAAM,IAAA,EAAM,KAAA,GAAQ,CAAC,CAAA;AAAA,UACjE;AACA,UAAA;AAAA,QACF;AACA,QAAA,IAAI,CAAC,MAAM,MAAA,EAAO,IAAK,CAAC,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG;AACvD,QAAA,IAAI,KAAA,CAAM,IAAA,KAAS,cAAA,IAAkB,KAAA,CAAM,SAAS,gBAAA,EAAkB;AACtE,QAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,SAAS,MAAM,CAAA;AACjD,QAAA,IAAI,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,IAAK,IAAA,CAAK,SAAS,cAAc,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AACrF,UAAA;AACF,QAAA,MAAM,YAAY,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,IAAA;AACjD,QAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA;AAC9C,QAAA,IAAI,KAAA,EAAO,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AAAA,MAC3B;AAAA,IACF,CAAA;AACA,IAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,GAAA,EAAK,EAAA,EAAI,CAAC,CAAA;AAC7B,IAAA,OAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,WAAA,CAAY,aAAA,CAAc,CAAA,CAAE,WAAW,CAAC,CAAA;AAAA,EACtE;AAAA;AAAA,EAIQ,SAAS,SAAA,EAA2B;AAI1C,IAAA,OAAO,iBAAA,CAAkB,IAAA,CAAK,GAAA,EAAK,SAAA,EAAW,QAAQ,CAAA;AAAA,EACxD;AAGF;ACxLA,IAAM,YAAA,GAAe,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAoBlC,IAAM,mBAAA,GAAsB,GAAA;AAErB,IAAM,eAAN,MAAmB;AAAA,EACP,GAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAEA,QAAA,uBAAe,GAAA,EAAoB;AAAA;AAAA,EAEnC,SAAA,uBAAgB,GAAA,EAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpC,QAAA,uBAAe,GAAA,EAA+C;AAAA;AAAA,EAE9D,cAAA,uBAAqB,GAAA,EAAoB;AAAA,EACzC,WAAA,uBAAkB,GAAA,EAA2B;AAAA,EAC7C,UAAA;AAAA,EAEjB,YAAY,IAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,mBAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,KAAA,EAOW;AACtB,IAAA,IAAI,KAAA;AACJ,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,SAAA,EAAW,YAAY;AAC9C,QAAA,MAAM,YAAA,CAAa,IAAI,YAAY;AAOjC,UAAA,MAAM,MAAM,MAAM,IAAA,CAAK,gBAAA,CAAiB,KAAA,CAAM,WAAW,EAAE,CAAA;AAC3D,UAAA,MAAM,WAAW,GAAA,CAAI,QAAA;AACrB,UAAA,MAAM,QAAQ,GAAA,CAAI,SAAA;AAElB,UAAA,MAAM,KAAKP,UAAAA,EAAW;AACtB,UAAA,MAAM,EAAA,GAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAClC,UAAA,MAAM,OAAA,GAAU;AAAA,YACd,EAAA;AAAA,YACA,EAAA;AAAA,YACA,QAAA;AAAA,YACA,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,OAAO,KAAA,CAAM,KAAA;AAAA,YACb,QAAQ,KAAA,CAAM,MAAA;AAAA,YACd,SAAS,KAAA,CAAM,OAAA;AAAA,YACf;AAAA,WACF;AACA,UAAA,MAAM,IAAA,GAAOE,UAAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAOM,gBAAAA,CAAgB,OAAO,CAAA,EAAG,MAAM,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AACvF,UAAA,KAAA,GAAQ;AAAA,YACN,EAAA;AAAA,YACA,EAAA;AAAA,YACA,QAAA;AAAA,YACA,IAAA;AAAA,YACA,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,OAAO,KAAA,CAAM,KAAA;AAAA,YACb,QAAQ,KAAA,CAAM,MAAA;AAAA,YACd,SAAS,KAAA,CAAM,OAAA;AAAA,YACf;AAAA,WACF;AAOA,UAAA,MAASC,eAAW,EAAA,EAAI,IAAA,CAAK,UAAU,KAAK,CAAA,GAAI,MAAM,MAAM,CAAA;AAK5D,UAAA,IAAI;AACF,YAAA,MAAM,EAAA,GAAK,MAASA,GAAA,CAAA,IAAA,CAAK,EAAE,CAAA;AAC3B,YAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,EAAE,OAAA,EAAS,EAAA,CAAG,OAAA,EAAS,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,CAAA;AAAA,UAC3E,CAAA,CAAA,MAAQ;AAAA,UAER;AACA,UAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,IAAI,CAAA;AACvC,UAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAC,CAAA;AAC7C,UAAA,MAAM,IAAA,CAAK,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,EAAE,CAAA;AAE7C,UAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,UAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,YACjC,WAAW,KAAA,CAAM,SAAA;AAAA,YACjB,KAAA,EAAO,OAAA;AAAA,YACP,QAAA,EAAU,EAAA;AAAA,YACV,SAAA,EAAW,QAAA;AAAA,YACX,OAAA,EAAS,SAAA;AAAA,YACT,UAAA;AAAA,YACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,WAC/D,CAAA;AAAA,QACH,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA,OAAO,KAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,QACjC,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,KAAA,EAAO,OAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,QAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,WAAA,EAAa,KAAA;AAAA,QACb,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,gBAAA,CACZ,SAAA,EACA,EAAA,EACkD;AAClD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAC9C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA;AAChD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAE9C,IAAA,IAAI,UAAA,KAAe,MAAA,IAAa,WAAA,KAAgB,MAAA,IAAa,UAAA,EAAY;AAIvE,MAAA,IAAI;AACF,QAAA,MAAM,EAAA,GAAK,MAASA,GAAA,CAAA,IAAA,CAAK,EAAE,CAAA;AAC3B,QAAA,IAAI,GAAG,OAAA,KAAY,UAAA,CAAW,WAAW,EAAA,CAAG,IAAA,KAAS,WAAW,IAAA,EAAM;AACpE,UAAA,OAAO,EAAE,QAAA,EAAU,UAAA,EAAY,SAAA,EAAW,WAAA,EAAY;AAAA,QACxD;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,IAAK,GAAA,CAA8B,SAAS,QAAA,EAAU;AAEpD,UAAA,IAAA,CAAK,QAAA,CAAS,OAAO,SAAS,CAAA;AAC9B,UAAA,IAAA,CAAK,SAAA,CAAU,OAAO,SAAS,CAAA;AAC/B,UAAA,IAAA,CAAK,QAAA,CAAS,OAAO,SAAS,CAAA;AAC9B,UAAA,OAAO,EAAE,QAAA,EAAU,YAAA,EAAc,SAAA,EAAW,CAAA,EAAE;AAAA,QAChD;AAEA,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,IACF;AAGA,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,EAAA,CAAG,EAAE,CAAA;AAC1B,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,IAAQ,YAAA;AAC/B,IAAA,MAAM,SAAA,GAAY,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,CAAA,GAAI,CAAA;AAC1C,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAA,EAAW,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,EAAW,SAAS,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,MAASA,GAAA,CAAA,IAAA,CAAK,EAAE,CAAA;AAC3B,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAA,EAAW,EAAE,OAAA,EAAS,GAAG,OAAA,EAAS,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,CAAA;AAAA,IACrE,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,SAAA,EAA0C;AACrD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AAAA,IACxC,SAAS,GAAA,EAAK;AAIZ,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,OAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,QAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,CAAA,EAAE;AAAA,IAChC;AAIA,IAAA,MAAM,WAAW,MAAoB;AACnC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,SAAS,CAAA,EAAE;AAExD,MAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,QAAA,KAAa,YAAA,EAAc;AACzC,QAAA,OAAO;AAAA,UACL,EAAA,EAAI,KAAA;AAAA,UACJ,QAAA,EAAU,CAAA;AAAA,UACV,MAAA,EAAQ;AAAA,SACV;AAAA,MACF;AACA,MAAA,IAAI,QAAA,GAAW,YAAA;AACf,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,QAAA,MAAM,CAAA,GAAI,aAAA,CAAc,OAAA,CAAQ,CAAC,CAAC,CAAA;AAClC,QAAA,IAAI,CAAA,CAAE,aAAa,QAAA,EAAU;AAC3B,UAAA,OAAO;AAAA,YACL,EAAA,EAAI,KAAA;AAAA,YACJ,QAAA,EAAU,CAAA;AAAA,YACV,MAAA,EAAQ,CAAA,2BAAA,EAA8B,CAAC,CAAA,WAAA,EAAc,SAAS,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,eAAU,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,OAAA;AAAA,WAC3G;AAAA,QACF;AAGA,QAAA,MAAM,OAAA,GAAU;AAAA,UACd,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,WAAW,CAAA,CAAE,SAAA;AAAA,UACb,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,OAAO,CAAA,CAAE;AAAA,SACX;AACA,QAAA,MAAM,YAAA,GAAeP,UAAAA,CAAW,QAAQ,CAAA,CACrC,MAAA,CAAOM,gBAAAA,CAAgB,OAAO,CAAA,EAAG,MAAM,CAAA,CACvC,MAAA,CAAO,KAAK,CAAA;AACf,QAAA,IAAI,YAAA,KAAiB,EAAE,IAAA,EAAM;AAC3B,UAAA,OAAO;AAAA,YACL,EAAA,EAAI,KAAA;AAAA,YACJ,QAAA,EAAU,CAAA;AAAA,YACV,MAAA,EAAQ,0BAA0B,CAAC,CAAA,6BAAA;AAAA,WACrC;AAAA,QACF;AACA,QAAA,QAAA,GAAW,CAAA,CAAE,IAAA;AAAA,MACf;AACA,MAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,QAAQ,MAAA,EAAO;AAAA,IAC7C,CAAA,GAAG;AAEH,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAChC,SAAA;AAAA,MACA,KAAA,EAAO,OAAA;AAAA,MACP,QAAA,EAAU,EAAA;AAAA,MACV,SAAA,EAAW,QAAA;AAAA,MACX,OAAA,EAAS,OAAA,CAAQ,EAAA,GAAK,SAAA,GAAY,SAAA;AAAA,MAClC,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,KAC/D,CAAA;AACD,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAK,SAAA,EAA0C;AACnD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AAC5C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,OAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA;AAAA,QACA,GAAI,KAAK,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,OAAO,OAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAChC,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAChC,SAAA;AAAA,QACA,KAAA,EAAO,OAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA;AAAA,QACA,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,QACzB,GAAI,KAAK,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ,GAAI;AAAC,OAC/D,CAAA;AACD,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAIQ,SAAS,SAAA,EAA2B;AAI1C,IAAA,OAAO,iBAAA,CAAkB,IAAA,CAAK,GAAA,EAAK,SAAA,EAAW,cAAc,CAAA;AAAA,EAC9D;AAAA,EAEA,MAAc,QAAQ,SAAA,EAA0C;AAC9D,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASC,GAAA,CAAA,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AACxC,MAAA,MAAM,MAAoB,EAAC;AAC3B,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAClC,QAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,UAAsB,IAAI,CAAA;AACzC,UAAA,IAAI,OAAO,EAAA,IAAM,MAAA,CAAO,OAAO,GAAA,CAAI,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,QACtD,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AACA,MAAA,OAAO,GAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,EAAC;AAG9D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,cAAA,CAAe,SAAA,EAAmB,EAAA,EAA2B;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,SAAS,KAAK,CAAA,IAAK,CAAA;AAC1D,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,SAAA,EAAW,KAAK,CAAA;AACxC,IAAA,IAAI,KAAK,UAAA,KAAe,MAAA,CAAO,qBAAqB,KAAA,GAAQ,IAAA,CAAK,eAAe,CAAA,EAAG;AACjF,MAAA,MAAM,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,EAAE,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,SAAA,EAAkC;AAC5C,IAAA,MAAM,KAAK,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,CAAA;AAAA,EACrD;AAAA,EAEA,MAAc,IAAA,CAAK,SAAA,EAAmB,EAAA,EAA2B;AAC/D,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,MAASA,GAAA,CAAA,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AACjC,MAAA,IAAI;AACF,QAAA,MAAM,GAAG,IAAA,EAAK;AAAA,MAChB,CAAA,SAAE;AACA,QAAA,MAAM,GAAG,KAAA,EAAM;AAAA,MACjB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,SAAA,EAAW,CAAC,CAAA;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,OAAA,CAAQ,WAAmB,EAAA,EAAwC;AACzE,IAAA,MAAM,OAAO,IAAA,CAAK,WAAA,CAAY,IAAI,SAAS,CAAA,IAAK,QAAQ,OAAA,EAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA;AAC7B,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,MACf,SAAA;AAAA,MACA,IAAA,CAAK,KAAA,CAAM,MAAM,MAAS;AAAA,KAC5B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAASD,iBAAgB,KAAA,EAAwB;AAC/C,EAAA,OAAO,IAAA,CAAK,SAAA,CAAUE,SAAAA,CAAS,KAAK,CAAC,CAAA;AACvC;AAEA,SAASA,UAAS,KAAA,EAAyB;AACzC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAIA,SAAQ,CAAA;AACnD,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACtC,IAAA,MAAM,GAAA,GAAM,KAAA;AACZ,IAAA,MAAM,SAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAK,EAAG;AACzC,MAAA,MAAA,CAAO,GAAG,CAAA,GAAIA,SAAAA,CAAS,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;;;ACzbO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,QAAQ,MAAA,EAAyC;AAC/C,IAAA,MAAM,iBAAyC,EAAC;AAChD,IAAA,MAAM,SAAyB,EAAC;AAChC,IAAA,MAAM,cAA4B,EAAC;AACnC,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAyB;AAC/C,IAAA,IAAI,SAAA,GAAY,EAAA;AAEhB,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,eAAA,IAAmB,KAAA,CAAM,SAAS,iBAAA,EAAmB;AACtE,QAAA,IAAI,CAAC,SAAA,EAAW,SAAA,GAAY,KAAA,CAAM,EAAA;AAAA,MACpC;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,UAAA,EAAY;AAC7B,QAAA,cAAA,CAAe,MAAM,IAAI,CAAA,GAAA,CAAK,eAAe,KAAA,CAAM,IAAI,KAAK,CAAA,IAAK,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,KAAA,EAAO,KAAA,CAAM,KAAA,EAAO,OAAA,EAAS,KAAA,CAAM,OAAA,EAAS,CAAA;AAAA,MAC1E;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,QAAA,WAAA,CAAY,IAAA,CAAK,EAAE,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,QAAA,SAAA,CAAU,GAAA,CAAI,MAAM,MAAA,EAAQ;AAAA,UAC1B,QAAQ,KAAA,CAAM,MAAA;AAAA,UACd,OAAO,KAAA,CAAM,KAAA;AAAA,UACb,MAAA,EAAQ,SAAA;AAAA,UACR,WAAW,KAAA,CAAM;AAAA,SAClB,CAAA;AAAA,MACH;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,QAAA,MAAM,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACpC,QAAA,IAAI,CAAA,EAAG,CAAA,CAAE,MAAA,GAAS,KAAA,CAAM,MAAA;AAAA,MAC1B;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,gBAAA,EAAkB;AACnC,QAAA,MAAM,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACpC,QAAA,IAAI,CAAA,EAAG;AACL,UAAA,CAAA,CAAE,MAAA,GAAS,WAAA;AACX,UAAA,CAAA,CAAE,cAAc,KAAA,CAAM,EAAA;AAAA,QACxB,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,GAAA,CAAI,MAAM,MAAA,EAAQ;AAAA,YAC1B,QAAQ,KAAA,CAAM,MAAA;AAAA,YACd,OAAO,KAAA,CAAM,KAAA;AAAA,YACb,MAAA,EAAQ,WAAA;AAAA,YACR,WAAW,KAAA,CAAM,EAAA;AAAA,YACjB,aAAa,KAAA,CAAM;AAAA,WACpB,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,aAAA,EAAe;AAChC,QAAA,MAAM,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACpC,QAAA,IAAI,CAAA,EAAG;AACL,UAAA,CAAA,CAAE,MAAA,GAAS,QAAA;AACX,UAAA,CAAA,CAAE,cAAc,KAAA,CAAM,EAAA;AAAA,QACxB,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,GAAA,CAAI,MAAM,MAAA,EAAQ;AAAA,YAC1B,QAAQ,KAAA,CAAM,MAAA;AAAA,YACd,OAAO,KAAA,CAAM,KAAA;AAAA,YACb,MAAA,EAAQ,QAAA;AAAA,YACR,WAAW,KAAA,CAAM,EAAA;AAAA,YACjB,aAAa,KAAA,CAAM;AAAA,WACpB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,aAAA,EAAe,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA;AAAA,MACvC,cAAA;AAAA,MACA,YAAY,MAAA,CAAO,MAAA;AAAA,MACnB,WAAA;AAAA,MACA,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,QAAQ;AAAA,KACtC;AAAA,EACF;AAAA,EAEA,KAAA,CAAM,QAAwB,MAAA,EAAqC;AACjE,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM;AAC1B,MAAA,IAAI,MAAA,CAAO,UAAA,EAAY,MAAA,IAAU,CAAC,MAAA,CAAO,WAAW,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA,EAAG,OAAO,KAAA;AAC7E,MAAA,IAAI,MAAA,CAAO,SAAA,EAAW,MAAA,IAAU,CAAA,CAAE,SAAS,UAAA,EAAY;AACrD,QAAA,MAAM,SAAA,GAAY,CAAA;AAClB,QAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,SAAS,SAAA,CAAU,IAAI,GAAG,OAAO,KAAA;AAAA,MACzD;AACA,MAAA,IAAI,OAAO,SAAA,EAAW;AACpB,QAAA,MAAM,KAAK,IAAI,IAAA,CAAK,CAAA,CAAE,EAAE,EAAE,OAAA,EAAQ;AAClC,QAAA,MAAM,QAAQ,IAAI,IAAA,CAAK,OAAO,SAAA,CAAU,KAAK,EAAE,OAAA,EAAQ;AACvD,QAAA,MAAM,MAAM,IAAI,IAAA,CAAK,OAAO,SAAA,CAAU,GAAG,EAAE,OAAA,EAAQ;AACnD,QAAA,IAAI,EAAA,GAAK,KAAA,IAAS,EAAA,GAAK,GAAA,EAAK,OAAO,KAAA;AAAA,MACrC;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,aAAa,MAAA,EAAgC;AACnD,IAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,CAAA;AAC9B,IAAA,MAAM,UAAA,GAAa,OAAO,CAAC,CAAA;AAC3B,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AAE1C,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,SAAA,EAAW,OAAO,CAAA;AACtC,IAAA,MAAM,QAAQ,IAAI,IAAA,CAAK,UAAA,CAAW,EAAE,EAAE,OAAA,EAAQ;AAC9C,IAAA,MAAM,OAAO,IAAI,IAAA,CAAK,SAAA,CAAU,EAAE,EAAE,OAAA,EAAQ;AAC5C,IAAA,OAAO,IAAA,GAAO,KAAA;AAAA,EAChB;AACF;ACxDA,IAAM,aAAA,GAAgB,uBAAA;AACtB,IAAM,qBAAA,GAAwB,GAAA;AAC9B,IAAM,gBAAA,GAAmB,GAAA;AAGzB,IAAM,gBAAA,GAAmB,IAAA;AAGzB,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,YAAA,GAAe,GAAA;AACrB,IAAM,mBAAA,GAAsB,EAAA;AAI5B,SAAS,SAAS,GAAA,EAAsB;AACtC,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAC,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAIO,IAAM,kBAAN,MAAsB;AAAA,EACV,QAAA;AAAA,EACT,cAAA,GAAwD,IAAA;AAAA,EACxD,gBAAA,GAAkC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlC,SAAA,GAAyC,IAAA;AAAA,EAEjD,YAAY,UAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,QAAA,GAAgBC,KAAA,CAAA,IAAA,CAAK,UAAA,EAAY,aAAa,CAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SACJ,KAAA,EAGe;AAOf,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AACjC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AACA,IAAA,IAAA,CAAK,mBAAmB,KAAA,CAAM,SAAA;AAC9B,IAAA,MAAM,IAAA,GAA6B;AAAA,MACjC,GAAG,KAAA;AAAA,MACH,MAAA,EAAQ,QAAA;AAAA,MACR,eAAA,EAAA,iBAAiB,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MACxC,UAAA,EAAY,KAAA,CAAM,MAAA,EAAQ,MAAA,IAAU,CAAA;AAAA,MACpC,MAAA,EAAQ,KAAA,CAAM,MAAA,IAAU;AAAC,KAC3B;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,QAAA,KAAa;AAGpC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,QAAQ,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACrD,QAAA,IAAI,QAAA,CAAS,GAAA,KAAQ,KAAA,CAAM,GAAA,EAAK;AAK9B,UAAA,IAAI,EAAA,KAAO,KAAA,CAAM,SAAA,EAAW,OAAO,SAAS,EAAE,CAAA;AAC9C,UAAA;AAAA,QACF;AACA,QAAA,MAAM,eAAe,GAAA,GAAM,IAAI,KAAK,QAAA,CAAS,eAAe,EAAE,OAAA,EAAQ;AACtE,QAAA,IAAI,eAAe,gBAAA,IAAoB,CAAC,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC9D,UAAA,OAAO,SAAS,EAAE,CAAA;AAAA,QACpB;AAAA,MACF;AACA,MAAA,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,GAAI,IAAA;AAAA,IAC9B,CAAC,CAAA;AAGD,IAAA,IAAA,CAAK,cAAA,GAAiB,YAAY,MAAM;AACtC,MAAA,KAAK,KAAK,SAAA,EAAU;AAAA,IACtB,GAAG,qBAAqB,CAAA;AACxB,IAAA,IAAI,IAAA,CAAK,cAAA,CAAe,KAAA,EAAO,IAAA,CAAK,eAAe,KAAA,EAAM;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,MAAA,EAAqC;AACtD,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAE5B,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,MAAA,KAAW,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW,WAAW,CAAA;AACxF,IAAA,MAAM,aAAa,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,cAAc,CAAA;AACjE,IAAA,MAAM,WAAW,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AACxD,IAAA,MAAM,MAAA,GAA4B,UAAA,IAAc,UAAA,IAAc,QAAA,GAAW,QAAA,GAAW,MAAA;AACpF,IAAA,MAAM,MAAA,GAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAGtC,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,IAAA,CAAK,UAAU,MAAA,GAAS,MAAA;AACxB,MAAA,IAAA,CAAK,SAAA,CAAU,aAAa,MAAA,CAAO,MAAA;AACnC,MAAA,IAAA,CAAK,UAAU,MAAA,GAAS,MAAA;AACxB,MAAA,IAAA,CAAK,UAAU,eAAA,GAAkB,MAAA;AAAA,IACnC;AAEA,IAAA,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,QAAA,KAAa;AACpC,MAAA,IAAI,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,gBAAiB,CAAA;AAC3C,MAAA,IAAI,CAAC,KAAA,EAAO;AAEV,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,QAAA,KAAA,GAAQ,EAAE,GAAG,IAAA,CAAK,SAAA,EAAU;AAC5B,QAAA,QAAA,CAAS,IAAA,CAAK,gBAAiB,CAAA,GAAI,KAAA;AAAA,MACrC;AACA,MAAA,KAAA,CAAM,MAAA,GAAS,MAAA;AACf,MAAA,KAAA,CAAM,aAAa,MAAA,CAAO,MAAA;AAC1B,MAAA,KAAA,CAAM,MAAA,GAAS,MAAA;AACf,MAAA,KAAA,CAAM,eAAA,GAAkB,MAAA;AAAA,IAC1B,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAA,GAA6B;AACjC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AACjC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AACA,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,QAAA,KAAa;AACpC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,gBAAiB,CAAA;AAC7C,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,KAAA,CAAM,MAAA,GAAS,SAAA;AACf,MAAA,KAAA,CAAM,eAAA,GAAA,iBAAkB,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IACjD,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AACjC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AACA,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,MAAM,MAAM,IAAA,CAAK,gBAAA;AACjB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,QAAA,KAAa;AACpC,MAAA,OAAO,SAAS,GAAG,CAAA;AAAA,IACrB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,GAAwC;AAC5C,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,YAAA,EAAa;AACzC,IAAA,OAAO,MAAA,CAAO,OAAO,QAAQ,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,SAAA,EAA8D;AACtE,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,YAAA,EAAa;AACzC,IAAA,OAAO,SAAS,SAAS,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAcC,YAAAA,EAAsD;AACxE,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,EAAK;AAC5B,IAAA,OAAO,IAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgBA,YAAW,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA,EAIA,MAAc,SAAA,GAA2B;AACvC,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,YAAY,IAAA,CAAK,gBAAA;AACvB,MAAA,MAAM,MAAA,GAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACtC,MAAA,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,QAAA,KAAa;AACpC,QAAA,MAAM,KAAA,GAAQ,SAAS,SAAS,CAAA;AAChC,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,KAAA,CAAM,eAAA,GAAkB,MAAA;AAExB,UAAA,IAAI,KAAA,CAAM,WAAW,SAAA,EAAW;AAC9B,YAAA,MAAM,UAAA,GAAA,CAAc,KAAA,CAAM,MAAA,IAAU,EAAC,EAAG,IAAA;AAAA,cACtC,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAA,IAAa,EAAE,MAAA,KAAW;AAAA,aAChD;AACA,YAAA,KAAA,CAAM,MAAA,GAAS,aAAa,QAAA,GAAW,MAAA;AAAA,UACzC;AACA,UAAA;AAAA,QACF;AACA,QAAA,IAAI,KAAK,SAAA,EAAW;AAIlB,UAAA,QAAA,CAAS,SAAS,CAAA,GAAI,EAAE,GAAG,IAAA,CAAK,SAAA,EAAW,iBAAiB,MAAA,EAAO;AAAA,QACrE;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,YAAA,GAA8D;AAC1E,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASC,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,UAAU,MAAM,CAAA;AACnD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC/B,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,IAAI,MAAA,GAAS,KAAA;AAEb,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAClD,QAAA,MAAM,eAAe,GAAA,GAAM,IAAI,KAAK,KAAA,CAAM,eAAe,EAAE,OAAA,EAAQ;AAGnE,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,SAAA,IAAa,YAAA,GAAe,gBAAA,EAAkB;AACjE,UAAA,OAAO,SAAS,EAAE,CAAA;AAClB,UAAA,MAAA,GAAS,IAAA;AACT,UAAA;AAAA,QACF;AACA,QAAA,IAAI,eAAe,gBAAA,IAAoB,CAAC,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA,EAAG;AAC3D,UAAA,KAAA,CAAM,MAAA,GAAS,OAAA;AAEf,UAAA,MAAM,aAAa,GAAA,GAAM,IAAI,KAAK,KAAA,CAAM,SAAS,EAAE,OAAA,EAAQ;AAC3D,UAAA,IAAI,UAAA,GAAa,IAAI,GAAA,EAAQ;AAC3B,YAAA,OAAO,SAAS,EAAE,CAAA;AAClB,YAAA,MAAA,GAAS,IAAA;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,KAAK,WAAA,CAAY,QAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,MACxD;AAEA,MAAA,OAAO,QAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAc,aACZ,EAAA,EACe;AACf,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,KAAA,CAAA;AACjC,IAAA,MAAM,UAAA,GAAa,CAAA;AACnB,IAAA,MAAM,YAAA,GAAe,EAAA;AAErB,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,GAAU,UAAA,EAAY,OAAA,EAAA,EAAW;AACrD,MAAA,IAAI;AAEF,QAAA,MAASA,GAAA,CAAA,KAAA,CAAWF,cAAQ,IAAA,CAAK,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAG/D,QAAA,IAAI,UAAA,GAAa,MAASE,GAAA,CAAA,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAC/D,QAAA,IAAI,CAAC,UAAA,EAAY;AAMf,UAAA,IAAI,MAAM,IAAA,CAAK,cAAA,CAAe,QAAQ,CAAA,EAAG;AACvC,YAAA,UAAA,GAAa,MAASA,GAAA,CAAA,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAAA,UAC7D;AACA,UAAA,IAAI,CAAC,UAAA,EAAY;AACf,YAAA,MAAM,IAAI,QAAQ,CAAC,CAAA,KAAM,WAAW,CAAA,EAAG,YAAA,IAAgB,OAAA,GAAU,CAAA,CAAE,CAAC,CAAA;AACpE,YAAA;AAAA,UACF;AAAA,QACF;AAEA,QAAA,IAAI;AAEF,UAAA,MAAM,UAAA,CAAW,UAAU,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AACrE,UAAA,MAAM,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,UAAU,MAAM,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AACrE,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC/B,UAAA,EAAA,CAAG,QAAQ,CAAA;AACX,UAAA,MAAM,IAAA,CAAK,kBAAkB,QAAQ,CAAA;AACrC,UAAA;AAAA,QACF,CAAA,SAAE;AACA,UAAA,MAAM,WAAW,KAAA,EAAM;AACvB,UAAA,MAASA,GAAA,CAAA,MAAA,CAAO,QAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,QACjD;AAAA,MACF,CAAA,CAAA,MAAQ;AAEN,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,eAAe,QAAA,EAAoC;AAC/D,IAAA,IAAI;AACF,MAAA,MAAM,CAAClC,KAAAA,EAAM,OAAO,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,QACrCkC,SAAK,QAAQ,CAAA;AAAA,QACbA,aAAS,QAAA,EAAU,MAAM,CAAA,CAAE,KAAA,CAAM,MAAM,EAAE;AAAA,OAC7C,CAAA;AACD,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,EAAI,GAAIlC,KAAAA,CAAK,OAAA;AAChC,MAAA,MAAM,WAAW,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,IAAA,IAAQ,EAAE,CAAA;AACnD,MAAA,MAAM,SAAA,GACJ,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA,IAAK,QAAA,GAAW,CAAA,IAAK,QAAA,KAAa,OAAA,CAAQ,GAAA,IAAO,CAAC,QAAA,CAAS,QAAQ,CAAA;AAC9F,MAAA,IAAI,SAAA,IAAa,QAAQ,aAAA,EAAe;AACtC,QAAA,MAASkC,GAAA,CAAA,MAAA,CAAO,QAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAC/C,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,KAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,kBAAkB,QAAA,EAA+D;AAC7F,IAAA,MAAM,KAAK,mBAAA,EAAoB;AAC/B,IAAA,MAAM,IAAA,CAAK,gBAAgB,QAAQ,CAAA;AAAA,EACrC;AAAA;AAAA,EAGA,MAAc,YAAY,QAAA,EAA+D;AACvF,IAAA,MAAM,KAAK,mBAAA,EAAoB;AAC/B,IAAA,MAAM,IAAA,CAAK,gBAAgB,QAAQ,CAAA;AAAA,EACrC;AAAA,EAEA,MAAc,gBAAgB,QAAA,EAA+D;AAC3F,IAAA,MAAM,GAAA,GAAWF,KAAA,CAAA,IAAA;AAAA,MACVA,KAAA,CAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,MAC1B,CAAA,CAAA,EAASA,KAAA,CAAA,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAA,EAAIX,UAAAA,EAAW,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,IAAA;AAAA,KAC9D;AACA,IAAA,IAAI;AACF,MAAA,MAASa,GAAA,CAAA,SAAA,CAAU,KAAK,IAAA,CAAK,SAAA,CAAU,UAAU,IAAA,EAAM,CAAC,GAAG,MAAM,CAAA;AACjE,MAAA,MAASA,GAAA,CAAA,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,QAAQ,CAAA;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,MAASA,GAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAC1C,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,mBAAA,GAAqC;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAWF,KAAA,CAAA,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA;AACtC,MAAA,MAAM,IAAA,GAAYA,KAAA,CAAA,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AACxC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,QAAkD,EAAC;AAEzD,MAAA,KAAA,MAAW,IAAA,IAAQ,MAASE,GAAA,CAAA,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,QAAA,MAAM,MAAA,GAAA,CACH,IAAA,CAAK,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,IAAI,IAAI,CAAA,CAAA,CAAG,CAAA,KAAM,IAAA,CAAK,SAAS,MAAM,CAAA;AACvF,QAAA,IAAI,CAAC,MAAA,EAAQ;AACb,QAAA,MAAMlC,KAAAA,GAAO,MAASkC,GAAA,CAAA,IAAA,CAAUF,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,IAAI,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AACjE,QAAA,IAAI,CAAChC,KAAAA,EAAM;AACX,QAAA,IAAI,GAAA,GAAMA,KAAAA,CAAK,OAAA,GAAU,YAAA,EAAc,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAASA,KAAAA,CAAK,OAAA,EAAS,CAAA;AAAA,MACnF;AAEA,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,OAAA,GAAU,EAAE,OAAO,CAAA;AAC1C,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,KAAA,CAAM,MAAM,mBAAmB,CAAA,CAAE,IAAI,OAAO,EAAE,MAAK,KAAM;AACvD,UAAA,MAASkC,GAAA,CAAA,MAAA,CAAYF,WAAK,GAAA,EAAK,IAAI,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,QAC7D,CAAC;AAAA,OACH;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAGA,IAAI,SAAA,GAAoC,IAAA;AAEjC,SAAS,mBAAmB,UAAA,EAAsC;AACvE,EAAA,IAAI,CAAC,aAAa,UAAA,EAAY;AAC5B,IAAA,SAAA,GAAY,IAAI,gBAAgB,UAAU,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,6EAA6E,CAAA;AAAA,EAC/F;AACA,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,kBAAA,GAA8B;AAC5C,EAAA,OAAO,SAAA,KAAc,IAAA;AACvB;;;ACteA,IAAM,aAAA,GAAgB,GAAA;AAEtB,IAAM,uBAAA,GAA0B,GAAA;AAEhC,IAAM,gBAAA,GAAmB,IAAA;AAEzB,IAAM,yBAAA,GAA4B,GAAA;AAe3B,IAAM,qBAAN,MAAyB;AAAA,EACb,MAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA;AAAA,EAGT,MAAA,uBAAa,GAAA,EAAwB;AAAA;AAAA,EAGrC,YAAA,GAAgC,MAAA;AAAA,EAChC,iBAAA;AAAA,EACA,gBAAA,GAAmB,CAAA;AAAA,EACnB,eAAA,GAAkB,CAAA;AAAA,EAClB,aAAA,GAAgB,CAAA;AAAA,EAChB,cAAA,GAAiB,CAAA;AAAA,EACjB,eAAA,GAAkB,CAAA;AAAA,EAClB,YAAA;AAAA,EACA,WAAA;AAAA,EACA,iBAAA,GAAoB,EAAA;AAAA,EAEpB,gBAAmC,EAAC;AAAA,EAC3B,QAAA;AAAA,EACT,UAAA,GAAoD,IAAA;AAAA,EACpD,YAAA,GAAqD,IAAA;AAAA,EAE7D,YAAY,IAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,QAAA;AACrC,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AAAA,EACvB;AAAA,EAEA,KAAA,GAAc;AAEZ,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,mBAAA,EAAqB,MAAM;AAC/C,QAAA,IAAA,CAAK,YAAA,GAAe,SAAA;AACpB,QAAA,IAAA,CAAK,gBAAA,EAAA;AACL,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAGA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,mBAAA,EAAqB,CAAC,IAAI,OAAA,KAAY;AAC1D,QAAA,MAAM,MAAO,OAAA,EAAgG,GAAA;AAC7G,QAAA,IAAI,CAAC,GAAA,EAAK;AACV,QAAA,IAAI,GAAA,CAAI,KAAA,EAAO,IAAA,CAAK,WAAA,GAAc,GAAA,CAAI,KAAA;AACtC,QAAA,IAAI,OAAO,GAAA,CAAI,UAAA,KAAe,QAAA,IAAY,OAAO,IAAI,UAAA,KAAe,QAAA,IAAY,GAAA,CAAI,UAAA,GAAa,CAAA,EAAG;AAClG,UAAA,IAAA,CAAK,eAAe,IAAA,CAAK,KAAA,CAAO,IAAI,UAAA,GAAa,GAAA,CAAI,aAAc,GAAG,CAAA;AAAA,QACxE;AACA,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,qBAAA,EAAuB,MAAM;AACjD,QAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AACpB,QAAA,IAAA,CAAK,iBAAA,GAAoB,MAAA;AACzB,QAAA,IAAA,CAAK,iBAAA,GAAoB,EAAA;AACzB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,iBAAA,EAAmB,MAAM;AAC7C,QAAA,IAAA,CAAK,YAAA,GAAe,OAAA;AACpB,QAAA,IAAA,CAAK,iBAAA,GAAoB,MAAA;AACzB,QAAA,IAAA,CAAK,iBAAA,GAAoB,EAAA;AACzB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAGA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,cAAA,EAAgB,CAAC,QAAQ,OAAA,KAAY;AACzD,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,GAAG,IAAA,EAAM;AACX,UAAA,IAAA,CAAK,oBAAoB,CAAA,CAAE,IAAA;AAC3B,UAAA,IAAA,CAAK,eAAA,EAAA;AAAA,QACP;AACA,QAAA,IAAA,CAAK,YAAA,GAAe,SAAA;AACpB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,eAAA,EAAiB,MAAM;AAC3C,QAAA,IAAA,CAAK,iBAAA,GAAoB,MAAA;AACzB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAGA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,iBAAA,EAAmB,MAAM;AAC7C,QAAA,IAAA,CAAK,YAAA,GAAe,cAAA;AACpB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAGA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,oBAAA,EAAsB,MAAM;AAChD,QAAA,IAAA,CAAK,YAAA,GAAe,WAAA;AAEpB,QAAA,IAAA,CAAK,iBAAA,GAAoB,EAAA;AACzB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAKA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,qBAAA,EAAuB,CAAC,IAAI,OAAA,KAAY;AAC5D,QAAA,MAAM,OAAQ,OAAA,EAA2C,IAAA;AACzD,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,IAAA,CAAK,YAAA,GAAe,WAAA;AACpB,QAAA,MAAM,IAAA,GAAO,KAAK,iBAAA,GAAoB,IAAA;AACtC,QAAA,IAAA,CAAK,iBAAA,GACH,KAAK,MAAA,GAAS,gBAAA,GAAmB,KAAK,KAAA,CAAM,IAAA,CAAK,MAAA,GAAS,gBAAgB,CAAA,GAAI,IAAA;AAChF,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,MAC5B,CAAC;AAAA,KACH;AAGA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,iBAAA,EAAmB,CAAC,IAAI,OAAA,KAAY;AACxD,QAAA,MAAM,CAAA,GAAI,OAAA;AAGV,QAAA,IAAI,CAAC,CAAA,EAAG;AACR,QAAA,IAAA,CAAK,cAAA,IAAkB,CAAA,CAAE,KAAA,EAAO,KAAA,IAAS,CAAA;AACzC,QAAA,IAAA,CAAK,eAAA,IAAmB,CAAA,CAAE,KAAA,EAAO,MAAA,IAAU,CAAA;AAC3C,QAAA,IAAA,CAAK,aAAA,IAAiB,CAAA,CAAE,IAAA,EAAM,KAAA,IAAS,CAAA;AACvC,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAOA,IAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAA2B;AACxC,MAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAC9B,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,KAAA,GAAQ,EAAE,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,QAAQ,MAAA,EAAQ,UAAA,EAAY,CAAA,EAAG,SAAA,EAAW,GAAG,cAAA,EAAA,iBAAgB,IAAI,IAAA,EAAK,EAAE,aAAY,EAAE;AAC9G,QAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAAA,MAC3B;AACA,MAAA,KAAA,CAAM,cAAA,GAAA,iBAAiB,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAC9C,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,kBAAA,EAAoB,CAAC,IAAI,OAAA,KAAY;AACzD,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAA,CAAE,UAAU,CAAA;AAChC,QAAA,KAAA,CAAM,IAAA,GAAO,CAAA,CAAE,IAAA,EAAM,IAAA,MAAU,KAAA,CAAM,IAAA;AACrC,QAAA,IAAI,CAAA,CAAE,KAAA,EAAO,KAAA,CAAM,KAAA,GAAQ,CAAA,CAAE,KAAA;AAC7B,QAAA,KAAA,CAAM,MAAA,GAAS,SAAA;AACf,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,kBAAA,EAAoB,CAAC,IAAI,OAAA,KAAY;AACzD,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAA,CAAE,UAAU,CAAA;AAChC,QAAA,IAAI,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,EAAU,KAAA,CAAM,SAAS,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAA,GAAO,GAAG,CAAA;AACtE,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,uBAAA,EAAyB,CAAC,IAAI,OAAA,KAAY;AAC9D,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAA,CAAE,UAAU,CAAA;AAChC,QAAA,KAAA,CAAM,MAAA,GAAS,SAAA;AACf,QAAA,KAAA,CAAM,UAAA,EAAA;AACN,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,wBAAA,EAA0B,CAAC,IAAI,OAAA,KAAY;AAC/D,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAA,CAAE,UAAU,CAAA;AAChC,QAAA,KAAA,CAAM,MAAA,GAAS,SAAA;AACf,QAAA,KAAA,CAAM,cAAc,CAAA,CAAE,IAAA;AACtB,QAAA,KAAA,CAAM,SAAA,EAAA;AACN,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,4BAAA,EAA8B,CAAC,IAAI,OAAA,KAAY;AACnE,QAAA,MAAM,CAAA,GAAI,OAAA;AAUV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAA,CAAE,UAAU,CAAA;AAChC,QAAA,KAAA,CAAM,MAAA,GAAS,SAAA;AACf,QAAA,IAAI,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,EAAU,KAAA,CAAM,aAAa,CAAA,CAAE,SAAA;AAC1D,QAAA,IAAI,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,EAAU,KAAA,CAAM,YAAY,CAAA,CAAE,SAAA;AACzD,QAAA,IAAI,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,EAAU,KAAA,CAAM,UAAU,CAAA,CAAE,OAAA;AACrD,QAAA,IAAI,CAAA,CAAE,WAAA,EAAa,KAAA,CAAM,WAAA,GAAc,CAAA,CAAE,WAAA;AAGzC,QAAA,IAAI,OAAO,CAAA,CAAE,WAAA,KAAgB,QAAA,EAAU;AACrC,UAAA,KAAA,CAAM,WAAA,GACJ,CAAA,CAAE,WAAA,CAAY,MAAA,GAAS,gBAAA,GACnB,CAAA,CAAE,WAAA,CAAY,KAAA,CAAM,CAAA,CAAE,WAAA,CAAY,MAAA,GAAS,gBAAgB,IAC3D,CAAA,CAAE,WAAA;AAAA,QACV;AACA,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,yBAAA,EAA2B,CAAC,IAAI,OAAA,KAAY;AAChE,QAAA,MAAM,CAAA,GAAI,OAAA;AAGV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AAGpB,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,EAAE,UAAU,CAAA;AAC1C,QAAA,IAAI,CAAC,KAAA,EAAO;AACZ,QAAA,KAAA,CAAM,SAAS,CAAA,CAAE,MAAA,KAAW,YAAY,CAAA,CAAE,MAAA,KAAW,YAAY,OAAA,GAAU,MAAA;AAC3E,QAAA,KAAA,CAAM,WAAA,GAAc,MAAA;AACpB,QAAA,KAAA,CAAM,WAAA,GAAc,MAAA;AACpB,QAAA,IAAI,OAAO,CAAA,CAAE,UAAA,KAAe,QAAA,EAAU,KAAA,CAAM,aAAa,CAAA,CAAE,UAAA;AAC3D,QAAA,IAAI,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,EAAU,KAAA,CAAM,YAAY,CAAA,CAAE,SAAA;AACzD,QAAA,KAAA,CAAM,cAAA,GAAA,iBAAiB,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAC9C,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAC;AAAA,KACH;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,IAAA;AAAA,MACjB,KAAK,MAAA,CAAO,SAAA,CAAU,kBAAA,EAAoB,CAAC,IAAI,OAAA,KAAY;AACzD,QAAA,MAAM,CAAA,GAAI,OAAA;AACV,QAAA,IAAI,CAAC,GAAG,UAAA,EAAY;AACpB,QAAA,IAAI,KAAK,MAAA,CAAO,MAAA,CAAO,EAAE,UAAU,CAAA,OAAQ,KAAA,EAAM;AAAA,MACnD,CAAC;AAAA,KACH;AAKA,IAAA,IAAA,CAAK,aAAa,WAAA,CAAY,MAAM,IAAA,CAAK,KAAA,IAAS,uBAAuB,CAAA;AACzE,IAAA,IAAI,OAAO,IAAA,CAAK,UAAA,CAAW,UAAU,UAAA,EAAY,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,EACzE;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,aAAA,EAAe;AACtC,MAAA,IAAI;AAAE,QAAA,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAe;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,gBAAgB,EAAC;AACtB,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,YAAA,CAAa,KAAK,YAAY,CAAA;AAC9B,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAA,GAA6B;AACnC,IAAA,IAAI,KAAK,YAAA,EAAc;AACvB,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,MAAM;AACnC,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb,GAAG,yBAAyB,CAAA;AAC5B,IAAA,IAAI,OAAO,IAAA,CAAK,YAAA,CAAa,UAAU,UAAA,EAAY,IAAA,CAAK,aAAa,KAAA,EAAM;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,KAAA,GAAc;AACpB,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,CAAC,CAAA,IAAK,KAAK,MAAA,EAAQ;AACjC,MAAA,MAAM,QAAA,GAAW,EAAE,MAAA,KAAW,SAAA,IAAa,EAAE,MAAA,KAAW,WAAA,IAAe,EAAE,MAAA,KAAW,cAAA;AACpF,MAAA,MAAM,GAAA,GAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,EAAE,cAAc,CAAA;AAC7C,MAAA,IAAI,YAAY,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,IAAK,MAAM,aAAA,EAAe;AAC3D,QAAA,IAAA,CAAK,MAAA,CAAO,OAAO,EAAE,CAAA;AACrB,QAAA,OAAA,GAAU,IAAA;AAAA,MACZ;AAAA,IACF;AACA,IAAA,IAAI,OAAA,OAAc,KAAA,EAAM;AAAA,EAC1B;AAAA,EAEQ,KAAA,GAAc;AACpB,IAAA,MAAM,WAAA,GAA0B;AAAA,MAC9B,EAAA,EAAI,QAAA;AAAA,MACJ,MAAM,IAAA,CAAK,UAAA;AAAA,MACX,QAAQ,IAAA,CAAK,YAAA;AAAA,MACb,aAAa,IAAA,CAAK,iBAAA;AAAA,MAClB,YAAY,IAAA,CAAK,gBAAA;AAAA,MACjB,WAAW,IAAA,CAAK,eAAA;AAAA,MAChB,SAAS,IAAA,CAAK,aAAA;AAAA,MACd,UAAU,IAAA,CAAK,cAAA;AAAA,MACf,WAAW,IAAA,CAAK,eAAA;AAAA,MAChB,QAAQ,IAAA,CAAK,YAAA;AAAA,MACb,OAAO,IAAA,CAAK,WAAA;AAAA,MACZ,WAAA,EAAa,KAAK,iBAAA,IAAqB,MAAA;AAAA,MACvC,cAAA,EAAA,iBAAgB,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACzC;AAEA,IAAA,MAAM,YAAY,CAAC,WAAA,EAAa,GAAG,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAGvD,IAAA,IAAA,CAAK,QAAA,CACF,YAAA,CAAa,SAAS,CAAA,CACtB,KAAK,MAAM;AACV,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,QAAA,IAAW;AAAA,MAClB,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,EAC1B;AACF;ACtWA,IAAM,cAAA,GAAiB,sBAAA;AACvB,IAAM,gBAAA,GAAmB,IAAA;AACzB,IAAM,WAAA,GAAc,EAAA;AACpB,IAAM,eAAA,GAAkB,GAAA;AASxB,SAASG,UAAS,GAAA,EAAsB;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA,IAAK,GAAA,IAAO,GAAG,OAAO,KAAA;AAC/C,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAC,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,OAAQ,IAA8B,IAAA,KAAS,OAAA;AAAA,EACjD;AACF;AAGA,SAAS,SAAS,IAAA,EAAsB;AACtC,EAAA,MAAM,QAAA,GAAgBC,cAAQ,IAAI,CAAA;AAClC,EAAA,OAAO,OAAA,CAAQ,QAAA,KAAa,OAAA,GAAU,QAAA,CAAS,aAAY,GAAI,QAAA;AACjE;AAaO,IAAM,gBAAN,MAAoB;AAAA,EACR,OAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EAET,KAAA,GAA+C,IAAA;AAAA,EAC/C,KAAA,GAA8C,IAAA;AAAA,EAC9C,QAAA,GAAW,KAAA;AAAA,EAEnB,YAAY,IAAA,EAA4B;AACtC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpB,IAAA,IAAA,CAAK,WAAA,GAAc,QAAA,CAAS,IAAA,CAAK,WAAW,CAAA;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,OAAA,CAAQ,GAAA;AACvC,IAAA,IAAA,CAAK,MAAA,GAAS,KAAK,IAAA,IAAQ,WAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,MAAA,GAAe;AACb,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,KAAA,EAAO;AACjC,IAAA,IAAA,CAAK,KAAA,GAAQ,WAAW,MAAM;AAC5B,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,KAAK,KAAK,KAAA,EAAM;AAAA,IAClB,GAAG,WAAW,CAAA;AACd,IAAA,IAAI,OAAO,IAAA,CAAK,KAAA,CAAM,UAAU,UAAA,EAAY,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,SAAA,GAA+B;AACnC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,IAAA,CAAK,SAAS,GAAA,GAAM,IAAA,CAAK,MAAM,EAAA,GAAK,gBAAA,EAAkB,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA;AAC5E,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,EAAS;AACjC,IAAA,IAAA,CAAK,KAAA,GAAQ,EAAE,EAAA,EAAI,GAAA,EAAK,IAAA,EAAK;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,KAAK,KAAK,CAAA;AACvB,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAc,KAAA,GAAuB;AACnC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,SAAA,EAAU;AAClC,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAC,CAAC,CAAA;AAAA,EAC1E;AAAA,EAEA,MAAc,QAAA,GAA8B;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASC,GAAA,CAAA,QAAA,CAAcD,KAAA,CAAA,IAAA,CAAK,KAAK,OAAA,EAAS,cAAc,GAAG,MAAM,CAAA;AAC7E,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,IAAA,EAAM,SAAS,CAAA,GAAI,IAAA,CAAK,YAAY,EAAC;AAChE,MAAA,OAAO,KACJ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,IAAK,OAAO,CAAA,CAAE,QAAA,KAAa,QAAQ,CAAA,CACjD,OAAO,CAAC,CAAA,KAAM,EAAE,GAAA,KAAQ,IAAA,CAAK,OAAO,CAAA,CACpC,MAAA,CAAO,CAAC,CAAA,KAAM,SAAS,CAAA,CAAE,WAAW,CAAA,KAAM,IAAA,CAAK,WAAW,CAAA,CAC1D,MAAA,CAAO,CAAC,CAAA,KAAMD,UAAS,CAAA,CAAE,GAAG,CAAC,CAAA,CAC7B,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,QAAA,MAAM,IAAA,GAAO,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,CAAA,CAAE,IAAA,KAAS,IAAA,IAAQ,CAAC,CAAA,CAAE,IAAA,GAAO,WAAA,GAAc,CAAA,CAAE,IAAA;AAClF,QAAA,OAAO,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,eAAA,CAAA;AAAA,MACrC,CAAC,CAAA;AAAA,IACL,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AACF;AAEA,eAAe,YAAY,GAAA,EAA4B;AACrD,EAAA,MAAM,MAAM,GAAA,EAAK;AAAA,IACf,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,eAAe;AAAA,GAC5C,CAAA;AACH;AC3HO,IAAM,yBAAN,MAAwD;AAAA,EAC7D,WAAA,CAA6B,aAAsC,WAAA,EAAqB;AAA3D,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAsC,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAAsB;AAAA,EAA5D,WAAA;AAAA,EAAsC,WAAA;AAAA,EAEnE,MAAM,gBAAgB,SAAA,EAA8C;AAClE,IAAA,MAAM,OAAYG,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAG9B,IAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoB;AAC7C,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,KAAA,CAAM,SAAS,eAAA,EAAiB;AAClC,QAAA,MAAM,CAAA,GAAI,KAAA;AACV,QAAA,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,WAAA,EAAA,CAAc,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,IAAK,CAAA,IAAK,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA;AAAA,MACzF;AAAA,IACF;AAEA,IAAA,MAAM,cAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,QAAA,MAAM,CAAA,GAAI,KAAA;AACV,QAAA,WAAA,CAAY,IAAA,CAAK;AAAA,UACf,aAAa,CAAA,CAAE,WAAA;AAAA,UACf,eAAe,CAAA,CAAE,aAAA;AAAA,UACjB,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,SAAA,EAAW,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,IAAK;AAAA,SAC/C,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,kBAAA,CACJ,SAAA,EACA,eAAA,EAC+B;AAC/B,IAAA,MAAM,OAAYD,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAE9B,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAA,CAAO,CAAC,CAAC,CAAA;AACrC,MAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,QAAA,MAAM,eAAA,GAAkB,KAAA;AACxB,QAAA,IAAI,eAAA,CAAgB,gBAAgB,eAAA,EAAiB;AACnD,UAAA,SAAA,GAAY,CAAA;AACZ,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,cAAc,EAAA,EAAI;AACpB,MAAA,MAAM,IAAI,YAAA,CAAa;AAAA,QACrB,OAAA,EAAS,cAAc,eAAe,CAAA,UAAA,CAAA;AAAA,QACtC,MAAM,WAAA,CAAY,iBAAA;AAAA,QAClB,OAAA,EAAS,EAAE,eAAA;AAAgB,OAC5B,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,oBAA2E,EAAC;AAClF,IAAA,KAAA,IAAS,IAAI,SAAA,GAAY,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAClD,MAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAA,CAAO,CAAC,CAAC,CAAA;AACrC,MAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,eAAA,EAAiB;AAClC,QAAA,MAAM,aAAA,GAAgB,KAAA;AACtB,QAAA,IAAI,aAAA,CAAc,eAAe,eAAA,EAAiB;AAChD,UAAA,iBAAA,CAAkB,IAAA,CAAK,EAAE,WAAA,EAAa,aAAA,CAAc,aAAa,KAAA,EAAO,aAAA,CAAc,OAAO,CAAA;AAAA,QAC/F;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,iBAAA,EAAmB,KAAK,WAAW,CAAA;AACxE,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,MAAA,GAAS,SAAA,GAAY,CAAA;AAClD,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,aAAA,EAAe,iBAAiB,aAAA,EAAc;AAAA,EACpE;AAAA,EAEA,MAAM,WAAA,CAAY,SAAA,EAAmB,CAAA,EAA0C;AAC7E,IAAA,MAAM,OAAYD,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAE9B,IAAA,MAAM,cAA0D,EAAC;AACjE,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,QAAA,WAAA,CAAY,IAAA,CAAK,EAAE,WAAA,EAAa,KAAA,CAAM,aAAa,EAAA,EAAI,KAAA,CAAM,IAAI,CAAA;AAAA,MACnE;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,MAAA,OAAO,EAAE,aAAA,EAAe,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAG,aAAA,EAAe,CAAA,EAAG,aAAA,EAAe,CAAA,EAAE;AAAA,IAC7E;AAEA,IAAA,WAAA,CAAY,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,WAAA,GAAc,EAAE,WAAW,CAAA;AACxD,IAAA,MAAM,WAAA,GAAc,WAAA,CAAY,CAAC,CAAA,EAAG,WAAA,IAAe,CAAA;AAEnD,IAAA,MAAM,oBAA2E,EAAC;AAClF,IAAA,IAAI,YAAA,GAAe,KAAA;AAEnB,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,YAAA,IAAgB,KAAA,CAAM,gBAAgB,WAAA,EAAa;AACpE,QAAA,YAAA,GAAe,IAAA;AACf,QAAA;AAAA,MACF;AACA,MAAA,IAAI,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,eAAA,EAAiB;AAClD,QAAA,iBAAA,CAAkB,IAAA,CAAK,EAAE,WAAA,EAAa,KAAA,CAAM,aAAa,KAAA,EAAO,KAAA,CAAM,OAAO,CAAA;AAAA,MAC/E;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,MAAM,eAAA,CAAgB,kBAAkB,OAAA,EAAQ,EAAG,KAAK,WAAW,CAAA;AAClF,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,eAAe,WAAA,EAAa,aAAA,EAAe,kBAAkB,MAAA,EAAO;AAAA,EAC1F;AAAA,EAEA,MAAM,cAAc,SAAA,EAAkD;AACpE,IAAA,MAAM,OAAYD,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAE9B,IAAA,MAAM,eAAsE,EAAC;AAC7E,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,IAAI,KAAA,CAAM,SAAS,eAAA,EAAiB;AAClC,QAAA,YAAA,CAAa,IAAA,CAAK,EAAE,WAAA,EAAa,KAAA,CAAM,aAAa,KAAA,EAAO,KAAA,CAAM,OAAO,CAAA;AAAA,MAC1E;AAAA,IACF;AAEA,IAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,MAAA,OAAO,EAAE,aAAA,EAAe,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAG,aAAA,EAAe,CAAA,EAAG,aAAA,EAAe,CAAA,EAAE;AAAA,IAC7E;AAEA,IAAA,MAAM,SAAS,MAAM,eAAA,CAAgB,aAAa,OAAA,EAAQ,EAAG,KAAK,WAAW,CAAA;AAC7E,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,eAAe,CAAA,EAAG,aAAA,EAAe,aAAa,MAAA,EAAO;AAAA,EAC3E;AACF;AAEA,SAAS,YAAY,GAAA,EAA6B;AAChD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA;AACpD,EAAA,MAAM,SAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,MAAA,IACE,MAAA,KAAW,IAAA,IACX,OAAO,MAAA,KAAW,QAAA,IAClB,OAAQ,MAAA,CAA0C,IAAA,KAAS,QAAA,IAC3D,OAAQ,MAAA,CAAwC,EAAA,KAAO,QAAA,EACvD;AACA,QAAA,MAAA,CAAO,KAAK,MAAsB,CAAA;AAAA,MACpC;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,eAAA,CACb,WACA,WAAA,EACuB;AACvB,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,SAAS,KAAA,EAAO;AACjC,MAAA,IAAI;AAKF,QAAA,MAAM,OAAA,GAAeD,KAAA,CAAA,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AACtC,QAAA,MAAM,IAAA,GAAYA,cAAQ,WAAW,CAAA;AACrC,QAAA,MAAM,GAAA,GAAWA,KAAA,CAAA,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AACvC,QAAA,IAAI,IAAI,UAAA,CAAW,IAAI,CAAA,IAAUA,KAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAG;AAChD,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,oDAAA,CAAiD,CAAA;AACzE,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,IAAA,CAAK,WAAW,SAAA,EAAW;AAE7B,UAAA,IAAI,IAAA,CAAK,WAAW,IAAA,EAAM;AAExB,YAAA,MAAM,WAAA,CAAY,KAAK,IAAA,EAAM,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAM,KAAO,CAAA;AACzD,YAAA,aAAA,CAAc,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,UAC9B;AAAA,QACF,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,KAAW,SAAA,EAAW;AAEpC,UAAA,MAAUC,GAAA,CAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAC1B,UAAA,aAAA,CAAc,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,QAC9B,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,KAAW,UAAA,EAAY;AAErC,UAAA,IAAI,IAAA,CAAK,WAAW,IAAA,EAAM;AAExB,YAAA,MAAM,WAAA,CAAY,KAAK,IAAA,EAAM,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAM,KAAO,CAAA;AACzD,YAAA,aAAA,CAAc,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,UAC9B;AAAA,QACF;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,MAAA,CAAO,IAAA,CAAK,GAAG,IAAA,CAAK,IAAI,KAAK,cAAA,CAAe,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,eAAe,MAAA,EAAO;AACjC;ACtMA,eAAsB,mBAAA,CACpB,QAAA,EACA,MAAA,EACA,OAAA,EAC4B;AAC5B,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAC3C,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,YAAY,CAAA,IAAK,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AACzD,MAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,QACtB,KAAA,EAAO,OAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,gBAAA;AAAA,QACP,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,OACxC,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAO,OAAO,KAAA,CAAM,MAAA;AAAA,MAClB,CAAC,MACC,CAAC,CAAC,KACF,OAAO,CAAA,CAAE,EAAA,KAAO,QAAA,IAChB,OAAO,CAAA,CAAE,YAAY,QAAA,IACrB,OAAO,EAAE,MAAA,KAAW,QAAA,KACnB,EAAE,UAAA,KAAe,KAAA,CAAA,IAAa,OAAO,CAAA,CAAE,UAAA,KAAe,QAAA;AAAA,KAC3D;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,KAAA,EAAO,cAAA;AAAA,MACP,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAsB,mBAAA,CACpB,QAAA,EACA,SAAA,EACA,KAAA,EACA,QACA,OAAA,EACe;AACf,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,MAAM,OAAA,GAA+B;AAAA,IACnC,OAAA,EAAS,CAAA;AAAA,IACT,SAAA;AAAA,IACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,KAAA,EAAO,CAAC,GAAG,KAAK;AAAA,GAClB;AACA,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,CAAY,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC7E,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,SAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,SAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,MAC1B,KAAA,EAAO,MAAA;AAAA,MACP,KAAA,EAAO,8BAAA;AAAA,MACP,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,MAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACnC,CAAC,CAAA;AAAA,EACJ;AACF;AAUO,SAAS,qBAAA,CACd,KAAA,EACA,QAAA,EACA,SAAA,EACA,QACA,OAAA,EACuB;AACvB,EAAA,IAAI,KAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,OAAA,GAAsC,IAAA;AAC1C,EAAA,IAAI,UAAA,GAA4B,QAAQ,OAAA,EAAQ;AAEhD,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAA+B;AACnD,IAAA,UAAA,GAAa,UAAA,CACV,IAAA,CAAK,MAAM,mBAAA,CAAoB,QAAA,EAAU,SAAA,EAAW,KAAA,EAAO,MAAA,EAAQ,OAAO,CAAC,CAAA,CAE3E,KAAA,CAAM,CAAC,GAAA,KAAQ;AAGd,MAAA,MAAM,GAAA,GAAM,eAAe,GAAG,CAAA;AAC9B,MAAA,OAAA,CAAQ,KAAA,CAAM,KAAK,SAAA,CAAU;AAAA,QAC3B,KAAA,EAAO,OAAA;AAAA,QACP,KAAA,EAAO,qCAAA;AAAA,QACP,SAAA;AAAA,QACA,OAAA,EAAS,GAAA;AAAA,QACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AAAA,IACJ,CAAC,CAAA;AAEH,IAAA,OAAO,UAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,KAAA,GAAQ,IAAA;AACR,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,KAAA,GAAQ,OAAA;AACd,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,OAAO,aAAa,KAAK,CAAA;AAAA,IAC3B;AAEA,IAAA,OAAO,UAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,QAAA,CAAS,CAAC,MAAA,KAAW;AAC7C,IAAA,IAAI,MAAA,CAAO,SAAS,gBAAA,EAAkB;AACtC,IAAA,OAAA,GAAU,MAAA,CAAO,KAAA;AACjB,IAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAC7B,IAAA,KAAA,GAAQ,WAAW,MAAM;AACvB,MAAA,KAAK,KAAA,EAAM;AAAA,IACb,GAAG,GAAG,CAAA;AAAA,EACR,CAAC,CAAA;AACD,EAAA,OAAO,YAAY;AACjB,IAAA,WAAA,EAAY;AACZ,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,YAAA,CAAa,KAAK,CAAA;AAGlB,MAAA,MAAM,KAAA,EAAM;AAAA,IACd,CAAA,MAAO;AACL,MAAA,MAAM,UAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;ACnLA,eAAsB,QAAA,CAAS,UAAkB,MAAA,EAA6C;AAC5F,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAC3C,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,YAAY,CAAA,IAAK,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AACzD,MAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAC3B,SAAA,EAAW,QAAA;AAAA,QACX,KAAA,EAAO,MAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,KAC1B,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,KAAA,EAAO;AAAA,KACR,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AASA,eAAsB,QAAA,CAAS,QAAA,EAAkB,IAAA,EAAgB,MAAA,EAAqC;AACpG,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,CAAY,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC1E,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,KAC1B,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,2BAAA;AAAA,MACA,eAAe,GAAG;AAAA,KACpB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAGO,SAAS,SAAA,CAAU,WAAmB,KAAA,EAA0B;AACrE,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,SAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,OAAO;AAAC,GACV;AACF;AAEO,SAAS,WAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,EACoC;AACpC,EAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,EAAA,MAAM,IAAA,GAAiB;AAAA,IACrB,EAAA,EAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAIpB,UAAAA,EAAW,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAAA,IAClD,KAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,GAAA;AAAA,IACX,SAAA,EAAW;AAAA,GACb;AACA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,CAAC,GAAG,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA,EAAG,SAAA,EAAW,GAAA,EAAI;AAAA,IAC9D;AAAA,GACF;AACF;AAEO,SAAS,cAAA,CAAe,MAAgB,SAAA,EAA6B;AAC1E,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AACtC,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,KAAA,EAAO,KAAK,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,MAAM,GAAG,CAAA;AAAA,IAC5C,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GACpC;AACF;AAEO,SAAS,iBAAA,CACd,IAAA,EACA,SAAA,EACA,MAAA,EACU;AACV,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AACtC,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,GAAA;AAAA,IAAI,CAAC,EAAA,EAAI,CAAA,KAChC,CAAA,KAAM,GAAA,GAAM,EAAE,GAAG,EAAA,EAAI,MAAA,EAAQ,SAAA,EAAW,GAAA,EAAI,GAAI;AAAA,GAClD;AACA,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,WAAW,GAAA,EAAI;AAC1C;AAEO,SAAS,UAAU,IAAA,EAA0B;AAClD,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,EAAC,EAAG,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAE;AACnE;AAGO,SAAS,WAAW,IAAA,EAAwB;AACjD,EAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,gBAAA;AACpC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,KAAK,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,IAAA,CAAK,KAAK,CAAA,CAAE,CAAA;AAC5C,EAAA,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,EAAA,EAAI,CAAA,KAAM;AAC5B,IAAA,MAAM,IAAA,GAAO,GAAG,MAAA,KAAW,MAAA,GAAS,QAAQ,EAAA,CAAG,MAAA,KAAW,gBAAgB,KAAA,GAAQ,KAAA;AAClF,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,GAAI,CAAC,KAAK,IAAI,CAAA,CAAA,EAAI,EAAA,CAAG,KAAK,CAAA,CAAE,CAAA;AAC1C,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,KAAA,MAAW,IAAA,IAAQ,EAAA,CAAG,OAAA,CAAQ,KAAA,CAAM,IAAI,GAAG,KAAA,CAAM,IAAA,CAAK,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,IACtE;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,SAAS,UAAA,CAAW,MAAgB,SAAA,EAA2B;AAC7D,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AAC3C,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA,IAAK,KAAA,IAAS,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ,OAAO,KAAA,GAAQ,CAAA;AACrF,EAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,SAAA,CAAU,CAAC,EAAA,KAAO,EAAA,CAAG,OAAO,SAAS,CAAA;AAC7D,EAAA,IAAI,IAAA,KAAS,IAAI,OAAO,IAAA;AACxB,EAAA,MAAM,KAAA,GAAQ,UAAU,WAAA,EAAY;AACpC,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,CAAC,EAAA,KAAO,EAAA,CAAG,KAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA;AAC5E;AASO,SAAS,uBAAA,CACd,IAAA,EACA,SAAA,EACA,QAAA,EACmM;AACnM,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AACtC,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,IAAA;AAEvB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAE3B,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAGlB,EAAA,IAAI,WAAA,GAAc,IAAA;AAClB,EAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,IAAA,WAAA,GAAc,iBAAA,CAAkB,IAAA,EAAM,SAAA,EAAW,aAAa,CAAA;AAAA,EAChE;AAEA,EAAA,MAAM,QAAyK,EAAC;AAGhL,EAAA,KAAA,CAAM,IAAA,CAAK;AAAA,IACT,EAAA,EAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,CAAA,KAAA,CAAA;AAAA,IACtB,SAAS,IAAA,CAAK,KAAA;AAAA,IACd,MAAA,EAAQ,aAAA;AAAA,IACR,YAAY,IAAA,CAAK,KAAA;AAAA,IACjB,kBAAkB,IAAA,CAAK;AAAA,GACxB,CAAA;AAGD,EAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACnC,IAAA,KAAA,MAAW,MAAM,QAAA,EAAU;AACzB,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,EAAA,EAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAIA,UAAAA,EAAW,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAAA,QAClD,OAAA,EAAS,EAAA;AAAA,QACT,MAAA,EAAQ,SAAA;AAAA,QACR,kBAAkB,IAAA,CAAK;AAAA,OACxB,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAM;AACpC;AAMA,eAAsB,UAAA,CACpB,QAAA,EACA,SAAA,EACA,EAAA,EACmB;AACnB,EAAA,OAAO,YAAA,CAAa,UAAU,YAAY;AACxC,IAAA,MAAM,OAAQ,MAAM,QAAA,CAAS,QAAQ,CAAA,IAAM,UAAU,SAAS,CAAA;AAC9D,IAAA,MAAM,OAAA,GAAU,MAAM,EAAA,CAAG,IAAI,CAAA;AAC7B,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAClD,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAQ,CAAA,iCAAA,CAA8B,CAAA;AAAA,IACrF;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAC,CAAA;AACH;AAQO,SAAS,oBAAA,CACd,MAAA,EACA,SAAA,EACA,UAAA,EACY;AACZ,EAAA,OAAO,MAAM,MAAA;AACf;;;AChRA,IAAM,SAAA,GAA0C;AAAA,EAC9C,aAAA,EAAe;AAAA,IACb,IAAA,EAAM,aAAA;AAAA,IACN,WAAA,EAAa,4CAAA;AAAA,IACb,QAAA,EAAU,aAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,kCAAA,EAAoC,OAAA,EAAS,+CAAA,EAAgD;AAAA,MACtG,EAAE,KAAA,EAAO,uBAAA,EAAyB,OAAA,EAAS,6BAAA,EAA8B;AAAA,MACzE,EAAE,KAAA,EAAO,sBAAA,EAAwB,OAAA,EAAS,wCAAA,EAAoC;AAAA,MAC9E,EAAE,KAAA,EAAO,gBAAA,EAAkB,OAAA,EAAS,8BAAA,EAA+B;AAAA,MACnE,EAAE,KAAA,EAAO,uBAAA,EAAyB,OAAA,EAAS,qCAAA,EAAsC;AAAA,MACjF,EAAE,KAAA,EAAO,sBAAA,EAAwB,OAAA,EAAS,6BAAA,EAA8B;AAAA,MACxE,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,sCAAA,EAAuC;AAAA,MACxE,EAAE,KAAA,EAAO,kBAAA,EAAoB,OAAA,EAAS,uBAAA;AAAwB;AAChE,GACF;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,QAAA,EAAU,aAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,2BAAA,EAA4B;AAAA,MACnE,EAAE,KAAA,EAAO,qBAAA,EAAuB,OAAA,EAAS,8BAAA,EAA+B;AAAA,MACxE,EAAE,KAAA,EAAO,oBAAA,EAAsB,OAAA,EAAS,2BAAA,EAA4B;AAAA,MACpE,EAAE,KAAA,EAAO,eAAA,EAAiB,OAAA,EAAS,0BAAA,EAA2B;AAAA,MAC9D,EAAE,KAAA,EAAO,YAAA,EAAc,OAAA,EAAS,2CAAA,EAA4C;AAAA,MAC5E,EAAE,KAAA,EAAO,iBAAA,EAAmB,OAAA,EAAS,gCAAA,EAAiC;AAAA,MACtE,EAAE,KAAA,EAAO,uBAAA,EAAyB,OAAA,EAAS,gCAAA;AAAiC;AAC9E,GACF;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,2BAAA;AAAA,IACb,QAAA,EAAU,aAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,6BAAA,EAA+B,OAAA,EAAS,kDAAA,EAAmD;AAAA,MACpG,EAAE,KAAA,EAAO,sBAAA,EAAwB,OAAA,EAAS,2CAAA,EAA4C;AAAA,MACtF,EAAE,KAAA,EAAO,8BAAA,EAAgC,OAAA,EAAS,wCAAA,EAAyC;AAAA,MAC3F,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,+BAAA,EAAgC;AAAA,MACvE,EAAE,KAAA,EAAO,qBAAA,EAAuB,OAAA,EAAS,qBAAA,EAAsB;AAAA,MAC/D,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,sBAAA,EAAuB;AAAA,MAC9D,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,oCAAA;AAAqC;AACxE,GACF;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,yBAAA;AAAA,IACb,QAAA,EAAU,SAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,cAAA,EAAgB,OAAA,EAAS,+BAAA,EAAgC;AAAA,MAClE,EAAE,KAAA,EAAO,kBAAA,EAAoB,OAAA,EAAS,gCAAA,EAAiC;AAAA,MACvE,EAAE,KAAA,EAAO,qBAAA,EAAuB,OAAA,EAAS,0BAAA,EAA2B;AAAA,MACpE,EAAE,KAAA,EAAO,iBAAA,EAAmB,OAAA,EAAS,kCAAA,EAAmC;AAAA,MACxE,EAAE,KAAA,EAAO,qBAAA,EAAuB,OAAA,EAAS,2BAAA,EAA4B;AAAA,MACrE,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,sBAAA,EAAuB;AAAA,MAC9D,EAAE,KAAA,EAAO,0BAAA,EAA4B,OAAA,EAAS,4BAAA,EAA6B;AAAA,MAC3E,EAAE,KAAA,EAAO,kBAAA,EAAoB,OAAA,EAAS,oCAAA;AAAqC;AAC7E,GACF;AAAA,EACA,gBAAA,EAAkB;AAAA,IAChB,IAAA,EAAM,gBAAA;AAAA,IACN,WAAA,EAAa,+BAAA;AAAA,IACb,QAAA,EAAU,gBAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,kBAAA,EAAoB,OAAA,EAAS,oCAAA,EAAqC;AAAA,MAC3E,EAAE,KAAA,EAAO,aAAA,EAAe,OAAA,EAAS,wCAAA,EAAyC;AAAA,MAC1E,EAAE,KAAA,EAAO,uBAAA,EAAyB,OAAA,EAAS,6BAAA,EAA8B;AAAA,MACzE,EAAE,KAAA,EAAO,wBAAA,EAA0B,OAAA,EAAS,oCAAA,EAAqC;AAAA,MACjF,EAAE,KAAA,EAAO,uBAAA,EAAyB,OAAA,EAAS,0CAAA,EAA2C;AAAA,MACtF,EAAE,KAAA,EAAO,wBAAA,EAA0B,OAAA,EAAS,2BAAA,EAA4B;AAAA,MACxE,EAAE,KAAA,EAAO,wBAAA,EAA0B,OAAA,EAAS,gCAAA;AAAiC;AAC/E,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,YAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,QAAA,EAAU,gBAAA;AAAA,IACV,KAAA,EAAO;AAAA,MACL,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,2BAAA,EAA4B;AAAA,MACnE,EAAE,KAAA,EAAO,yBAAA,EAA2B,OAAA,EAAS,iCAAA,EAAkC;AAAA,MAC/E,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,oBAAA,EAAqB;AAAA,MAC5D,EAAE,KAAA,EAAO,wBAAA,EAA0B,OAAA,EAAS,+BAAA,EAAgC;AAAA,MAC5E,EAAE,KAAA,EAAO,cAAA,EAAgB,OAAA,EAAS,+BAAA,EAAgC;AAAA,MAClE,EAAE,KAAA,EAAO,0BAAA,EAA4B,OAAA,EAAS,kCAAA,EAAmC;AAAA,MACjF,EAAE,KAAA,EAAO,mBAAA,EAAqB,OAAA,EAAS,qBAAA;AAAsB;AAC/D;AAEJ,CAAA;AAEO,SAAS,iBAAA,GAAoC;AAClD,EAAA,OAAO,MAAA,CAAO,OAAO,SAAS,CAAA;AAChC;AAEO,SAAS,gBAAgB,IAAA,EAAwC;AACtE,EAAA,OAAO,UAAU,IAAI,CAAA;AACvB;AAEO,SAAS,mBAAA,GAA8B;AAC5C,EAAA,MAAM,IAAA,uBAAW,GAAA,EAA8C;AAC/D,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,SAAS,CAAA,EAAG;AACxC,IAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,QAAQ,KAAK,EAAC;AACrC,IAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,IAAA,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,QAAA,EAAU,GAAG,CAAA;AAAA,EAC1B;AAEA,EAAA,MAAM,KAAA,GAAkB,CAAC,2BAA2B,CAAA;AACpD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,IAAA,EAAM;AAC/B,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,EAAK,GAAG,CAAA,CAAA,CAAG,CAAA;AACtB,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,MAAA,CAAO,EAAE,CAAC,CAAA,QAAA,EAAM,CAAA,CAAE,WAAW,CAAA,CAAE,CAAA;AAAA,IACxD;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AC9GO,SAAS,cAAc,SAAA,EAA6B;AACzD,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,SAAA;AAAA,IACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,OAAO;AAAC,GACV;AACF;AAGA,eAAsB,SAAA,CACpB,QAAA,EACA,MAAA,EACA,OAAA,EAC0B;AAC1B,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUqB,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAC3C,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,YAAY,CAAA,IAAK,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AACzD,MAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,QACtB,KAAA,EAAO,OAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO,gBAAA;AAAA,QACP,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,OACxC,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,KAAA,EAAO,cAAA;AAAA,MACP,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAYA,eAAsB,SAAA,CACpB,QAAA,EACA,KAAA,EACA,MAAA,EACA,OAAA,EACkB;AAClB,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI;AACF,IAAA,KAAA,CAAM,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACzC,IAAA,MAAM,WAAA,CAAY,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC3E,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,GAAI,OAAA,KAAY,KAAA,CAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,WAAW,OAAA,IAAW,QAAA;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa,KAAA;AAAA,MACb,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA;AAAQ,KACxC,CAAA;AACD,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,2BAAA;AAAA,MACA,eAAe,GAAG;AAAA,KACpB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAWA,eAAsB,WAAA,CACpB,QAAA,EACA,SAAA,EACA,EAAA,EACA,QACA,OAAA,EACmB;AACnB,EAAA,OAAO,YAAA,CAAa,UAAU,YAAY;AACxC,IAAA,MAAM,IAAA,GAAQ,MAAM,SAAA,CAAU,QAAA,EAAU,QAAQ,OAAO,CAAA,IAAM,cAAc,SAAS,CAAA;AACpF,IAAA,MAAM,OAAA,GAAU,MAAM,EAAA,CAAG,IAAI,CAAA;AAC7B,IAAA,MAAM,YAAY,MAAM,SAAA,CAAU,QAAA,EAAU,OAAA,EAAS,QAAQ,OAAO,CAAA;AACpE,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,QAAQ,CAAA,iCAAA,CAA8B,CAAA;AAAA,IACtF;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAC,CAAA;AACH;AClHA,eAAsB,kBAAkB,QAAA,EAAyD;AAC/F,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUC,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAC3C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,OAAA,KAAY,CAAA,EAAG,OAAO,IAAA;AAClC,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAkBA,eAAsB,wBAAA,CACpB,QAAA,EACA,SAAA,GAAY,OAAA,CAAQ,GAAA,EACF;AAClB,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAUA,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAChD,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,IAAI;AACF,MAAA,MAAMC,KAAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAEhC,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,IAAA,CAAKA,KAAAA,CAAK,GAAA,EAAK,CAAC,CAAA;AAGxB,QAAA,OAAO,KAAA;AAAA,MACT,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,MAAM,IAAA,GAA0B;AAAA,IAC9B,GAAA,EAAK,SAAA;AAAA,IACL,UAAUC,QAAAA,EAAS;AAAA,IACnB,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GACpC;AACA,EAAA,MAAM,WAAA,CAAY,UAAU,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AACjE,EAAA,OAAO,IAAA;AACT;AAMA,eAAsB,yBAAyB,QAAA,EAAiC;AAC9E,EAAA,IAAI;AACF,IAAA,MAAUF,WAAO,QAAQ,CAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAaO,IAAM,0BAAN,MAA8B;AAAA,EAC3B,QAAA;AAAA,EACS,QAAA;AAAA,EACA,QAAA;AAAA,EACT,KAAA,GAA+B,IAAA;AAAA,EACtB,UAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA,EACV,gBAAA,GAAmB,KAAA;AAAA,EAE3B,WAAA,CACE,QAAA,EACA,IAAA,EASA,UAAA,GAAa,GAAA,EACb;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAEhB,IAAA,IAAA,CAAK,QAAA,GAAW,GAAG,QAAQ,CAAA,KAAA,CAAA;AAC3B,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,OAAA,EAAS,CAAA;AAAA,MACT,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,UAAA,EAAY,CAAA;AAAA,MACZ,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,gBAAgB,IAAA,CAAK,cAAA;AAAA,MACrB,WAAW,EAAC;AAAA,MACZ,OAAO;AAAC,KACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAA,GAAgC;AACpC,IAAA,OAAO,wBAAA,CAAyB,KAAK,QAAQ,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAA,GAA6B;AACjC,IAAA,OAAO,wBAAA,CAAyB,KAAK,QAAQ,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAA,EAAuC;AAC5C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA,EAEA,OAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,WAAA,CAAY,KAA4B,UAAA,EAA0B;AAChE,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,GAAG,IAAA,CAAK,QAAA;AAAA,MACR,UAAA;AAAA,MACA,SAAA,EAAW,CAAC,GAAG,IAAA,CAAK,SAAS,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,GAAA,CAAI,EAAE,GAAG,GAAG;AAAA,KAC5E;AACA,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA,EAEA,mBAAmB,IAAA,EAA+B;AAChD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,IAAA,CAAK,MAAM,CAAA;AACvE,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,GAAG,IAAA,CAAK,QAAA;AAAA,MACR,KAAA,EAAO,MAAA,GACH,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,IAAI,CAAC,CAAA,KAAO,CAAA,CAAE,MAAA,KAAW,IAAA,CAAK,MAAA,GAAS,EAAE,GAAG,CAAA,EAAG,GAAG,IAAA,EAAK,GAAI,CAAE,CAAA,GACjF,CAAC,GAAG,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,IAAI;AAAA,KACnC;AACA,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA,EAEA,gBAAA,CACE,QACA,KAAA,EACM;AACN,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,GAAG,IAAA,CAAK,QAAA;AAAA,MACR,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,GAAA;AAAA,QAAI,CAAC,CAAA,KAC9B,CAAA,CAAE,MAAA,KAAW,MAAA,GAAS,EAAE,GAAG,CAAA,EAAG,GAAG,KAAA,EAAM,GAAI;AAAA;AAC7C,KACF;AACA,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA,EAEA,SAAS,KAAA,EAAsB;AAC7B,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,IAAA,CAAK,UAAU,KAAA,EAAM;AAC1C,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,IAAA,CAAK,QAAA,EAAS;AAAA,EAChB;AAAA;AAAA,EAGA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,KAAK,KAAK,CAAA;AACvB,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,IACf;AACA,IAAA,MAAM,KAAK,OAAA,EAAQ;AAKnB,IAAA,OAAO,KAAK,gBAAA,EAAkB;AAC5B,MAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,MAAA,MAAM,KAAK,OAAA,EAAQ;AAAA,IACrB;AAAA,EAEF;AAAA,EAEQ,aAAA,GAAsB;AAC5B,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,4BAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAE;AAAA,EAC1E;AAAA,EAEQ,QAAA,GAAiB;AACvB,IAAA,IAAI,KAAK,KAAA,EAAO;AAChB,IAAA,IAAA,CAAK,KAAA,GAAQ,WAAW,MAAM;AAC5B,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,KAAK,KAAK,OAAA,EAAQ;AAAA,IACpB,CAAA,EAAG,KAAK,UAAU,CAAA;AAAA,EACpB;AAAA,EAEA,MAAc,OAAA,GAAyB;AACrC,IAAA,IAAI,KAAK,OAAA,EAAS;AAIhB,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,KAAK,QAAA,EAAU,IAAA,CAAK,UAAU,IAAA,CAAK,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA,EAAG;AAAA,QACvE,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,2CAAA;AAAA,QACA,eAAe,GAAG;AAAA,OACpB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AAEf,MAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,QAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,QAAA,IAAA,CAAK,QAAA,EAAS;AAAA,MAChB;AAAA,IAEF;AAAA,EACF;AACF;ACrOO,IAAM,mBAAA,GAAsB;AAgB5B,SAAS,aAAa,WAAA,EAA6B;AACxD,EAAA,OAAO,kBAAA,CAAmB,EAAE,WAAA,EAAa,CAAA,CAAE,WAAA;AAC7C;AAEA,eAAsB,QAAA,CAAS,UAAkB,MAAA,EAA6C;AAC5F,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,MAAUG,GAAA,CAAA,QAAA,CAAS,QAAA,EAAU,MAAM,CAAA;AAAA,EAC3C,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAC3B,SAAA,EAAW,QAAA;AAAA,QACX,KAAA,EAAO,MAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,OAC1B,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,OAAA,KAAY,CAAA,IAAK,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AAC9F,MAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,QAC1B,KAAA,EAAO,MAAA;AAAA,QACP,KAAA,EAAO,2BAAA;AAAA,QACP,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS,yDAAA;AAAA,QACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACnC,CAAC,CAAA;AACF,MAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,QAC3B,SAAA,EAAW,QAAA;AAAA,QACX,KAAA,EAAO,MAAA;AAAA,QACP,QAAA;AAAA,QACA,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,SAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,QACzB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,KAC1B,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAK,SAAA,CAAU;AAAA,MAC1B,KAAA,EAAO,MAAA;AAAA,MACP,KAAA,EAAO,yBAAA;AAAA,MACP,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,4DAAA;AAAA,MACT,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACnC,CAAC,CAAA;AACF,IAAA,MAAA,EAAQ,KAAK,cAAA,EAAgB;AAAA,MAC3B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,EAAA;AAAA,MACzB,KAAA,EAAO;AAAA,KACR,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,QAAA,CAAS,QAAA,EAAkB,IAAA,EAAgB,MAAA,EAAkC;AACjG,EAAA,MAAM,EAAA,GAAK,KAAK,GAAA,EAAI;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,CAAY,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC1E,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,SAAA;AAAA,MACT,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI;AAAA,KAC1B,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,KAAK,eAAA,EAAiB;AAAA,MAC5B,SAAA,EAAW,QAAA;AAAA,MACX,KAAA,EAAO,MAAA;AAAA,MACP,QAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,KAAA,EAAO,eAAe,GAAG,CAAA;AAAA,MACzB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,MAAM,IAAI,OAAA,CAAQ;AAAA,MAChB,OAAA,EAAS,eAAe,GAAG,CAAA;AAAA,MAC3B,MAAM,WAAA,CAAY,sBAAA;AAAA,MAClB,IAAA,EAAM,QAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF;AAuDO,SAAS,UAAU,IAAA,EAAwB;AAChD,EAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,IAAA;AAAA,IACA,KAAA,EAAO,GAAA;AAAA,IACP,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY,CAAA;AAAA,IACZ,WAAA,EAAa,MAAA;AAAA,IACb,SAAA,EAAW,QAAA;AAAA,IACX,cAAc,EAAC;AAAA,IACf,SAAS;AAAC,GACZ;AACF;AAMO,SAAS,WAAA,CACd,IAAA,EACA,QAAA,EACA,IAAA,EACU;AACV,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AACnD,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,QAAA,EAAU,OAAA;AAAA,IACV,YAAA,EAAc,QAAQ,OAAA,GAAU;AAAA,GAClC;AACF;AAMO,SAAS,aAAA,CAAc,MAAgB,KAAA,EAAyD;AACrG,EAAA,MAAM,SAAA,GAAY,KAAK,UAAA,GAAa,CAAA;AACpC,EAAA,MAAM,EAAA,GAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAClC,EAAA,MAAM,IAAA,GAAqB,EAAE,GAAG,KAAA,EAAO,WAAW,EAAA,EAAG;AACrD,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,IAAA,CAAK,SAAS,IAAI,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,QAAQ,MAAA,GAAS,mBAAA,GAC7B,QAAQ,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,mBAAmB,CAAA,GAClD,OAAA;AACJ,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,UAAA,EAAY,SAAA;AAAA,IACZ,cAAA,EAAgB,EAAA;AAAA,IAChB,OAAA,EAAS;AAAA,GACX;AACF;AAKO,SAAS,eAAe,IAAA,EAK7B;AACA,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,EAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,EAAA,IAAI,mBAAA,GAAsB,CAAA;AAC1B,EAAA,KAAA,MAAW,CAAA,IAAK,KAAK,OAAA,EAAS;AAC5B,IAAA,IAAI,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,kBAA0B,CAAA,CAAE,OAAA;AACrD,IAAA,IAAI,EAAE,MAAA,EAAQ;AACZ,MAAA,gBAAA,IAAoB,EAAE,MAAA,CAAO,KAAA;AAC7B,MAAA,iBAAA,IAAqB,EAAE,MAAA,CAAO,MAAA;AAAA,IAChC;AACA,IAAA,IAAI,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,IAAY,EAAE,MAAA,EAAQ,mBAAA,EAAA;AAAA,EACjD;AACA,EAAA,OAAO,EAAE,YAAA,EAAc,gBAAA,EAAkB,iBAAA,EAAmB,mBAAA,EAAoB;AAClF;AAEA,IAAM,MAAA,GAAS,GAAA;AAGR,SAAS,UAAA,CAAW,IAAA,EAAgB,YAAA,GAAe,EAAA,EAAY;AACpE,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,IAAA;AAC7C,EAAA,KAAA,CAAM,KAAK,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,GAAI,OAAO,WAAW,CAAA;AAClD,EAAA,IAAI,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,WAAA,KAAgB,KAAK,IAAA,EAAM;AACtD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,QAAA,GAAM,IAAA,CAAK,IAAA;AAC5E,IAAA,KAAA,CAAM,KAAK,KAAA,CAAM,GAAA,CAAI,gBAAA,GAAmB,OAAA,GAAU,IAAI,CAAC,CAAA;AAAA,EACzD;AAGA,EAAA,IAAI,OAAO,IAAA,CAAK,QAAA,KAAa,QAAA,EAAU;AACrC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAChE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAC,CAAA;AACjC,IAAA,MAAM,QAAQ,EAAA,GAAK,MAAA;AACnB,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,KAAA,CAAM,QAAA,CAAI,MAAA,CAAO,MAAM,CAAC,CAAA,GAAI,KAAA,CAAM,GAAA,CAAI,QAAA,CAAI,MAAA,CAAO,KAAK,CAAC,CAAA;AACzE,IAAA,KAAA,CAAM,IAAA,CAAK,eAAe,GAAA,GAAM,GAAA,GAAM,MAAM,IAAA,CAAK,GAAA,GAAM,GAAG,CAAC,CAAA;AAC3D,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,KAAA,CAAM,KAAK,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,YAAY,CAAC,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,MAAM,SAAA,GAAY,KAAK,aAAA,KAAkB,cAAA,GAAiB,cACtD,IAAA,CAAK,aAAA,KAAkB,aAAa,cAAA,GACpC,cAAA;AACJ,MAAA,KAAA,CAAM,IAAA,CAAK,WAAA,GAAc,SAAA,GAAY,GAAA,GAAM,KAAK,aAAa,CAAA;AAAA,IAC/D;AAAA,EACF;AAGA,EAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG;AACrD,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,eAAe,CAAC,CAAA;AACtC,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,YAAA,EAAc;AACjC,MAAA,MAAM,IAAA,GAAO,uBAAA,CAAwB,IAAA,CAAK,CAAC,CAAA;AAC3C,MAAA,MAAM,MAAA,GAAS,OAAO,KAAA,CAAM,KAAA,CAAM,QAAG,CAAA,GAAI,KAAA,CAAM,IAAI,QAAG,CAAA;AACtD,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,MAAA,GAAS,GAAA,GAAM,CAAC,CAAA;AAAA,IACpC;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,KAAK,CAAA;AAC/B,EAAA,KAAA,CAAM,IAAA,CAAK,iBAAA,GAAoB,IAAA,CAAK,cAAc,CAAA;AAClD,EAAA,KAAA,CAAM,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,UAAU,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,KAAK,SAAA,IAAa,QAAA;AACrC,EAAA,KAAA,CAAM,IAAA,CAAK,SAAA,GAAY,UAAA,IAAc,IAAA,CAAK,UAAA,GAAa,IAAI,eAAA,GAAkB,IAAA,CAAK,UAAA,GAAa,GAAA,GAAM,EAAA,CAAG,CAAA;AACxG,EAAA,KAAA,CAAM,IAAA,CAAK,UAAA,GAAa,IAAA,CAAK,WAAW,CAAA;AACxC,EAAA,MAAM,KAAA,GAAQ,eAAe,IAAI,CAAA;AACjC,EAAA,IAAI,KAAA,CAAM,sBAAsB,CAAA,EAAG;AACjC,IAAA,MAAM,QAAQ,SAAA,GAAY,MAAA,GAAS,KAAA,CAAM,YAAA,CAAa,QAAQ,CAAC,CAAA,GAC3D,QAAA,GAAW,KAAA,CAAM,mBAAmB,SAAA,GAAY,KAAA,CAAM,iBAAA,GACtD,iBAAA,GAAoB,MAAM,mBAAA,GAAsB,cAAA;AACpD,IAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,EAClB;AACA,EAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC3B,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,CAAM,IAAA,CAAK,0BAA0B,IAAA,CAAK,GAAA,CAAI,cAAc,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,GAAI,IAAI,CAAA;AACvF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAC,YAAY,CAAA;AAC7C,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,MAAA,KAAW,SAAA,GAAY,QAAA,GAAM,CAAA,CAAE,MAAA,KAAW,SAAA,GAAY,QAAA,GAAM,CAAA,CAAE,MAAA,KAAW,SAAA,GAAY,QAAA,GAAM,MAAA;AAC1G,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,IAAA,GAAO,UAAA,GAAQ,EAAE,IAAA,GAAO,EAAA;AACvC,MAAA,MAAM,IAAA,GAAO,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,IAAA,GAAO,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,GAAI,GAAA,GAAM,EAAA;AAC1F,MAAA,KAAA,CAAM,IAAA,CAAK,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,GAAA,GAAM,IAAA,GAAO,IAAA,GAAO,CAAA,CAAE,MAAA,GAAS,IAAA,GAAO,CAAA,CAAE,IAAA,GAAO,OAAO,IAAI,CAAA;AAAA,IAC7F;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAiBO,SAAS,sBAAsB,IAAA,EAA0D;AAC9F,EAAA,MAAM,EAAA,GAAK,gDAAA;AACX,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA;AACvB,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AAGf,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,CAAA,EAAG,MAAA,CAAO,QAAA,CAAS,EAAE,CAAC,CAAA,IAAK,GAAA,EAAK,EAAE,CAAC,CAAC,CAAA;AAC5E,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,EAAG,MAAK,IAAK,MAAA;AAC7B,EAAA,OAAO,SAAS,MAAA,GAAY,EAAE,UAAS,GAAI,EAAE,UAAU,IAAA,EAAK;AAC9D;AAQO,SAAS,cAAA,CACd,IAAA,EACA,QAAA,EACA,IAAA,EACU;AACV,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AACnD,EAAA,MAAM,UAAU,CAAC,GAAI,IAAA,CAAK,eAAA,IAAmB,EAAC,EAAI,EAAE,EAAA,EAAA,iBAAI,IAAI,MAAK,EAAE,WAAA,IAAe,QAAA,EAAU,OAAA,EAAS,MAAM,CAAA;AAE3G,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,OAAA;AAE7D,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,QAAA,EAAU,OAAA;AAAA,IACV,YAAA,EAAc,IAAA,IAAQ,CAAA,EAAG,OAAO,CAAA,UAAA,CAAA;AAAA,IAChC,eAAA,EAAiB,OAAA;AAAA,IACjB,aAAA,EAAe,aAAa,OAAO;AAAA,GACrC;AACF;AAGO,IAAM,oBAAA,GAAuB;AAEpC,SAAS,aAAa,OAAA,EAAiF;AACrG,EAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,OAAO,MAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,EAAE,CAAA;AAC/B,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,MAAA,CAAO,IAAA,CAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,QAAA,IAAY,CAAA,KAAM,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,QAAA,IAAY,CAAA,CAAE,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,MAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,GAAI,MAAA,CAAO,MAAA;AAC5D,EAAA,IAAI,QAAA,GAAW,GAAG,OAAO,cAAA;AACzB,EAAA,IAAI,QAAA,GAAW,IAAI,OAAO,UAAA;AAC1B,EAAA,OAAO,QAAA;AACT;ACzcO,IAAM,qBAAN,MAAgD;AAAA,EACpC,GAAA;AAAA,EAEjB,YAAY,KAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,MAAM,KAAA,CAAM,aAAA;AAAA,EACnB;AAAA,EAEA,MAAM,IAAA,GAA+B;AACnC,IAAA,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AACxB,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAASC,GAAA,CAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AACvC,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC7B,QAAA,IAAI;AACF,UAAA,MAAM,MAAqB,IAAA,CAAK,KAAA;AAAA,YAC9B,MAASA,GAAA,CAAA,QAAA,CAAcC,KAAA,CAAA,IAAA,CAAK,KAAK,GAAA,EAAK,IAAI,GAAG,MAAM;AAAA,WACrD;AACA,UAAA,OAAA,CAAQ,IAAA,CAAK,IAAI,KAAK,CAAA;AAAA,QACxB,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,OAAA,CAAQ,IAAA;AAAA,MACb,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,KAAK,CAAA,CAAE,SAAS,CAAA,CAAE,OAAA,KAAY,IAAI,IAAA,CAAK,CAAA,CAAE,SAAS,EAAE,OAAA;AAAQ,KAC5E;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,EAAA,EAAyC;AACjD,IAAA,MAAM,OAAYA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,EAAE,CAAA,KAAA,CAAO,CAAA;AAC7C,IAAA,IAAI;AACF,MAAA,MAAM,MAAqB,IAAA,CAAK,KAAA,CAAM,MAASD,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAC,CAAA;AACrE,MAAA,OAAO,GAAA,CAAI,KAAA;AAAA,IACb,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,KAAA,EAAmC;AAC5C,IAAA,MAAM,SAAA,CAAU,KAAK,GAAG,CAAA;AACxB,IAAA,MAAM,OAAYC,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,EAAG,KAAA,CAAM,EAAE,CAAA,KAAA,CAAO,CAAA;AACnD,IAAA,MAAM,GAAA,GAAqB,EAAE,OAAA,EAAS,CAAA,EAAG,KAAA,EAAM;AAC/C,IAAA,MAAM,YAAY,IAAA,EAAM,IAAA,CAAK,UAAU,GAAA,EAAK,IAAA,EAAM,CAAC,CAAC,CAAA;AAAA,EACtD;AAAA,EAEA,MAAM,OAAO,EAAA,EAA8B;AACzC,IAAA,MAAM,OAAYA,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,EAAE,CAAA,KAAA,CAAO,CAAA;AAC7C,IAAA,IAAI;AACF,MAAA,MAASD,WAAO,IAAI,CAAA;AACpB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,KAAA,EAAuC;AAChD,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,EAAK;AAC5B,IAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY;AAChC,IAAA,OAAO,GAAA,CAAI,MAAA;AAAA,MACT,CAAC,CAAA,KACC,CAAA,CAAE,KAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,KAAK,CAAA,IACpC,CAAA,CAAE,OAAA,CAAQ,WAAA,EAAY,CAAE,SAAS,KAAK,CAAA,IACtC,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,CAAE,QAAA,CAAS,KAAK,CAAC;AAAA,KACtD;AAAA,EACF;AAAA;AAAA,EAGA,SAAA,CAAU,KAAA,EAAe,OAAA,EAAiB,IAAA,GAAiB,EAAC,EAAgB;AAC1E,IAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,IAAA,OAAO;AAAA,MACL,EAAA,EAAI1B,UAAAA,EAAW,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,MAC3B,KAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,GAAA;AAAA,MACX,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AACF;ACtGO,IAAM,sBAAsC,CAAC,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAU,SAAS;AAuBjG,IAAM,YAAN,MAAgB;AAAA,EAIrB,WAAA,CACmB,KAAA,EACA,SAAA,EACA,SAAA,EACjB;AAHiB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAEjB,IAAA,IAAA,CAAK,SAAA,GAAiB4B,KAAA,CAAA,IAAA,CAAK,KAAA,CAAM,UAAA,EAAY,iBAAiB,CAAA;AAAA,EAChE;AAAA,EALmB,KAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EANF,SAAA;AAAA,EACT,KAAA,GAA8B,IAAA;AAAA;AAAA,EAYtC,MAAM,MAAA,GAA0B;AAC9B,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,OAAO,sDAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAO,YAAA;AACzB,IAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,OAAA,CAAQ,IAAI,CAAA,GAAI,OAAA;AACrC,IAAA,OAAO;AAAA,MACL,CAAA,kBAAA,CAAA;AAAA,MACA,CAAA,cAAA,EAAiB,IAAI,IAAI,CAAA,CAAA;AAAA,MACzB,CAAA,cAAA,EAAiB,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,MAC1C,iBAAiB,KAAK,CAAA;AAAA,KACxB,CAAE,KAAK,IAAI,CAAA;AAAA,EACb;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAe,WAAA,EAA8C;AAExE,IAAA,OAAO,0BAAA;AAAA,EACT;AAAA,EAEA,MAAM,OAAA,GAA2B;AAC/B,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAO,8BAAA;AACjB,IAAA,MAAM,IAAA,GAAO,EAAE,GAAG,GAAA,EAAK,SAAS,KAAA,EAAM;AACtC,IAAA,MAAM,IAAA,CAAK,UAAU,IAAI,CAAA;AACzB,IAAA,OAAO,sCAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,KAAA,EAAoC;AAC7C,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK,OAAA,EAAS,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,UAAA,EAAY,EAAC,EAAG,SAAS,cAAA,EAAe;AAE/F,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAChC,IAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACpC,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACvC,IAAA,MAAM,MAAA,GAAS,MAAA;AACf,IAAA,MAAM,WAAA,GAAc,KAAK,KAAA,EAAO,GAAA;AAEhC,IAAA,MAAM,EAAE,aAAa,GAAA,EAAI,GAAI,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,UAAU,CAAA;AACrE,IAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,aAAA,CAAc,OAAO,KAAA,EAAO,QAAA,EAAU,aAAa,WAAW,CAAA;AAE5F,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA;AAAA,MAC3B,KAAA;AAAA,MAAO,KAAA;AAAA,MAAO,QAAA;AAAA,MAAU,UAAA;AAAA,MACxB,WAAA;AAAA,MACA,CAAA,KAAA,EAAQ,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,QAAA,EAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAa,CAAA;AAAA,KACjE;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,SAAA,CAAU,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,QAAQ,SAAS,CAAA;AAAA,IAChE,SAAS,GAAA,EAAK;AAEZ,MAAA,IAAI,eAAe,KAAA,IAAS,GAAA,CAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AACvD,QAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,KAAA,EAAO,KAAA,EAAO,UAAU,MAAM,CAAA;AAC/D,QAAA,MAAM,UAAA,GAAa,OAAO,MAAA,CAAO,GAAA;AACjC,QAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,YAAA;AAAA,UAClC,KAAA;AAAA,UAAO,KAAA;AAAA,UAAO,QAAA;AAAA,UAAU,UAAA;AAAA,UACxB,UAAA;AAAA,UACA,CAAA,KAAA,EAAQ,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,QAAA,EAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAa,CAAA;AAAA,SACjE;AACA,QAAA,MAAM,KAAK,SAAA,CAAU,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,QAAQ,gBAAgB,CAAA;AAAA,MACvE,CAAA,MAAO;AACL,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAA2B;AAAA,MAC/B,OAAA,EAAS,CAAA;AAAA,MACT,GAAA,EAAK,SAAA;AAAA,MACL,YAAA,EAAA,iBAAc,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MACrC,QAAA,EAAU;AAAA,KACZ;AACA,IAAA,MAASC,GAAA,CAAA,SAAA,CAAU,KAAK,SAAA,EAAW,IAAA,CAAK,UAAU,SAAA,EAAW,IAAA,EAAM,CAAC,CAAA,EAAG,MAAM,CAAA;AAC7E,IAAA,IAAA,CAAK,KAAA,GAAQ,SAAA;AAEb,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,IAAA;AAAA,MACJ,MAAA,EAAQ,MAAA;AAAA,MACR,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,WAAA,EAAa,SAAA;AAAA,MACb,OAAA,EAAS,CAAA,OAAA,EAAU,GAAA,CAAI,UAAA,CAAW,KAAK,IAAI,CAAC,CAAA,IAAA,EAAO,GAAA,CAAI,IAAI,CAAA,UAAA,EAAa,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,KAC/F;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,KAAA,EAAoC;AAC7C,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,GAAA,EAAK,OAAA,EAAS,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,UAAA,EAAY,EAAC,EAAG,SAAS,cAAA,EAAe;AAE/F,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,SAAA,CAAU,CAAC,CAAC,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,SAAA,CAAU,CAAC,CAAC,CAAA;AAE3C,IAAA,MAAM,aAAa,MAAM,IAAA,CAAK,OAAO,KAAA,EAAO,KAAA,EAAO,UAAU,MAAM,CAAA;AACnE,IAAA,MAAM,UAAA,GAAa,WAAW,MAAA,CAAO,GAAA;AAErC,IAAA,MAAM,aAAa,MAAM,IAAA,CAAK,UAAU,KAAA,EAAO,KAAA,EAAO,UAAU,UAAU,CAAA;AAC1E,IAAA,MAAM,OAAA,GAAU,WAAW,IAAA,CAAK,GAAA;AAEhC,IAAA,MAAM,cAAc,MAAM,IAAA,CAAK,eAAe,KAAA,EAAO,KAAA,EAAO,UAAU,OAAO,CAAA;AAE7E,IAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAC/B,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AAG3B,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACrC,MAAA,IAAI,SAAS,CAAC,CAAA,KAAM,UAAU,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG;AAC5C,MAAA,MAAM,GAAA,GAAM,SAAS,CAAC,CAAA;AACtB,MAAA,IAAI,CAAC,CAAC,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAU,SAAS,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,EAAG;AAE3E,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AACzC,MAAA,IAAI,CAAC,SAAA,EAAW;AAMhB,MAAA,MAAM,MAAM,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AACtC,MAAA,MAAM,WAAW,yBAAA,CAA0B,GAAA,EAAK,SAAA,EAAW,GAAA,EAAK,MAAM,IAAI,CAAA;AAE1E,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,KAAA,EAAO,QAAA,EAAU,MAAM,GAAG,CAAA;AACrE,MAAA,MAASA,UAAWD,KAAA,CAAA,OAAA,CAAQ,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC1D,MAAA,MAASC,cAAU,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,mBAAA,CAAoB,IAAI,UAAU,CAAA;AAC9D,IAAA,MAAM,SAAA,GAA2B;AAAA,MAC/B,OAAA,EAAS,CAAA;AAAA,MACT,GAAA,EAAK,UAAA;AAAA,MACL,YAAA,EAAA,iBAAc,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MACrC;AAAA,KACF;AACA,IAAA,MAASA,GAAA,CAAA,SAAA,CAAU,KAAK,SAAA,EAAW,IAAA,CAAK,UAAU,SAAA,EAAW,IAAA,EAAM,CAAC,CAAA,EAAG,MAAM,CAAA;AAC7E,IAAA,IAAA,CAAK,KAAA,GAAQ,SAAA;AAEb,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,IAAA;AAAA,MACJ,MAAA,EAAQ,MAAA;AAAA,MACR,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,WAAA,EAAa,UAAA;AAAA,MACb,OAAA,EAAS,CAAA,OAAA,EAAU,GAAA,CAAI,UAAA,CAAW,KAAK,IAAI,CAAC,CAAA,MAAA,EAAS,GAAA,CAAI,IAAI,CAAA,UAAA,EAAa,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,KAClG;AAAA,EACF;AAAA,EAEA,MAAM,eAAA,GAAoC;AACxC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,OAAO,IAAA;AACxB,IAAA,MAAM,GAAA,GAAM,KAAK,SAAA,EAAU;AAC3B,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,mBAAA,CAAoB,IAAI,UAAU,CAAA;AAC7D,IAAA,OAAO,OAAA,KAAY,KAAK,KAAA,CAAM,QAAA;AAAA,EAChC;AAAA,EAEA,MAAM,SAAA,GAA2B;AAC/B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAASA,GAAA,CAAA,QAAA,CAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AACpD,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,WAAA,CACZ,KAAA,EACA,OACA,IAAA,EACA,MAAA,EACA,aACA,IAAA,EACkB;AAClB,IAAA,MAAM,MAAM,CAAA,6BAAA,EAAgC,KAAK,CAAA,CAAA,EAAI,IAAI,GAAG,WAAW,CAAA,CAAA;AACvE,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,IAAM,CAAA;AAAA,MAClC,MAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,QAC9B,MAAA,EAAQ,6BAAA;AAAA,QACR,sBAAA,EAAwB,YAAA;AAAA,QACxB,cAAA,EAAgB;AAAA;AAClB,KACF;AACA,IAAA,IAAI,SAAS,MAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AACvD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,IAAI,CAAA;AAEjC,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/B,MAAA,MAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,OAAA,EAAS,cAAc,MAAM,CAAA,CAAA,EAAI,WAAW,CAAA,SAAA,EAAY,GAAA,CAAI,MAAM,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA;AAAA,QAC/E,MAAM,WAAA,CAAY,OAAA;AAAA,QAClB,SAAA,EAAW,SAAA;AAAA,QACX,OAAA,EAAS,EAAE,MAAA,EAAQ,WAAA,EAAa,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAG,OAC9E,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,OAAO,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,IAAI,EAAC;AAAA,EACpC;AAAA,EAEA,MAAc,MAAA,CAAO,KAAA,EAAe,KAAA,EAAe,MAAc,GAAA,EAAa;AAC5E,IAAA,OAAQ,MAAM,KAAK,WAAA,CAAY,KAAA,EAAO,OAAO,IAAA,EAAM,KAAA,EAAO,CAAA,gBAAA,EAAmB,GAAG,CAAA,CAAE,CAAA;AAAA,EAGpF;AAAA,EAEA,MAAc,SAAA,CAAU,KAAA,EAAe,KAAA,EAAe,IAAA,EAAc,KAAa,GAAA,EAAa;AAC5F,IAAA,MAAM,IAAA,CAAK,YAAY,KAAA,EAAO,KAAA,EAAO,MAAM,OAAA,EAAS,CAAA,gBAAA,EAAmB,GAAG,CAAA,CAAA,EAAI;AAAA,MAC5E,GAAA;AAAA,MACA,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,SAAA,CAAU,KAAA,EAAe,KAAA,EAAe,MAAc,GAAA,EAAa;AAC/E,IAAA,OAAQ,MAAM,KAAK,WAAA,CAAY,KAAA,EAAO,OAAO,IAAA,EAAM,KAAA,EAAO,CAAA,aAAA,EAAgB,GAAG,CAAA,CAAE,CAAA;AAAA,EAIjF;AAAA,EAEA,MAAc,cAAA,CAAe,KAAA,EAAe,KAAA,EAAe,MAAc,OAAA,EAAiB;AACxF,IAAA,OAAQ,MAAM,KAAK,WAAA,CAAY,KAAA,EAAO,OAAO,IAAA,EAAM,KAAA,EAAO,CAAA,WAAA,EAAc,OAAO,CAAA,YAAA,CAAc,CAAA;AAAA,EAK/F;AAAA,EAEA,MAAc,aACZ,KAAA,EAAe,KAAA,EAAe,MAC9B,OAAA,EAAiB,SAAA,EAAgC,UAAU,MAAA,EAC3D;AACA,IAAA,MAAM,IAAA,GAAgC,EAAE,OAAA,EAAS,IAAA,EAAM,OAAA,EAAQ;AAC/D,IAAA,IAAI,SAAA,EAAW,IAAA,CAAK,OAAA,GAAU,CAAC,SAAS,CAAA;AACxC,IAAA,MAAM,MAAA,GAAU,MAAM,IAAA,CAAK,WAAA,CAAY,OAAO,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,cAAA,EAAgB,IAAI,CAAA;AACvF,IAAA,OAAO,MAAA,CAAO,GAAA;AAAA,EAChB;AAAA,EAEA,MAAc,aAAA,CACZ,KAAA,EAAe,KAAA,EAAe,IAAA,EAC9B,SACA,WAAA,EACiB;AACjB,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAC/B,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,IAAA,EAAM,MAAA;AAAA,MACN,SAAS,CAAA,CAAE;AAAA,KACb,CAAE,CAAA;AACF,IAAA,MAAM,IAAA,GAAgC,EAAE,IAAA,EAAK;AAC7C,IAAA,IAAI,WAAA,OAAkB,SAAA,GAAY,WAAA;AAClC,IAAA,MAAM,MAAA,GAAU,MAAM,IAAA,CAAK,WAAA,CAAY,OAAO,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,YAAA,EAAc,IAAI,CAAA;AACrF,IAAA,OAAO,MAAA,CAAO,GAAA;AAAA,EAChB;AAAA,EAEA,MAAc,OAAA,CAAQ,KAAA,EAAe,KAAA,EAAe,MAAc,GAAA,EAA8B;AAC9F,IAAA,MAAM,MAAA,GAAU,MAAM,IAAA,CAAK,WAAA,CAAY,KAAA,EAAO,OAAO,IAAA,EAAM,KAAA,EAAO,CAAA,WAAA,EAAc,GAAG,CAAA,CAAE,CAAA;AACrF,IAAA,OAAO,MAAA,CAAO,OAAA;AAAA,EAChB;AAAA;AAAA,EAIA,MAAc,eAAe,UAAA,EAG1B;AACD,IAAA,MAAM,UAAkE,EAAC;AACzE,IAAA,MAAM,SAAmB,EAAC;AAE1B,IAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AACzC,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,IAAI;AACF,QAAA,MAAMlD,KAAAA,GAAO,MAASkD,GAAA,CAAA,IAAA,CAAK,SAAS,CAAA;AACpC,QAAA,IAAIlD,KAAAA,CAAK,aAAY,EAAG;AACtB,UAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACrD,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,OAAA,GAAU,MAASkD,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,MAAM,CAAA;AAC9C,YAAA,MAAM,MAAWD,KAAA,CAAA,QAAA,CAAS,SAAA,EAAW,IAAI,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC7D,YAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,CAAA;AACpE,YAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,UACrB;AAAA,QACF,CAAA,MAAO;AACL,UAAA,MAAM,OAAA,GAAU,MAASC,GAAA,CAAA,QAAA,CAAS,SAAA,EAAW,MAAM,CAAA;AACnD,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA,EAAI,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,CAAA;AAC7D,UAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,QACrB;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM3B,UAAAA,CAAW,QAAQ,CAAA,CAAE,OAAO,MAAA,CAAO,IAAA,CAAK,EAAE,CAAC,EAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAClF,IAAA,OAAO,EAAE,WAAA,EAAa,OAAA,EAAS,GAAA,EAAI;AAAA,EACrC;AAAA,EAEA,MAAc,oBAAoB,UAAA,EAA6C;AAC7E,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AACzC,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,IAAI;AACF,QAAA,MAAMvB,KAAAA,GAAO,MAASkD,GAAA,CAAA,IAAA,CAAK,SAAS,CAAA;AACpC,QAAA,IAAIlD,KAAAA,CAAK,aAAY,EAAG;AACtB,UAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACrD,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,OAAA,GAAU,MAASkD,GAAA,CAAA,QAAA,CAAS,IAAI,CAAA;AACtC,YAAA,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ,IAAI,IAAI,CAAA;AAAA,UAC/C;AAAA,QACF,CAAA,MAAO;AACL,UAAA,MAAM,OAAA,GAAU,MAASA,GAAA,CAAA,QAAA,CAAS,SAAS,CAAA;AAC3C,UAAA,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ,IAAI,SAAS,CAAA;AAAA,QACpD;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,OAAO3B,UAAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,OAAO,IAAA,CAAK,EAAE,CAAC,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,EAC/E;AAAA,EAEQ,eAAe,GAAA,EAAkC;AACvD,IAAA,QAAQ,GAAA;AAAK,MACX,KAAK,UAAA;AAAY,QAAA,OAAO,KAAK,KAAA,CAAM,YAAA;AAAA,MACnC,KAAK,QAAA;AAAY,QAAA,OAAO,KAAK,KAAA,CAAM,YAAA;AAAA,MACnC,KAAK,SAAA;AAAY,QAAA,OAAO,KAAK,KAAA,CAAM,aAAA;AAAA,MACnC,KAAK,QAAA;AAAY,QAAA,OAAO,KAAK,KAAA,CAAM,YAAA;AAAA,MACnC,KAAK,SAAA;AAAY,QAAA,OAAO,KAAK,KAAA,CAAM,WAAA;AAAA;AAAA,MAEnC;AAAiB,QAAA,OAAO,IAAA;AAAA;AAC1B,EACF;AAAA,EAEA,MAAc,OAAA,CAAQ,GAAA,EAAa,IAAA,EAAiC;AAClE,IAAA,MAAM,UAAoB,EAAC;AAC3B,IAAA,MAAM,UAAU,MAAS2B,GAAA,CAAA,OAAA,CAAQ,KAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAC7D,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,MAAM,IAAA,GAAYD,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AACtC,MAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,QAAA,OAAA,CAAQ,KAAK,GAAI,MAAM,KAAK,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAE,CAAA;AAAA,MAClD,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MACnB;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAEA,SAAS,yBAAA,CACP,GAAA,EACA,SAAA,EACA,GAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,eAAA,GAAkB,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,SAAA;AACpD,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,IAAI,GAAA,EAAK,MAAM,IAAI,OAAA,CAAQ;AAAA,MACzB,OAAA,EAAS,qDAAqD,UAAU,CAAA,CAAA;AAAA,MACxE,MAAM,WAAA,CAAY,gBAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,OAAA,EAAS,EAAE,MAAA,EAAQ,sBAAA,EAAwB,UAAU,GAAA;AAAI,KAC1D,CAAA;AACD,IAAA,OAAO,SAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,KAAK,OAAO,SAAA;AACjB,EAAA,MAAM,aAAA,GAAqBA,gBAAU,GAAG,CAAA;AACxC,EAAA,MAAM,cAAc,aAAA,KAAkB,IAAA,IAAQ,cAAc,UAAA,CAAW,CAAA,EAAA,EAAUA,SAAG,CAAA,CAAE,CAAA;AACtF,EAAA,IAASA,KAAA,CAAA,UAAA,CAAW,aAAa,CAAA,IAAK,WAAA,EAAa;AACjD,IAAA,MAAM,IAAI,OAAA,CAAQ;AAAA,MAChB,OAAA,EAAS,sCAAsC,UAAU,CAAA,CAAA;AAAA,MACzD,MAAM,WAAA,CAAY,gBAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,OAAA,EAAS,EAAE,MAAA,EAAQ,gBAAA,EAAkB,aAAA;AAAc,KACpD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,IAAA,GAAYA,KAAA,CAAA,OAAA,CAAQ,SAAA,EAAW,aAAa,CAAA;AAClD,EAAA,MAAM,IAAA,GAAYA,cAAQ,SAAS,CAAA;AACnC,EAAA,MAAME,SAAAA,GAAgBF,KAAA,CAAA,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAEzC,EAAA,IAAIE,UAAS,UAAA,CAAW,IAAI,CAAA,IAAUF,KAAA,CAAA,UAAA,CAAWE,SAAQ,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,OAAA,CAAQ;AAAA,MAChB,OAAA,EAAS,kDAAkD,UAAU,CAAA,CAAA;AAAA,MACrE,MAAM,WAAA,CAAY,gBAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,OAAA,EAAS,EAAE,MAAA,EAAQ,uBAAA,EAAyB,UAAU,GAAA;AAAI,KAC3D,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,QAAQ,GAAA,EAAqB;AACpC,EAAA,MAAM,IAAA,GAAO,KAAK,GAAA,EAAI,GAAI,IAAI,IAAA,CAAK,GAAG,EAAE,OAAA,EAAQ;AAChD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,GAAM,CAAA;AACrC,EAAA,IAAI,IAAA,GAAO,GAAG,OAAO,UAAA;AACrB,EAAA,IAAI,IAAA,GAAO,EAAA,EAAI,OAAO,CAAA,EAAG,IAAI,CAAA,KAAA,CAAA;AAC7B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,EAAE,CAAA;AAChC,EAAA,IAAI,GAAA,GAAM,EAAA,EAAI,OAAO,CAAA,EAAG,GAAG,CAAA,KAAA,CAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,EAAE,CAAA;AAChC,EAAA,OAAO,GAAG,IAAI,CAAA,KAAA,CAAA;AAChB;;;AClYA,IAAM,uBAAA,uBAA8B,GAAA,CAA0B;AAAA,EAC5D,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAC;AAMD,IAAM,qBAAA,uBAA4B,GAAA,CAA0B;AAAA,EAC1D,aAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,mBAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAC;AAMD,IAAM,gBAAA,uBAAuB,GAAA,CAA0B;AAAA,EACrD;AACF,CAAC,CAAA;AAMD,SAAS,SAAA,CAAU,MAA4B,KAAA,EAA4B;AACzE,EAAA,IAAI,uBAAA,CAAwB,GAAA,CAAI,IAAI,CAAA,EAAG,OAAO,IAAA;AAC9C,EAAA,IAAI,KAAA,KAAU,WAAW,OAAO,KAAA;AAEhC,EAAA,IAAI,qBAAA,CAAsB,GAAA,CAAI,IAAI,CAAA,EAAG,OAAO,IAAA;AAC5C,EAAA,IAAI,KAAA,KAAU,YAAY,OAAO,KAAA;AAGjC,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC9B,IAAA,OAAO,KAAA,KAAU,MAAA;AAAA,EACnB;AAGA,EAAA,OAAO,IAAA;AACT;AAeO,SAAS,yBACd,MAAA,EAKA,KAAA,GAAoB,UAAA,EACpB,OAAA,GAAqC,EAAC,EAClB;AAEpB,EAAA,IAAI,eAA2B,KAAA,IAAS,UAAA;AAMxC,EAAA,MAAM,aAAA,GACJ,OAAO,MAAA,KAAW,UAAA,GAAa,SAAS,MAAM,MAAA;AAIhD,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAoB;AAEjD,EAAA,MAAM,kBAAA,GAAqB,OAAA,CAAQ,QAAA,EAAU,YAAA,IAAgB,EAAC;AAC9D,EAAA,MAAM,yBAAA,GAA4B,mBAAmB,UAAA,IAAc,CAAA;AAMnE,EAAA,SAAS,aAAa,KAAA,EAA8B;AAClD,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,eAAA,EAAiB,OAAO,IAAA;AAE3C,IAAA,MAAM,SAAA,GAAY,KAAA;AAClB,IAAA,MAAM,SAAA,GAAY,UAAU,KAAA,EAAO,IAAA;AAGnC,IAAA,IAAI,SAAA,KAAc,SAAA,IAAa,SAAA,KAAc,QAAA,IAAY,cAAc,cAAA,EAAgB;AACrF,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,SAAA,KAAc,KAAA,IAAS,SAAA,KAAc,gBAAA,EAAkB;AACzD,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,EAAA,IAAM,SAAA,CAAU,IAAA;AACtC,MAAA,MAAM,KAAA,GAAA,CAAS,gBAAA,CAAiB,GAAA,CAAI,GAAG,KAAK,CAAA,IAAK,CAAA;AACjD,MAAA,gBAAA,CAAiB,GAAA,CAAI,KAAK,KAAK,CAAA;AAG/B,MAAA,OAAO,KAAA,KAAU,CAAA,IAAM,KAAA,GAAQ,yBAAA,KAA8B,CAAA;AAAA,IAC/D;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,IAAI,KAAA,GAAQ;AACV,MAAA,OAAO,YAAA;AAAA,IACT,CAAA;AAAA,IAEA,cAAc,IAAA,EAAM;AAClB,MAAA,YAAA,GAAe,IAAA,IAAQ,UAAA;AAAA,IACzB,CAAA;AAAA,IAEA,OAAO,IAAA,EAAM;AACX,MAAA,OAAO,SAAA,CAAU,MAAM,YAAY,CAAA;AAAA,IACrC,CAAA;AAAA,IAEA,MAAM,OAAO,KAAA,EAAO;AAClB,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,IAAI,CAAC,SAAA,CAAU,KAAA,CAAM,IAAA,EAAM,YAAY,CAAA,EAAG;AAG1C,MAAA,IAAI,CAAC,YAAA,CAAa,KAAK,CAAA,EAAG;AAE1B,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,MAC3B,SAAS,IAAA,EAAM;AAAA,MAKf;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,YAAY,MAAA,EAAQ;AACxB,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACpC,MAAA,MAAM,UAAU,MAAA,CAAO,MAAA;AAAA,QACrB,CAAC,MAAM,SAAA,CAAU,CAAA,CAAE,MAAM,YAAY,CAAA,IAAK,aAAa,CAAC;AAAA,OAC1D;AACA,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,YAAY,OAAO,CAAA;AAAA,MAClC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,GACF;AACF;AASO,SAAS,kBACd,GAAA,EACY;AACZ,EAAA,MAAM,GAAA,GAAM,KAAK,OAAA,EAAS,UAAA;AAC1B,EAAA,IAAI,GAAA,KAAQ,SAAA,IAAa,GAAA,KAAQ,UAAA,IAAc,QAAQ,MAAA,EAAQ;AAC7D,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,OAAO,UAAA;AACT;AAMO,SAAS,4BACd,GAAA,EAaA;AACA,EAAA,MAAM,OAAA,GAAU,GAAA,EAAK,OAAA,IAAW,EAAC;AAEjC,EAAA,MAAM,UAAA,GAAa,kBAAkB,GAAG,CAAA;AAExC,EAAA,MAAM,sBAAA,GACJ,OAAA,CAAQ,QAAA,EAAU,YAAA,EAAc,UAAA,IAAc,CAAA;AAEhD,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,YAAA,EAAc;AAAA,QACZ,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAC;AAAA;AAC5D;AACF,GACF;AACF","file":"index.js","sourcesContent":["import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { expectDefined } from './expect-defined.js';\nimport type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (msg?.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (msg?.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (input?.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (envFlag(process.env.NO_COLOR)) return false;\n if (envFlag(process.env.FORCE_COLOR)) return true;\n return isStdoutTTY();\n};\n\nfunction envFlag(value: string | undefined): boolean {\n if (value === undefined) return false;\n if (value.trim() === '') return false;\n return !/^(0|false|no|off)$/i.test(value.trim());\n}\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(/\\x1b\\[[0-9;]*[A-Za-z]/g, '');\n}\n","/**\n * Deep merge utility — safely merges nested objects with configurable\n * conflict resolution, array merging, and prototype-pollution guarding.\n *\n * Used by:\n * - config-loader (config layer merging with primitive-array concatenation)\n * - secret-vault (config patching)\n * - json-path (json_merge tool with prefer-base / prefer-patch semantics)\n *\n * @module utils/deep-merge\n */\n\n// ---------------------------------------------------------------------------\n// Prototype-pollution guard — shared set of forbidden __proto__ keys\n// ---------------------------------------------------------------------------\n\nexport const FORBIDDEN_PROTO_KEYS = new Set([\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n]);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** True when every element is a primitive or null (no nested objects/arrays). */\nexport function isPrimitiveArray(a: unknown[]): boolean {\n return a.every((v) => v === null || (typeof v !== 'object' && typeof v !== 'function'));\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DeepMergeOptions {\n /**\n * Which side wins on collision for scalars and arrays.\n *\n * - `'prefer-patch'` (default): patch value replaces base value.\n * - `'prefer-base'`: base value is kept, patch value is ignored.\n */\n conflictResolution?: 'prefer-base' | 'prefer-patch';\n\n /**\n * How to handle array values.\n *\n * - `'replace'` (default): patch array replaces base array entirely.\n * - `'concat-primitives'`: when both values are primitive arrays,\n * they are concatenated and deduped (via Set). Non-primitive\n * arrays still replace the base wholesale.\n */\n arrayMode?: 'replace' | 'concat-primitives';\n\n /**\n * Skip prototype-pollution keys (`__proto__`, `constructor`, etc.).\n * Enabled by default. Only disable when you control both inputs\n * and the keyset (e.g. when merging trusted JSON schemas).\n */\n protectProto?: boolean;\n\n /**\n * Optional callback fired when a non-primitive (object) array is\n * replaced wholesale (only relevant with `arrayMode: 'concat-primitives'`).\n * Receives the key name, existing array length, and patch array length.\n * Used by config-loader for debug logging.\n */\n onNonPrimitiveArrayReplace?: (\n key: string,\n existingLen: number,\n patchLen: number,\n ) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively merge `patch` into `base`, returning a new object.\n *\n * - Nested plain objects are merged recursively.\n * - Arrays are handled per `options.arrayMode`.\n * - Scalar collisions are resolved per `options.conflictResolution`.\n * - `null` and non-object values in `patch` replace the base value\n * (unless `conflictResolution` is `'prefer-base'`).\n * - Keys in `base` that are absent from `patch` are preserved.\n * - `FORBIDDEN_PROTO_KEYS` are skipped in the patch (unless\n * `options.protectProto` is set to `false`).\n *\n * The function is generic over `T extends Record<string, unknown>` for\n * callers that pass typed config objects, but the runtime signature\n * also accepts `unknown` inputs (used by the json-path plugin).\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n base: T,\n patch: Record<string, unknown>,\n options?: DeepMergeOptions,\n): T;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options?: DeepMergeOptions,\n): unknown;\n\nexport function deepMerge(\n base: unknown,\n patch: unknown,\n options: DeepMergeOptions = {},\n): unknown {\n const {\n conflictResolution = 'prefer-patch',\n arrayMode = 'replace',\n protectProto = true,\n onNonPrimitiveArrayReplace,\n } = options;\n\n // Non-object / null handling — delegate to conflict resolution.\n if (typeof base !== 'object' || base === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n if (typeof patch !== 'object' || patch === null) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Arrays — handled *before* the object merge so array-of-objects\n // aren't accidentally treated as plain records.\n if (Array.isArray(base) && Array.isArray(patch)) {\n if (\n arrayMode === 'concat-primitives' &&\n isPrimitiveArray(base) &&\n isPrimitiveArray(patch)\n ) {\n return [...new Set([...base, ...patch])];\n }\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // If only one side is an array, treat as scalar collision.\n if (Array.isArray(base) || Array.isArray(patch)) {\n return conflictResolution === 'prefer-patch' ? patch : base;\n }\n\n // Plain object merge.\n const baseObj = base as Record<string, unknown>;\n const patchObj = patch as Record<string, unknown>;\n const out: Record<string, unknown> = { ...baseObj };\n\n for (const [k, v] of Object.entries(patchObj)) {\n if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;\n\n const existing = out[k];\n if (\n v !== null &&\n typeof v === 'object' &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === 'object' &&\n !Array.isArray(existing)\n ) {\n // Recursive merge for nested plain objects.\n out[k] = deepMerge(existing, v, options);\n } else if (Array.isArray(v) && Array.isArray(existing)) {\n // Delegate to top-level array handling so arrayMode\n // (e.g. 'concat-primitives') applies to nested arrays too.\n // Fire debug hook when a non-primitive array replaces an existing\n // array (for non-primitive arrays, concat-primitives is a no-op and\n // the result is always a wholesale replacement).\n if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {\n onNonPrimitiveArrayReplace(k, existing.length, v.length);\n }\n out[k] = deepMerge(existing, v, options);\n } else if (v !== undefined) {\n // Fire debug hook when a non-primitive (object) array replaces an\n // existing value in concat-primitives mode.\n if (\n onNonPrimitiveArrayReplace &&\n Array.isArray(v) &&\n !isPrimitiveArray(v)\n ) {\n const existingLen = Array.isArray(existing) ? existing.length : 0;\n onNonPrimitiveArrayReplace(k, existingLen, v.length);\n }\n out[k] = v;\n }\n // When v === undefined, leave the existing value untouched\n // (this matches config-loader's behaviour: undefined in patch\n // means \"don't change this key\").\n }\n\n return out;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import { toErrorMessage } from './error.js';\n\nexport interface SafeParseResult<T> {\n ok: boolean;\n value?: T | undefined;\n error?: string | undefined;\n}\n\nexport function safeParse<T = unknown>(input: string, maxBytes = 5_000_000): SafeParseResult<T> {\n if (input.length > maxBytes) {\n return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };\n }\n try {\n return { ok: true, value: JSON.parse(input) as T };\n } catch (err) {\n return {\n ok: false,\n error: toErrorMessage(err),\n };\n }\n}\n\nexport function safeStringify(value: unknown, pretty = false): string {\n const seen = new WeakSet();\n const replacer = (_k: string, v: unknown): unknown => {\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Error) {\n return { name: v.name, message: v.message, stack: v.stack };\n }\n if (typeof v === 'object' && v !== null) {\n if (seen.has(v as object)) return '[Circular]';\n seen.add(v as object);\n }\n return v;\n };\n try {\n return JSON.stringify(value, replacer, pretty ? 2 : undefined) ?? 'null';\n } catch (err) {\n return JSON.stringify({\n __serialization_error: toErrorMessage(err),\n });\n }\n}\n\n/**\n * Attempt to parse JSON5-style input and return a valid JSON string.\n * Handles trailing commas, single-line comments, and unquoted keys\n * that are common in provider output.\n *\n * Returns the sanitized string if it parses successfully as JSON,\n * or `null` if the input cannot be made valid. Callers use this to\n * decide whether to proceed with the parsed result or fall back to\n * raw handling.\n */\nexport function sanitizeJsonString(s: string): string | null {\n let out = s.trim();\n\n // Stage 1: strip single-line comments (// to end of line) that appear\n // outside of string values. This is a heuristic: comments inside strings\n // are preserved because we only strip // when preceded by a char that\n // strongly suggests we're not in a string (quote count modulo 2 is even).\n out = stripSingleLineComments(out);\n\n // Stage 2: strip trailing commas before } or ]\n out = out.replace(/,(\\s*[}\\]])/g, '$1');\n\n // Stage 3: escape literal control characters that appear *inside* string\n // values. Models frequently emit raw newlines/tabs inside a code payload\n // (e.g. edit's old_string/new_string) instead of the required \\n / \\t, which\n // makes JSON.parse throw. This is the single most common malformed-args case.\n out = escapeControlCharsInStrings(out);\n\n // Stage 4: attempt full parse; return null if it fails so callers can\n // distinguish \"already valid JSON\" from \"unrecoverable\".\n try {\n JSON.parse(out);\n return out;\n } catch {\n return null; // stripped but still not valid JSON; caller handles it\n }\n}\n\n/**\n * Walk the string tracking whether we are inside a JSON string literal and\n * replace raw control characters (U+0000–U+001F) that appear inside strings\n * with their valid JSON escape sequences. Characters outside strings are left\n * untouched (insignificant whitespace stays as-is). Already-escaped sequences\n * are not double-escaped because we only act on *literal* control bytes.\n */\nfunction escapeControlCharsInStrings(s: string): string {\n let inString = false;\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s[i - 1] !== '\\\\')) {\n inString = !inString;\n out += c;\n continue;\n }\n const code = c.charCodeAt(0);\n if (inString && code < 0x20) {\n switch (c) {\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n default:\n out += `\\\\u${code.toString(16).padStart(4, '0')}`;\n }\n continue;\n }\n out += c;\n }\n return out;\n}\n\nfunction stripSingleLineComments(s: string): string {\n let inString = false;\n const chars: string[] = [];\n let i = 0;\n while (i < s.length) {\n const c = s.charAt(i);\n if (c === '\"' && (i === 0 || s.charAt(i - 1) !== '\\\\')) {\n inString = !inString;\n chars.push(c);\n } else if (c === '/' && s.charAt(i + 1) === '/' && !inString) {\n // skip to end of line\n while (i < s.length && s.charAt(i) !== '\\n') i++;\n } else {\n chars.push(c);\n }\n i++;\n }\n return chars.join('');\n}\n","import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack — global root. */\n globalRoot: string;\n /**\n * ~/.wrongstack — directory for user-global stateful config files\n * (mode.json, theme.json, …). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key — 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md — user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills — user-global skills. */\n globalSkills: string;\n /** ~/.wrongstack/prompts — user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/cache — fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json — cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir — NOT inside the repo — so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history — REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json — optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json — per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md — committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills — committed project skills. */\n inProjectSkills: string;\n /** <project>/.wrongstack/worktrees — git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json — goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/specs — SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs — SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json — SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json — plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase — AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/sync.json — CloudSync configuration */\n syncConfig: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state — config, secrets, logs, projects/, mailboxes — away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n","import { randomBytes } from 'node:crypto';\nimport type { Dirent } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\nimport type {\n ResumedSession,\n SessionData,\n SessionEvent,\n SessionMetadata,\n SessionStore,\n SessionSummary,\n SessionWriter,\n} from '../types/session.js';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { toErrorMessage } from '../utils/index.js';\n// ─── Session ID naming ───────────────────────────────────────────────────────\n\n/** Sanitize a model name for use in filenames: alphanumeric + dash + underscore. */\nfunction sanitizeModel(model: string): string {\n return model\n .replace(/[^a-zA-Z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n\n/**\n * Generate a session ID in the format:\n * `YYYY-MM-DD/HH-MM-SSZ[_model]_xxxx.jsonl`\n *\n * Examples:\n * `2026-06-06/12-30-45Z_claude-sonnet_a1b2.jsonl`\n * `2026-06-06/14-22-10Z_a1b2.jsonl` (no model)\n *\n * The date prefix becomes a subdirectory so sessions group naturally by day.\n * The model name (when available) lets you see at a glance which provider was\n * used, without opening the file. The 4-byte random suffix prevents collisions\n * within the same second.\n */\nfunction generateSessionId(startedAt: string, model?: string): string {\n const date = startedAt.slice(0, 10); // \"2026-06-06\"\n const time = startedAt.slice(11, 19).replace(/:/g, '-'); // \"12-30-45\"\n const suffix = randomBytes(2).toString('hex'); // \"a1b2\"\n const modelPart = model ? `_${sanitizeModel(model)}` : '';\n return `${date}/${time}Z${modelPart}_${suffix}`;\n}\n\nexport interface SessionStoreOptions {\n dir: string;\n /** Optional EventBus for emitting session diagnostics. */\n events?: EventBus | undefined;\n /**\n * Optional secret scrubber. When set, `user_input` and `llm_response` event\n * content is scrubbed before being persisted to the JSONL log and the\n * summary sidecar — so a secret a user pastes or the model echoes does not\n * sit in cleartext on disk (and does not ride along in history cloud-sync).\n * Tool output is already scrubbed upstream by the executor; this closes the\n * conversation-turn gap (finding F-06).\n */\n secretScrubber?: SecretScrubber | undefined;\n}\n\n/**\n * Cache entry for load() — stores the parsed SessionData along with the\n * file's mtimeMs and size at the time of loading. On subsequent calls,\n * if the file's mtimeMs+size match, we return the cached data without\n * re-reading or re-parsing the JSONL.\n */\ninterface LoadCacheEntry {\n mtimeMs: number;\n size: number;\n data: SessionData;\n}\n\ninterface IndexCacheEntry {\n mtimeMs: number;\n size: number;\n summaries: SessionSummary[];\n}\n\nexport class DefaultSessionStore implements SessionStore {\n private readonly dir: string;\n private readonly events?: EventBus | undefined;\n private readonly secretScrubber?: SecretScrubber | undefined;\n\n /**\n * In-memory cache for load() results, keyed by session ID. The cache is\n * invalidated when the file's mtimeMs or size changes (indicating the\n * file was written to). This eliminates redundant full-file reads and\n * JSON parses when the same session is loaded multiple times within the\n * store's lifetime (e.g., webui session detail views, list() fallbacks).\n *\n * Max size is capped to prevent unbounded memory growth in long-running\n * processes. When the limit is reached, the oldest entry is evicted.\n */\n private readonly _loadCache = new Map<string, LoadCacheEntry>();\n private _indexCache: IndexCacheEntry | null = null;\n private static readonly LOAD_CACHE_MAX_ENTRIES = 50;\n\n constructor(opts: SessionStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.secretScrubber = opts.secretScrubber;\n }\n\n /**\n * Clear the load() cache. Useful for testing or when the caller knows\n * the file has changed externally (e.g., another process wrote to it).\n */\n clearLoadCache(sessionId?: string): void {\n if (sessionId !== undefined) {\n this._loadCache.delete(sessionId);\n } else {\n this._loadCache.clear();\n }\n }\n\n // ── Storage event helpers ───────────────────────────────────────────────────\n\n private emitRead(\n sessionId: string,\n filePath: string,\n operation: 'load' | 'list' | 'summary' | 'index_read',\n outcome: 'success' | 'failure',\n durationMs: number,\n error?: string,\n ): void {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n outcome,\n durationMs,\n ...(error !== undefined ? { error } : {}),\n });\n }\n\n private emitWrite(\n sessionId: string,\n filePath: string,\n operation: 'create' | 'resume' | 'append' | 'flush' | 'close' | 'index_append' | 'compact' | 'checkpoint',\n outcome: 'success' | 'failure',\n durationMs: number,\n eventCount?: number,\n error?: string,\n ): void {\n this.events?.emit('storage.write', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n outcome,\n durationMs,\n ...(eventCount !== undefined ? { eventCount } : {}),\n ...(error !== undefined ? { error } : {}),\n });\n }\n\n private emitError(\n sessionId: string,\n filePath: string,\n operation: string,\n error: string,\n recoverable: boolean,\n ): void {\n this.events?.emit('storage.error', {\n sessionId,\n store: 'session',\n filePath,\n operation,\n error,\n recoverable,\n });\n }\n\n /** Absolute path to the session index file. */\n private get indexFile(): string {\n return path.join(this.dir, '_index.jsonl');\n }\n\n /** Join session ID to its absolute path within the store directory. */\n private sessionPath(id: string, ext: '.jsonl' | '.summary.json'): string {\n return path.join(this.dir, `${id}${ext}`);\n }\n\n /**\n * Ensure the directory implied by the session ID exists. When the ID\n * contains a date prefix like `2026-06-06/...`, this creates the date\n * subdirectory so sessions group naturally by day.\n */\n private async ensureShardDir(id: string): Promise<string> {\n const dirPath = path.dirname(path.join(this.dir, id));\n await ensureDir(dirPath);\n return dirPath;\n }\n\n async create(meta: Omit<SessionMetadata, 'startedAt'>): Promise<SessionWriter> {\n const startedAt = new Date().toISOString();\n const id =\n meta.id && meta.id.length > 0\n ? meta.id\n : generateSessionId(startedAt, meta.model ?? meta.provider);\n const shardDir = await this.ensureShardDir(id);\n const file = path.join(shardDir, `${path.basename(id)}.jsonl`);\n const t0 = Date.now();\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n } catch (err) {\n this.emitError(id, file, 'create', toErrorMessage(err), false);\n throw new Error(\n `Failed to open session file: ${toErrorMessage(err)}`,\n { cause: err },\n );\n }\n try {\n const writer = new FileSessionWriter(id, handle, startedAt, meta, this.events, {\n dir: shardDir,\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n });\n this.emitWrite(id, file, 'create', 'success', Date.now() - t0);\n return writer;\n /* v8 ignore start -- defensive: FileSessionWriter ctor does not throw in practice */\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n this.emitError(id, file, 'create', toErrorMessage(err), true);\n throw err;\n }\n /* v8 ignore stop */\n }\n\n async resume(id: string): Promise<ResumedSession> {\n const file = this.sessionPath(id, '.jsonl');\n const t0 = Date.now();\n const data = await this.load(id);\n let handle: fsp.FileHandle;\n try {\n handle = await fsp.open(file, 'a', 0o600);\n /* v8 ignore start -- defensive: load() above already validated the file is readable */\n } catch (err) {\n this.emitError(id, file, 'resume', toErrorMessage(err), false);\n throw new Error(\n `Failed to open session \"${id}\" for append: ${toErrorMessage(err)}`,\n { cause: err },\n );\n }\n /* v8 ignore stop */\n try {\n const writer = new FileSessionWriter(\n id,\n handle,\n new Date().toISOString(),\n {\n id,\n model: data.metadata.model,\n provider: data.metadata.provider,\n },\n this.events,\n {\n resumed: true,\n // Shard directory (sessions/<date>/) — must match create() so the\n // .summary.json sidecar lands next to the JSONL instead of the\n // sessions root (where summaryFor() would never find it).\n dir: path.dirname(file),\n filePath: file,\n secretScrubber: this.secretScrubber,\n onClose: (s) => this.appendToIndex(s),\n },\n );\n this.emitWrite(id, file, 'resume', 'success', Date.now() - t0);\n return { writer, data };\n /* v8 ignore start -- defensive: FileSessionWriter ctor does not throw in practice */\n } catch (err) {\n await handle.close().catch((e) => console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.handle_close_failed',\n message: e instanceof Error ? e.message : String(e),\n timestamp: new Date().toISOString(),\n })));\n this.emitError(id, file, 'resume', toErrorMessage(err), true);\n throw err;\n }\n /* v8 ignore stop */\n }\n\n async load(id: string): Promise<SessionData> {\n const file = this.sessionPath(id, '.jsonl');\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n let cacheHit = false;\n try {\n // Stat the file first to check the cache. The stat is cheap (no content\n // read) and lets us skip the full readFile + JSON parse when the file\n // hasn't changed since the last load.\n const s = await fsp.stat(file);\n const stat: { mtimeMs: number; size: number } = { mtimeMs: s.mtimeMs, size: s.size };\n\n // Check cache: if mtimeMs AND size match, the file hasn't changed.\n const cached = this._loadCache.get(id);\n if (cached && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) {\n cacheHit = true;\n // Update insertion order to prevent frequent-access sessions from being\n // evicted by the LRU eviction logic.\n this._loadCache.delete(id);\n this._loadCache.set(id, cached);\n return cached.data;\n }\n\n // Cache miss — do the full read + parse.\n const raw = await fsp.readFile(file, 'utf8');\n const lines = raw.split('\\n').filter((l) => l.trim());\n const events: SessionEvent[] = [];\n for (const line of lines) {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\n ) {\n events.push(parsed as SessionEvent);\n }\n } catch {\n // skip malformed JSON\n }\n }\n const meta = this.metaFromEvents(id, events);\n const { messages, usage } = this.replay(events, id);\n // Extract tool_call_end events for TUI tool entry rendering on resume.\n const toolCallEnds = extractToolCallEnds(events);\n const data: SessionData = { metadata: meta, events, messages, usage, toolCallEnds };\n\n // Update the cache. Evict oldest entry if at capacity.\n if (this._loadCache.size >= DefaultSessionStore.LOAD_CACHE_MAX_ENTRIES) {\n // Map iteration order is insertion order — delete the first key.\n const oldest = this._loadCache.keys().next().value;\n if (oldest !== undefined) {\n this._loadCache.delete(oldest);\n }\n }\n this._loadCache.set(id, { mtimeMs: stat.mtimeMs, size: stat.size, data });\n\n return data;\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n throw err;\n } finally {\n this.emitRead(id, file, 'load', outcome, Date.now() - t0, errorMsg);\n if (cacheHit) {\n this.events?.emit('storage.cache_hit', {\n sessionId: id,\n store: 'session',\n filePath: file,\n operation: 'load',\n durationMs: Date.now() - t0,\n });\n }\n }\n }\n\n async list(limit = 20): Promise<SessionSummary[]> {\n try {\n await ensureDir(this.dir);\n // Try the index first; fall back to directory scan if the index is\n // missing, empty, or unreadable.\n const indexed = await this.readIndex();\n if (indexed.length > 0) {\n indexed.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return indexed.slice(0, limit);\n }\n // Index unavailable — fall back to full directory scan + summary parse.\n const ids = await this.collectSessionIds(this.dir);\n /* v8 ignore next -- summaryFor() never rejects for a collected id (its .jsonl exists) */\n const sessions = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const out = sessions.filter((s): s is SessionSummary => s !== null);\n out.sort((a, b) => {\n if (a.startedAt < b.startedAt) return 1;\n if (a.startedAt > b.startedAt) return -1;\n return a.id.localeCompare(b.id);\n });\n return out.slice(0, limit);\n } catch {\n return [];\n }\n }\n\n // ── Session index (_index.jsonl) ─────────────────────────────────────────\n //\n // One JSON line per closed session, appended atomically on close().\n // When a session is deleted, a tombstone {action:\"delete\",id:\"...\"} is\n // appended. On read, tombstones filter out matching session entries.\n // This keeps listing O(lines-in-index) instead of O(files-on-disk).\n //\n // The index auto-compacts every N appends to prevent unbounded growth\n // from tombstones and duplicate entries (resume cycles).\n\n private indexAppendCount = 0;\n private static readonly COMPACT_EVERY = 30;\n\n /** Append a session summary to the index. */\n private async appendToIndex(summary: SessionSummary): Promise<void> {\n // Note: storage.write for this operation is emitted by FileSessionWriter.doClose()\n // so it can include the traceId. Do NOT emit here to avoid duplicates.\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify(summary) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this._indexCache = null;\n this.indexAppendCount++;\n // Auto-compact the index periodically to remove tombstones and duplicates.\n if (this.indexAppendCount >= DefaultSessionStore.COMPACT_EVERY) {\n await this.compactIndex();\n this.indexAppendCount = 0;\n }\n } catch {\n // best-effort — error surfaced via the storage.write event in doClose()\n }\n }\n\n /** Append a tombstone entry for a deleted session. */\n private async writeTombstone(id: string): Promise<void> {\n try {\n await ensureDir(this.dir);\n const line = JSON.stringify({ action: 'delete', id }) + '\\n';\n await fsp.appendFile(this.indexFile, line, 'utf8');\n this._indexCache = null;\n this.indexAppendCount++;\n } catch {\n // best-effort\n }\n }\n\n /**\n * Compact the index: read all entries, drop tombstones, deduplicate\n * (keep latest per session), and rewrite. Atomic via temp+rename.\n */\n private async compactIndex(): Promise<void> {\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n const entries = await this.readIndex();\n if (entries.length === 0) return;\n const tmp = `${this.indexFile}.compact.tmp`;\n const lines = entries.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n this._indexCache = null;\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n } finally {\n // Compact is internal — use 'session' as the session ID placeholder.\n this.emitWrite('~compact~', this.indexFile, 'compact', outcome, Date.now() - t0, undefined, errorMsg);\n }\n }\n\n /**\n * Read the index file and return deduplicated session summaries.\n * Entries with a matching tombstone are filtered out.\n * Returns empty array when the index doesn't exist or is corrupt.\n */\n private async readIndex(): Promise<SessionSummary[]> {\n let stat: { mtimeMs: number; size: number };\n try {\n const s = await fsp.stat(this.indexFile);\n stat = { mtimeMs: s.mtimeMs, size: s.size };\n } catch {\n this._indexCache = null;\n return [];\n }\n\n if (\n this._indexCache !== null &&\n this._indexCache.mtimeMs === stat.mtimeMs &&\n this._indexCache.size === stat.size\n ) {\n return [...this._indexCache.summaries];\n }\n\n let raw: string;\n try {\n raw = await fsp.readFile(this.indexFile, 'utf8');\n } catch {\n this._indexCache = null;\n return [];\n }\n const deleted = new Set<string>();\n const seen = new Map<string, SessionSummary>();\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as { action?: string | undefined; id?: string | undefined } & SessionSummary;\n if (entry.action === 'delete' && entry.id) {\n deleted.add(entry.id);\n seen.delete(entry.id);\n continue;\n }\n if (entry.id && !deleted.has(entry.id)) {\n // Keep the latest entry for each session (multiple appends on resume).\n seen.set(entry.id, entry as SessionSummary);\n }\n } catch {\n // skip corrupt lines\n }\n }\n const summaries = Array.from(seen.values());\n this._indexCache = { ...stat, summaries };\n return [...summaries];\n }\n\n /**\n * Rebuild the index from disk by scanning all sessions and writing a\n * fresh _index.jsonl. Useful after manual cleanup or index corruption.\n */\n async rebuildIndex(): Promise<number> {\n const ids = await this.collectSessionIds(this.dir);\n /* v8 ignore next -- summaryFor() never rejects for a collected id (its .jsonl exists) */\n const summaries = await Promise.all(ids.map((id) => this.summaryFor(id).catch(() => null))); /* best-effort */\n const valid = summaries.filter((s): s is SessionSummary => s !== null);\n // Atomic rewrite: write to temp, then rename.\n const tmp = `${this.indexFile}.tmp`;\n const lines = valid.map((s) => JSON.stringify(s)).join('\\n') + '\\n';\n await fsp.writeFile(tmp, lines, 'utf8');\n await fsp.rename(tmp, this.indexFile);\n this._indexCache = null;\n return valid.length;\n }\n\n /** Recursively collect session IDs from date-shard subdirectories.\n * IDs include the date-prefix path (e.g. \"2026-06-06/17-46-57Z_…\").\n * Skips `.jsonl`/`.summary.json` root files, dot-files, and\n * sub-directories that belong to fleet/subagent sessions. */\n private async collectSessionIds(\n dir: string,\n prefix = '',\n depth = 0,\n ): Promise<string[]> {\n const ids: string[] = [];\n let entries: Dirent[];\n try {\n entries = await fsp.readdir(dir, { withFileTypes: true });\n } catch {\n return ids;\n }\n for (const entry of entries) {\n // Skip dot-files and known non-session directories\n if (entry.name.startsWith('.') && entry.name !== '.wrongstack') continue;\n if (entry.name === 'shared' || entry.name === 'subagents' || entry.name === 'attachments')\n continue;\n if (entry.isDirectory()) {\n // Date-shard directories become the prefix for their contents\n const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;\n ids.push(...(await this.collectSessionIds(path.join(dir, entry.name), childPrefix, depth + 1)));\n } else if (entry.isFile() && entry.name.endsWith('.jsonl')) {\n // Skip the session index itself — it's bookkeeping, not a session log.\n // (Only skip THIS file at root, not every root-level jsonl: flat/legacy\n // sessions and the test fixtures live directly under the sessions dir.)\n if (entry.name === '_index.jsonl') continue;\n const base = entry.name.replace(/\\.jsonl$/, '');\n // Subagent session logs live under subagents/ which we skip above.\n ids.push(prefix ? `${prefix}/${base}` : base);\n }\n }\n return ids;\n }\n\n private async summaryFor(id: string): Promise<SessionSummary> {\n const manifest = this.sessionPath(id, '.summary.json');\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n const raw = await fsp.readFile(manifest, 'utf8');\n this.emitRead(id, manifest, 'summary', 'success', Date.now() - t0);\n return JSON.parse(raw) as SessionSummary;\n } catch {\n const full = this.sessionPath(id, '.jsonl');\n const stat = await fsp.stat(full);\n const summary = await this.summarize(id, stat.mtime.toISOString());\n await atomicWrite(manifest, JSON.stringify(summary), { mode: 0o600 }).catch((err) => {\n const msg = toErrorMessage(err);\n this.emitError(id, manifest, 'summary_fallback', msg, true);\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.manifest_write_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n outcome = 'failure';\n errorMsg = 'summary fallback — manifest rebuilt';\n this.emitRead(id, manifest, 'summary', outcome, Date.now() - t0, errorMsg);\n return summary;\n }\n }\n\n /**\n * Delete a session and all associated files: JSONL, summary, plan/todos\n * sidecars, and the session directory (fleet.json, shared/, subagents/).\n *\n * Individual file deletions are best-effort (logged as structured warnings),\n * but a tombstone is always written so readIndex() filters this session out.\n * If the session directory itself can't be removed, the error is surfaced\n * to the caller so prune() can report it.\n */\n private async deleteSession(id: string): Promise<void> {\n const jsonlPath = this.sessionPath(id, '.jsonl');\n const summaryPath = this.sessionPath(id, '.summary.json');\n const shardDir = path.dirname(path.join(this.dir, id));\n const base = path.basename(id);\n const sessDir = path.join(shardDir, base);\n\n const deletions: Array<Promise<void>> = [\n fsp.unlink(jsonlPath),\n fsp.unlink(summaryPath),\n fsp.unlink(path.join(shardDir, `${base}.plan.json`)),\n fsp.unlink(path.join(shardDir, `${base}.todos.json`)),\n ];\n\n const results = await Promise.allSettled(deletions);\n for (const r of results) {\n if (r.status === 'rejected') {\n const msg = r.reason instanceof Error ? r.reason.message : String(r.reason);\n // ENOENT is expected (file may not exist — sidecars are optional).\n if ((r.reason as NodeJS.ErrnoException)?.code !== 'ENOENT') {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.delete_failed',\n sessionId: id,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n }\n\n // Remove the session directory (may contain fleet.json, shared/, subagents/).\n /* v8 ignore start -- defensive: rm with force:true rarely rejects */\n await fsp.rm(sessDir, { recursive: true, force: true }).catch((err) => {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'session_store.rmdir_failed',\n sessionId: id,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n });\n /* v8 ignore stop */\n\n // Write an index tombstone so readIndex() filters this session out.\n await this.writeTombstone(id);\n }\n\n async delete(id: string): Promise<void> {\n await this.deleteSession(id);\n }\n\n async prune(maxAgeDays = 30): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 86_400_000;\n let deleted = 0;\n\n // Read the active session lock to avoid pruning the current session.\n let activeSessionId: string | null = null;\n try {\n const raw = await fsp.readFile(path.join(this.dir, 'active.json'), 'utf8');\n const active = JSON.parse(raw) as { sessionId?: string | undefined };\n activeSessionId = active.sessionId ?? null;\n } catch {\n // no active.json — nothing to protect\n }\n\n const isPrunableJsonl = (name: string): boolean =>\n name.endsWith('.jsonl') &&\n name !== '_index.jsonl' &&\n name !== '_mailbox.jsonl' &&\n !name.endsWith('.replay.jsonl') &&\n !name.endsWith('.audit.jsonl');\n\n const pruneFile = async (dir: string, name: string, prefix: string): Promise<void> => {\n const jsonlPath = path.join(dir, name);\n try {\n const stat = await fsp.stat(jsonlPath);\n if (stat.mtimeMs >= cutoff) return;\n /* v8 ignore start -- defensive: file vanished between readdir and stat */\n } catch {\n return;\n }\n /* v8 ignore stop */\n const base = name.replace(/\\.jsonl$/, '');\n const id = prefix ? `${prefix}/${base}` : base;\n // Never prune the currently active session.\n if (activeSessionId && id === activeSessionId) return;\n await this.deleteSession(id);\n deleted++;\n };\n\n /* v8 ignore next -- defensive: store dir is ensured before prune runs */\n const entries = await fsp.readdir(this.dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (entry.isFile()) {\n // Flat legacy sessions at the sessions root — pre-shard layout.\n // A shard-only scan left these accumulating forever.\n if (isPrunableJsonl(entry.name)) await pruneFile(this.dir, entry.name, '');\n continue;\n }\n /* v8 ignore next -- defensive: root entries are only files or directories */\n if (!entry.isDirectory()) continue;\n // entry.name is a date-shard like \"2026-06-06\"\n const dateDir = path.join(this.dir, entry.name);\n /* v8 ignore next -- defensive: dateDir came from readdir and is readable */\n const files = await fsp.readdir(dateDir, { withFileTypes: true }).catch(() => []);\n for (const file of files) {\n if (!file.isFile() || !isPrunableJsonl(file.name)) continue;\n await pruneFile(dateDir, file.name, entry.name);\n }\n }\n if (deleted > 0) {\n // Compact the index to remove tombstones for deleted sessions.\n /* v8 ignore next -- best-effort: compactIndex swallows its own errors */\n await this.compactIndex().catch(() => undefined); /* best-effort */\n }\n // Clean up empty date-shard directories left behind after pruning.\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dateDir = path.join(this.dir, entry.name);\n try {\n const remaining = await fsp.readdir(dateDir);\n if (remaining.length === 0) {\n /* v8 ignore next -- best-effort: rmdir of a confirmed-empty dir does not reject */\n await fsp.rmdir(dateDir).catch(() => undefined);\n }\n } catch {\n // best-effort\n }\n }\n return deleted;\n }\n\n async clearHistory(id: string): Promise<void> {\n await this.ensureShardDir(id);\n const file = this.sessionPath(id, '.jsonl');\n const meta = this.sessionPath(id, '.summary.json');\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id,\n model: 'unknown',\n provider: 'unknown',\n })}\\n`;\n await fsp.writeFile(file, record, 'utf8');\n await fsp.unlink(meta).catch(() => undefined);\n }\n\n private async summarize(id: string, mtime: string): Promise<SessionSummary> {\n try {\n const data = await this.load(id);\n const firstUser = data.events.find((e) => e.type === 'user_input');\n const title =\n firstUser && firstUser.type === 'user_input'\n ? userInputTitle(firstUser.content)\n : '(empty session)';\n\n // Compute enriched stats from events.\n let iterationCount = 0;\n let toolCallCount = 0;\n let toolErrorCount = 0;\n let fileChangeCount = 0;\n const toolBreakdown: Record<string, number> = {};\n let outcome: SessionSummary['outcome'] ;\n const lastEvent = data.events[data.events.length - 1];\n\n for (const e of data.events) {\n if (e.type === 'in_flight_start') iterationCount++;\n else if (e.type === 'tool_call_start') {\n toolCallCount++;\n toolBreakdown[e.name] = (toolBreakdown[e.name] ?? 0) + 1;\n } else if (e.type === 'tool_result' && e.isError) toolErrorCount++;\n else if (e.type === 'file_snapshot') fileChangeCount += e.files.length;\n }\n\n // Determine outcome from the last event.\n if (lastEvent?.type === 'session_end') {\n outcome = 'completed';\n } else if (lastEvent?.type === 'in_flight_start') {\n outcome = 'aborted';\n } else if (data.events.some((e) => e.type === 'error')) {\n outcome = 'error';\n }\n\n return {\n id,\n title,\n startedAt: data.metadata.startedAt,\n endedAt: data.metadata.endedAt,\n model: data.metadata.model ?? 'unknown',\n provider: data.metadata.provider ?? 'unknown',\n tokenTotal: data.usage.input + data.usage.output,\n iterationCount: iterationCount > 0 ? iterationCount : undefined,\n toolCallCount: toolCallCount > 0 ? toolCallCount : undefined,\n toolErrorCount: toolErrorCount > 0 ? toolErrorCount : undefined,\n fileChangeCount: fileChangeCount > 0 ? fileChangeCount : undefined,\n toolBreakdown: Object.keys(toolBreakdown).length > 0 ? toolBreakdown : {},\n outcome,\n };\n } catch {\n return {\n id,\n title: '(damaged)',\n startedAt: mtime,\n model: 'unknown',\n provider: 'unknown',\n tokenTotal: 0,\n };\n }\n }\n\n private metaFromEvents(id: string, events: SessionEvent[]): SessionMetadata {\n const start = events.find((e) => e.type === 'session_start');\n // Use the LAST session_end: resume cycles append a new session_end on\n // every clean exit, and legacy /save commands wrote mid-stream markers.\n const end = events.findLast((e) => e.type === 'session_end');\n return {\n id,\n startedAt: start?.ts ?? new Date(0).toISOString(),\n endedAt: end?.ts,\n model: start?.model,\n provider: start?.provider,\n pendingToolUses: end?.pendingToolUses,\n };\n }\n\n private replay(\n events: SessionEvent[],\n sessionId = 'unknown',\n ): { messages: Message[]; usage: SessionData['usage'] } {\n const messages: Message[] = [];\n let usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n const openToolUses = new Set<string>();\n for (const e of events) {\n if (e.type === 'user_input') {\n openToolUses.clear();\n messages.push({ role: 'user', content: e.content, ts: e.ts });\n } else if (e.type === 'llm_response') {\n messages.push({ role: 'assistant', content: e.content, ts: e.ts });\n for (const b of e.content) {\n if (b.type === 'tool_use') openToolUses.add(b.id);\n }\n usage = {\n input: usage.input + (e.usage.input ?? 0),\n output: usage.output + (e.usage.output ?? 0),\n cacheRead: (usage.cacheRead ?? 0) + (e.usage.cacheRead ?? 0),\n cacheWrite: (usage.cacheWrite ?? 0) + (e.usage.cacheWrite ?? 0),\n };\n } else if (e.type === 'tool_result') {\n if (!openToolUses.has(e.id)) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `Orphan tool_result \"${e.id}\" has no matching tool_use`,\n });\n continue;\n }\n openToolUses.delete(e.id);\n // Provider protocol: tool_result blocks live in a USER message that\n // follows the assistant's tool_use turn — never inside the assistant\n // message itself (repairToolUseAdjacency would treat that as broken\n // adjacency and strip the tool_use blocks, silently dropping the\n // assistant turn on resume). Consecutive results from one turn are\n // grouped into a single user message.\n const resultBlock: ContentBlock = {\n type: 'tool_result',\n tool_use_id: e.id,\n content: typeof e.content === 'string' ? e.content : JSON.stringify(e.content),\n is_error: e.isError,\n };\n const last = messages[messages.length - 1];\n const lastIsToolResultUser =\n last?.role === 'user' &&\n Array.isArray(last.content) &&\n last.content.every((b) => (b as ContentBlock).type === 'tool_result');\n if (lastIsToolResultUser && Array.isArray(last.content)) {\n last.content.push(resultBlock);\n } else {\n messages.push({ role: 'user', content: [resultBlock], ts: e.ts });\n }\n }\n }\n if (openToolUses.size > 0) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail: `${openToolUses.size} tool_use blocks without matching results - replay repaired`,\n });\n }\n const repaired = repairToolUseAdjacency(messages);\n if (repaired.report.changed) {\n this.events?.emit('session.damaged', {\n sessionId,\n detail:\n `Repaired replay adjacency: removed ${repaired.report.removedToolUses.length} tool_use, ` +\n `${repaired.report.removedToolResults.length} tool_result, ` +\n `${repaired.report.removedMessages} empty messages`,\n });\n }\n return { messages: repaired.messages, usage };\n }\n}\n\n/**\n * Extract tool execution records from `tool_call_end` events in the JSONL.\n * These are used by the TUI to render tool entries (name, duration, ok/error)\n * when a session is resumed. Events are returned in JSONL order (the order\n * they appear in the file, which is chronological insertion order).\n */\nfunction extractToolCallEnds(events: SessionEvent[]): SessionData['toolCallEnds'] {\n const result: SessionData['toolCallEnds'] = [];\n for (const e of events) {\n if (e.type === 'tool_call_end') {\n result.push({\n name: e.name,\n id: e.id,\n durationMs: e.durationMs,\n ok: e.ok ?? false,\n outputBytes: e.outputBytes,\n outputTokens: e.outputTokens,\n outputLines: e.outputLines,\n });\n }\n }\n return result;\n}\n\nclass FileSessionWriter implements SessionWriter {\n private closed = false;\n private closePromise: Promise<void> | null = null;\n private manifestFile: string;\n private summary: SessionSummary;\n private tokenIn = 0;\n private tokenOut = 0;\n private readonly filePath: string;\n get transcriptPath(): string | undefined {\n return this.filePath || undefined;\n }\n /**\n * Lazy session_start/session_resumed init, shared by all appenders.\n * A single promise (not a boolean) so a second append racing the first\n * can't push its event into the buffer BEFORE the first append's event —\n * every appender awaits the same init and resumes in FIFO call order.\n */\n private initPromise: Promise<void> | null = null;\n private ensureInit(): Promise<void> {\n if (!this.initPromise) this.initPromise = this.writeSessionStartLazy();\n return this.initPromise;\n }\n private readonly resumed: boolean;\n private appendFailCount = 0;\n private lastAppendWarnAt = 0;\n private readonly secretScrubber?: SecretScrubber | undefined;\n private readonly onCloseCb?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n /** Implements SessionWriter.traceId — propagated from ContextInit.traceId. */\n traceId: string | undefined;\n\n // ── Write buffer — batches events to reduce per-event disk I/O ─────────\n //\n // Every append() pushes the scrubbed event into an in-memory buffer instead\n // of calling handle.appendFile() synchronously. The buffer flushes to disk\n // when it reaches FLUSH_SIZE events OR after FLUSH_INTERVAL_MS of inactivity.\n // This cuts the number of disk writes by ~95% without changing the on-disk\n // format — the JSONL is still one JSON object per line.\n private writeBuffer: SessionEvent[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly FLUSH_INTERVAL_MS = 500;\n private static readonly FLUSH_SIZE = 50;\n\n // ── Write serialization ─────────────────────────────────────────────────\n //\n // All disk writes are funneled through a FIFO promise chain. Without it,\n // a timer-driven flush racing an explicit flush()/close() issues two\n // concurrent appendFile() calls on the shared O_APPEND handle — the kernel\n // may complete them out of order (chronology breaks) or, for large\n // batches, interleave partial writes (torn JSONL lines). The chain keeps\n // exactly one write in flight; failures don't break the chain.\n private writeChain: Promise<void> = Promise.resolve();\n\n /** Enqueue a write on the FIFO chain. Resolves/rejects with that write. */\n private enqueueWrite(data: string): Promise<void> {\n const write = this.writeChain.then(() => this.handle.appendFile(data, 'utf8'));\n this.writeChain = write.then(\n () => undefined,\n () => undefined,\n );\n return write;\n }\n\n // ── Enriched summary tracking ──────────────────────────────────────────\n private iterationCount = 0;\n private toolCallCount = 0;\n private toolErrorCount = 0;\n private toolBreakdown: Record<string, number> = {};\n private fileChangeCount = 0;\n private compactionCount = 0;\n private outcome: SessionSummary['outcome'] = undefined;\n\n /**\n * Scrub secrets out of conversation-turn events before they are observed\n * for the summary, written to the JSONL log, or surfaced on resume. Only\n * `user_input` / `llm_response` carry free-form user/model text; other event\n * types either have no secret-bearing content or are already scrubbed\n * upstream (tool results). Returns the event unchanged when no scrubber is\n * configured.\n */\n private scrubEvent(event: SessionEvent): SessionEvent {\n const s = this.secretScrubber;\n if (!s) return event;\n if (event.type === 'user_input') {\n return {\n ...event,\n content:\n typeof event.content === 'string' ? s.scrub(event.content) : s.scrubObject(event.content),\n };\n }\n if (event.type === 'llm_response') {\n return { ...event, content: s.scrubObject(event.content) };\n }\n return event;\n }\n\n private pendingFileSnapshots: Array<{\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }> = [];\n /** Tracks open tool_use IDs during the current run to serialize on close for resume. */\n private openToolUses = new Set<string>();\n\n recordFileChange(input: {\n path: string;\n action: 'created' | 'modified' | 'deleted';\n before: string | null;\n after: string | null;\n }): void {\n this.pendingFileSnapshots.push(input);\n }\n\n constructor(\n public readonly id: string,\n private handle: fsp.FileHandle,\n private readonly startedAt: string,\n private readonly meta: Omit<SessionMetadata, 'startedAt'>,\n private readonly events?: EventBus | undefined,\n opts: {\n resumed?: boolean | undefined;\n dir?: string | undefined;\n filePath?: string | undefined;\n secretScrubber?: SecretScrubber | undefined;\n /** Called on close() with the finalized summary for index/sidecar writes. */\n onClose?: (((summary: SessionSummary) => void | Promise<void>)) | undefined;\n } = {},\n traceId?: string | undefined,\n ) {\n this.resumed = opts.resumed ?? false;\n // id already contains a date-prefix shard (e.g. \"2026-06-06/17-46-57Z_…\").\n // opts.dir is the shard directory — join with basename so the manifest\n // lives next to the JSONL file instead of creating a double-nested path.\n this.manifestFile = opts.dir ? path.join(opts.dir, `${path.basename(id)}.summary.json`) : '';\n this.filePath = opts.filePath ?? '';\n this.secretScrubber = opts.secretScrubber;\n this.onCloseCb = opts.onClose;\n this.summary = {\n id,\n title: '(empty session)',\n startedAt,\n model: meta.model ?? 'unknown',\n provider: meta.provider ?? 'unknown',\n tokenTotal: 0,\n };\n // Propagated from ContextInit.traceId via SessionWriter.traceId so that\n // storage events carry the run-level trace ID without needing a Context\n // handle in every storage operation.\n this.traceId = traceId;\n }\n\n get pendingToolUses(): string[] {\n return Array.from(this.openToolUses);\n }\n\n private async writeSessionStartLazy(): Promise<void> {\n // Write through the SAME file handle that flushBuffer() uses — avoids\n // cross-fd issues on Windows where a separate fsp.writeFile can contend\n // with the already-open append-mode handle. The handle was opened with\n // O_APPEND so this write lands at the current end-of-file regardless of\n // whether the file is empty or already contains prior session data.\n const record = `${JSON.stringify({\n type: this.resumed ? 'session_resumed' : 'session_start',\n ts: this.startedAt,\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n try {\n await this.enqueueWrite(record);\n } catch {\n // best-effort\n }\n }\n\n async append(event: SessionEvent): Promise<void> {\n if (this.closed) return;\n await this.ensureInit();\n // Scrub before observing (the summary title is derived from user_input\n // content) and before buffering, so neither the JSONL nor the sidecar\n // ever holds a cleartext secret.\n const scrubbed = this.scrubEvent(event);\n // observeForSummary MUST run synchronously here — the summary counters\n // (toolCallCount, tokenIn/Out, outcome) drive the .summary.json sidecar\n // and the session index. Deferring observation to flush time would leave\n // the summary stale if close() fires before the next timer tick.\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n // Buffer full — flush immediately. Cancel any pending timer so we\n // don't double-flush on the next tick.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n async appendBatch(events: SessionEvent[]): Promise<void> {\n if (this.closed || events.length === 0) return;\n await this.ensureInit();\n for (const event of events) {\n const scrubbed = this.scrubEvent(event);\n this.observeForSummary(scrubbed);\n this.writeBuffer.push(scrubbed);\n }\n if (this.writeBuffer.length >= FileSessionWriter.FLUSH_SIZE) {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n } else {\n this.scheduleFlush();\n }\n }\n\n /**\n * Flush buffered events to disk immediately. Critical events\n * (user_input, llm_response) call this so they survive SIGKILL/crash\n * instead of sitting in the in-memory buffer for up to 500ms.\n *\n * Idempotent — cancels any pending timer and writes whatever has\n * accumulated in the buffer. Safe to call even when the buffer\n * is empty (no-op).\n */\n async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n }\n\n /** Schedule a deferred flush. No-op if a timer is already pending. */\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n /* v8 ignore start -- defensive: flushBuffer logs its own errors; this guards the timer callback */\n this.flushBuffer().catch(() => {\n // flushBuffer already logs via the throttled-warning path;\n // this catch prevents an unhandled rejection in the timer callback.\n });\n /* v8 ignore stop */\n }, FileSessionWriter.FLUSH_INTERVAL_MS);\n }\n\n /**\n * Flush all buffered events to disk as a single appendFile call.\n * Errors use the same throttled-warning pattern the old per-event\n * append path used — one warning every 5s with a suppressed count.\n * On failure the buffer is cleared (events are best-effort, same as\n * the old per-event path where a failed write was silently dropped).\n */\n private async flushBuffer(): Promise<void> {\n if (this.writeBuffer.length === 0) return;\n const eventCount = this.writeBuffer.length;\n const batch = this.writeBuffer.map((e) => JSON.stringify(e)).join('\\n') + '\\n';\n this.writeBuffer = [];\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n await this.enqueueWrite(batch);\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n this.appendFailCount += eventCount;\n const now = Date.now();\n if (now - this.lastAppendWarnAt > 5000) {\n const suppressed = this.appendFailCount - 1;\n const tail = suppressed > 0 ? ` (+${suppressed} suppressed)` : '';\n console.warn(\n '[session] flush failed:',\n toErrorMessage(err),\n tail,\n );\n this.lastAppendWarnAt = now;\n this.appendFailCount = 0;\n }\n } finally {\n this.events?.emit('storage.write', {\n sessionId: this.id,\n store: 'session',\n filePath: this.filePath,\n operation: 'flush',\n outcome,\n durationMs: Date.now() - t0,\n ...(errorMsg !== undefined ? { error: errorMsg } : {}),\n ...(eventCount !== undefined ? { eventCount } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n }\n\n private observeForSummary(event: SessionEvent): void {\n // Track open tool uses so we can serialize them on close for resume.\n // The authoritative source is the llm_response content (a core event,\n // always written at every audit level); the legacy 'tool_use' event is\n // kept for alternate writers that still emit it.\n if (event.type === 'llm_response') {\n for (const block of event.content) {\n if (block.type === 'tool_use') this.openToolUses.add(block.id);\n }\n }\n if (event.type === 'tool_use') {\n this.openToolUses.add(event.id);\n } else if (event.type === 'tool_call_start') {\n this.toolCallCount++;\n this.toolBreakdown[event.name] = (this.toolBreakdown[event.name] ?? 0) + 1;\n } else if (event.type === 'tool_result') {\n this.openToolUses.delete(event.id);\n if (event.isError) {\n this.toolErrorCount++;\n this.outcome = 'error';\n }\n } else if (event.type === 'file_snapshot') {\n this.fileChangeCount += event.files.length;\n } else if (event.type === 'compaction') {\n this.compactionCount++;\n }\n // Error events (provider errors, execution errors) mark the session as failed.\n if (event.type === 'error' || event.type === 'provider_error') {\n this.outcome = 'error';\n }\n if (event.type === 'user_input' && this.summary.title === '(empty session)') {\n this.summary = { ...this.summary, title: userInputTitle(event.content) };\n } else if (event.type === 'llm_response') {\n this.tokenIn += event.usage.input;\n this.tokenOut += event.usage.output;\n this.summary = { ...this.summary, tokenTotal: this.tokenIn + this.tokenOut };\n } else if (event.type === 'session_end') {\n const total = event.usage.input + event.usage.output;\n if (total > 0) this.summary = { ...this.summary, tokenTotal: total };\n } else if (event.type === 'in_flight_start') {\n this.iterationCount++;\n }\n }\n\n async close(): Promise<void> {\n // Idempotent AND awaitable: concurrent/repeat callers share the same\n // promise, so nobody proceeds (e.g. to tear down the session directory)\n // while the first close is still flushing.\n if (this.closePromise) return this.closePromise;\n this.closePromise = this.doClose();\n return this.closePromise;\n }\n\n private async doClose(): Promise<void> {\n this.closed = true;\n // Flush any buffered events before finalizing. The summary counters\n // (toolCallCount, tokenIn/Out, outcome) are already up to date because\n // observeForSummary runs synchronously on every append, but the JSONL\n // must have all events on disk before we write the .summary.json sidecar.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain any write enqueued outside flushBuffer (e.g. the lazy\n // session_start record) before the handle is closed.\n await this.writeChain;\n // Finalize the summary before writing.\n this.summary = {\n ...this.summary,\n endedAt: new Date().toISOString(),\n iterationCount: this.iterationCount,\n toolCallCount: this.toolCallCount,\n toolErrorCount: this.toolErrorCount,\n fileChangeCount: this.fileChangeCount,\n compactionCount: this.compactionCount > 0 ? this.compactionCount : undefined,\n toolBreakdown:\n { ...this.toolBreakdown },\n outcome: this.outcome ?? 'completed',\n };\n // Emit storage.write for the manifest sidecar.\n if (this.manifestFile) {\n const t0 = Date.now();\n let outcome: 'success' | 'failure' = 'success';\n let errorMsg: string | undefined;\n try {\n await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 0o600 });\n } catch (err) {\n outcome = 'failure';\n errorMsg = toErrorMessage(err);\n // manifest write is best-effort\n } finally {\n this.events?.emit('storage.write', {\n sessionId: this.id,\n store: 'session',\n filePath: this.manifestFile,\n operation: 'close',\n outcome,\n durationMs: Date.now() - t0,\n ...(errorMsg !== undefined ? { error: errorMsg } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n }\n // Notify the store so it can update the session index. Await so the\n // index write completes before close() resolves — otherwise the\n // fire-and-forget _index.jsonl append races callers that tear down the\n // session directory right after close() (e.g. ENOTEMPTY on Windows).\n // Emit storage.write here so it carries this.traceId; the actual I/O\n // is delegated to onCloseCb (appendToIndex) which no longer emits.\n const idxT0 = Date.now();\n let idxOutcome: 'success' | 'failure' = 'success';\n let idxError: string | undefined;\n try {\n await this.onCloseCb?.(this.summary);\n /* v8 ignore start -- best-effort: appendToIndex swallows its own errors */\n } catch (err) {\n idxOutcome = 'failure';\n idxError = toErrorMessage(err);\n // best-effort\n } finally {\n /* v8 ignore stop */\n this.events?.emit('storage.write', {\n sessionId: this.summary.id,\n store: 'session',\n filePath: this.filePath,\n operation: 'index_append',\n outcome: idxOutcome,\n durationMs: Date.now() - idxT0,\n ...(idxError !== undefined ? { error: idxError } : {}),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n try {\n await this.handle.close();\n } catch {\n // ignore\n }\n }\n\n async writeCheckpoint(promptIndex: number, promptPreview: string): Promise<void> {\n const fileCount = this.pendingFileSnapshots.length;\n if (fileCount > 0) {\n await this.writeFileSnapshot(promptIndex, [...this.pendingFileSnapshots]);\n this.pendingFileSnapshots = [];\n }\n await this.append({\n type: 'checkpoint',\n ts: new Date().toISOString(),\n promptIndex,\n promptPreview,\n });\n this.events?.emit('checkpoint.written', {\n promptIndex,\n promptPreview,\n ts: new Date().toISOString(),\n fileCount,\n });\n }\n\n async writeFileSnapshot(\n promptIndex: number,\n files: import('../types/session.js').FileSnapshot[],\n ): Promise<void> {\n await this.append({\n type: 'file_snapshot',\n ts: new Date().toISOString(),\n promptIndex,\n files,\n });\n }\n\n /**\n * Truncate the session file to the checkpoint with the given promptIndex,\n * removing all events that follow it. Uses a single-pass byte-offset scan\n * so post-checkpoint content is never read or parsed — O(1) memory instead\n * of O(N) JSON.parse calls over the full file.\n */\n async truncateToCheckpoint(targetPromptIndex: number): Promise<number> {\n /* v8 ignore next -- defensive: filePath is always set for a live writer */\n if (!this.filePath) return 0;\n\n // Flush buffered events to disk before reading — otherwise the in-memory\n // events that haven't hit the JSONL yet would be invisible to the\n // truncation logic and would be silently dropped by the rewrite.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n await this.flushBuffer();\n // Drain the write chain so no in-flight write straddles the close/rename/reopen.\n await this.writeChain;\n\n // Single-pass scan: track byte offset of each line start. Stop as soon as\n // the target checkpoint is found — no I/O or parsing for post-checkpoint data.\n const CHUNK_SIZE = 65_536;\n let fd: fsp.FileHandle | undefined;\n let fileOffset = 0; // cumulative byte position of the start of the current chunk\n let lineStartOffset = 0; // byte offset within the file where the current line begins\n let checkpointByteOffset = -1; // byte offset where we will truncate the file\n let removedCount = 0;\n let targetCheckpointSeen = false; // has the target checkpoint been found yet?\n\n try {\n fd = await fsp.open(this.filePath, 'r', 0o600);\n\n while (true) {\n const buf = Buffer.alloc(CHUNK_SIZE);\n const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);\n if (bytesRead === 0) break;\n\n let chunkPos = 0;\n while (chunkPos < bytesRead) {\n const idx = buf.indexOf('\\n', chunkPos);\n if (idx === -1) {\n // No complete line in this chunk — save partial for next iteration.\n lineStartOffset = fileOffset + chunkPos;\n break;\n }\n\n if (checkpointByteOffset !== -1) {\n // Target already found — every subsequent line is removed.\n removedCount++;\n } else {\n // Only parse lines that could precede or be the checkpoint.\n const lineBytes = buf.subarray(chunkPos, idx);\n // eslint-disable-next-line no-sync\n const line = new TextDecoder('utf-8', { fatal: false }).decode(lineBytes);\n if (line.trim()) {\n try {\n const event = JSON.parse(line) as { type?: string; promptIndex?: number };\n if (event.type === 'checkpoint') {\n if (event.promptIndex === targetPromptIndex) {\n // Target found — record its byte offset and stop scanning.\n checkpointByteOffset = lineStartOffset;\n targetCheckpointSeen = true;\n } else if (event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n // A checkpoint with a higher promptIndex means the target is absent.\n // Truncate before this line (exclusive) — it and all following events\n // will be replaced by the new rewinded history.\n checkpointByteOffset = lineStartOffset;\n }\n } else if (targetCheckpointSeen && event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n // Post-target event with a later promptIndex — count as removed.\n removedCount++;\n } else if (targetCheckpointSeen && event.promptIndex === undefined) {\n // After the target checkpoint was found: remove events with no\n // promptIndex. (In the original this is the afterTarget &&\n // targetCheckpointLine !== -1 branch.)\n removedCount++;\n } else if (!targetCheckpointSeen && event.promptIndex === undefined) {\n // Past a higher checkpoint but the target checkpoint not yet found.\n // Matches original: remove events with undefined promptIndex\n // (malformed lines, file_snapshots, etc.) that appear after a\n // higher checkpoint but before the target.\n removedCount++;\n } else if (!targetCheckpointSeen && event.promptIndex !== undefined && event.promptIndex > targetPromptIndex) {\n // Past a higher checkpoint but the target not yet found.\n // Matches original: remove events with promptIndex > target that\n // appear before the target checkpoint (e.g. user_inputs belonging\n // to a later prompt).\n removedCount++;\n }\n // Events with promptIndex <= targetPromptIndex (before the target is\n // found) are implicitly kept — no action needed.\n } catch {\n // Malformed JSON — matches original: keep it.\n }\n }\n }\n\n // Move to start of next line.\n chunkPos = idx + 1;\n lineStartOffset = fileOffset + chunkPos;\n }\n\n fileOffset += bytesRead;\n if (chunkPos >= bytesRead) {\n // Finished all complete lines; prepare for next chunk.\n lineStartOffset = fileOffset;\n }\n }\n } finally {\n await fd?.close();\n }\n\n if (checkpointByteOffset === -1) return 0;\n\n // Windows EPERM fix: close the append-mode handle before replacing the\n // file. Windows rejects rename() when the destination still has an open\n // handle, even if that handle belongs to this process.\n await this.writeChain;\n await this.handle.close();\n const tmpPath = `${this.filePath}.rewind.tmp`;\n const src = await fsp.open(this.filePath, 'r', 0o600);\n try {\n const statResult = await src.stat();\n const totalSize = statResult.size;\n // checkpointByteOffset points to the start of the checkpoint line.\n // We want to keep everything up to and including that line's '\\n'.\n // Since the file ends with '\\n', keeping bytes [0 .. lineStartAfterCheckpoint]\n // means we include the trailing newline. We find that '\\n' by scanning\n // from checkpointByteOffset forward (at most one chunk's worth).\n const prefixBytes = checkpointByteOffset;\n let newlineAfterCheckpoint = prefixBytes;\n\n if (prefixBytes < totalSize) {\n const probeBuf = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize - prefixBytes));\n const { bytesRead: probeRead } = await src.read(probeBuf, 0, probeBuf.length, prefixBytes);\n if (probeRead > 0) {\n const nl = probeBuf.indexOf('\\n');\n newlineAfterCheckpoint = nl !== -1 ? prefixBytes + nl + 1 : totalSize;\n }\n } else {\n newlineAfterCheckpoint = totalSize;\n }\n\n const writeFd = await fsp.open(tmpPath, 'w', 0o600);\n try {\n let copied = 0;\n let readOffset = 0;\n while (readOffset < newlineAfterCheckpoint) {\n const toCopy = Math.min(CHUNK_SIZE, newlineAfterCheckpoint - readOffset);\n const copyBuf = Buffer.alloc(toCopy);\n const { bytesRead: r } = await src.read(copyBuf, 0, toCopy, readOffset);\n if (r === 0) break;\n await writeFd.write(copyBuf, 0, r);\n readOffset += r;\n copied += r;\n }\n\n // Preserve malformed JSONL records even after the rewind target. They\n // are not replayable session events, but keeping them avoids silently\n // deleting diagnostic/corruption evidence during a truncate.\n const raw = await fsp.readFile(this.filePath);\n const tail = raw.subarray(newlineAfterCheckpoint).toString('utf8');\n for (const line of tail.split('\\n')) {\n if (!line.trim()) continue;\n try {\n JSON.parse(line);\n } catch {\n await writeFd.write(`${line}\\n`, undefined, 'utf8');\n }\n }\n } finally {\n await writeFd.close();\n }\n\n await src.close();\n await fsp.rename(tmpPath, this.filePath);\n // Re-open in append mode for continued use of this file.\n this.handle = await fsp.open(this.filePath, 'a', 0o600);\n /* v8 ignore start -- defensive: close/rename/reopen of a just-written temp file */\n } catch (err) {\n await fsp.unlink(tmpPath).catch(() => undefined);\n this.handle = await fsp.open(this.filePath, 'a', 0o600).catch(() => this.handle);\n throw err;\n }\n /* v8 ignore stop */\n\n await this.append({\n type: 'rewound',\n ts: new Date().toISOString(),\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n });\n\n this.events?.emit('session.rewound', {\n toPromptIndex: targetPromptIndex,\n revertedFiles: [],\n removedEvents: removedCount,\n });\n\n return removedCount;\n }\n\n async clearSession(): Promise<void> {\n /* v8 ignore next -- defensive: filePath is always set for a live writer */\n if (!this.filePath) return;\n // Discard any buffered events — the caller is explicitly resetting the\n // session to a clean slate. Cancel the timer so it doesn't fire and\n // append stale events to the freshly-cleared file.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.writeBuffer = [];\n // Let any in-flight append land first — otherwise it would re-append\n // stale events AFTER the reset record below.\n await this.writeChain;\n const record = `${JSON.stringify({\n type: 'session_start',\n ts: new Date().toISOString(),\n id: this.id,\n model: this.meta.model ?? 'unknown',\n provider: this.meta.provider ?? 'unknown',\n })}\\n`;\n await fsp.writeFile(this.filePath, record, 'utf8');\n }\n\n /**\n * Idea #1 — write an in-flight marker. The agent loop should call\n * this at the start of each long-running operation; a matching\n * `clearInFlightMarker` follows on clean exit. A stale marker\n * (no end) is what `SessionRecovery.detectStale` looks for.\n */\n async writeInFlightMarker(context: string): Promise<void> {\n if (!context || context.length > 500) {\n throw new Error('In-flight context must be 1..500 chars');\n }\n await this.append({\n type: 'in_flight_start',\n ts: new Date().toISOString(),\n context,\n });\n this.events?.emit('in_flight.started', { context, ts: new Date().toISOString() });\n }\n\n /**\n * Idea #1 — close the in-flight marker. Idempotent in spirit\n * (you can call it after a successful iteration even if you\n * didn't open one this round) — but the session log records\n * every call so postmortem tooling can see \"the agent finished\n * cleanly X times, then died without finishing Y\".\n */\n async clearInFlightMarker(reason: 'clean' | 'aborted' | 'recovered'): Promise<void> {\n await this.append({\n type: 'in_flight_end',\n ts: new Date().toISOString(),\n reason,\n });\n this.events?.emit('in_flight.ended', { reason, ts: new Date().toISOString() });\n }\n}\n\nfunction userInputTitle(content: string | ContentBlock[]): string {\n const text =\n typeof content === 'string'\n ? content\n : content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join(' ');\n return (text || '(non-text input)').slice(0, 60);\n}\n","import * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * The persisted form of a single queued user message. The TUI's\n * in-memory QueueItem has a render id; that's pure UI bookkeeping, so\n * we drop it when serializing — fresh ids are assigned on rehydrate.\n */\nexport interface PersistedQueueItem {\n displayText: string;\n blocks: ContentBlock[];\n}\n\n/**\n * Side-file storage for a session's pending input queue. Lives at\n * `<sessionDir>/queue.json` next to the attachment spool. Reads are\n * tolerant (missing/malformed file → empty array); writes are atomic\n * (tmp + rename) so a crash mid-write can never leave a partial file\n * the next launch would choke on.\n *\n * The contract is \"snapshot replacement\": every mutation hands the\n * full queue and we rewrite the file. The queue is small (rarely more\n * than a handful of messages), so this is cheaper than delta logging\n * and avoids the replay complexity.\n */\nexport class QueueStore {\n private readonly file: string;\n // Use `| undefined` (not `?`) so exactOptionalPropertyTypes doesn't\n // reject assigning an optional constructor parameter to these fields.\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n\n constructor(opts: { dir: string; events?: EventBus; traceId?: string }) {\n this.file = path.join(opts.dir, 'queue.json');\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n async write(items: PersistedQueueItem[]): Promise<void> {\n const t0 = Date.now();\n if (items.length === 0) {\n // Empty queue → remove the file rather than write `[]`. Keeps\n // a clean idle state on disk and makes `read()` cheaper.\n await this.clear();\n return;\n }\n try {\n await atomicWrite(this.file, JSON.stringify(items), { mode: 0o600 });\n this.events?.emit('storage.write', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'write',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'write',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.write_failed',\n path: this.file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n async read(): Promise<PersistedQueueItem[]> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.read_failed',\n path: this.file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n if (!Array.isArray(parsed)) {\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return [];\n }\n this.events?.emit('storage.read', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'read',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n const out: PersistedQueueItem[] = [];\n for (const v of parsed) {\n if (isPersistedQueueItem(v)) out.push(v);\n }\n return out;\n }\n\n async clear(): Promise<void> {\n const t0 = Date.now();\n try {\n await fsp.unlink(this.file);\n this.events?.emit('storage.write', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'clear',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n this.events?.emit('storage.error', {\n sessionId: this.traceId ?? '~boot~',\n store: 'queue',\n filePath: this.file,\n operation: 'clear',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n // Best-effort: a permission/lock error during clear is rare and\n // the queue slash command is non-critical. Warn so it's observable\n // but don't throw so the slash command doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'queue_store.clear_failed',\n path: this.file,\n message: (err as Error).message,\n timestamp: new Date().toISOString(),\n }));\n }\n }\n}\n\nfunction isPersistedQueueItem(v: unknown): v is PersistedQueueItem {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return typeof o['displayText'] === 'string' && Array.isArray(o['blocks']);\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type {\n AddAttachmentInput,\n Attachment,\n AttachmentKind,\n AttachmentRef,\n AttachmentStore,\n} from '../types/attachment.js';\nimport type { ContentBlock } from '../types/blocks.js';\n\nexport interface AttachmentStoreOptions {\n /**\n * Directory for spooling payloads larger than `spoolThresholdBytes`.\n * When omitted, all payloads stay in memory.\n */\n spoolDir?: string | undefined;\n spoolThresholdBytes?: number | undefined;\n}\n\nconst DEFAULT_SPOOL_THRESHOLD = 256 * 1024; // 256 KB\n// Two placeholder shapes:\n// - seq-keyed `[<kind> #<seq>…]` — kind is `pasted` / `image` / `file`. A\n// cosmetic suffix after the seq (e.g. `, 123 lines`) is tolerated so the\n// TUI can render `[pasted #1, 123 lines]` while still resolving by seq.\n// - path-keyed `[file:<path>]` — resolves to the most recent file ref whose\n// stored path matches, so the TUI can show a human-readable file chip.\nconst PLACEHOLDER_RE = /\\[(pasted|image|file) #(\\d+)[^\\]]*\\]|\\[file:([^\\]]+)\\]/g;\n\n/**\n * In-memory attachment store with optional disk spool. Placeholder syntax\n * is `[<kind> #<seq>]` (seq-keyed) or `[file:<path>]` (path-keyed) where kind\n * is `pasted` / `image` / `file`. Unknown placeholders are passed through\n * as-is so users can write that literal text without losing it.\n */\nexport class DefaultAttachmentStore implements AttachmentStore {\n private readonly items = new Map<string, Attachment>();\n private readonly refs: AttachmentRef[] = [];\n private nextSeq: Record<AttachmentKind, number> = { text: 0, image: 0, file: 0 };\n private readonly spoolDir: string | undefined;\n private readonly spoolThreshold: number;\n\n constructor(opts: AttachmentStoreOptions = {}) {\n this.spoolDir = opts.spoolDir;\n this.spoolThreshold = opts.spoolThresholdBytes ?? DEFAULT_SPOOL_THRESHOLD;\n }\n\n async add(input: AddAttachmentInput): Promise<AttachmentRef> {\n const seq = ++this.nextSeq[input.kind];\n const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes(3).toString('hex')}`;\n const bytes = Buffer.byteLength(input.data, input.kind === 'image' ? 'base64' : 'utf8');\n let spooledPath: string | undefined;\n let data: string | undefined = input.data;\n if (this.spoolDir && bytes >= this.spoolThreshold) {\n await fsp.mkdir(this.spoolDir, { recursive: true });\n spooledPath = path.join(this.spoolDir, `${id}.bin`);\n // atomicWrite: torn spool would silently corrupt the attachment;\n // the user would see garbled output the next time it's expanded.\n await atomicWrite(spooledPath, input.data, {\n encoding: input.kind === 'image' ? 'base64' : 'utf8',\n });\n data = undefined;\n }\n const att: Attachment = {\n id,\n kind: input.kind,\n meta: input.meta ?? {},\n data,\n path: spooledPath,\n bytes,\n createdAt: new Date().toISOString(),\n };\n this.items.set(id, att);\n const ref: AttachmentRef = { id, kind: input.kind, seq, meta: att.meta };\n this.refs.push(ref);\n return ref;\n }\n\n async get(id: string): Promise<Attachment | undefined> {\n return this.items.get(id);\n }\n\n list(): AttachmentRef[] {\n return [...this.refs];\n }\n\n async expand(text: string): Promise<ContentBlock[]> {\n const matches = [...text.matchAll(PLACEHOLDER_RE)];\n if (matches.length === 0) return text ? [{ type: 'text', text }] : [];\n const blocks: ContentBlock[] = [];\n let lastIndex = 0;\n for (const m of matches) {\n const idx = m.index ?? 0;\n const before = text.slice(lastIndex, idx);\n if (before) blocks.push({ type: 'text', text: before });\n let ref: AttachmentRef | undefined;\n if (m[3] !== undefined) {\n // Path-keyed `[file:<path>]` — most recent matching file ref wins.\n const wantPath = m[3];\n ref = findLast(this.refs, (r) => r.kind === 'file' && refPath(r) === wantPath);\n } else {\n const kind = prefixToKind(m[1] as string);\n const seq = Number(m[2]);\n ref = this.refs.find((r) => r.kind === kind && r.seq === seq);\n }\n const att = ref ? this.items.get(ref.id) : undefined;\n if (!att) {\n blocks.push({ type: 'text', text: m[0] });\n } else {\n blocks.push(await this.toBlock(att));\n }\n lastIndex = idx + m[0].length;\n }\n const tail = text.slice(lastIndex);\n if (tail) blocks.push({ type: 'text', text: tail });\n return mergeAdjacentText(blocks);\n }\n\n async clear(): Promise<void> {\n // Unlink any spooled files so we don't leak disk space.\n if (this.spoolDir) {\n const toDelete: string[] = [];\n for (const att of this.items.values()) {\n if (att.path) toDelete.push(att.path);\n }\n /* v8 ignore next -- best-effort: unlink of a just-spooled file does not reject */\n await Promise.all(toDelete.map((p) => fsp.unlink(p).catch(() => undefined)));\n }\n this.items.clear();\n this.refs.length = 0;\n this.nextSeq = { text: 0, image: 0, file: 0 };\n }\n\n private async toBlock(att: Attachment): Promise<ContentBlock> {\n if (att.kind === 'image') {\n const data =\n att.data ?? (att.path ? await fsp.readFile(att.path, { encoding: 'base64' }) : '');\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: att.meta.mediaType ?? 'image/png',\n data,\n },\n };\n }\n const raw = att.data ?? (att.path ? await fsp.readFile(att.path, 'utf8') : '');\n const label = att.meta.filename ? `<file path=\"${att.meta.filename}\">` : '<pasted>';\n const close = att.meta.filename ? '</file>' : '</pasted>';\n return { type: 'text', text: `${label}\\n${raw}\\n${close}` };\n }\n}\n\nfunction kindPrefix(kind: AttachmentKind): string {\n return kind === 'text' ? 'pasted' : kind;\n}\n\nfunction prefixToKind(prefix: string): AttachmentKind {\n if (prefix === 'pasted') return 'text';\n if (prefix === 'image') return 'image';\n return 'file';\n}\n\n/** Path a file ref was registered under, for `[file:<path>]` lookup. */\nfunction refPath(ref: AttachmentRef): string | undefined {\n return ref.meta.filename ?? ref.meta.label;\n}\n\n/** Last element matching the predicate (Node < 20 lacks Array.findLast). */\nfunction findLast<T>(arr: readonly T[], pred: (v: T) => boolean): T | undefined {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (pred(arr[i] as T)) return arr[i];\n }\n return undefined;\n}\n\nfunction mergeAdjacentText(blocks: ContentBlock[]): ContentBlock[] {\n const out: ContentBlock[] = [];\n for (const b of blocks) {\n const prev = out[out.length - 1];\n if (b.type === 'text' && prev && prev.type === 'text') {\n prev.text += b.text;\n } else {\n out.push(b);\n }\n }\n return out;\n}\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n /**\n * Attach a trace ID to this store so that all subsequent `storage.*`\n * events include it for observability correlation. Mutates the store\n * in place and returns the same instance (convenience chaining).\n */\n withTraceId(traceId: string): MemoryStore;\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { MEMORY_TYPE_LABELS, type MemoryPriority, type MemoryType } from '../types/memory.js';\nimport { atomicWrite, ensureDir, withFileLock } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\n// ── Backend interface ──────────────────────────────────────────────────\n\nexport interface MemoryBackend {\n readonly kind: string;\n remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void>;\n forget(scope: MemoryScope, query: string, filePath: string): Promise<number>;\n readAll(scope: MemoryScope, filePath: string): Promise<string>;\n list(scope: MemoryScope, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n search(scope: MemoryScope, query: string, filePath: string, limit?: number | undefined): Promise<MemoryEntry[]>;\n /** Find memories related to the given text via graph traversal. Optional — falls back to search. */\n findRelated?(scope: MemoryScope, filePath: string, text: string, limit: number): Promise<MemoryEntry[]>;\n clear(scope: MemoryScope, filePath: string): Promise<void>;\n consolidate(scope: MemoryScope, filePath: string): Promise<number>;\n}\n\n// ── Entry serialization format ─────────────────────────────────────────\n//\n// Full format:\n// - [ISO] [TYPE|PRIORITY] mem_<id> text content #tag1 #tag2\n//\n// Examples:\n// - [2026-06-07T...] mem_1234_abcd Project uses pnpm #pnpm #build\n// - [2026-06-07T...] [convention|high] mem_5678_ef01 Use conventional commits #git #commit\n//\n// Old format (backward compatible):\n// - [ISO] mem_<id> text content\n\nconst TYPE_PRIORITY_RE = /^\\[(\\w+)\\|(\\w+)\\]\\s+/;\nconst TAG_RE = /#([\\w-]+)/g;\nconst MAX_MEMORY_CONSOLIDATE_BACKUPS = 5;\n\nfunction formatMetadata(entry: MemoryEntry): string {\n const parts: string[] = [];\n if (entry.type && entry.priority) {\n parts.push(`[${entry.type}|${entry.priority}]`);\n } else if (entry.type) {\n parts.push(`[${entry.type}]`);\n } else if (entry.priority) {\n parts.push(`[${entry.priority}]`);\n }\n if (entry.tags && entry.tags.length > 0) {\n parts.push(entry.tags.map((t) => `#${t}`).join(' '));\n }\n return parts.length > 0 ? ` ${parts.join(' ')}` : '';\n}\n\nfunction lineToEntry(line: string, scope: MemoryScope): MemoryEntry | null {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- [')) return null;\n\n // Parse timestamp: `- [ISO] ...`\n const tsMatch = trimmed.match(/^-\\s*\\[([^\\]]+)\\]/);\n if (!tsMatch) return null;\n const ts = tsMatch[1] ?? '';\n\n let rest = trimmed.slice(tsMatch[0].length).trim();\n\n // Parse optional type|priority: `[convention|high]` or `[fact]`\n let type: MemoryType | undefined;\n let priority: MemoryPriority | undefined;\n const tpMatch = rest.match(TYPE_PRIORITY_RE);\n if (tpMatch) {\n const a = tpMatch[1] ?? '';\n const b = tpMatch[2] ?? '';\n if (isMemoryType(a)) {\n type = a;\n priority = isPriority(b) ? b : undefined;\n } else if (isPriority(a)) {\n priority = a;\n }\n rest = rest.slice(tpMatch[0].length).trim();\n }\n\n // Parse optional entry ID: `mem_<ts>_<rand>`\n const idMatch = rest.match(/^mem_\\d+_\\w+\\s+/);\n let text: string;\n if (idMatch) {\n text = rest.slice(idMatch[0].length).trim();\n } else {\n text = rest.trim();\n }\n\n // Extract #tags from text\n const tags: string[] = [];\n let tagMatch: RegExpExecArray | null;\n TAG_RE.lastIndex = 0;\n // biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop\n while ((tagMatch = TAG_RE.exec(text)) !== null) {\n tags.push(tagMatch[1] ?? '');\n }\n // Remove tags from display text\n const cleanText = text.replace(TAG_RE, '').replace(/\\s{2,}/g, ' ').trim();\n\n if (!cleanText) return null;\n\n return {\n scope,\n text: cleanText,\n ts,\n type,\n priority,\n tags: tags.length > 0 ? tags : undefined,\n };\n}\n\nfunction isMemoryType(s: string): s is MemoryType {\n return s in MEMORY_TYPE_LABELS;\n}\n\nfunction isPriority(s: string): s is MemoryPriority {\n return s === 'critical' || s === 'high' || s === 'medium' || s === 'low';\n}\n\n// ── File-based backend ─────────────────────────────────────────────────\n\nexport interface FileMemoryBackendOptions {\n paths: WstackPaths;\n}\n\nexport class FileMemoryBackend implements MemoryBackend {\n readonly kind = 'file';\n private readonly files: Record<MemoryScope, string>;\n\n constructor(opts: FileMemoryBackendOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n }\n\n private resolveFile(filePath: string, scope: MemoryScope): string {\n return filePath || this.files[scope];\n }\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await ensureDir(path.dirname(file));\n let existing = '';\n try { existing = await fs.readFile(file, 'utf8'); } catch { /* new file */ }\n\n const id = `mem_${Date.now()}_${randomUUID().slice(0, 8)}`;\n const meta = formatMetadata(entry);\n const line = `\\n- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\\n/g, ' ')}\\n`;\n const next = existing.trim()\n ? existing.replace(/\\n+$/, '') + line\n : `# Agent Memory\\n${line}`;\n await atomicWrite(file, next);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n return withFileLock(file, async () => {\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const needle = query.toLowerCase();\n const idMatcher = /mem_\\d+_\\w+/;\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n if (idMatcher.test(query)) {\n const entryIdMatch = /mem_\\d+_\\w+/.exec(trimmed);\n if (entryIdMatch && entryIdMatch[0] === query) { removed++; return false; }\n }\n if (trimmed.toLowerCase().includes(needle)) { removed++; return false; }\n return true;\n });\n if (removed > 0) {\n if (lines.length === 0 || (lines.length === 1 && !lines[0]?.trim())) {\n await atomicWrite(file, '');\n } else {\n await atomicWrite(file, lines.join('\\n'));\n }\n }\n return removed;\n });\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n const file = this.resolveFile(filePath, scope);\n try { return await fs.readFile(file, 'utf8'); } catch { return ''; /* best-effort */ }\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const raw = await this.readAll(scope, filePath);\n if (!raw.trim()) return [];\n const entries = parseEntries(raw, scope);\n return limit ? entries.slice(0, limit) : entries;\n }\n\n async search(scope: MemoryScope, query: string, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n const entries = await this.list(scope, filePath);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Score by word overlap + tag match\n const scored = entries.map((e) => {\n const words = e.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n // Tag matches are weighted higher\n if (e.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n return { entry: e, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.filter((s) => s.score > 0).map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n const file = this.resolveFile(filePath, scope);\n await atomicWrite(file, '');\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n const file = this.resolveFile(filePath, scope);\n let existing: string;\n try { existing = await fs.readFile(file, 'utf8'); } catch { return 0; /* best-effort */ }\n\n const seen = new Set<string>();\n let removed = 0;\n const lines = existing.split('\\n').filter((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith('- ')) return true;\n // Normalize: strip timestamp, ID, type|priority, tags\n const norm = trimmed\n .replace(/\\[[^\\]]+\\]/g, '')\n .replace(/\\bmem_\\d+_\\w+\\s*/, '')\n .replace(/#[\\w-]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .toLowerCase();\n if (seen.has(norm)) { removed++; return false; }\n seen.add(norm);\n return true;\n });\n\n const next = lines.join('\\n');\n const backup = `${file}.bak.${Date.now()}`;\n try {\n await fs.copyFile(file, backup);\n await pruneConsolidateBackups(file);\n } catch { /* best-effort */ }\n /* v8 ignore next -- best-effort: atomicWrite failure during consolidate is non-fatal */\n try { await atomicWrite(file, next); } catch { return 0; /* best-effort */ }\n return removed;\n }\n}\n\nasync function pruneConsolidateBackups(file: string): Promise<void> {\n const dir = path.dirname(file);\n const base = path.basename(file);\n const prefix = `${base}.bak.`;\n const backups = (await fs.readdir(dir))\n .filter((name) => name.startsWith(prefix))\n .sort()\n .reverse();\n\n await Promise.all(\n backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {\n try {\n await fs.unlink(path.join(dir, name));\n } catch {\n // best-effort\n }\n }),\n );\n}\n\n// ── Entry parsing ──────────────────────────────────────────────────────\n\nexport function parseEntries(raw: string, scope: MemoryScope = 'project-memory'): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n for (const line of raw.split('\\n')) {\n const entry = lineToEntry(line, scope);\n if (entry) entries.push(entry);\n }\n return entries.reverse(); // newest first\n}\n","import type {\n MemoryClearedPayload,\n MemoryConsolidatedPayload,\n MemoryEntry,\n MemoryForgottenPayload,\n MemoryRelevanceContext,\n MemoryRememberedPayload,\n MemoryScope,\n MemoryStore,\n ScoredEntry,\n} from '../types/memory.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { type MemoryBackend, FileMemoryBackend } from './memory-backend.js';\n\nconst MAX_BYTES_TOTAL = 32_000; // ~8K tokens\n\nexport interface MemoryStoreOptions {\n paths: WstackPaths;\n /**\n * Optional event bus — when provided, mutations emit events so plugins\n * and other subsystems can react to memory changes.\n */\n events?: EventBus | undefined;\n /**\n * Storage backend. Defaults to FileMemoryBackend when omitted.\n * Plugins can register a custom backend (graph, semantic, vector)\n * via the DI container to override storage behavior.\n */\n backend?: MemoryBackend | undefined;\n}\n\n/**\n * Three scopes:\n * project-agents → <project>/.wrongstack/AGENTS.md (committed)\n * project-memory → ~/.wrongstack/projects/<hash>/memory.md (per-project agent notes)\n * user-memory → ~/.wrongstack/memory.md (global personal memory)\n */\nexport class DefaultMemoryStore implements MemoryStore {\n private readonly files: Record<MemoryScope, string>;\n private readonly events?: EventBus | undefined;\n private traceId?: string | undefined;\n private readonly backend: MemoryBackend;\n\n /**\n * Per-scope serialization queue. `remember` / `forget` / `consolidate` /\n * `clear` are read-modify-write against a single file; without a lock,\n * two concurrent calls on the same scope can read the same baseline and\n * the later write silently drops the earlier entry. We chain each\n * mutation onto the prior promise for the same scope so they run in\n * issue order. Different scopes still proceed in parallel.\n *\n * The chain tracks only the last pending write. If a write fails, its\n * error is caught and swallowed so the chain stays alive for subsequent\n * calls. The error is stored in `writeErrors` so callers can learn about\n * it on the next read operation.\n */\n private readonly writeChain = new Map<MemoryScope, Promise<unknown>>();\n /** Last write error per scope — surfaced as warnings on the next readAll(). */\n private readonly writeErrors = new Map<MemoryScope, Error>();\n\n /**\n * When the global root is a temporary directory (opencode, CI sandboxes),\n * memory files are also mirrored to the project tree so they survive\n * session cleanup. The primary path stays in the temp root for isolation;\n * this backup ensures memory is never lost.\n */\n private readonly persistBackup: boolean;\n private readonly backupDir: string;\n\n constructor(opts: MemoryStoreOptions) {\n this.files = {\n 'project-agents': opts.paths.inProjectAgentsFile,\n 'project-memory': opts.paths.projectMemory,\n 'user-memory': opts.paths.globalMemory,\n };\n this.events = opts.events;\n this.backend = opts.backend ?? new FileMemoryBackend({ paths: opts.paths });\n\n // Detect temporary global roots: opencode, CI, test sandboxes.\n // When detected, mirror writes to the project's .wrongstack/ dir.\n const root = opts.paths.globalRoot.toLowerCase();\n this.persistBackup = /[/\\\\](tmp|temp|cache)[/\\\\]/.test(root);\n this.backupDir = this.persistBackup\n ? opts.paths.inProjectAgentsFile.replace(/AGENTS\\.md$/, 'memory-persist')\n : '';\n }\n\n /** Expose the backend for plugin introspection and advanced queries. */\n getBackend(): MemoryBackend {\n return this.backend;\n }\n\n private async runSerialized<T>(scope: MemoryScope, work: () => Promise<T>): Promise<T> {\n const prior = this.writeChain.get(scope) ?? Promise.resolve();\n // Chain: catch errors from the prior write, then run the next work item.\n const next = prior\n .catch((err) => {\n this.writeErrors.set(scope, err as Error);\n })\n .then(() => work());\n this.writeChain.set(scope, next as Promise<unknown>);\n try {\n return await next;\n } catch (err) {\n this.writeErrors.set(scope, err as Error);\n throw err;\n } finally {\n if (this.writeChain.get(scope) === next) {\n this.writeChain.delete(scope);\n }\n }\n }\n\n async readAll(): Promise<string> {\n const parts: string[] = [];\n for (const scope of ['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]) {\n const writeErr = this.writeErrors.get(scope);\n if (writeErr) {\n parts.push(`> ⚠️ Memory write error (${labelOf(scope)}): ${writeErr.message}`);\n }\n const t0 = Date.now();\n const filePath = this.files[scope];\n try {\n const body = await this.backend.readAll(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'readAll',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n if (body.trim()) parts.push(`## ${labelOf(scope)}\\n\\n${body.trim()}`);\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'readAll',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n }\n return parts.join('\\n\\n');\n }\n\n async read(scope: MemoryScope): Promise<string> {\n const t0 = Date.now();\n const filePath = this.files[scope];\n try {\n const body = await this.backend.readAll(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'read',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n return body;\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'read',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n }\n\n /**\n * List entries from a scope, newest first. Delegates to the backend\n * so graph/semantic backends can return enriched or filtered results.\n */\n async list(scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.list(scope, this.files[scope], limit);\n }\n\n /**\n * Find memories related to the given text via graph traversal.\n * Falls back to content search when no graph backend is available.\n */\n async findRelated(text: string, scope: MemoryScope = 'project-memory', limit = 5): Promise<MemoryEntry[]> {\n if (this.backend.findRelated) {\n return this.backend.findRelated(scope, this.files[scope], text, limit);\n }\n return this.search(text, scope, limit);\n }\n\n async search(query: string, scope: MemoryScope = 'project-memory', limit?: number): Promise<MemoryEntry[]> {\n return this.backend.search(scope, query, this.files[scope], limit);\n }\n\n async remember(\n text: string,\n scope: MemoryScope = 'project-memory',\n metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>,\n ): Promise<void> {\n const ts = new Date().toISOString();\n return this.runSerialized(scope, async () => {\n const entry: MemoryEntry = { scope, text, ts, ...metadata };\n const filePath = this.files[scope];\n const t0 = Date.now();\n try {\n await this.backend.remember(scope, entry, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'remember',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'remember',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n\n // Size check — consolidate if the file exceeds the cap.\n const raw = await this.backend.readAll(scope, this.files[scope]);\n if (Buffer.byteLength(raw, 'utf8') > MAX_BYTES_TOTAL) {\n const removed = await this.backend.consolidate(scope, this.files[scope]);\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n }\n }\n\n // Mirror to persistent backup when running in a temp sandbox.\n await this.mirrorBackup(scope);\n\n this.events?.emit('memory.remembered', {\n scope,\n text,\n ts,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n } satisfies MemoryRememberedPayload);\n });\n }\n\n /**\n * Score and rank memories by relevance to the current context.\n * Returns entries with score >= MIN_RELEVANCE_SCORE, sorted highest first.\n */\n async scoreRelevant(\n ctx: MemoryRelevanceContext,\n scope: MemoryScope = 'project-memory',\n limit = 8,\n ): Promise<ScoredEntry[]> {\n const all = await this.list(scope);\n if (all.length === 0) return [];\n\n const taskWords = ctx.currentTask.toLowerCase().split(/\\s+/).filter((w) => w.length > 2);\n const skillWords = (ctx.activeSkills ?? []).flatMap((s) => s.split('-'));\n const toolWords = (ctx.toolNames ?? []).flatMap((t) => t.toLowerCase().split('_'));\n const now = Date.now();\n\n const scored: ScoredEntry[] = [];\n\n for (const entry of all) {\n let score = 0;\n const reasons: string[] = [];\n const textLower = entry.text.toLowerCase();\n const tagsLower = (entry.tags ?? []).map((t) => t.toLowerCase());\n\n // Word overlap with current task (primary signal)\n let taskHits = 0;\n for (const w of taskWords) {\n if (textLower.includes(w)) { taskHits++; score += 2; }\n if (tagsLower.some((t) => t.includes(w))) { taskHits++; score += 3; }\n }\n if (taskHits > 0) reasons.push(`task match (${taskHits})`);\n\n // Skill/tool relevance\n let skillHits = 0;\n for (const w of skillWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n skillHits++;\n }\n }\n score += skillHits;\n if (skillHits > 0) reasons.push(`skill match (${skillHits})`);\n\n for (const w of toolWords) {\n if (w.length > 2 && (textLower.includes(w) || tagsLower.some((t) => t.includes(w)))) {\n score += 1;\n reasons.push(`tool mention: ${w}`);\n }\n }\n\n // Priority boost\n switch (entry.priority) {\n case 'critical': score += 5; reasons.push('critical'); break;\n case 'high': score += 3; reasons.push('high priority'); break;\n case 'medium': score += 1; break;\n case 'low': score -= 2; reasons.push('low priority'); break;\n }\n\n // Type boost — decisions, conventions, anti-patterns are high-value\n switch (entry.type) {\n case 'decision': score += 2; reasons.push('decision'); break;\n case 'convention': score += 2; reasons.push('convention'); break;\n case 'anti_pattern': score += 3; reasons.push('anti-pattern'); break;\n case 'preference': score += 1; reasons.push('preference'); break;\n case 'reference': break;\n case 'fact': break;\n }\n\n // Recency boost — newer entries get +1, very old get 0\n const ageDays = (now - new Date(entry.ts).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays < 1) score += 1;\n else if (ageDays > 30) score -= 1;\n\n // Confidence penalty\n if (entry.confidence !== undefined && entry.confidence < 0.5) {\n score -= 2;\n reasons.push('low confidence');\n }\n\n // Repetition avoidance — recently accessed entries get slight penalty\n if (entry.lastAccessed) {\n const hoursSinceAccess = (now - new Date(entry.lastAccessed).getTime()) / (1000 * 60 * 60);\n if (hoursSinceAccess < 1) score -= 1;\n }\n\n if (score > 0) {\n scored.push({\n ...entry,\n score,\n matchReason: reasons.join(', ') || 'keyword match',\n });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n\n // Filter to entries that meet the minimum relevance threshold.\n // Critical or high-priority entries always pass.\n const threshold = 2;\n const relevant = scored.filter(\n (s) => s.score >= threshold || s.priority === 'critical' || s.priority === 'high',\n );\n\n return relevant.slice(0, Math.min(limit, 15));\n }\n\n async forget(query: string, scope: MemoryScope = 'project-memory'): Promise<number> {\n return this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n let removed = 0;\n try {\n removed = await this.backend.forget(scope, query, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'forget',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'forget',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n if (removed > 0) {\n this.events?.emit('memory.forgotten', {\n scope,\n query,\n removed,\n } satisfies MemoryForgottenPayload);\n await this.mirrorBackup(scope);\n }\n return removed;\n });\n }\n\n async consolidate(scope: MemoryScope): Promise<void> {\n return this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n let removed = 0;\n try {\n removed = await this.backend.consolidate(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'consolidate',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'consolidate',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n if (removed > 0) {\n this.events?.emit('memory.consolidated', {\n scope,\n removed,\n } satisfies MemoryConsolidatedPayload);\n await this.mirrorBackup(scope);\n }\n });\n }\n\n async clear(scope?: MemoryScope): Promise<void> {\n if (scope) {\n await this.runSerialized(scope, async () => {\n const filePath = this.files[scope];\n const t0 = Date.now();\n try {\n await this.backend.clear(scope, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n this.events?.emit('memory.cleared', { scope } satisfies MemoryClearedPayload);\n await this.mirrorBackup(scope);\n });\n return;\n }\n await Promise.all(\n (['project-agents', 'project-memory', 'user-memory'] as MemoryScope[]).map(async (s) =>\n this.runSerialized(s, async () => {\n const filePath = this.files[s];\n const t0 = Date.now();\n try {\n await this.backend.clear(s, filePath);\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'success',\n durationMs: dur,\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n } catch (err) {\n const dur = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: '~memory~',\n store: 'memory',\n filePath,\n operation: 'clear',\n outcome: 'failure',\n durationMs: dur,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined && { traceId: this.traceId }),\n });\n throw err;\n }\n this.events?.emit('memory.cleared', { scope: s } satisfies MemoryClearedPayload);\n await this.mirrorBackup(s);\n }),\n ),\n );\n }\n\n /**\n * Return a new MemoryStore proxy that carries `traceId` on every storage\n * event. The original store is left unchanged — callers that need a\n * trace-decorated view (e.g. session-run tools) receive the proxy while\n * the singleton remains trace-free for boot-time use.\n *\n * The proxy implements the full `MemoryStore` interface; all other\n * properties (backend, etc.) are delegated to the original store.\n */\n withTraceId(traceId: string): MemoryStore {\n // Mutate the singleton's traceId so that all subsequent I/O (including\n // calls from tools that captured the original store reference) emits\n // storage events with the correct session trace ID.\n this.traceId = traceId;\n return this;\n }\n private async mirrorBackup(scope: MemoryScope): Promise<void> {\n if (!this.persistBackup || scope === 'project-agents') return;\n try {\n const content = await this.backend.readAll(scope, this.files[scope]);\n const { writeFile, mkdir } = await import('node:fs/promises');\n await mkdir(this.backupDir, { recursive: true });\n await writeFile(`${this.backupDir}/${scope}.md`, content, 'utf8');\n } catch {\n // best-effort\n }\n }\n}\n\nfunction labelOf(scope: MemoryScope): string {\n switch (scope) {\n case 'project-agents':\n return 'Project AGENTS.md';\n case 'project-memory':\n return 'Project memory';\n case 'user-memory':\n return 'User memory';\n }\n}\n","import * as fs from 'node:fs/promises';\nimport type { MemoryEntry, MemoryScope } from '../types/memory.js';\nimport { type FileMemoryBackendOptions, FileMemoryBackend } from './memory-backend.js';\nimport type { MemoryBackend } from './memory-backend.js';\n\n// ── Graph node and edge types ──────────────────────────────────────────\n\ninterface GraphNode {\n id: string;\n entry: MemoryEntry;\n firstSeen: string;\n count: number;\n /** Extracted metadata for fast lookup. */\n type?: MemoryEntry['type'] | undefined;\n tags?: string[] | undefined;\n priority?: MemoryEntry['priority'] | undefined;\n}\n\ninterface GraphEdge {\n from: string;\n to: string;\n /** Why these nodes are related. */\n relation: 'co_occurring' | 'similar' | 'same_turn' | 'explicit';\n weight: number;\n ts: string;\n}\n\n// ── Backend ────────────────────────────────────────────────────────────\n\nexport interface GraphMemoryBackendOptions extends FileMemoryBackendOptions {\n /**\n * Path to the graph metadata file (edges + node metadata).\n * Defaults to `<projectDir>/memory-graph.json`.\n */\n graphPath?: string | undefined;\n}\n\n/**\n * Graph-based memory backend that tracks relationships between entries.\n * Builds on top of FileMemoryBackend — entries are still persisted as\n * markdown bullets, but the graph layer adds:\n *\n * - Co-occurrence edges (entries from the same remember() batch)\n * - Content similarity edges (simple Jaccard on word overlap)\n * - Turn-based edges (entries created in the same LLM turn)\n * - Graph traversal queries (find related memories)\n *\n * The graph metadata persists to `<projectDir>/memory-graph.json`.\n */\nexport class GraphMemoryBackend implements MemoryBackend {\n readonly kind = 'graph';\n\n private readonly file: FileMemoryBackend;\n private readonly graphFile: string;\n\n // In-memory graph state — lazily loaded, saved on mutation.\n private nodes = new Map<string, GraphNode>();\n private edges: GraphEdge[] = [];\n private loadedScope: MemoryScope | null = null;\n private loaded = false;\n\n constructor(opts: GraphMemoryBackendOptions) {\n this.file = new FileMemoryBackend({ paths: opts.paths });\n this.graphFile = opts.graphPath ?? `${opts.paths.projectDir}/memory-graph.json`;\n }\n\n // ── Backend interface ──────────────────────────────────────────────\n\n async remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise<void> {\n await this.file.remember(scope, entry, filePath);\n await this.loadGraph(scope);\n\n const nodeId = this.nodeId(entry);\n const existing = this.nodes.get(nodeId);\n if (existing) {\n existing.count++;\n existing.entry = entry;\n existing.type = entry.type;\n existing.tags = entry.tags;\n existing.priority = entry.priority;\n } else {\n this.nodes.set(nodeId, {\n id: nodeId,\n entry,\n firstSeen: entry.ts,\n count: 1,\n type: entry.type,\n tags: entry.tags,\n priority: entry.priority,\n });\n\n // Create similarity edges with existing nodes\n for (const [, other] of this.nodes) {\n if (other.id === nodeId) continue;\n const sim = wordOverlap(entry.text, other.entry.text);\n // Also create edges for shared tags\n const tagSim = sharedTags(entry.tags ?? [], other.tags ?? []);\n const weight = Math.max(sim, tagSim * 0.5);\n if (weight > 0.15) {\n this.edges.push({\n from: nodeId,\n to: other.id,\n relation: sim >= tagSim ? 'similar' : 'same_turn',\n weight,\n ts: entry.ts,\n });\n }\n }\n }\n\n await this.saveGraph(scope);\n }\n\n async forget(scope: MemoryScope, query: string, filePath: string): Promise<number> {\n const removed = await this.file.forget(scope, query, filePath);\n if (removed > 0) {\n await this.loadGraph(scope);\n // Remove nodes whose entry text matches the query\n const n = query.toLowerCase();\n const toRemove: string[] = [];\n for (const [id, node] of this.nodes) {\n if (node.entry.text.toLowerCase().includes(n)) {\n toRemove.push(id);\n }\n }\n for (const id of toRemove) this.nodes.delete(id);\n this.edges = this.edges.filter((e) => !toRemove.includes(e.from) && !toRemove.includes(e.to));\n await this.saveGraph(scope);\n }\n return removed;\n }\n\n async readAll(scope: MemoryScope, filePath: string): Promise<string> {\n return this.file.readAll(scope, filePath);\n }\n\n async list(scope: MemoryScope, filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n // Merge: file entries are canonical, graph adds metadata and dedup\n const fileEntries = await this.file.list(scope, filePath);\n const nodeMap = new Map(this.nodes.entries());\n\n // Enrich file entries with graph metadata\n const enriched = fileEntries.map((fe) => {\n const nodeId = this.nodeId(fe);\n const node = nodeMap.get(nodeId);\n if (node) {\n return {\n ...fe,\n type: node.type ?? fe.type,\n tags: node.tags ?? fe.tags,\n priority: node.priority ?? fe.priority,\n };\n }\n return fe;\n });\n\n // Add graph-only nodes not in file (shouldn't happen normally, but safety)\n const fileIds = new Set(fileEntries.map((e) => this.nodeId(e)));\n for (const [id, node] of this.nodes) {\n if (!fileIds.has(id)) {\n enriched.push(node.entry);\n }\n }\n\n enriched.sort((a, b) => b.ts.localeCompare(a.ts));\n return limit ? enriched.slice(0, limit) : enriched;\n }\n\n async search(scope: MemoryScope, query: string, _filePath: string, limit?: number): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const needle = query.toLowerCase().split(/\\s+/);\n\n // Use in-memory nodes directly instead of re-reading the file.\n // loadGraph() already keeps nodes/edges synchronized incrementally.\n const scored: { entry: MemoryEntry; score: number }[] = [];\n for (const node of this.nodes.values()) {\n // Skip nodes from other scopes\n if (node.entry.scope !== scope) continue;\n\n const words = node.entry.text.toLowerCase().split(/\\s+/);\n let score = 0;\n for (const n of needle) {\n if (words.some((w) => w.includes(n))) score += 1;\n if (node.entry.tags?.some((t) => t.toLowerCase().includes(n))) score += 2;\n }\n if (node.priority === 'critical') score += 3;\n else if (node.priority === 'high') score += 2;\n score += node.count * 0.5;\n if (score > 0) scored.push({ entry: node.entry, score });\n }\n\n scored.sort((a, b) => b.score - a.score);\n const matched = scored.map((s) => s.entry);\n return limit ? matched.slice(0, limit) : matched;\n }\n\n async clear(scope: MemoryScope, filePath: string): Promise<void> {\n await this.file.clear(scope, filePath);\n this.nodes.clear();\n this.edges = [];\n this.loadedScope = scope;\n this.loaded = true;\n // Write empty graph\n try { await fs.unlink(this.graphFile); } catch { /* ok */ }\n }\n\n async consolidate(scope: MemoryScope, filePath: string): Promise<number> {\n return this.file.consolidate(scope, filePath);\n }\n\n // ── Graph-specific queries ─────────────────────────────────────────\n\n /**\n * Find memories related to the given entry, ordered by edge weight.\n */\n async findRelated(scope: MemoryScope, _filePath: string, entryText: string, limit = 5): Promise<MemoryEntry[]> {\n await this.loadGraph(scope);\n const targetId = this.nodeId({ scope, text: entryText, ts: '' });\n const related = this.edges\n .filter((e) => e.from === targetId || e.to === targetId)\n .sort((a, b) => b.weight - a.weight)\n .slice(0, limit);\n\n const result: MemoryEntry[] = [];\n for (const edge of related) {\n const otherId = edge.from === targetId ? edge.to : edge.from;\n const node = this.nodes.get(otherId);\n if (node) result.push(node.entry);\n }\n return result;\n }\n\n /**\n * Get all edges for visualization or traversal.\n */\n getGraph(): { nodes: GraphNode[]; edges: GraphEdge[] } {\n return {\n nodes: [...this.nodes.values()],\n edges: [...this.edges],\n };\n }\n\n // ── Persistence ────────────────────────────────────────────────────\n\n private nodeId(entry: MemoryEntry): string {\n // Stable ID from scope + normalized text\n const norm = entry.text.toLowerCase().trim().replace(/\\s+/g, ' ');\n return `${entry.scope ?? 'mem'}::${simpleHash(norm)}`;\n }\n\n private async loadGraph(scope: MemoryScope): Promise<void> {\n if (this.loaded && this.loadedScope === scope) return;\n try {\n const raw = await fs.readFile(this.graphFile, 'utf8');\n const data: { nodes: Array<[string, GraphNode]>; edges: GraphEdge[] } = JSON.parse(raw);\n this.nodes = new Map(data.nodes);\n this.edges = data.edges;\n } catch {\n this.nodes = new Map();\n this.edges = [];\n }\n this.loadedScope = scope;\n this.loaded = true;\n }\n\n private async saveGraph(scope: MemoryScope): Promise<void> {\n this.loadedScope = scope;\n this.loaded = true;\n try {\n const data = {\n nodes: [...this.nodes.entries()],\n edges: this.edges,\n };\n await fs.mkdir(\n this.graphFile.substring(0, this.graphFile.lastIndexOf('/')),\n { recursive: true },\n );\n // Atomic write via temp file\n const tmp = `${this.graphFile}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(data));\n await fs.rename(tmp, this.graphFile);\n } catch {\n // best-effort — graph is an enhancement, not critical\n }\n }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────\n\n/** Jaccard-style word overlap between two strings. 0.0 = no overlap, 1.0 = identical. */\nfunction wordOverlap(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n if (wordsA.size === 0 || wordsB.size === 0) return 0;\n let intersection = 0;\n for (const w of wordsA) {\n if (wordsB.has(w)) intersection++;\n }\n return intersection / Math.max(wordsA.size, wordsB.size);\n}\n\n/** Tag overlap ratio — how many tags two nodes share. */\nfunction sharedTags(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const setB = new Set(b);\n let shared = 0;\n for (const t of a) if (setB.has(t)) shared++;\n return shared / Math.max(a.length, b.length);\n}\n\n/** Fast non-crypto hash for stable node IDs. */\nfunction simpleHash(s: string): string {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h).toString(36);\n}\n","import type { RunResult } from '../core/agent-types.js';\nimport type { Context } from '../core/context.js';\nimport type { AfterRunHook, AgentExtension } from '../extension/extension-points.js';\nimport type { MemoryEntry, MemoryStore } from '../types/memory.js';\nimport type { Provider } from '../types/provider.js';\n\n// ── Types ───────────────────────────────────────────────────────────────\n\nexport interface ConsolidationOp {\n action: 'add' | 'edit' | 'delete';\n /** For add: the fact to remember. For edit: the new text replacing the old. */\n text?: string | undefined;\n /** For edit/delete: the query to match existing entries. */\n query?: string | undefined;\n /** Memory type for categorization. */\n type?: string | undefined;\n /** Tags for grouping. */\n tags?: string[] | undefined;\n /** Priority level. */\n priority?: string | undefined;\n}\n\ninterface ConsolidationResponse {\n operations: ConsolidationOp[];\n summary?: string | undefined;\n}\n\nexport interface MemoryConsolidatorOptions {\n memoryStore: MemoryStore;\n /**\n * Provider used for the consolidation LLM call. Uses the session's\n * provider by default.\n */\n provider?: Provider | undefined;\n /**\n * Model override for the consolidation call. Uses the session's model\n * by default. A smaller/faster model is recommended (e.g. haiku, flash).\n */\n model?: string | undefined;\n /**\n * Minimum session iterations before consolidation fires.\n * Sessions shorter than this are skipped (default 2).\n */\n minIterations?: number | undefined;\n /**\n * Maximum memory entries to include in the prompt as context.\n */\n maxExistingEntries?: number | undefined;\n}\n\n// ── Prompt ──────────────────────────────────────────────────────────────\n\nfunction buildConsolidationPrompt(\n finalText: string,\n iterations: number,\n existingEntries: MemoryEntry[],\n): string {\n const existingBlock =\n existingEntries.length > 0\n ? `\\n\\nExisting memory entries:\\n${existingEntries\n .map((e) => `- [${e.ts.slice(0, 10)}] ${e.text}`)\n .join('\\n')}`\n : '';\n\n return `You are a memory consolidator. Review the following session summary and decide what key facts, conventions, decisions, or learnings should be persisted to long-term memory.\n\nSession summary (${iterations} iterations):\n${finalText.slice(0, 3000)}${existingBlock}\n\nReturn a JSON object with an \"operations\" array. Each operation must have an \"action\" field:\n- \"add\": create a new memory entry. Include \"text\", and optionally \"type\", \"tags\", \"priority\".\n- \"edit\": replace an existing entry. Include \"query\" (to match) and \"text\" (replacement).\n- \"delete\": remove an entry. Include \"query\" (to match).\n\nMemory types:\n- \"fact\": Objective truth about the project (e.g. \"uses pnpm workspaces\")\n- \"decision\": A choice that was made (e.g. \"decided to use biome over eslint\")\n- \"convention\": A recurring pattern or standard (e.g. \"commit messages use conventional format\")\n- \"preference\": User or team preference (e.g. \"prefers short variable names\")\n- \"reference\": Pointer to a file or location (e.g. \"auth logic in packages/core/src/auth/\")\n- \"anti_pattern\": Something to avoid (e.g. \"never use any in TypeScript\")\n\nPriority levels:\n- \"critical\": Must always be known (e.g. security constraints)\n- \"high\": Important for most tasks\n- \"medium\": Useful context\n- \"low\": Nice to know\n\nRules:\n- Only persist facts likely useful across multiple future sessions.\n- Do NOT persist task progress, temporary state, or one-off observations.\n- Prefer \"add\" over \"edit\" unless the existing entry is clearly outdated.\n- Assign a type and priority to every \"add\" operation.\n- Use 1-3 hashtag tags for each entry (e.g. #typescript #build).\n- Be concise — each memory entry should be one clear sentence.\n\nReturn ONLY valid JSON, no markdown, no explanation:\n{\n \"operations\": [\n { \n \"action\": \"add\", \n \"text\": \"Project uses pnpm workspaces with TypeScript strict mode\",\n \"type\": \"convention\",\n \"priority\": \"high\",\n \"tags\": [\"pnpm\", \"typescript\", \"build\"]\n },\n { \n \"action\": \"edit\", \n \"query\": \"pnpm\", \n \"text\": \"Project uses pnpm v9+ with ESM-only modules\",\n \"type\": \"fact\",\n \"priority\": \"medium\"\n },\n { \"action\": \"delete\", \"query\": \"outdated convention\" }\n ]\n}`;\n}\n\n// ── Consolidator ────────────────────────────────────────────────────────\n\nexport class SessionMemoryConsolidator implements AgentExtension {\n name = 'session-memory-consolidator';\n owner = 'core';\n\n private readonly memoryStore: MemoryStore;\n private readonly provider?: Provider | undefined;\n private readonly model?: string | undefined;\n private readonly minIterations: number;\n private readonly maxExistingEntries: number;\n\n constructor(opts: MemoryConsolidatorOptions) {\n this.memoryStore = opts.memoryStore;\n this.provider = opts.provider;\n this.model = opts.model;\n this.minIterations = opts.minIterations ?? 2;\n this.maxExistingEntries = opts.maxExistingEntries ?? 15;\n }\n\n afterRun: AfterRunHook = async (ctx: Context, result: RunResult) => {\n // Only consolidate successful sessions with meaningful output\n if (result.status !== 'done') return;\n if (!result.finalText || result.finalText.trim().length < 20) return;\n if (result.iterations < this.minIterations) return;\n\n const provider = this.provider ?? ctx.provider;\n if (!provider?.complete) return;\n\n try {\n // Load existing memory for dedup context\n const existingEntries = await this.memoryStore.list('project-memory', this.maxExistingEntries);\n const prompt = buildConsolidationPrompt(\n result.finalText,\n result.iterations,\n existingEntries,\n );\n\n // Call the LLM with a focused, one-shot prompt\n const signal = AbortSignal.timeout(15_000);\n const response = await provider.complete(\n {\n model: this.model ?? ctx.model,\n system: [{ type: 'text', text: prompt }],\n messages: [\n { role: 'user', content: 'Review the session and return memory operations as JSON.' },\n ],\n maxTokens: 500,\n },\n { signal },\n );\n\n const text = response.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('')\n .trim();\n if (!text) return;\n\n // Extract JSON from possible markdown wrapper\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) return;\n\n const parsed: ConsolidationResponse = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(parsed.operations) || parsed.operations.length === 0) return;\n\n // Apply operations\n let added = 0;\n let edited = 0;\n let deleted = 0;\n\n for (const op of parsed.operations) {\n switch (op.action) {\n case 'add': {\n if (op.text?.trim()) {\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n added++;\n }\n break;\n }\n case 'edit': {\n if (op.query && op.text?.trim()) {\n await this.memoryStore.forget(op.query);\n await this.memoryStore.remember(op.text.trim(), undefined, {\n type: op.type as MemoryEntry['type'],\n tags: op.tags,\n priority: op.priority as MemoryEntry['priority'],\n });\n edited++;\n }\n break;\n }\n case 'delete': {\n if (op.query) {\n const n = await this.memoryStore.forget(op.query);\n deleted += n;\n }\n break;\n }\n }\n }\n\n if (added > 0 || edited > 0 || deleted > 0) {\n const parts: string[] = [];\n if (added) parts.push(`${added} added`);\n if (edited) parts.push(`${edited} edited`);\n if (deleted) parts.push(`${deleted} deleted`);\n // Log to stderr so it surfaces in the terminal\n process.stderr.write(`[memory] Session consolidation: ${parts.join(', ')}\\n`);\n }\n } catch {\n // Silent — memory consolidation is best-effort, never blocks session cleanup\n }\n };\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { Config, ConfigStore } from '../types/config.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n\n/**\n * Strip fields that originated from environment variables so they are never\n * persisted back to disk. This prevents an env-sourced secret (e.g.\n * WRONGSTACK_API_KEY) from being accidentally written to ~/.wrongstack/config.json.\n */\nfunction stripEphemeralFields(cfg: Partial<Config>): Partial<Config> {\n const env = (cfg as Partial<Config & { _envSource?: Set<string> | undefined}>)._envSource;\n if (!env?.size) return cfg;\n const out: Partial<Config> = { ...cfg };\n for (const field of env) {\n delete (out as Record<string, unknown>)[field];\n }\n delete (out as Record<string, unknown>)._envSource;\n return out;\n}\n\n/**\n * Reference implementation of `ConfigStore`. Stores a single frozen Config\n * and notifies watchers synchronously on every update. Updates use a deep\n * clone so callers can mutate their `partial` argument freely without\n * tainting state.\n *\n * For the CLI: instantiate once at boot, pass the store (not the Config)\n * to subsystems that care about runtime changes (provider switching,\n * extension reload).\n */\nexport class DefaultConfigStore implements ConfigStore {\n private current: Readonly<Config>;\n private watchers = new Set<(next: Readonly<Config>, prev: Readonly<Config>) => void>();\n\n constructor(initial: Config) {\n this.current = deepFreeze(structuredClone(initial));\n }\n\n get(): Readonly<Config> {\n return this.current;\n }\n\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]> {\n return this.current[key] as Readonly<Config[K]>;\n }\n\n getExtension(pluginName: string): Readonly<Record<string, unknown>> {\n const ext = this.current.extensions?.[pluginName];\n return ext ? (ext as Readonly<Record<string, unknown>>) : FROZEN_EMPTY;\n }\n\n update(partial: Partial<Config>): Readonly<Config> {\n // Strip env-sourced fields before persisting to prevent secrets leaking\n // from in-memory env-derived config values into the on-disk config file.\n const scrubbed = stripEphemeralFields(partial);\n // Shallow merge — top-level fields replace, nested objects do too unless\n // the caller passes a fully-formed sub-object. That matches the JSON\n // config user mental model (replace `tools.maxIterations` by passing\n // the whole `tools` block, or by patching `extensions.<name>`).\n const next = deepFreeze(structuredClone({ ...this.current, ...scrubbed })) as Readonly<Config>;\n\n if (next.version !== 1) {\n throw new ConfigError({\n message: `ConfigStore.update: version must remain 1, got ${String(next.version)}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: next.version },\n });\n }\n\n const prev = this.current;\n this.current = next;\n // Notify watchers AFTER mutating `current` so re-entrant watcher reads\n // see the new state. Watcher exceptions are caught individually so one\n // misbehaving subscriber can't block the others.\n for (const w of this.watchers) {\n try {\n w(next, prev);\n } catch (err) {\n // A plugin watcher that crashes on /model switch or similar would\n // otherwise leave the system in a quietly-inconsistent state. We\n // still don't propagate (one bad subscriber must not break the\n // others), but we surface the error so it's discoverable.\n console.error(JSON.stringify({\n level: 'error',\n event: 'config_store.watcher_threw',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n return next;\n }\n\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void {\n this.watchers.add(cb);\n return () => this.watchers.delete(cb);\n }\n}\n\nconst FROZEN_EMPTY: Readonly<Record<string, unknown>> = Object.freeze({});\n\nfunction deepFreeze<T>(obj: T): T {\n /* v8 ignore start -- defensive: callers (and the recursion guard below) only pass unfrozen objects */\n if (obj === null || typeof obj !== 'object') return obj;\n if (Object.isFrozen(obj)) return obj;\n /* v8 ignore stop */\n for (const key of Object.keys(obj as object)) {\n const v = (obj as Record<string, unknown>)[key];\n if (v !== null && typeof v === 'object' && !Object.isFrozen(v)) {\n deepFreeze(v);\n }\n }\n return Object.freeze(obj);\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Logger } from '../types/logger.js';\nimport type { RotatableSecretVault, SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport {\n ENCRYPTED_PREFIX_PATTERN,\n encryptedPrefixForVersion,\n} from '../types/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface SecretVaultOptions {\n /** Absolute path to the key file. Created with mode 0o600 if missing. */\n keyFile: string;\n}\n\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\nconst TAG_BYTES = 16;\nconst ALGO = 'aes-256-gcm';\n// Desired file mode for the key file on POSIX systems.\nconst KEY_FILE_MODE = 0o600;\n\n/**\n * Key file format v2+: 4-byte magic + 1-byte version + 32-byte key = 37 bytes.\n * The magic header distinguishes versioned key files from legacy 32-byte raw keys.\n */\nconst KEY_FILE_MAGIC = Buffer.from('WSKV', 'ascii');\nconst VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES; // 37 bytes\n\n/**\n * Check and warn if the key file has incorrect permissions on POSIX.\n * On Windows this is a no-op (mode bits don't apply).\n */\nfunction checkKeyFilePermissions(keyFile: string): void {\n if (process.platform === 'win32') return; // No mode bits on Windows\n try {\n const stat = fs.statSync(keyFile);\n const actualMode = stat.mode & 0o777;\n if (actualMode !== KEY_FILE_MODE) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'vault.key_file_wrong_permissions',\n message: `Key file ${keyFile} has mode ${actualMode.toString(8)} — expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,\n keyFile,\n expectedMode: KEY_FILE_MODE,\n actualMode,\n timestamp: new Date().toISOString(),\n }));\n }\n } catch {\n // stat can fail for reasons other than the file not existing;\n // if it does, the ENOENT path handles it.\n }\n}\n\n/**\n * Default vault: AES-256-GCM with a key stored at `keyFile` (mode 0o600).\n * The key is loaded lazily on first encrypt/decrypt; if it does not exist,\n * a fresh one is generated. Decryption of plaintext values is a no-op so\n * legacy configs continue to work.\n *\n * Key file format:\n * - Legacy (v1): exactly 32 raw bytes\n * - Versioned (v2+): 4-byte magic `WSKV` + 1-byte version + 32-byte key (37 bytes)\n *\n * Encrypted value format: `enc:v<N>:<iv>:<tag>:<ciphertext>` where N is the\n * key version. After rotation, encrypt() emits the new version prefix.\n */\nexport class DefaultSecretVault implements RotatableSecretVault {\n private readonly keyFile: string;\n private key?: Buffer | undefined;\n private _keyVersion: number = 1;\n\n constructor(opts: SecretVaultOptions) {\n this.keyFile = opts.keyFile;\n }\n\n /** Current key version. Starts at 1; incremented by rotateKey(). */\n get keyVersion(): number {\n // Ensure key is loaded so version is accurate\n if (!this.key) this.loadOrCreateKey();\n return this._keyVersion;\n }\n\n isEncrypted(value: string): boolean {\n return typeof value === 'string' && ENCRYPTED_PREFIX_PATTERN.test(value);\n }\n\n encrypt(plaintext: string): string {\n if (this.isEncrypted(plaintext)) return plaintext;\n const key = this.loadOrCreateKey();\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGO, key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n const prefix = encryptedPrefixForVersion(this._keyVersion);\n return `${prefix}${iv.toString('base64')}:${tag.toString('base64')}:${ct.toString('base64')}`;\n }\n\n decrypt(value: string): string {\n if (!this.isEncrypted(value)) return value;\n // Strip the versioned prefix (enc:v1:, enc:v2:, etc.)\n const prefixMatch = value.match(ENCRYPTED_PREFIX_PATTERN);\n if (!prefixMatch) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const rest = value.slice(prefixMatch[0].length);\n const parts = rest.split(':');\n if (parts.length !== 3) {\n throw new ConfigError({\n message: 'SecretVault: malformed encrypted value',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { field: 'encrypted_value' },\n });\n }\n const [ivB64, tagB64, ctB64] = parts as [string, string, string];\n const iv = Buffer.from(ivB64, 'base64');\n const tag = Buffer.from(tagB64, 'base64');\n const ct = Buffer.from(ctB64, 'base64');\n if (iv.length !== IV_BYTES) throw new ConfigError({\n message: 'SecretVault: bad IV length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: IV_BYTES, actual: iv.length },\n });\n if (tag.length !== TAG_BYTES) throw new ConfigError({\n message: 'SecretVault: bad tag length',\n code: ERROR_CODES.CONFIG_PARSE_FAILED,\n context: { expected: TAG_BYTES, actual: tag.length },\n });\n const key = this.loadOrCreateKey();\n const decipher = createDecipheriv(ALGO, key, iv);\n decipher.setAuthTag(tag);\n const pt = Buffer.concat([decipher.update(ct), decipher.final()]);\n return pt.toString('utf8');\n }\n\n /**\n * Generate a new encryption key, write it to disk, and increment the key version.\n * After rotation, encrypt() emits the new version prefix (e.g. enc:v2:).\n * The caller must re-encrypt existing config values (see rotateConfigKeys()).\n */\n rotateKey(): { oldVersion: number; newVersion: number } {\n const oldVersion = this._keyVersion;\n const newKey = randomBytes(KEY_BYTES);\n const newVersion = oldVersion + 1;\n\n // Write versioned key file: WSKV + version byte + key\n const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);\n KEY_FILE_MAGIC.copy(keyFileBuf, 0);\n keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;\n newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);\n\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n fs.writeFileSync(this.keyFile, keyFileBuf, { mode: 0o600 });\n checkKeyFilePermissions(this.keyFile);\n\n this.key = newKey;\n this._keyVersion = newVersion;\n return { oldVersion, newVersion };\n }\n\n private loadOrCreateKey(): Buffer {\n // readFileSync blocks the event loop, but this is a one-time cost per\n // process: the key is cached after the first load and reused for every\n // subsequent encrypt/decrypt. For CLI usage (single run → exit) this is\n // negligible. For server contexts (eternal autonomy, MCP server mode),\n // the first encrypt/decrypt call causes a brief (<1ms) event loop stall.\n // Prefer calling vault.encrypt('') during boot to warm the cache if this\n // is a concern in your deployment.\n if (this.key) return this.key;\n try {\n const buf = fs.readFileSync(this.keyFile);\n\n // Detect key file format:\n if (buf.length === KEY_BYTES) {\n // Legacy v1: raw 32-byte key\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned v2+: WSKV magic + version byte + 32-byte key\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const key = buf.subarray(KEY_FILE_MAGIC.length + 1);\n if (key.length !== KEY_BYTES) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has wrong key size (${key.length} bytes, expected ${KEY_BYTES})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: key.length },\n });\n }\n this.key = Buffer.from(key);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n\n // Wrong size — neither legacy nor versioned format\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n // Create a fresh key. Use sync APIs so the constructor-free getter\n // remains synchronous from the caller's perspective.\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n // Use exclusive-create flag 'wx' to prevent races: if two processes race\n // to create the key file, only one succeeds and the loser gets EEXIST.\n try {\n fs.writeFileSync(this.keyFile, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;\n // Another process won the race — re-read what they wrote.\n const buf = fs.readFileSync(this.keyFile);\n if (buf.length === KEY_BYTES) {\n // Legacy v1 format\n this.key = buf;\n this._keyVersion = 1;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n if (buf.length === VERSIONED_KEY_FILE_SIZE) {\n // Versioned format\n const magic = buf.subarray(0, KEY_FILE_MAGIC.length);\n if (!magic.equals(KEY_FILE_MAGIC)) {\n throw new ConfigError({\n message: `SecretVault: key file ${this.keyFile} has invalid magic header`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile },\n });\n }\n const version = buf[KEY_FILE_MAGIC.length]!;\n const winnerKey = buf.subarray(KEY_FILE_MAGIC.length + 1);\n this.key = Buffer.from(winnerKey);\n this._keyVersion = version;\n checkKeyFilePermissions(this.keyFile);\n return this.key;\n }\n throw new ConfigError({\n message:\n `SecretVault: key file ${this.keyFile} is ${buf.length} bytes ` +\n `(expected ${KEY_BYTES} for v1 or ${VERSIONED_KEY_FILE_SIZE} for v2+). ` +\n `Remove it manually to generate a new key.`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { keyFile: this.keyFile, expectedBytes: KEY_BYTES, actualBytes: buf.length },\n });\n }\n this.key = key;\n this._keyVersion = 1;\n return key;\n }\n}\n\n/**\n * Walk a Config-shaped object and decrypt any apiKey-like fields in place,\n * returning a new object. Used by the config loader so the rest of the\n * system never has to know about the wire format.\n *\n * @param warn — callback for decryption warnings. Defaults to `console.warn`\n * for backward compatibility; pass `logger.warn` when a structured logger\n * is available (preferred in long-running/server contexts).\n */\nexport function decryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n opts?: { warn?: (msg: string) => void },\n): T {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n // A single corrupted/malformed encrypted field should not kill the entire\n // config load. Swallow per-field decrypt errors (zero the field so callers\n // see \"missing key\" instead of holding ciphertext) and surface a warning.\n return walk(cfg, vault, (v, key) => {\n try {\n return vault.decrypt(v);\n } catch (err) {\n warn(\n `[secret-vault] Failed to decrypt \"${key}\": ${err instanceof Error ? err.message : err}`,\n );\n return '';\n }\n });\n}\n\nexport function encryptConfigSecrets<T>(\n cfg: T,\n vault: SecretVault,\n _opts?: { warn?: (msg: string) => void },\n): T {\n return walk(cfg, vault, (v) => vault.encrypt(v));\n}\n\nfunction walk<T>(node: T, vault: SecretVault, transform: (s: string, key: string) => string): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walk(item, vault, transform)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k)) {\n out[k] = transform(v, k);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walk(v, vault, transform);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * A key is treated as secret-bearing if its name (case-insensitive) contains\n * one of these tokens. Captures common variants like `apiKey`, `authToken`,\n * `refreshToken`, `sessionKey`, `password`, `client_secret`, `bearer`, etc.\n * Use a named field with `isSecret: false` annotation if you must opt out —\n * see `NON_SECRET_OVERRIDES` below.\n */\nconst SECRET_KEY_PATTERN =\n /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;\n\n// Field names that contain the literal substring \"key\" but are not secrets.\n// Keep this list short; the substring rule itself is intentionally narrow.\nconst NON_SECRET_OVERRIDES = new Set(['publickey', 'public_key']);\n\nexport function isSecretField(name: string): boolean {\n const lc = name.toLowerCase();\n if (NON_SECRET_OVERRIDES.has(lc)) return false;\n return SECRET_KEY_PATTERN.test(lc);\n}\n\n/**\n * Re-write `~/.wrongstack/config.json` (or any path) with all secret-bearing\n * fields encrypted. Used by the `wstack auth` subcommand.\n */\nexport async function rewriteConfigEncrypted(\n configPath: string,\n vault: SecretVault,\n patch?: Record<string, unknown>,\n): Promise<void> {\n let current: Record<string, unknown> = {};\n try {\n const raw = await fsp.readFile(configPath, 'utf8');\n current = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // start from empty\n }\n const merged = deepMerge(current, patch ?? {});\n const encrypted = encryptConfigSecrets(merged, vault);\n await fsp.mkdir(path.dirname(configPath), { recursive: true });\n // atomicWrite: torn write here would erase every saved encrypted API key.\n await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath);\n}\n\n/**\n * Scan a config file on disk for plaintext secret-bearing fields and\n * rewrite the file with them encrypted in place. Returns a count of how\n * many fields were migrated. Idempotent — calling on a fully-encrypted\n * file is a no-op and writes nothing. Used by the CLI on every boot so\n * users who had plaintext keys before the vault landed are upgraded\n * transparently.\n */\nexport async function migratePlaintextSecrets(\n configPath: string,\n vault: SecretVault,\n logger?: Pick<Logger, 'warn'>,\n): Promise<{ migrated: number; file: string }> {\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n return { migrated: 0, file: configPath };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { migrated: 0, file: configPath };\n }\n const counter = { n: 0 };\n const migrated = walkCount(parsed, vault, counter);\n if (counter.n === 0) return { migrated: 0, file: configPath };\n // atomicWrite: runs on every boot for legacy users — torn write = wipe.\n await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 0o600 });\n await restrictFilePermissions(\n configPath,\n logger ? { warn: (msg) => logger.warn(msg) } : undefined,\n );\n return { migrated: counter.n, file: configPath };\n}\n\n/**\n * Rotate the vault's encryption key and re-encrypt all secret-bearing\n * fields in a config file. This is the atomic key rotation operation:\n *\n * 1. Read the config file\n * 2. Decrypt all encrypted values with the old key\n * 3. Generate a new key (vault.rotateKey())\n * 4. Re-encrypt all values with the new key (new version prefix)\n * 5. Write the config file atomically\n *\n * Returns the number of fields re-encrypted and the version transition.\n * If the config file doesn't exist or has no encrypted fields, returns\n * { rotated: 0 } without modifying the key.\n */\nexport async function rotateConfigKeys(\n configPath: string,\n vault: RotatableSecretVault,\n logger?: Pick<Logger, 'warn' | 'info'>,\n): Promise<{ rotated: number; oldVersion: number; newVersion: number; file: string }> {\n const log = logger?.info ?? (() => {});\n const warn = logger?.warn ?? ((msg: string) => console.warn(msg));\n\n // Read the config file\n let raw: string;\n try {\n raw = await fsp.readFile(configPath, 'utf8');\n } catch {\n // No config file — just rotate the key without re-encrypting anything\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no config file to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n warn(`[secret-vault] Config file ${configPath} is not valid JSON — skipping rotation`);\n return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };\n }\n\n // Count encrypted fields and decrypt them\n const counter = { n: 0, failed: [] as string[] };\n const decrypted = walkDecryptCount(parsed, vault, counter);\n\n // Abort BEFORE rotating if any encrypted field could not be decrypted with\n // the current key. Rotation would discard the old key while these fields\n // still hold old-key ciphertext, and walkReencrypt skips already-encrypted\n // values — so they would become permanently undecryptable. Surface the\n // corruption and leave the key intact for the operator to investigate.\n if (counter.failed.length > 0) {\n throw new Error(\n `[secret-vault] Aborting key rotation: ${counter.failed.length} field(s) could not be decrypted ` +\n `with the current key and would be permanently lost on rotation: ${counter.failed.join(', ')}. ` +\n `Restore or remove these fields before rotating.`,\n );\n }\n\n if (counter.n === 0) {\n // No encrypted fields — just rotate the key\n const { oldVersion, newVersion } = vault.rotateKey();\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — no encrypted fields to re-encrypt`);\n return { rotated: 0, oldVersion, newVersion, file: configPath };\n }\n\n // Rotate the key (generates new key, increments version)\n const { oldVersion, newVersion } = vault.rotateKey();\n\n // Re-encrypt all secret fields with the new key\n const reencrypted = walkReencrypt(decrypted, vault);\n\n // Write the config file atomically\n await atomicWrite(configPath, JSON.stringify(reencrypted, null, 2), { mode: 0o600 });\n await restrictFilePermissions(configPath, { warn });\n\n log(`[secret-vault] Key rotated (v${oldVersion} → v${newVersion}) — re-encrypted ${counter.n} field(s)`);\n return { rotated: counter.n, oldVersion, newVersion, file: configPath };\n}\n\n/**\n * Walk a config object, decrypt all encrypted values, and count them.\n * Returns a new object with decrypted values.\n *\n * `counter.failed` collects the key paths of any field that is encrypted but\n * could NOT be decrypted with the current key. These are left as-is (old\n * ciphertext). The caller MUST treat a non-empty `failed` list as a hard stop\n * before rotating: rotation discards the old key, and `walkReencrypt` skips\n * already-encrypted values, so a retained old-key ciphertext would become\n * permanently undecryptable. Surfacing it is strictly safer than entombing it.\n */\nfunction walkDecryptCount<T>(\n node: T,\n vault: SecretVault,\n counter: { n: number; failed: string[] },\n pathPrefix = '',\n): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item, i) =>\n walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`),\n ) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;\n if (typeof v === 'string' && vault.isEncrypted(v)) {\n try {\n out[k] = vault.decrypt(v);\n counter.n++;\n } catch {\n // Decryption failed — record the path and keep the old ciphertext.\n // The caller aborts rotation when counter.failed is non-empty, so\n // the old key is never discarded while this value still depends on it.\n counter.failed.push(keyPath);\n out[k] = v;\n }\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkDecryptCount(v, vault, counter, keyPath);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Walk a config object and re-encrypt all secret-bearing fields.\n * Unlike encryptConfigSecrets, this encrypts ALL string values that\n * were previously decrypted (they're now plaintext), not just those\n * matching the secret field pattern. This ensures we re-encrypt values\n * that were successfully decrypted in walkDecryptCount.\n */\nfunction walkReencrypt<T>(node: T, vault: SecretVault): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkReencrypt(item, vault)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && v.length > 0 && !vault.isEncrypted(v)) {\n // This was a decrypted secret — re-encrypt it\n out[k] = vault.encrypt(v);\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkReencrypt(v, vault);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/**\n * Restrict a file to owner-only access. On POSIX this is chmod 0o600.\n * On Windows, chmod is a no-op — we use icacls to remove inherited\n * permissions and grant only the current user. Failures are logged\n * but not thrown so callers are not blocked on unsupported platforms.\n */\nasync function restrictFilePermissions(\n filePath: string,\n opts?: { warn?: (msg: string) => void },\n): Promise<void> {\n const warn = opts?.warn ?? ((msg: string) => console.warn(msg));\n if (process.platform === 'win32') {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n const user = windowsAccountName();\n if (!user) {\n warn(\n `[secret-vault] Could not determine the current Windows user for ${filePath}; skipping icacls hardening.`,\n );\n return;\n }\n // Remove inherited ACEs, grant full control only to current user.\n await execFileAsync('icacls', [filePath, '/inheritance:r', '/grant:r', `${user}:(F)`]);\n } catch {\n // Best-effort: icacls may not be available in all environments.\n warn(\n `[secret-vault] Could not restrict permissions on ${filePath} — config file may be readable by other users on this system.`,\n );\n }\n } else {\n try {\n await fsp.chmod(filePath, 0o600);\n } catch {\n // Best-effort\n }\n }\n}\n\nfunction windowsAccountName(): string | undefined {\n const username = process.env.USERNAME || process.env.USER;\n if (!username || username.includes('\\0')) return undefined;\n const domain = process.env.USERDOMAIN;\n if (domain && !domain.includes('\\0')) return `${domain}\\\\${username}`;\n return username;\n}\n\nfunction walkCount<T>(node: T, vault: SecretVault, counter: { n: number }): T {\n if (node === null || node === undefined) return node;\n if (typeof node !== 'object') return node;\n if (Array.isArray(node)) {\n return node.map((item) => walkCount(item, vault, counter)) as never as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (typeof v === 'string' && isSecretField(k) && !vault.isEncrypted(v) && v.length > 0) {\n out[k] = vault.encrypt(v);\n counter.n++;\n } else if (typeof v === 'object' && v !== null) {\n out[k] = walkCount(v, vault, counter);\n } else {\n out[k] = v;\n }\n }\n return out as T;\n}\n\n/** Keys that, when written into a plain object, can poison the prototype\n * chain. We never want user config to carry these. */\nimport { deepMerge } from '../utils/deep-merge.js';\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n autoExtendLimit: true,\n restrictToProjectRoot: false,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/**\n * Default process circuit-breaker config. Protection is OFF by default — the\n * breaker only gates `bash`/`exec` once the user opts in via `/settings breaker on`.\n * The auto kill/reset delay is only consulted when protection is enabled.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({\n enabled: false,\n autoKillResetMs: 60_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","import * as fs from 'node:fs/promises';\nimport { decryptConfigSecrets } from '../security/secret-vault.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport {\n DEFAULT_CONTEXT_WINDOW_MODE_ID,\n isContextWindowModeId,\n listContextWindowModes,\n} from '../types/context-window.js';\nimport type { Config, ConfigLoader, SyncConfig } from '../types/config.js';\nimport type { SecretVault } from '../types/secret-vault.js';\nimport { ConfigError, ERROR_CODES } from '../types/errors.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { deepMerge as deepMergeCore, type DeepMergeOptions } from '../utils/deep-merge.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport {\n DEFAULT_AUTONOMY_CONFIG,\n DEFAULT_TOOLS_CONFIG,\n DEFAULT_CONTEXT_CONFIG,\n DEFAULT_SESSION_LOGGING_CONFIG,\n} from '../types/default-config.js';\nimport type { EventBus } from '../kernel/events.js';\n\n/**\n * Surface the OS error code (EACCES, ENOSPC, …) alongside the message in\n * storage.* event payloads. Codes are stable and locale-independent, so\n * they are what dashboards and alerts key on; the message is supplementary.\n */\nfunction storageErrorString(err: unknown): string {\n if (err instanceof Error) {\n const code = (err as NodeJS.ErrnoException).code;\n return code ? `${code}: ${err.message}` : err.message;\n }\n /* v8 ignore next -- defensive: callers only pass fs Error instances */\n return String(err);\n}\n\n/**\n * Defaults express *behavior*, not identity. Provider and model are NOT\n * hardcoded — they must be resolved at runtime from config + env + the\n * ModelsRegistry. A bare Config returned by this loader will throw when\n * the agent tries to construct a provider, with a message that points\n * users at `wstack init`.\n */\nconst BEHAVIOR_DEFAULTS: Omit<Config, 'provider' | 'model'> = {\n version: 1,\n context: {\n mode: DEFAULT_CONTEXT_WINDOW_MODE_ID,\n warnThreshold: 0.6,\n softThreshold: 0.75,\n hardThreshold: 0.9,\n autoCompact: true,\n preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,\n eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold,\n },\n tools: {\n defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,\n maxIterations: DEFAULT_TOOLS_CONFIG.maxIterations,\n iterationTimeoutMs: DEFAULT_TOOLS_CONFIG.iterationTimeoutMs,\n sessionTimeoutMs: DEFAULT_TOOLS_CONFIG.sessionTimeoutMs,\n perIterationOutputCapBytes: DEFAULT_TOOLS_CONFIG.perIterationOutputCapBytes,\n autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit,\n restrictToProjectRoot: DEFAULT_TOOLS_CONFIG.restrictToProjectRoot,\n },\n log: { level: 'info' },\n features: {\n mcp: true,\n plugins: true,\n memory: true,\n modelsRegistry: true,\n skills: true,\n tokenSavingMode: 'off',\n allowOutsideProjectRoot: true,\n },\n mcpServers: {},\n indexing: {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n },\n session: { ...DEFAULT_SESSION_LOGGING_CONFIG },\n autonomy: { autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs },\n};\n\n/** Parse a boolean-ish env var: \"0\"/\"false\"/\"no\"/\"off\" → false, anything else → true. */\nfunction envBool(v: string): boolean {\n return !/^(0|false|no|off)$/i.test(v.trim());\n}\n\nfunction envBoolOptional(v: string | undefined): boolean {\n return v !== undefined && envBool(v);\n}\n\nconst LOG_LEVELS = new Set<Config['log']['level']>(['error', 'warn', 'info', 'debug', 'trace']);\n\nfunction envLogLevel(v: string): Config['log']['level'] {\n return LOG_LEVELS.has(v as Config['log']['level']) ? (v as Config['log']['level']) : 'info';\n}\n\nconst ENV_MAP: Record<string, (cfg: PartialConfig, val: string) => void> = {\n WRONGSTACK_PROVIDER: (c, v) => {\n c.provider = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('provider');\n },\n WRONGSTACK_MODEL: (c, v) => {\n c.model = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('model');\n },\n WRONGSTACK_API_KEY: (c, v) => {\n c.apiKey = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('apiKey');\n },\n WRONGSTACK_BASE_URL: (c, v) => {\n c.baseUrl = v;\n if (c._envSource === undefined) c._envSource = new Set();\n c._envSource.add('baseUrl');\n },\n WRONGSTACK_LOG_LEVEL: (c, v) => {\n /* v8 ignore next -- defensive: config defaults always seed c.log before env handlers run */\n if (!c.log) c.log = { level: 'info' };\n c.log.level = envLogLevel(v);\n },\n WRONGSTACK_INDEX_ON_START: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onSessionStart: envBool(v) };\n },\n WRONGSTACK_INDEX_ON_EDIT: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, onEdit: envBool(v) };\n },\n WRONGSTACK_INDEX_WATCH: (c, v) => {\n c.indexing = { ...defaultIndexing, ...c.indexing, watchExternal: envBool(v) };\n },\n};\n\nconst defaultIndexing = {\n onSessionStart: true,\n onEdit: true,\n watchExternal: true,\n debounceMs: 400,\n} as const;\n\ntype PartialConfig = Partial<Config> & {\n providers?: Record<\n string,\n { apiKey?: string | undefined; baseUrl?: string | undefined; type?: string | undefined }\n >;\n /** Fields that came from environment variables — must not be persisted. */\n _envSource?: Set<string> | undefined;\n};\n\n/**\n * Config-layer deep merge — delegates to the shared utility with\n * `arrayMode: 'concat-primitives'` and optional debug logging for\n * non-primitive array replacements.\n */\nfunction deepMerge<T>(base: T, patch: Partial<T>): T {\n const opts: DeepMergeOptions = { arrayMode: 'concat-primitives' };\n if (envBoolOptional(process.env.WRONGSTACK_DEBUG_CONFIG)) {\n opts.onNonPrimitiveArrayReplace = (key, existingLen, patchLen) => {\n console.warn(\n `[config] Non-primitive array for \"${key}\" replaced (global + local config merge). ` +\n `Global entries: ${existingLen}, local entries: ${patchLen}.`,\n );\n };\n }\n return deepMergeCore(base as Record<string, unknown>, patch as Record<string, unknown>, opts) as T;\n}\n\n/**\n * A single config source. Higher priority wins in merges.\n * Sources are applied in priority order (lowest first), so a source\n * with priority=10 overrides one with priority=1.\n */\nexport interface ConfigSource {\n /** Unique name for debugging and error messages. */\n name: string;\n /** Lower numbers merge first, higher numbers override lower. Default: 50. */\n priority?: number | undefined;\n /**\n * Read the raw config patch. Return an empty object if unavailable.\n * Errors are surfaced but do not abort loading — the source is skipped.\n */\n read(): Promise<Partial<Config>>;\n}\n\nexport interface ConfigLoaderOptions {\n paths: WstackPaths;\n strict?: boolean | undefined;\n vault?: SecretVault | undefined;\n /** Extra sources merged after the built-in layers. */\n sources?: ConfigSource[] | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class DefaultConfigLoader implements ConfigLoader {\n private readonly paths: WstackPaths;\n private readonly strict: boolean;\n private readonly vault: SecretVault | undefined;\n private readonly extraSources: ConfigSource[];\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n\n constructor(opts: ConfigLoaderOptions) {\n this.paths = opts.paths;\n this.strict = opts.strict ?? false;\n this.vault = opts.vault;\n this.extraSources = opts.sources ?? [];\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n async load(\n opts: { cliFlags?: Partial<Config> | undefined; cwd?: string | undefined } = {},\n ): Promise<Config> {\n let cfg: PartialConfig = { ...BEHAVIOR_DEFAULTS } as PartialConfig;\n\n // Layer 2, 3 & 3b: global + project-local + in-project config — read in parallel.\n // inProjectConfig (<project>/.wrongstack/config.json) merges AFTER\n // projectLocalConfig so it takes priority (user-intended > auto-cached).\n const [global, local, inProject] = await Promise.all([\n this.readJson(this.paths.globalConfig),\n this.readJson(this.paths.projectLocalConfig),\n this.readJson(this.paths.inProjectConfig),\n ]);\n cfg = deepMerge(cfg, global);\n cfg = deepMerge(cfg, local);\n cfg = deepMerge(cfg, inProject);\n\n // Layer 4: env vars\n for (const [key, fn] of Object.entries(ENV_MAP)) {\n const v = process.env[key];\n if (v) fn(cfg, v);\n }\n\n // Layer 5: extra sources — sorted by priority (lowest first).\n // When priorities tie, sort by name for deterministic order.\n const sorted = [...this.extraSources].sort((a, b) => {\n const pd = (a.priority ?? 50) - (b.priority ?? 50);\n if (pd !== 0) return pd;\n return a.name.localeCompare(b.name);\n });\n for (const src of sorted) {\n try {\n const patch = await src.read();\n if (patch && Object.keys(patch).length > 0) {\n cfg = deepMerge(cfg, patch);\n }\n } catch (err) {\n // Best-effort: skip failing sources so one bad source doesn't block boot.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.source_load_failed',\n source: src.name,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n }\n\n // Layer 6: CLI flags\n if (opts.cliFlags) {\n cfg = deepMerge(cfg, opts.cliFlags);\n }\n\n // Decrypt apiKey-like fields if a vault is configured.\n if (this.vault) {\n cfg = decryptConfigSecrets(cfg, this.vault);\n }\n\n // Multi-key resolution: when a provider has `apiKeys[]` configured,\n // mirror the active entry into `apiKey` so downstream construction\n // code (provider registry, wire adapters) needs no changes. Honors\n // `activeKey` (by label), else falls back to the first entry. A\n // pre-existing `apiKey` set by env/CLI flags wins so an explicit\n // override still beats the saved list.\n if (cfg.providers) {\n for (const pcfg of Object.values(cfg.providers)) {\n if (!pcfg || typeof pcfg !== 'object') continue;\n const rawKeys = (pcfg as { apiKeys?: unknown | undefined }).apiKeys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) continue;\n // Each apiKeys entry came from arbitrary JSON. Filter to entries\n // that actually have a string apiKey + label so a malformed array\n // (null entry, missing field) doesn't crash the .find / chosen.apiKey\n // path below.\n const keys = rawKeys.filter(\n (k): k is { label: string; apiKey: string } =>\n !!k &&\n typeof k === 'object' &&\n typeof (k as { label?: unknown | undefined }).label === 'string' &&\n typeof (k as { apiKey?: unknown | undefined }).apiKey === 'string',\n );\n if (keys.length === 0) continue;\n const existing = (pcfg as { apiKey?: string | undefined }).apiKey;\n if (existing && existing.length > 0) continue;\n const activeLabel = (pcfg as { activeKey?: string | undefined }).activeKey;\n const chosen = activeLabel\n ? (keys.find((k) => k.label === activeLabel) ?? keys[0])\n : keys[0];\n if (chosen?.apiKey) {\n (pcfg as { apiKey?: string | undefined }).apiKey = chosen.apiKey;\n }\n }\n }\n\n this.validateBehavior(cfg);\n if (this.strict) {\n this.validateIdentity(cfg);\n }\n // In strict mode, validateIdentity has confirmed provider/model are set;\n // it's safe to assert the full Config contract. In non-strict mode the\n // caller (e.g. early-boot wizard) accepts a Partial and constructs the\n // provider later, so we deliberately return without the cast.\n return Object.freeze(cfg) as Config;\n }\n\n /**\n * Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted\n * by the vault (if provided). The file is isolated from the main config\n * hierarchy to prevent accidental commits.\n */\n async persistSyncConfig(cfg: SyncConfig): Promise<void> {\n let toWrite = { ...cfg };\n if (this.vault && toWrite.githubToken && !toWrite.githubToken.startsWith('enc:')) {\n // Re-encrypt if plaintext (e.g. came from in-memory configStore update\n // rather than direct /sync enable call). Idempotent for already-encrypted.\n toWrite = { ...toWrite, githubToken: this.vault.encrypt(toWrite.githubToken) };\n }\n const fp = this.paths.syncConfig;\n const t0 = Date.now();\n try {\n await atomicWrite(fp, JSON.stringify(toWrite, null, 2), { mode: 0o600 });\n this.events?.emit('storage.write', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'persist_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'persist_sync',\n outcome: 'failure',\n error: storageErrorString(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Read ~/.wrongstack/sync.json (encrypted GitHub token storage) and decrypt\n * the token if a vault is available. Returns null if the file doesn't exist.\n * This is separate from main config loading because sync.json is intentionally\n * isolated — it should never be part of project-local or env-driven config.\n */\n async loadSyncConfig(): Promise<SyncConfig | null> {\n const fp = this.paths.syncConfig;\n const t0 = Date.now();\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const parsed = safeParse<SyncConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse error or empty file',\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return null;\n }\n\n // Decrypt the token if vault is available (field name matches secret pattern)\n if (this.vault) {\n const decrypted = decryptConfigSecrets({ sync: parsed.value } as PartialConfig, this.vault);\n const result = (decrypted as { sync: SyncConfig }).sync ?? null;\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return result;\n }\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return parsed.value;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Non-ENOENT failures (EACCES, ENOSPC, etc.) — emit storage.read failure, then return null\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: fp,\n operation: 'load_sync',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.sync_load_failed',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n return null;\n }\n }\n\n private async readJson(file: string): Promise<PartialConfig> {\n let raw: string;\n const t0 = Date.now();\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n // Missing file is the common case (per-project local config rarely\n // exists at start). Surface anything else (EACCES, EISDIR) so a\n // mis-permissioned config doesn't silently fall back to defaults.\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: file,\n operation: 'read_json',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.read_failed',\n path: file,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return {};\n }\n const parsed = safeParse<PartialConfig>(raw);\n if (!parsed.ok || !parsed.value) {\n // The file exists but isn't valid JSON. Don't silently reset to\n // defaults — that's hours of debug timesink for users who'd typo'd\n // their config. Warn loudly and keep the in-memory defaults.\n this.events?.emit('storage.read', {\n sessionId: '~config~',\n store: 'config',\n filePath: file,\n operation: 'read_json',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse error or empty file',\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'config.parse_failed',\n path: file,\n message: 'invalid JSON — falling back to defaults for this layer',\n timestamp: new Date().toISOString(),\n }));\n return {};\n }\n return parsed.value;\n }\n\n private validateBehavior(cfg: PartialConfig): void {\n /* v8 ignore start -- defensive: config defaults always seed version:1 before validation */\n if (cfg.version === undefined) throw new ConfigError({\n message: 'Config: missing version field',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version' },\n });\n /* v8 ignore stop */\n if (cfg.version !== 1) throw new ConfigError({\n message: `Config: unsupported version ${cfg.version}`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'version', actual: cfg.version },\n });\n const c = cfg.context;\n if (!c) throw new ConfigError({\n message: 'Config: missing context section',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'context' },\n });\n // A user-edited config.json can land strings here (\"0.6\") and slip past\n // truthiness checks; the `>=` comparison then coerces silently and the\n // threshold ordering check passes for nonsense values. Validate types\n // explicitly so misconfigs surface here, not as confusing failures deep\n // in the auto-compaction logic.\n const fields: Array<keyof typeof c> = ['warnThreshold', 'softThreshold', 'hardThreshold'];\n for (const f of fields) {\n const v = c[f];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n throw new ConfigError({\n message: `Config: context.${String(f)} must be a finite number (got ${typeof v})`,\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: `context.${String(f)}`, actualType: typeof v },\n });\n }\n }\n if (c.warnThreshold >= c.softThreshold || c.softThreshold >= c.hardThreshold) {\n throw new ConfigError({\n message: 'Config: context thresholds must satisfy warn < soft < hard',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { warn: c.warnThreshold, soft: c.softThreshold, hard: c.hardThreshold },\n });\n }\n if (c.mode !== undefined && !isContextWindowModeId(c.mode)) {\n // An unknown mode (typo or value from an older/renamed scheme) should not\n // brick the CLI — unlike the numeric thresholds above there is a safe\n // default. Warn and fall back rather than throwing.\n const known = listContextWindowModes()\n .map((m) => m.id)\n .join(', ');\n console.warn(\n `[config] Ignoring unknown context.mode \"${c.mode}\" (expected one of: ${known}); ` +\n `falling back to \"${DEFAULT_CONTEXT_WINDOW_MODE_ID}\".`,\n );\n c.mode = DEFAULT_CONTEXT_WINDOW_MODE_ID;\n }\n }\n\n private validateIdentity(cfg: PartialConfig): void {\n if (!cfg.provider) {\n throw new ConfigError({\n message: 'Config: no provider configured. Run `wstack init` or set WRONGSTACK_PROVIDER.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'provider' },\n });\n }\n if (!cfg.model) {\n throw new ConfigError({\n message: 'Config: no model configured. Run `wstack init` or set WRONGSTACK_MODEL.',\n code: ERROR_CODES.CONFIG_INVALID,\n context: { field: 'model' },\n });\n }\n }\n}\n","/**\n * L2-D: Config version migration framework. Pure functions, decoupled\n * from disk/CLI — caller passes a parsed JSON object and gets back the\n * up-to-date `Config` shape (or a structured error explaining why\n * migration failed).\n *\n * Migrations are registered as `{ from, to, migrate }` triples and run\n * sequentially. Each migration is independently testable. Adding a new\n * version means appending one migration; existing user configs are\n * upgraded in place at load time.\n */\n\nexport interface MigrationContext {\n /**\n * Original on-disk version of the input. Migrations may use this to\n * decide between in-place patches and rewrites.\n */\n fromVersion: number;\n /**\n * Set when the migration writes back to disk. Callers persist the\n * migrated config when this is true so the user doesn't see the same\n * migration banner on every boot.\n */\n shouldPersist: boolean;\n}\n\nexport interface ConfigMigration {\n /** Version of the input this migration accepts. */\n from: number;\n /** Version of the output it produces. */\n to: number;\n /** Pure transform — no I/O. */\n migrate(input: Record<string, unknown>, ctx: MigrationContext): Record<string, unknown>;\n /** Optional human-readable description for migration logs / banners. */\n describe?: string | undefined;\n}\n\nexport interface MigrationResult {\n /** Final config (still typed as `unknown`-keyed — caller validates). */\n config: Record<string, unknown>;\n /** Ordered list of `from→to` versions that ran. */\n applied: string[];\n /** True when at least one migration produced changes worth persisting. */\n shouldPersist: boolean;\n}\n\nexport class ConfigMigrationError extends Error {\n readonly fromVersion: number;\n readonly targetVersion: number;\n readonly missingStep: number | null;\n\n constructor(opts: {\n message: string;\n fromVersion: number;\n targetVersion: number;\n missingStep: number | null;\n }) {\n super(opts.message);\n this.name = 'ConfigMigrationError';\n this.fromVersion = opts.fromVersion;\n this.targetVersion = opts.targetVersion;\n this.missingStep = opts.missingStep;\n }\n}\n\n/**\n * Run registered migrations until the input reaches `targetVersion`.\n *\n * Resolution rules:\n * 1. If `input.version === targetVersion`, no migrations run; `shouldPersist`\n * is false.\n * 2. Otherwise walk the migration chain from `input.version` upward,\n * picking the migration whose `from` matches the current version.\n * 3. Stop when `current.version === targetVersion`.\n * 4. If no migration matches at some point, throw `ConfigMigrationError`\n * with the missing step recorded for diagnostics.\n *\n * Migrations may be downward (e.g. for staged rollouts), but `targetVersion`\n * must be reachable strictly via the registered chain — there's no implicit\n * \"skip\" or transitive resolution.\n */\nexport function runConfigMigrations(\n input: Record<string, unknown>,\n targetVersion: number,\n migrations: readonly ConfigMigration[],\n): MigrationResult {\n const initial = typeof input['version'] === 'number' ? (input['version'] as number) : 1;\n let current: Record<string, unknown> = { ...input };\n let currentVersion = initial;\n const applied: string[] = [];\n let shouldPersist = false;\n\n let guard = 0;\n while (currentVersion !== targetVersion) {\n if (++guard > 100) {\n throw new ConfigMigrationError({\n message: `Config migration looped past 100 steps (from v${initial} toward v${targetVersion})`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const step = migrations.find((m) => m.from === currentVersion);\n if (!step) {\n throw new ConfigMigrationError({\n message: `No migration registered from config v${currentVersion} (target v${targetVersion}). Update the framework or revert the config file.`,\n fromVersion: initial,\n targetVersion,\n missingStep: currentVersion,\n });\n }\n const ctx: MigrationContext = { fromVersion: currentVersion, shouldPersist: false };\n const next = step.migrate(current, ctx);\n // Ensure the migration set the new version. Be tolerant: if it didn't,\n // patch it in so the chain doesn't infinite-loop on author oversight.\n if (typeof next['version'] !== 'number' || next['version'] !== step.to) {\n next['version'] = step.to;\n }\n current = next;\n currentVersion = step.to;\n applied.push(`v${step.from}→v${step.to}`);\n shouldPersist = shouldPersist || ctx.shouldPersist || step.from < step.to;\n }\n return { config: current, applied, shouldPersist };\n}\n\n/**\n * Default empty migration registry. Real migrations are appended as new\n * Config versions are introduced. Example (when v2 lands):\n *\n * export const CONFIG_MIGRATIONS: readonly ConfigMigration[] = [\n * {\n * from: 1, to: 2, describe: 'rename `apiKey` → `auth.apiKey`',\n * migrate(cfg) {\n * const apiKey = cfg.apiKey;\n * delete cfg.apiKey;\n * return { ...cfg, auth: { ...(cfg.auth ?? {}), apiKey } };\n * },\n * },\n * ];\n */\nexport const DEFAULT_CONFIG_MIGRATIONS: readonly ConfigMigration[] = [];\n","import * as fsp from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { SessionStore } from '../types/session.js';\nimport { ensureDir } from '../utils/atomic-write.js';\n\n/**\n * Per-project lockfile used for crash detection. The CLI writes one of\n * these alongside the session JSONLs (`<projectSessions>/active.json`)\n * when an interactive run starts, and deletes it on clean exit. If we\n * find one on the next launch whose owning PID is dead (or whose host\n * doesn't match), we know the previous run was killed mid-flight and\n * the session it was writing to is a recovery candidate.\n *\n * The lockfile is intentionally per-project (already isolated by\n * `wpaths.projectSessions`), so two TUIs in two different repos do not\n * fight each other.\n */\nexport interface RecoveryLockOptions {\n /** Directory the lockfile lives in. Usually `wpaths.projectSessions`. */\n dir: string;\n /** This process's PID. Default: `process.pid`. */\n pid?: number | undefined;\n /** Hostname recorded for the lock. Default: `os.hostname()`. */\n hostname?: string | undefined;\n /** Locks older than this are considered orphaned (disk wiped, etc.). Default 24h. */\n maxAgeMs?: number | undefined;\n /** Used to check whether the abandoned session was actually closed cleanly. */\n sessionStore?: SessionStore | undefined;\n /**\n * Override the PID-liveness probe. Default: `process.kill(pid, 0)` —\n * succeeds (or throws EPERM) when the PID is alive, throws ESRCH when\n * it is gone. Tests inject a deterministic stub.\n */\n isPidAlive?: (((pid: number) => boolean)) | undefined;\n}\n\nexport interface AbandonedSession {\n sessionId: string;\n pid: number;\n startedAt: string;\n /** Lockfile age in ms at the time of the check. */\n ageMs: number;\n /** Number of messages already on disk for this session. */\n messageCount: number;\n}\n\ninterface LockFile {\n v: 1;\n sessionId: string;\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\nconst LOCK_FILE = 'active.json';\nconst DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport class RecoveryLock {\n private readonly file: string;\n private readonly pid: number;\n private readonly hostname: string;\n private readonly maxAgeMs: number;\n private readonly sessionStore?: SessionStore | undefined;\n private readonly probe: (pid: number) => boolean;\n\n constructor(opts: RecoveryLockOptions) {\n this.file = path.join(opts.dir, LOCK_FILE);\n this.pid = opts.pid ?? process.pid;\n this.hostname = opts.hostname ?? os.hostname();\n this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n this.sessionStore = opts.sessionStore;\n this.probe = opts.isPidAlive ?? defaultIsPidAlive;\n }\n\n /**\n * Examine the lockfile and decide whether it represents an abandoned\n * session. Returns `null` if the file is missing, points to a live\n * instance, references a clean-closed session, is too old, or is\n * malformed. Otherwise returns enough detail to prompt the user.\n *\n * Important: this is a read-only check. We never delete an active\n * lock from here — if another wstack instance is alive, the caller\n * should bail or run with a fresh session instead.\n */\n async checkAbandoned(): Promise<AbandonedSession | null> {\n const lock = await this.readLock();\n if (!lock) return null;\n\n const ageMs = Date.now() - new Date(lock.startedAt).getTime();\n if (Number.isNaN(ageMs) || ageMs < 0) {\n // Clock skew or corrupted timestamp — treat as orphan.\n return null;\n }\n if (ageMs > this.maxAgeMs) return null;\n\n // PID liveness only meaningful on the same host. Different host\n // means we can't probe — assume abandoned (the other machine's\n // wstack can't be holding *our* sessions dir unless it was\n // shared via network mount, in which case the user is on their\n // own).\n if (lock.hostname === this.hostname && this.probe(lock.pid)) {\n // Another wstack on this box is actively writing here.\n return null;\n }\n\n let messageCount = 0;\n if (this.sessionStore) {\n try {\n const data = await this.sessionStore.load(lock.sessionId);\n // Closed means the LAST session_end is not followed by further\n // conversation activity. Legacy /save wrote mid-stream session_end\n // markers — `some()` would treat a session that crashed AFTER such a\n // marker as cleanly closed and silently skip recovery.\n const lastEnd = data.events.findLastIndex((e) => e.type === 'session_end');\n const closed =\n lastEnd >= 0 &&\n !data.events\n .slice(lastEnd + 1)\n .some(\n (e) =>\n e.type === 'user_input' ||\n e.type === 'llm_response' ||\n e.type === 'in_flight_start',\n );\n if (closed) return null;\n messageCount = data.messages.length;\n } catch {\n // Lock points to a session that doesn't exist on disk (deleted\n // out from under us). Nothing to recover.\n return null;\n }\n }\n\n return {\n sessionId: lock.sessionId,\n pid: lock.pid,\n startedAt: lock.startedAt,\n ageMs,\n messageCount,\n };\n }\n\n /**\n * Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)\n * to detect whether another process acquired the lock between our\n * `checkAbandoned()` call and now. If the file already exists, it means\n * another process won the race and we throw instead of silently\n * overwriting their recovery record.\n *\n * The caller MUST have already called `checkAbandoned()` and handled its\n * null return before calling this.\n */\n async write(sessionId: string): Promise<void> {\n await ensureDir(path.dirname(this.file));\n const lock: LockFile = {\n v: 1,\n sessionId,\n pid: this.pid,\n hostname: this.hostname,\n startedAt: new Date().toISOString(),\n };\n // O_EXCL: atomic create — fails with EEXIST if another process wrote\n // the file between our checkAbandoned() and this write. This prevents\n // two processes that scanned the same stale lock from both believing\n // they hold it. The atomicWrite approach (temp+rename) would silently\n // replace on POSIX, hiding the race.\n try {\n await fsp.writeFile(this.file, JSON.stringify(lock), { flag: 'wx', mode: 0o600 });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') {\n throw new Error(`Recovery lock already held by another process`);\n }\n /* v8 ignore next -- defensive: an unexpected (non-EEXIST) write failure is rethrown */\n throw err;\n }\n }\n\n /**\n * Release the lock. Idempotent — silently succeeds if the file is\n * already gone (e.g. someone else cleared it, or the directory was\n * wiped).\n */\n async clear(): Promise<void> {\n try {\n await fsp.unlink(this.file);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return;\n /* v8 ignore next -- defensive: an unexpected (non-ENOENT) unlink failure is rethrown */\n throw err;\n }\n }\n\n private async readLock(): Promise<LockFile | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(this.file, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') return null;\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isLockFile(parsed)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n}\n\nfunction isLockFile(v: unknown): v is LockFile {\n if (typeof v !== 'object' || v === null) return false;\n const o = v as Record<string, unknown>;\n return (\n o['v'] === 1 &&\n typeof o['sessionId'] === 'string' &&\n typeof o['pid'] === 'number' &&\n typeof o['hostname'] === 'string' &&\n typeof o['startedAt'] === 'string'\n );\n}\n\n/**\n * Probe whether a process is alive without sending it a real signal.\n *\n * Unix: `process.kill(pid, 0)` succeeds for our own processes, throws\n * EPERM for others (still alive, just not ours), and throws ESRCH\n * when the PID is gone.\n * Windows (Node 22+): same call returns true if the process exists,\n * throws otherwise.\n */\nfunction defaultIsPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n /* v8 ignore next -- platform/permission-specific: EPERM means alive but owned by another user */\n if (code === 'EPERM') return true; // alive, but owned by someone else\n return false;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport type { ContentBlock } from '../types/blocks.js';\r\nimport type {\r\n DefaultSessionReaderOptions,\r\n SessionExportOptions,\r\n SessionQuery,\r\n SessionReader,\r\n SessionSearchHit,\r\n SessionSearchQuery,\r\n SessionSummaryLite,\r\n} from '../types/session-reader.js';\r\nimport { compileUserRegex } from '../utils/regex-guard.js';\r\nimport type { SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\r\n\r\n/**\r\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\r\n * and export helpers. Implemented on top of the public `SessionStore`\r\n * surface so any concrete store can be inspected without re-implementation.\r\n *\r\n * The heavy operations re-parse the JSONL stream on every call — fine for\r\n * /resume and one-off analytics. Wrap with a memoizing decorator if needed.\r\n */\r\nexport class DefaultSessionReader implements SessionReader {\r\n private readonly store: SessionStore;\r\n\r\n constructor(opts: DefaultSessionReaderOptions) {\r\n this.store = opts.store;\r\n }\r\n\r\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\r\n // Fetch only what's needed; in-process filters are cheap relative to store I/O.\r\n // If a caller needs pagination, it should pass `q.limit` and page through results.\r\n const raw = await this.store.list(q.limit ? Math.max(q.limit, 100) : 1000);\r\n const titleNeedle = q.titleContains?.toLowerCase();\r\n const filtered = raw.filter((s) => {\r\n if (q.since && s.startedAt < q.since) return false;\r\n if (q.until && s.startedAt > q.until) return false;\r\n if (q.provider && s.provider !== q.provider) return false;\r\n if (q.model && s.model !== q.model) return false;\r\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n const out: SessionSummaryLite[] = filtered.map((s) => ({\r\n id: s.id,\r\n title: s.title,\r\n startedAt: s.startedAt,\r\n provider: s.provider,\r\n model: s.model,\r\n tokenTotal: s.tokenTotal,\r\n }));\r\n return q.limit ? out.slice(0, q.limit) : out;\r\n }\r\n\r\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\r\n const data = await this.store.load(sessionId);\r\n for (const e of data.events) yield e;\r\n }\r\n\r\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\r\n const limit = q.limit ?? 100;\r\n const matcher = buildMatcher(q);\r\n const allowedTypes = q.types ? new Set(q.types) : null;\r\n\r\n // Filter sessions BEFORE loading events — avoids loading thousands of events\r\n // from sessions that don't match the time/provider/model criteria.\r\n let ids: string[];\r\n if (sessionId) {\r\n ids = [sessionId];\r\n } else {\r\n const sessions = await this.store.list(1000);\r\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\r\n const filtered = sessions.filter((s) => {\r\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\r\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\r\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\r\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\r\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\r\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\r\n return true;\r\n });\r\n ids = filtered.map((s) => s.id);\r\n }\r\n\r\n const hits: SessionSearchHit[] = [];\r\n for (const id of ids) {\r\n let data;\r\n try {\r\n data = await this.store.load(id);\r\n } catch {\r\n continue;\r\n }\r\n for (let i = 0; i < data.events.length; i++) {\r\n const ev = expectDefined(data.events[i]);\r\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\r\n const text = eventText(ev);\r\n if (text === null) continue;\r\n const hit = matcher(text);\r\n if (!hit) continue;\r\n hits.push({\r\n sessionId: id,\r\n eventIndex: i,\r\n ts: ev.ts,\r\n type: ev.type,\r\n snippet: snippetOf(text, hit.start, hit.end),\r\n });\r\n if (hits.length >= limit) return hits;\r\n }\r\n }\r\n return hits;\r\n }\r\n\r\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\r\n const data = await this.store.load(sessionId);\r\n const includeTools = opts.includeTools ?? true;\r\n const includeDiagnostics = opts.includeDiagnostics ?? true;\r\n\r\n const filtered = data.events.filter((e) => {\r\n if (\r\n !includeTools &&\r\n (e.type === 'tool_use' ||\r\n e.type === 'tool_result' ||\r\n e.type === 'tool_call_start' ||\r\n e.type === 'tool_call_end')\r\n ) {\r\n return false;\r\n }\r\n if (\r\n !includeDiagnostics &&\r\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\r\n ) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n if (opts.format === 'json') {\r\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\r\n }\r\n if (opts.format === 'text') {\r\n return renderPlainText(data.metadata, filtered);\r\n }\r\n return renderMarkdown(data.metadata, filtered);\r\n }\r\n\r\n async metadata(sessionId: string): Promise<SessionMetadata> {\r\n const data = await this.store.load(sessionId);\r\n return data.metadata;\r\n }\r\n}\r\n\r\nfunction buildMatcher(\r\n q: SessionSearchQuery,\r\n): (text: string) => { start: number; end: number } | null {\r\n const ci = q.caseInsensitive ?? true;\r\n if (q.regex) {\r\n const flags = ci ? 'i' : '';\r\n const compiled = compileUserRegex(q.query, flags);\r\n if (!compiled.ok) {\r\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\r\n }\r\n const re = compiled.regex;\r\n return (text) => {\r\n const m = re.exec(text);\r\n return m ? { start: m.index, end: m.index + m[0].length } : null;\r\n };\r\n }\r\n const needle = ci ? q.query.toLowerCase() : q.query;\r\n return (text) => {\r\n const hay = ci ? text.toLowerCase() : text;\r\n const idx = hay.indexOf(needle);\r\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\r\n };\r\n}\r\n\r\nfunction eventText(e: SessionEvent): string | null {\r\n switch (e.type) {\r\n case 'user_input':\r\n return contentToString(e.content);\r\n case 'llm_response':\r\n return contentToString(e.content);\r\n case 'tool_use':\r\n return `${e.name} ${JSON.stringify(e.input)}`;\r\n case 'tool_result':\r\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\r\n case 'error':\r\n return `${e.phase}: ${e.message}`;\r\n case 'session_start':\r\n case 'session_resumed':\r\n return `${e.model}/${e.provider}`;\r\n case 'task_created':\r\n case 'task_completed':\r\n return e.title;\r\n case 'task_failed':\r\n return `${e.title}: ${e.error}`;\r\n case 'skill_activated':\r\n case 'skill_deactivated':\r\n return e.skillName;\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\nfunction contentToString(content: string | ContentBlock[]): string {\r\n if (typeof content === 'string') return content;\r\n return content\r\n .map((b) => {\r\n switch (b.type) {\r\n case 'text':\r\n return b.text;\r\n case 'tool_use':\r\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\r\n case 'tool_result':\r\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\r\n default:\r\n return '';\r\n }\r\n })\r\n .join('\\n');\r\n}\r\n\r\nconst SNIPPET_RADIUS = 60;\r\n\r\nfunction snippetOf(text: string, start: number, end: number): string {\r\n const from = Math.max(0, start - SNIPPET_RADIUS);\r\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\r\n const prefix = from > 0 ? '…' : '';\r\n const suffix = to < text.length ? '…' : '';\r\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\r\n}\r\n\r\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(`# Session ${meta.id}`);\r\n lines.push('');\r\n if (meta.model || meta.provider) {\r\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\r\n }\r\n lines.push(`- **Started:** ${meta.startedAt}`);\r\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input': {\r\n lines.push(`## User — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n }\r\n case 'llm_response': {\r\n lines.push(`## Assistant — ${e.ts}`);\r\n lines.push('');\r\n lines.push(contentToString(e.content));\r\n if (e.stopReason && e.stopReason !== 'end_turn') {\r\n lines.push('');\r\n lines.push(`*stop: ${e.stopReason}*`);\r\n }\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_use': {\r\n lines.push(`### Tool call: \\`${e.name}\\``);\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify(e.input, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'tool_result': {\r\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\r\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(body);\r\n lines.push('```');\r\n lines.push('');\r\n break;\r\n }\r\n case 'error': {\r\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\r\n lines.push('');\r\n break;\r\n }\r\n case 'compaction': {\r\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\r\n lines.push('');\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\r\n const lines: string[] = [];\r\n lines.push(\r\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\r\n );\r\n lines.push(''.padEnd(72, '-'));\r\n for (const e of events) {\r\n switch (e.type) {\r\n case 'user_input':\r\n lines.push(`[${e.ts}] USER`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'llm_response':\r\n lines.push(`[${e.ts}] ASSISTANT`);\r\n lines.push(contentToString(e.content));\r\n lines.push('');\r\n break;\r\n case 'tool_use':\r\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\r\n break;\r\n case 'tool_result':\r\n lines.push(\r\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\r\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\r\n }`,\r\n );\r\n break;\r\n case 'error':\r\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/12-30-45Z_model_ab12\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\nimport type { EventBus } from '../kernel/events.js';\n/**\n * L2-B: AnnotationsStore — sidecar storage for collaboration annotations\n * (Phase 2 of idea #13 from IDEAS.md).\n *\n * Why a sidecar file, not the session JSONL?\n *\n * The session log is an event-sourced append-only journal\n * (`packages/core/src/types/session.ts` invariant: events are\n * append-only, with `truncateToCheckpoint` only as an explicit\n * rewind). Mixing in human-typed annotations would break that\n * invariant — the user's note about \"this rm looks dangerous\"\n * is not part of the agent's event history; it is meta-commentary\n * on the history.\n *\n * So we keep annotations in a sibling file: one JSON document per\n * session, at `<sessionDir>/<sessionId>.annotations.json`. The\n * shape is a simple versioned array, written atomically.\n *\n * Concurrency model:\n *\n * The store uses a per-session Promise chain to serialize writes.\n * Multiple annotators adding notes at the same time will queue,\n * not race. The atomic write itself is the second line of\n * defense (in case the chain is bypassed — e.g. two processes\n * pointing at the same dir).\n */\n\n/** Wire/storage shape for one annotation. */\nexport interface Annotation {\n /** Stable id (UUIDv4-ish). Referenced by resolve/delete. */\n id: string;\n /** Session this annotation belongs to. */\n sessionId: string;\n /** Index into the session event log the annotation refers to. */\n atEventIndex: number;\n /** Participant id of the annotator (matches WSCollabParticipantJoined.participantId). */\n authorId: string;\n /** Human-readable role label snapshot for display (e.g. \"annotator\"). */\n authorRole: 'annotator';\n /** The note itself. Trimmed, capped at `MAX_TEXT_LENGTH` on add. */\n text: string;\n /** ISO timestamp of creation. */\n createdAt: string;\n /** Resolved state. Annotations start unresolved. */\n resolved: boolean;\n /** ISO timestamp when resolved (if resolved). */\n resolvedAt?: string | undefined;\n /** Participant id of the resolver (if resolved). */\n resolvedBy?: string | undefined;\n}\n\ninterface AnnotationsFile {\n /** Bumped when the on-disk shape changes. v1 = initial release. */\n version: 1;\n annotations: Annotation[];\n}\n\n/** Bumped when the on-disk shape changes. Bump + migration on change. */\nconst FILE_VERSION = 1;\n/** Hard cap to keep a runaway annotator from writing megabytes. */\nconst MAX_TEXT_LENGTH = 2000;\n/** Hard cap on total annotations per session (oldest are evicted beyond this). */\nconst MAX_ANNOTATIONS = 1000;\n\nexport interface AnnotationsStoreOptions {\n /** Directory where `<sessionId>.annotations.json` files live. */\n dir: string;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class AnnotationsStore {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n /** Per-session write queue. Created lazily on first add. */\n private readonly writeChains = new Map<string, Promise<void>>();\n\n constructor(opts: AnnotationsStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n }\n\n // ── Reads ──────────────────────────────────────────────────────────────\n\n /**\n * Return all annotations for `sessionId` in insertion order\n * (oldest first). Returns an empty array when no file exists\n * yet (the normal case for a fresh session) and also degrades\n * gracefully to `[]` on a read error (permissions, corruption) —\n * the failure is still surfaced via a `storage.read` event so it\n * never silently hides I/O problems from observers.\n */\n async list(sessionId: string): Promise<Annotation[]> {\n const t0 = Date.now();\n const fp = this.filePath(sessionId);\n try {\n const file = await this.readFile(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'list',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return file ? file.annotations : [];\n } catch (err) {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'list',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return [];\n }\n }\n\n /**\n * Convenience: only unresolved annotations, newest first — the\n * common UI rendering for \"what still needs attention?\".\n */\n async listOpen(sessionId: string): Promise<Annotation[]> {\n const all = await this.list(sessionId);\n return all.filter((a) => !a.resolved).reverse();\n }\n\n // ── Writes ─────────────────────────────────────────────────────────────\n\n /**\n * Add a new annotation. Returns the persisted record (with id\n * and timestamps filled in). Throws when `text` is empty or\n * exceeds `MAX_TEXT_LENGTH`.\n */\n async add(input: {\n sessionId: string;\n atEventIndex: number;\n authorId: string;\n text: string;\n }): Promise<Annotation> {\n const text = input.text.trim();\n if (text.length === 0) {\n throw new WrongStackError({\n message: 'Annotation text must be non-empty',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', sessionId: input.sessionId },\n });\n }\n if (text.length > MAX_TEXT_LENGTH) {\n throw new WrongStackError({\n message: `Annotation text exceeds ${MAX_TEXT_LENGTH} chars (got ${text.length})`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'text', maxLength: MAX_TEXT_LENGTH, actualLength: text.length },\n });\n }\n if (!Number.isInteger(input.atEventIndex) || input.atEventIndex < 0) {\n throw new WrongStackError({\n message: 'atEventIndex must be a non-negative integer',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { field: 'atEventIndex', value: input.atEventIndex },\n });\n }\n const annotation: Annotation = {\n id: randomUUID(),\n sessionId: input.sessionId,\n atEventIndex: input.atEventIndex,\n authorId: input.authorId,\n authorRole: 'annotator',\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n };\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n const all = await this.list(input.sessionId);\n all.push(annotation);\n // Evict oldest if we crossed the cap. Resolved first, then oldest.\n if (all.length > MAX_ANNOTATIONS) {\n const sorted = all\n .map((a, i) => ({ a, i }))\n .sort((x, y) => {\n // resolved=false wins (keep unresolved); among same resolved state, oldest first.\n /* v8 ignore next -- scale+tiebreak: needs >1000 annotations with mixed resolved states */\n if (x.a.resolved !== y.a.resolved) return x.a.resolved ? 1 : -1;\n return x.a.createdAt.localeCompare(y.a.createdAt);\n });\n const evictCount = all.length - MAX_ANNOTATIONS;\n const toEvict = new Set(sorted.slice(0, evictCount).map((s) => s.a.id));\n const kept = all.filter((a) => !toEvict.has(a.id));\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: kept });\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'evict',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n } else {\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'add',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n }\n });\n });\n return annotation;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'add',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Mark an annotation as resolved. Returns the updated record, or\n * `null` if no annotation with that id exists in this session.\n * Idempotent: resolving an already-resolved annotation refreshes\n * `resolvedAt` / `resolvedBy` to the latest call.\n */\n async resolve(input: {\n sessionId: string;\n annotationId: string;\n resolvedBy: string;\n }): Promise<Annotation | null> {\n let updated: Annotation | null = null;\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n const all = await this.list(input.sessionId);\n const idx = all.findIndex((a) => a.id === input.annotationId);\n if (idx === -1) {\n updated = null;\n return;\n }\n const next: Annotation = {\n ...expectDefined(all[idx]),\n resolved: true,\n resolvedAt: new Date().toISOString(),\n resolvedBy: input.resolvedBy,\n };\n all[idx] = next;\n await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: all });\n updated = next;\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'resolve',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n });\n });\n return updated;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'annotations',\n filePath: fp,\n operation: 'resolve',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban here used to\n // throw for every modern session id, breaking annotations entirely.\n return sessionScopedPath(this.dir, sessionId, '.annotations.json');\n }\n\n private async readFile(sessionId: string): Promise<AnnotationsFile | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n // Non-ENOENT I/O errors (EACCES, ENOSPC): re-throw so callers emit\n // storage.error.\n throw err;\n }\n try {\n const parsed = JSON.parse(raw) as AnnotationsFile;\n if (parsed.version !== FILE_VERSION) {\n return { version: FILE_VERSION, annotations: [] };\n }\n return parsed;\n } catch {\n // JSON parse error (SyntaxError): treat as empty store — not an I/O failure.\n return null;\n }\n }\n\n private async writeFile(sessionId: string, file: AnnotationsFile): Promise<void> {\n const fp = this.filePath(sessionId);\n await atomicWrite(fp, JSON.stringify(file, null, 2));\n }\n\n /**\n * Serialize writes per-sessionId. We chain promises instead of\n * using a Mutex class so the contract is obvious from the\n * call-site: `enqueue(sid, fn)` runs `fn` after every prior\n * enqueue for `sid` has settled.\n */\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Keep the chain intact even when `fn` throws; failures\n // shouldn't break subsequent writes.\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { createHash } from 'node:crypto';\nimport type { Request } from '../types/provider.js';\n\n/**\n * Idea #2 from IDEAS.md — Deterministic Replay.\n *\n * The hash function is the foundation of replay: given a `Request`,\n * produce a stable identifier so a recorded `Response` can be looked\n * up later when we want to \"re-run\" the same agent loop without\n * burning API credits.\n *\n * Stability rules:\n *\n * - All object keys are sorted recursively before stringification.\n * Without this, two semantically identical requests that differ\n * only in key insertion order would produce different hashes.\n * - We hash ONLY the fields that affect the response: `model`,\n * `system`, `messages`, `tools`, `maxTokens`, and the four\n * sampling knobs (`temperature`, `topP`, `stopSequences`,\n * `toolChoice`). Anything else on the `Request` (metadata,\n * future extensions) is ignored so replay stays forward-compat.\n * - We serialize to JSON. The `ContentBlock` and `Message` shapes\n * are pure data; this works as long as no `undefined` values\n * sneak in (those get dropped by `JSON.stringify`, which is\n * fine — the structural diff is what matters).\n *\n * The SHA-256 output is hex-encoded and prefixed with the algorithm\n * tag so a future migration to a different hash (e.g. blake3) is\n * trivial to detect.\n */\nexport function stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n\nexport function hashRequest(request: Request): string {\n // Pick only the fields that affect the response. See stability rules.\n const payload = {\n model: request.model,\n system: request.system,\n messages: request.messages,\n tools: request.tools,\n maxTokens: request.maxTokens,\n temperature: request.temperature,\n topP: request.topP,\n stopSequences: request.stopSequences,\n toolChoice: request.toolChoice,\n };\n const json = stableStringify(payload);\n const digest = createHash('sha256').update(json, 'utf8').digest('hex');\n return `sha256:${digest}`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { hashRequest } from '../replay/hash.js';\nimport type { Request, Response } from '../types/provider.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport type { EventBus } from '../kernel/events.js';\n\n/**\n * Surface the OS error code (EACCES, ENOSPC, …) alongside the message in\n * storage.* event payloads. Codes are stable and locale-independent, so\n * they are what dashboards and alerts key on; the message is supplementary.\n */\nfunction storageErrorString(err: unknown): string {\n if (err instanceof Error) {\n const code = (err as NodeJS.ErrnoException).code;\n return code ? `${code}: ${err.message}` : err.message;\n }\n /* v8 ignore next -- defensive: fs/lock failures are always Error instances */\n return String(err);\n}\n\n/**\n * ReplayLogStore — sidecar store for deterministic-replay support\n * (idea #2 from IDEAS.md). One JSONL file per session, recording\n * every provider request/response pair so the same agent loop can\n * be re-run later with frozen API responses.\n *\n * Why a sidecar (not the session JSONL)?\n *\n * Same reason as `AnnotationsStore` — the session log is\n * event-sourced and append-only; a provider request payload can be\n * tens of kilobytes (especially with long conversation history),\n * and we want replay to be opt-in (recorded only when the user\n * runs with `--replay` or a future equivalent). Mixing it into\n * the event log would inflate every read for replay-irrelevant\n * paths.\n *\n * File layout: `<dir>/<sessionId>.replay.jsonl`, one entry per line.\n * Each entry: `{ hash, ts, request, response }`. The `hash` is\n * computed via `hashRequest` so lookups are O(1) by hash.\n *\n * Concurrency: per-session write queue (same pattern as\n * `AnnotationsStore`). Reads are lock-free; the write chain makes\n * the append + rehash sequence atomic.\n */\nexport interface ReplayEntry {\n hash: string;\n ts: string;\n request: Request;\n response: Response;\n}\n\nconst FILE_VERSION = 1;\n\n/** Default cap on the number of entries per session. */\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport interface ReplayLogStoreOptions {\n /** Directory where `<sessionId>.replay.jsonl` files live. */\n dir: string;\n /**\n * Cap on the number of entries per session. When a `record` would\n * push the file beyond this, the oldest entries are evicted (LRU\n * by insertion order). Set to `Infinity` to disable rotation.\n * Defaults to 1000 — a single LLM call averages ~5KB serialized\n * (messages + tools + response), so 1000 entries is ~5MB per\n * session which is a reasonable upper bound.\n */\n maxEntries?: number | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\nexport class ReplayLogStore {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n private readonly writeChains = new Map<string, Promise<void>>();\n /** Per-session hash → entry index, kept in memory after the first load. */\n private readonly cache = new Map<string, Map<string, ReplayEntry>>();\n /** Per-session entry count on disk, to detect when compaction is needed. */\n private readonly diskCount = new Map<string, number>();\n private readonly maxEntries: number;\n\n constructor(opts: ReplayLogStoreOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n // ── Writes ──────────────────────────────────────────────────────────────\n\n /**\n * Record a request/response pair. Idempotent on hash: a second\n * `record` for the same hash is a no-op (the existing entry wins).\n * Returns the hash.\n */\n async record(input: {\n sessionId: string;\n request: Request;\n response: Response;\n }): Promise<string> {\n const hash = hashRequest(input.request);\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n // Dedup via the in-memory hash map — O(1) instead of re-reading\n // and re-parsing the whole JSONL just to run `entries.some(...)`.\n // `ensureCache` populates both the cache and `diskCount` from a\n // single read on first contact; subsequent records reuse it.\n const cache = await this.ensureCache(input.sessionId);\n if (cache.has(hash)) return; // already recorded\n\n const entry: ReplayEntry = {\n hash,\n ts: new Date().toISOString(),\n request: input.request,\n response: input.response,\n };\n\n const currentCount = this.diskCount.get(input.sessionId) ?? 0;\n const willEvict = currentCount + 1 > this.maxEntries;\n\n if (!willEvict) {\n // Common path (the first `maxEntries` writes per session, plus\n // any session that never hits the cap): a single O(1) append.\n // The previous implementation did a full readAll + full rewrite\n // (atomicWrite of the entire file) on every single record, which\n // was quadratic in session length — a 1000-call session rewrote\n // a multi-MB file 1000 times.\n await fs.appendFile(fp, JSON.stringify(entry) + '\\n', 'utf8');\n cache.set(hash, entry);\n this.diskCount.set(input.sessionId, currentCount + 1);\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'record',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return;\n }\n\n // Eviction path: we're at capacity, drop the oldest entry to make\n // room. This does require a full read + rewrite, but it fires at\n // most once per `maxEntries` writes (default 1000), not per write.\n const all = await this.readAll(input.sessionId);\n all.push(entry);\n const keep = all.slice(-this.maxEntries);\n const refreshed = new Map<string, ReplayEntry>();\n for (const e of keep) refreshed.set(e.hash, e);\n this.cache.set(input.sessionId, refreshed);\n this.diskCount.set(input.sessionId, keep.length);\n await this.writeAll(input.sessionId, keep, 'compact');\n });\n });\n return hash;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'record',\n outcome: 'failure',\n error: storageErrorString(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Reads ───────────────────────────────────────────────────────────────\n\n /**\n * Look up an entry by hash. Returns `null` when the request has\n * not been recorded for this session. O(1) after the first call\n * per session (in-memory cache).\n */\n async lookup(sessionId: string, hash: string): Promise<ReplayEntry | null> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const cache = await this.ensureCache(sessionId);\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'lookup',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return cache.get(hash) ?? null;\n } catch (err) {\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'lookup',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /** All recorded entries for a session, in insertion order. */\n async load(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const cache = await this.ensureCache(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'load',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return [...cache.values()];\n } catch (err) {\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation: 'load',\n outcome: 'failure',\n durationMs,\n error: storageErrorString(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * List every session id that has a replay log in the store dir.\n * Returns an array of `{ sessionId, entryCount, path }` sorted\n * by sessionId for stable output. Used by `wstack replay --list`.\n */\n async list(): Promise<Array<{ sessionId: string; entryCount: number; path: string }>> {\n const out: Array<{ sessionId: string; entryCount: number; path: string }> = [];\n // Replay logs sit next to their session JSONL — flat at the root for\n // legacy/`record-<ts>` ids, inside a date-shard dir for modern ids.\n // Scan both levels; a root-only scan misses every sharded session.\n const scan = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if (depth === 0 && (err as NodeJS.ErrnoException).code !== 'ENOENT') {\n // EACCES, ENOTDIR, etc. — log the real error so the operator can\n // diagnose a misconfiguration, but still return empty list so the\n // caller (slash command display) doesn't crash.\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'replay_log_store.list_readdir_failed',\n dir,\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n if (depth === 0) await scan(path.join(dir, entry.name), entry.name, depth + 1);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.replay.jsonl')) continue;\n const base = entry.name.slice(0, -'.replay.jsonl'.length);\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const fp = path.join(dir, entry.name);\n out.push({\n sessionId,\n entryCount: await this.countEntries(fp),\n path: fp,\n });\n }\n };\n await scan(this.dir, '', 0);\n return out.sort((a, b) => a.sessionId.localeCompare(b.sessionId));\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // the moment a real (sharded) session id is used for --replay.\n return sessionScopedPath(this.dir, sessionId, '.replay.jsonl');\n }\n\n private async countEntries(filePath: string): Promise<number> {\n // list() only needs a count, not provider request/response payloads. Count\n // non-empty JSONL rows in fixed-size chunks so large replay logs are not\n // parsed or materialized just to render `wstack replay --list`.\n const handle = await fs.open(filePath, 'r');\n const buffer = Buffer.allocUnsafe(64 * 1024);\n let count = 0;\n let hasNonWhitespace = false;\n try {\n while (true) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);\n if (bytesRead === 0) break;\n for (let i = 0; i < bytesRead; i++) {\n const ch = buffer[i]!;\n if (ch === 10) {\n if (hasNonWhitespace) count++;\n hasNonWhitespace = false;\n continue;\n }\n if (ch !== 13 && ch !== 32 && ch !== 9) {\n hasNonWhitespace = true;\n }\n }\n }\n } finally {\n await handle.close();\n }\n if (hasNonWhitespace) count++;\n return count;\n }\n\n private async readAll(sessionId: string): Promise<ReplayEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: ReplayEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<\n { version?: number | undefined; entry?: ReplayEntry | undefined } & ReplayEntry\n >(line);\n if (!parsed.ok || !parsed.value) continue;\n // Forward-compat: v1 stores entries one per line, no envelope.\n // A future \"v2\" could wrap with `{version, entries:[...]}`;\n // the loader would then branch on `parsed.version`.\n if ('entry' in parsed.value && parsed.value.entry) {\n out.push(parsed.value.entry);\n } else {\n out.push(parsed.value);\n }\n } catch {\n // Skip a corrupt line — annotations-store and other sidecar\n // stores take the same approach (meta-data, not fatal).\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Non-ENOENT errors (EACCES, ENOSPC, etc.) are real I/O failures —\n // re-throw so callers can emit storage.error.\n throw err;\n }\n }\n\n private async writeAll(\n sessionId: string,\n entries: ReplayEntry[],\n operation: 'record' | 'compact' = 'record',\n ): Promise<void> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n const body = entries.map((e) => JSON.stringify(e)).join('\\n') + (entries.length ? '\\n' : '');\n await atomicWrite(fp, body);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId,\n store: 'replay',\n filePath: fp,\n operation,\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n // Drop the version-stamp comment at the top — v1 has no envelope,\n // but we keep a one-line marker for human readers / future tooling.\n // (The atomicWrite just wrote pure JSONL; that's correct for v1.)\n void FILE_VERSION;\n }\n\n private async ensureCache(sessionId: string): Promise<Map<string, ReplayEntry>> {\n let cache = this.cache.get(sessionId);\n if (cache) return cache;\n const all = await this.readAll(sessionId);\n cache = new Map();\n for (const e of all) cache.set(e.hash, e);\n this.cache.set(sessionId, cache);\n this.diskCount.set(sessionId, all.length);\n return cache;\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SessionEvent } from '../types/session.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\n/**\n * Idea #1 from IDEAS.md — Stateful Session Recovery.\n *\n * `SessionRecovery` is the read-side companion to the in-flight\n * marker mechanism. When the agent loop is running, it writes an\n * `in_flight_start` event at the current point in the log. On\n * clean shutdown, a matching `in_flight_end` follows. If the\n * process dies (crash, OOM, machine sleep, SIGKILL) the marker\n * is the last event in the file — and `detectStale` flags the\n * session as \"incomplete, can be resumed\".\n *\n * Phase 1 of this feature is **detection only**. The actual\n * re-execution of incomplete work is a follow-up: it requires\n * tracking pending tool calls, mid-stream LLM responses, and\n * uncommitted file changes — and re-running the agent loop from\n * the last `checkpoint` event. The detection layer is independent\n * and ships first because (a) it gives the user immediate\n * visibility into what died, and (b) it's the foundation for the\n * resume command and the CLI's \"Incomplete sessions\" surface.\n *\n * Concurrency: pure read; no writes. Safe to call from multiple\n * processes simultaneously.\n */\nexport interface StaleSession {\n sessionId: string;\n /** Path to the JSONL log. */\n path: string;\n /** Last event ts (the in_flight_start timestamp). */\n lastEventTs: string;\n /** Context the agent was working on when it died. */\n context: string;\n /** Total events in the log. */\n eventCount: number;\n}\n\nexport interface RecoveryPlan {\n sessionId: string;\n /** True if the session is stale (has a dangling in_flight_start). */\n stale: boolean;\n /** The last `checkpoint` event before the un-replayed work, or null. */\n lastCheckpoint: SessionEvent | null;\n /** All events after the last checkpoint (i.e. the work that needs re-execution). */\n pendingEvents: SessionEvent[];\n /** The dangling in_flight_start event, if any. */\n inFlightStart: SessionEvent | null;\n /** Free-form context the agent was working on, if any. */\n context: string | null;\n}\n\n/**\n * Result of `SessionRecovery.recover(sessionId)`. Distinct from\n * `StaleSession`: a session is \"stale\" if the last event is an\n * open marker, but a \"recovery plan\" can also be generated for\n * clean sessions whose last checkpoint is older than the\n * conversation history (e.g. a user-initiated \"rewind to last\n * good state\" flow). Phase 2 of idea #1: this returns the plan;\n * the actual kernel re-execution is a follow-up.\n */\nexport class SessionRecovery {\n /**\n * Scan a session log and return a `StaleSession` if and only\n * if the last event is an `in_flight_start` without a matching\n * `in_flight_end`. Returns `null` when:\n * - the log does not exist;\n * - the log is empty;\n * - the last event is `in_flight_end` (clean shutdown);\n * - the last event is something else (e.g. an unannotated\n * legacy log without in-flight markers).\n */\n async detectStale(sessionId: string): Promise<StaleSession | null> {\n const fp = this.filePath(sessionId);\n // Only read the last ~8KB — enough for several large events.\n // This is O(1) I/O vs O(n) of reading the entire file.\n const TAIL_SIZE = 8192;\n let stat;\n try {\n stat = await fs.stat(fp);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n /* v8 ignore next -- defensive: any other stat failure is also non-recoverable */\n return null;\n }\n if (stat.size === 0) return null;\n const position = Math.max(0, stat.size - TAIL_SIZE);\n const buf = Buffer.alloc(TAIL_SIZE);\n let fh;\n try {\n fh = await fs.open(fp, 'r');\n const { bytesRead } = await fh.read(buf, 0, TAIL_SIZE, position);\n // Count total events for StaleSession.eventCount — requires full scan.\n // For very large files this is a trade-off; count is informational.\n let eventCount = 0;\n const raw = buf.subarray(0, bytesRead).toString('utf8');\n for (const line of raw.split('\\n')) {\n if (line.trim()) eventCount++;\n }\n // Find the last complete JSON line in the tail.\n const lines = raw.split('\\n').filter((l) => l.trim());\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const ev = JSON.parse(expectDefined(lines[i])) as SessionEvent;\n if (ev.type === 'in_flight_start') {\n return {\n sessionId,\n path: fp,\n lastEventTs: ev.ts,\n context: ev.context,\n eventCount,\n };\n }\n // Found a different last event — clean shutdown or legacy\n return null;\n } catch {\n // Incomplete line (spans the read boundary) — skip\n }\n }\n return null;\n /* v8 ignore start -- defensive: tail open/read failure after a successful stat is rare */\n } catch {\n return null;\n } finally {\n if (fh) await fh.close();\n }\n /* v8 ignore stop */\n }\n\n /**\n * Generate a recovery plan for a session. The plan describes\n * \"what would be re-executed\" if the user chose to resume —\n * everything after the last `checkpoint` event, plus the\n * dangling in-flight marker if present.\n *\n * Returns a non-null plan for ANY session that has at least\n * one event after a checkpoint (or, for legacy sessions, at\n * least one event). Pure read; no mutation.\n */\n async recover(sessionId: string): Promise<RecoveryPlan | null> {\n const fp = this.filePath(sessionId);\n let raw: string;\n try {\n raw = await fs.readFile(fp, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n /* v8 ignore next -- defensive: any other read failure is also non-recoverable */\n return null;\n }\n const events: SessionEvent[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n if (events.length === 0) return null;\n // Find the last checkpoint.\n let lastCheckpoint: SessionEvent | null = null;\n let lastCheckpointIdx = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i]?.type === 'checkpoint') {\n lastCheckpoint = expectDefined(events[i]);\n lastCheckpointIdx = i;\n }\n }\n // Events after the last checkpoint = the work that needs re-execution.\n const pendingEvents =\n lastCheckpointIdx >= 0 ? events.slice(lastCheckpointIdx + 1) : events;\n // The dangling in_flight_start, if the last event is one.\n const lastEv = expectDefined(events[events.length - 1]);\n const inFlightStart =\n lastEv.type === 'in_flight_start' ? lastEv : null;\n const context = inFlightStart && inFlightStart.type === 'in_flight_start'\n ? inFlightStart.context\n : null;\n return {\n sessionId,\n stale: inFlightStart !== null,\n lastCheckpoint,\n pendingEvents,\n inFlightStart,\n context,\n };\n }\n\n /**\n * List every stale session in a directory. Returns an array\n * (possibly empty) sorted by `lastEventTs` descending — most\n * recent crash first.\n */\n async listResumable(): Promise<StaleSession[]> {\n const out: StaleSession[] = [];\n // Modern sessions live inside date-shard subdirectories\n // (\"2026-06-11/<base>.jsonl\"); legacy/flat sessions sit at the root.\n // Scan both — a root-only scan silently misses every modern crash.\n const collect = async (dir: string, prefix: string, depth: number): Promise<void> => {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n /* v8 ignore start -- defensive: the sessions dir (and its shards) are readable during a scan */\n } catch {\n return;\n }\n /* v8 ignore stop */\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (\n entry.name === 'shared' ||\n entry.name === 'subagents' ||\n entry.name === 'attachments'\n )\n continue;\n if (entry.isDirectory()) {\n if (depth === 0) {\n await collect(path.join(dir, entry.name), entry.name, depth + 1);\n }\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.jsonl')) continue;\n if (entry.name === '_index.jsonl' || entry.name === '_mailbox.jsonl') continue;\n const base = entry.name.slice(0, -'.jsonl'.length);\n if (base.includes('.replay') || base.includes('.annotations') || base.includes('.audit'))\n continue;\n const sessionId = prefix ? `${prefix}/${base}` : base;\n const stale = await this.detectStale(sessionId);\n if (stale) out.push(stale);\n }\n };\n await collect(this.dir, '', 0);\n return out.sort((a, b) => b.lastEventTs.localeCompare(a.lastEventTs));\n }\n\n // ── Internals ──────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. Shared with the other per-session\n // sidecar stores so the contract can't drift.\n return sessionScopedPath(this.dir, sessionId, '.jsonl');\n }\n\n constructor(private readonly dir: string) {}\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { createHash, randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { withFileLock } from '../utils/atomic-write.js';\nimport { safeParse } from '../utils/safe-json.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport type { EventBus } from '../kernel/events.js';\n/**\n * ToolAuditLog — idea #9 from IDEAS.md.\n *\n * Tamper-evident audit trail for tool calls. Every tool_use /\n * tool_result pair is appended to a sidecar JSONL with a chained\n * SHA-256 — each entry's `prevHash` is the prior entry's `hash`,\n * so any post-hoc modification of a single line breaks the chain\n * from that point forward.\n *\n * Why a sidecar (not the session JSONL)?\n * Same reason as `AnnotationsStore` and `ReplayLogStore`: the\n * session log is an event-sourced journal. Mixing in a hash\n * chain would inflate every read and tightly couple the\n * integrity check to the event format. Sidecar keeps both\n * concerns orthogonal.\n *\n * What \"tamper-evident\" means here:\n * - The hash covers the full serialized entry: tool name, id,\n * input, output, timestamp, author. Changing any byte\n * changes the hash.\n * - The chain is sequential — a verifier walks the file in\n * order, recomputing each hash, and checks `prevHash`\n * matches the previous entry's `hash`.\n * - Any insertion, deletion, or modification of a single\n * entry surfaces as a \"chain broken at entry N\" verdict.\n *\n * What it does NOT defend against:\n * - An attacker who rewrites the whole file consistently.\n * For that you'd need an external anchor (signing key,\n * transparency log, etc.) — out of scope for Phase 1.\n * - The agent itself misbehaving; this is post-hoc audit, not\n * real-time enforcement. Use `PermissionPolicy` for that.\n *\n * File layout: `<dir>/<sessionId>.audit.jsonl`, one entry per\n * line. The chain starts with a `genesis` entry whose\n * `prevHash` is all zeros.\n */\nexport interface AuditEntry {\n /** Monotonic index (0-based). */\n index: number;\n /** UUID for cross-referencing with logs. */\n id: string;\n /** ISO timestamp. */\n ts: string;\n /** Hash of the previous entry (or all-zeros for the genesis entry). */\n prevHash: string;\n /** Hash of this entry's content (sha256 over the canonical JSON). */\n hash: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n}\n\nconst GENESIS_PREV = '0'.repeat(64);\n\nexport type VerifyResult =\n | { ok: true; entries: number }\n | { ok: false; brokenAt: number; reason: string };\n\nexport interface ToolAuditLogOptions {\n /** Directory where `<sessionId>.audit.jsonl` files live. */\n dir: string;\n /**\n * Flush the file system cache to disk every N writes per session.\n * Default 100. Lower values = better crash durability, more I/O overhead.\n * Set to `Infinity` to disable periodic fsync (fastest, but highest data-loss risk).\n */\n fsyncEvery?: number | undefined;\n events?: EventBus;\n traceId?: string;\n}\n\n/** Default number of writes between fsync calls. */\nconst DEFAULT_FSYNC_EVERY = 100;\n\nexport class ToolAuditLog {\n private readonly dir: string;\n private readonly events: EventBus | undefined;\n private readonly traceId: string | undefined;\n /** In-memory cache of the last entry's hash (per session), to compute chains efficiently. */\n private readonly tailHash = new Map<string, string>();\n /** In-memory counter for entry indices — avoids re-reading the file on every write. */\n private readonly tailIndex = new Map<string, number>();\n /**\n * File mtime+size recorded after our last write, per session. Used to\n * detect cross-process writes (session handoff, recovery) that would\n * invalidate the in-memory tail cache: if the stat no longer matches\n * we re-read the file to re-establish the chain tip before appending.\n */\n private readonly tailStat = new Map<string, { mtimeMs: number; size: number }>();\n /** Tracks writes since last fsync, per session. */\n private readonly unSyncedWrites = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly fsyncEvery: number;\n\n constructor(opts: ToolAuditLogOptions) {\n this.dir = opts.dir;\n this.events = opts.events;\n this.traceId = opts.traceId;\n this.fsyncEvery = opts.fsyncEvery ?? DEFAULT_FSYNC_EVERY;\n }\n\n /**\n * Append a tool call/result pair to the chain. Returns the\n * resulting entry. Idempotency is not guaranteed — if you\n * record the same tool_use twice you get two entries. That's\n * intentional: the audit log is a record, not a cache.\n */\n async record(input: {\n sessionId: string;\n toolName: string;\n toolUseId: string;\n input: unknown;\n output: unknown;\n isError: boolean;\n }): Promise<AuditEntry> {\n let entry!: AuditEntry; // assigned inside the enqueue callback\n const fp = this.filePath(input.sessionId);\n const t0 = Date.now();\n try {\n await this.enqueue(input.sessionId, async () => {\n await withFileLock(fp, async () => {\n // Resolve the chain tip from the in-memory cache when possible,\n // re-reading the file only on first contact or when an external\n // writer (cross-process session handoff) changed it under us.\n // The previous implementation did `readAll` on every single\n // record just to find `entries.at(-1)` — a full parse of the\n // audit file per tool call.\n const tip = await this._resolveChainTip(input.sessionId, fp);\n const prevHash = tip.prevHash;\n const index = tip.nextIndex;\n\n const id = randomUUID();\n const ts = new Date().toISOString();\n const content = {\n id,\n ts,\n prevHash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n const hash = createHash('sha256').update(stableStringify(content), 'utf8').digest('hex');\n entry = {\n id,\n ts,\n prevHash,\n hash,\n toolName: input.toolName,\n toolUseId: input.toolUseId,\n input: input.input,\n output: input.output,\n isError: input.isError,\n index,\n };\n\n // True O(1) append — one line, no full-file rewrite. The previous\n // `writeAll(entries)` path re-serialized every entry on every\n // record; a 1000-call session rewrote a multi-MB audit file 1000\n // times (quadratic in session length). `withFileLock` above\n // guarantees no concurrent writer interleaves with our append.\n await fs.appendFile(fp, JSON.stringify(entry) + '\\n', 'utf8');\n\n // Refresh caches + fsync bookkeeping. We stat post-write so the\n // mtime+size tracker reflects the just-appended line — the next\n // record can trust the cache without re-reading.\n try {\n const st = await fs.stat(fp);\n this.tailStat.set(input.sessionId, { mtimeMs: st.mtimeMs, size: st.size });\n } catch {\n /* best-effort; next record will just re-read */\n }\n this.tailHash.set(input.sessionId, hash);\n this.tailIndex.set(input.sessionId, index + 1);\n await this._trackUnsynced(input.sessionId, fp);\n\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.write', {\n sessionId: input.sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'record',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n });\n });\n return entry;\n } catch (err) {\n this.events?.emit('storage.error', {\n sessionId: input.sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'record',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n /**\n * Resolve the chain tip (previous hash + next index) for an append.\n * Uses the in-memory `tailHash`/`tailIndex` cache when the file's\n * stat matches our last known write; falls back to a full read on\n * cache miss or when an external writer has extended the file.\n */\n private async _resolveChainTip(\n sessionId: string,\n fp: string,\n ): Promise<{ prevHash: string; nextIndex: number }> {\n const cachedHash = this.tailHash.get(sessionId);\n const cachedIndex = this.tailIndex.get(sessionId);\n const cachedStat = this.tailStat.get(sessionId);\n\n if (cachedHash !== undefined && cachedIndex !== undefined && cachedStat) {\n // Verify no other process appended since our last write. Stat is a\n // single inode lookup; the common case (same-process sequential\n // writes) returns immediately and we skip the full read.\n try {\n const st = await fs.stat(fp);\n if (st.mtimeMs === cachedStat.mtimeMs && st.size === cachedStat.size) {\n return { prevHash: cachedHash, nextIndex: cachedIndex };\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n // File was removed out from under us — reset and start a new chain.\n this.tailHash.delete(sessionId);\n this.tailIndex.delete(sessionId);\n this.tailStat.delete(sessionId);\n return { prevHash: GENESIS_PREV, nextIndex: 0 };\n }\n /* v8 ignore next -- defensive: a non-ENOENT stat failure during cache-hit is rare */\n throw err;\n }\n }\n\n // Cache miss or external write detected — read the true tail.\n const entries = await this.readAll(sessionId);\n const prev = entries.at(-1);\n const prevHash = prev?.hash ?? GENESIS_PREV;\n const nextIndex = prev ? prev.index + 1 : 0;\n this.tailHash.set(sessionId, prevHash);\n this.tailIndex.set(sessionId, nextIndex);\n try {\n const st = await fs.stat(fp);\n this.tailStat.set(sessionId, { mtimeMs: st.mtimeMs, size: st.size });\n } catch {\n /* leave cache empty; next record re-reads */\n }\n return { prevHash, nextIndex };\n }\n\n /**\n * Walk the chain and verify every entry's hash and prevHash.\n * Returns a structured verdict — never throws.\n */\n async verify(sessionId: string): Promise<VerifyResult> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n let entries: AuditEntry[];\n try {\n entries = await this.readAll(sessionId);\n } catch (err) {\n // The file exists but can't be read (permissions, corruption). We\n // can't verify it, so emit a read failure for observability and\n // degrade gracefully — this method's contract is \"never throws\".\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'verify',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return { ok: true, entries: 0 };\n }\n\n // Walk the chain into a verdict, then emit a single storage.read whose\n // outcome reflects the verification result (a broken chain is a failure).\n const verdict = ((): VerifyResult => {\n if (entries.length === 0) return { ok: true, entries: 0 };\n // The first entry's prevHash must be the all-zeros genesis marker.\n if (entries[0]?.prevHash !== GENESIS_PREV) {\n return {\n ok: false,\n brokenAt: 0,\n reason: 'first entry is not the genesis (prevHash != 0…0)',\n };\n }\n let prevHash = GENESIS_PREV;\n for (let i = 0; i < entries.length; i++) {\n const e = expectDefined(entries[i]);\n if (e.prevHash !== prevHash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `prevHash mismatch at entry ${i} (expected ${prevHash.slice(0, 8)}…, got ${e.prevHash.slice(0, 8)}…)`,\n };\n }\n // Recompute the hash from the entry's content (without the\n // `hash` field itself, which is what we are verifying).\n const content = {\n id: e.id,\n ts: e.ts,\n prevHash: e.prevHash,\n toolName: e.toolName,\n toolUseId: e.toolUseId,\n input: e.input,\n output: e.output,\n isError: e.isError,\n index: e.index,\n };\n const expectedHash = createHash('sha256')\n .update(stableStringify(content), 'utf8')\n .digest('hex');\n if (expectedHash !== e.hash) {\n return {\n ok: false,\n brokenAt: i,\n reason: `hash mismatch at entry ${i} (entry content was modified)`,\n };\n }\n prevHash = e.hash;\n }\n return { ok: true, entries: entries.length };\n })();\n\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'verify',\n outcome: verdict.ok ? 'success' : 'failure',\n durationMs: Date.now() - t0,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return verdict;\n }\n\n /** All entries for a session, in insertion order. */\n async load(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n const t0 = Date.now();\n try {\n const entries = await this.readAll(sessionId);\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'load',\n outcome: 'success',\n durationMs,\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n return entries;\n } catch (err) {\n const durationMs = Date.now() - t0;\n this.events?.emit('storage.read', {\n sessionId,\n store: 'audit',\n filePath: fp,\n operation: 'load',\n outcome: 'failure',\n durationMs,\n error: toErrorMessage(err),\n ...(this.traceId !== undefined ? { traceId: this.traceId } : {}),\n });\n throw err;\n }\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n private filePath(sessionId: string): string {\n // Containment-checked: date-sharded ids (\"2026-06-11/<base>\") are\n // legitimate; traversal is rejected. A plain slash ban would throw\n // for every modern session id the moment record() gets wired in.\n return sessionScopedPath(this.dir, sessionId, '.audit.jsonl');\n }\n\n private async readAll(sessionId: string): Promise<AuditEntry[]> {\n const fp = this.filePath(sessionId);\n try {\n const raw = await fs.readFile(fp, 'utf8');\n const out: AuditEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n const parsed = safeParse<AuditEntry>(line);\n if (parsed.ok && parsed.value) out.push(parsed.value);\n } catch {\n // Skip corrupt lines — audit data is meta, not fatal.\n }\n }\n return out;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n // Non-ENOENT errors (EACCES, ENOSPC, etc.) are real I/O failures —\n // re-throw so callers (verify, load) can emit storage.error.\n throw err;\n }\n }\n\n /**\n * Tracks writes since last fsync and triggers periodic fsync.\n * Called after each O(1) append to maintain the same durability\n * guarantees as the old writeAll approach.\n */\n private async _trackUnsynced(sessionId: string, fp: string): Promise<void> {\n const count = (this.unSyncedWrites.get(sessionId) ?? 0) + 1;\n this.unSyncedWrites.set(sessionId, count);\n if (this.fsyncEvery !== Number.POSITIVE_INFINITY && count % this.fsyncEvery === 0) {\n await this.sync(sessionId, fp);\n }\n }\n\n /**\n * Explicitly sync the file to disk. Called automatically every\n * `fsyncEvery` writes, and available for callers who want to\n * force a sync before closing or during graceful shutdown.\n */\n async flush(sessionId: string): Promise<void> {\n await this.sync(sessionId, this.filePath(sessionId));\n }\n\n private async sync(sessionId: string, fp: string): Promise<void> {\n try {\n const fh = await fs.open(fp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync is best-effort; a failure here does not corrupt the chain.\n } finally {\n this.unSyncedWrites.set(sessionId, 0);\n }\n }\n\n private enqueue(sessionId: string, fn: () => Promise<void>): Promise<void> {\n const prev = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n this.writeChains.set(\n sessionId,\n next.catch(() => undefined),\n );\n return next;\n }\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortKeys(obj[key]);\n }\n return sorted;\n }\n return value;\n}\n","import type { SessionEvent } from '../types/session.js';\n\nexport interface QueryFilter {\n eventTypes?: string[] | undefined;\n toolNames?: string[] | undefined;\n timeRange?: { start: string; end: string } | undefined;\n}\n\nexport interface ToolInvocation {\n ts: string;\n name: string;\n input: unknown;\n output?: unknown | undefined;\n error?: string | undefined;\n durationMs: number;\n}\n\nexport interface SessionError {\n ts: string;\n phase: string;\n message: string;\n}\n\nexport interface ModeChange {\n ts: string;\n from: string;\n to: string;\n}\n\nexport interface TaskSummary {\n taskId: string;\n title: string;\n status: string;\n createdAt: string;\n completedAt?: string | undefined;\n}\n\nexport interface SessionAnalysis {\n sessionId: string;\n totalDuration: number;\n toolUsageCount: Record<string, number>;\n errorCount: number;\n modeChanges: ModeChange[];\n tasks: TaskSummary[];\n}\n\nexport class SessionAnalyzer {\n analyze(events: SessionEvent[]): SessionAnalysis {\n const toolUsageCount: Record<string, number> = {};\n const errors: SessionError[] = [];\n const modeChanges: ModeChange[] = [];\n const tasksById = new Map<string, TaskSummary>();\n let sessionId = '';\n\n for (const event of events) {\n // sessionId comes from session_start / session_resumed.\n if (event.type === 'session_start' || event.type === 'session_resumed') {\n if (!sessionId) sessionId = event.id;\n }\n if (event.type === 'tool_use') {\n toolUsageCount[event.name] = (toolUsageCount[event.name] ?? 0) + 1;\n }\n if (event.type === 'error') {\n errors.push({ ts: event.ts, phase: event.phase, message: event.message });\n }\n if (event.type === 'mode_changed') {\n modeChanges.push({ ts: event.ts, from: event.from, to: event.to });\n }\n if (event.type === 'task_created') {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'created',\n createdAt: event.ts,\n });\n }\n if (event.type === 'task_updated') {\n const t = tasksById.get(event.taskId);\n if (t) t.status = event.status;\n }\n if (event.type === 'task_completed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'completed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'completed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n if (event.type === 'task_failed') {\n const t = tasksById.get(event.taskId);\n if (t) {\n t.status = 'failed';\n t.completedAt = event.ts;\n } else {\n tasksById.set(event.taskId, {\n taskId: event.taskId,\n title: event.title,\n status: 'failed',\n createdAt: event.ts,\n completedAt: event.ts,\n });\n }\n }\n }\n\n return {\n sessionId,\n totalDuration: this.calcDuration(events),\n toolUsageCount,\n errorCount: errors.length,\n modeChanges,\n tasks: Array.from(tasksById.values()),\n };\n }\n\n query(events: SessionEvent[], filter: QueryFilter): SessionEvent[] {\n return events.filter((e) => {\n if (filter.eventTypes?.length && !filter.eventTypes.includes(e.type)) return false;\n if (filter.toolNames?.length && e.type === 'tool_use') {\n const toolEvent = e as { type: 'tool_use'; name: string };\n if (!filter.toolNames.includes(toolEvent.name)) return false;\n }\n if (filter.timeRange) {\n const ts = new Date(e.ts).getTime();\n const start = new Date(filter.timeRange.start).getTime();\n const end = new Date(filter.timeRange.end).getTime();\n if (ts < start || ts > end) return false;\n }\n return true;\n });\n }\n\n private calcDuration(events: SessionEvent[]): number {\n if (events.length < 2) return 0;\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n /* v8 ignore next -- defensive: length>=2 guard above guarantees both ends exist */\n if (!firstEvent || !lastEvent) return 0;\n const first = new Date(firstEvent.ts).getTime();\n const last = new Date(lastEvent.ts).getTime();\n return last - first;\n }\n}\n","/**\n * SessionRegistry — cross-process session and agent tracker.\n *\n * Each WrongStack process registers its session on start and updates its\n * status periodically. The registry is a single JSON file at\n * `~/.wrongstack/session-registry.json`. Entries are keyed by session ID.\n *\n * Because multiple processes may write concurrently, every write is an\n * atomic read-modify-write protected by a per-file advisory lock (flock on\n * Unix, exclusive open on Windows). Stale entries (process no longer alive)\n * are pruned on every read.\n *\n * @module session-registry\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\n/** Live status of a single agent within a session. */\nexport type AgentLiveStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user' // brain.ask_human, confirm prompt\n | 'error';\n\nexport interface AgentEntry {\n /** Unique agent id (ULID or UUID). */\n id: string;\n /** Human-readable label (e.g. \"leader\", \"bug-hunter #1\"). */\n name: string;\n status: AgentLiveStatus;\n /** Current tool name if running, undefined otherwise. */\n currentTool?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** Cumulative cost in USD for this agent, when known. */\n costUsd?: number | undefined;\n /** Cumulative input tokens, when known. */\n tokensIn?: number | undefined;\n /** Cumulative output tokens, when known. */\n tokensOut?: number | undefined;\n /** Context window fill 0–100 (may exceed 100 when over limit), when known. */\n ctxPct?: number | undefined;\n /** Model id this agent is running on, when known. */\n model?: string | undefined;\n /**\n * Tail of the assistant text currently being streamed (capped, throttled).\n * Lets a cross-process watcher see the response form in near-real-time\n * instead of waiting for the completed turn to land in the session log.\n */\n partialText?: string | undefined;\n /** UTC ISO timestamp of last activity. */\n lastActivityAt: string;\n}\n\nexport type SessionLiveStatus =\n | 'active' // process running, agents may be idle or busy\n | 'idle' // process running, no agent activity\n | 'closing' // session_end written, process shutting down\n | 'stale'; // process no longer alive (pruned on next read)\n\nexport interface SessionRegistryEntry {\n sessionId: string;\n projectSlug: string;\n projectRoot: string;\n projectName: string;\n workingDir: string;\n /**\n * Which surface owns this session — `'tui'` / `'webui'` / `'cli'` (one-shot or\n * REPL). Lets cross-process consumers (e.g. the WebUI Fleet HQ office map) label\n * each live session by client kind. Optional for back-compat with older entries.\n */\n clientType?: 'tui' | 'webui' | 'cli' | 'repl' | string | undefined;\n /** Current git branch, if the project is a git repo. Detected at registration. */\n gitBranch?: string | undefined;\n status: SessionLiveStatus;\n pid: number;\n /** UTC ISO */\n startedAt: string;\n /** UTC ISO — updated on every heartbeat */\n lastHeartbeatAt: string;\n /** Count of tracked agents */\n agentCount: number;\n agents: AgentEntry[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\nconst REGISTRY_FILE = 'session-registry.json';\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst STALE_TIMEOUT_MS = 30_000; // entry considered stale after 30s without heartbeat\n// A session that announced `closing` (heartbeat stopped) is dropped this long\n// after its last heartbeat, so the fleet view doesn't keep a dead client around.\nconst CLOSING_GRACE_MS = 15_000;\n// A held lock is released within milliseconds; anything older is a crashed\n// owner's leftover and is safe to break so writes never wedge permanently.\nconst STALE_LOCK_MS = 10_000;\nconst STALE_TMP_MS = 60_000;\nconst MAX_STALE_TMP_FILES = 20;\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Registry class ────────────────────────────────────────────────────────\n\nexport class SessionRegistry {\n private readonly filePath: string;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private currentSessionId: string | null = null;\n /**\n * Last full entry this process registered. Kept so the heartbeat can\n * re-create our entry if it ever goes missing — e.g. our initial register()\n * write was dropped (a wedged lock), the file was reset, or we were pruned.\n */\n private lastEntry: SessionRegistryEntry | null = null;\n\n constructor(globalRoot: string) {\n this.filePath = path.join(globalRoot, REGISTRY_FILE);\n }\n\n // ── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Register the current session. Call once on session start.\n * Starts the heartbeat timer.\n */\n async register(\n entry: Omit<SessionRegistryEntry, 'status' | 'lastHeartbeatAt' | 'agentCount' | 'agents'> & {\n agents?: AgentEntry[] | undefined;\n },\n ): Promise<void> {\n // Safe to call again on a project switch: the WebUI re-roots in place and\n // creates a fresh session id pointing at the new project. Clear the prior\n // heartbeat timer (otherwise each switch leaks a timer that keeps writing).\n // A process owns exactly one entry, so the same-pid dedup below drops our\n // own previous entry — the registry never carries a phantom session still\n // pointing at the old project's root/workingDir.\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n this.currentSessionId = entry.sessionId;\n const full: SessionRegistryEntry = {\n ...entry,\n status: 'active',\n lastHeartbeatAt: new Date().toISOString(),\n agentCount: entry.agents?.length ?? 0,\n agents: entry.agents ?? [],\n };\n this.lastEntry = full;\n await this.atomicUpdate((registry) => {\n // Prune dead entries that haven't heartbeated recently.\n // A just-created entry has no heartbeat yet — don't prune it.\n const now = Date.now();\n for (const [id, existing] of Object.entries(registry)) {\n if (existing.pid === entry.pid) {\n // Our own process owns exactly one entry. When re-registering under\n // a new session id (project switch re-roots in place), drop the\n // stale same-pid entry so it doesn't linger pointing at the old\n // project's root/workingDir.\n if (id !== entry.sessionId) delete registry[id];\n continue;\n }\n const heartbeatAge = now - new Date(existing.lastHeartbeatAt).getTime();\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(existing.pid)) {\n delete registry[id];\n }\n }\n registry[entry.sessionId] = full;\n });\n\n // Start heartbeat\n this.heartbeatTimer = setInterval(() => {\n void this.heartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n if (this.heartbeatTimer.unref) this.heartbeatTimer.unref();\n }\n\n /**\n * Update agent status for the current session. Call on every\n * significant status change (agent start, tool start, user wait, error).\n */\n async updateAgents(agents: AgentEntry[]): Promise<void> {\n if (!this.currentSessionId) return;\n // Derive session status from the agent collective.\n const hasRunning = agents.some((a) => a.status === 'running' || a.status === 'streaming');\n const hasWaiting = agents.some((a) => a.status === 'waiting_user');\n const hasError = agents.some((a) => a.status === 'error');\n const status: SessionLiveStatus = hasRunning || hasWaiting || hasError ? 'active' : 'idle';\n const nowIso = new Date().toISOString();\n\n // Keep the cached entry current so a heartbeat re-insert carries live agents.\n if (this.lastEntry) {\n this.lastEntry.agents = agents;\n this.lastEntry.agentCount = agents.length;\n this.lastEntry.status = status;\n this.lastEntry.lastHeartbeatAt = nowIso;\n }\n\n await this.atomicUpdate((registry) => {\n let entry = registry[this.currentSessionId!];\n if (!entry) {\n // Our entry vanished (dropped write / reset / pruned) — re-create it.\n if (!this.lastEntry) return;\n entry = { ...this.lastEntry };\n registry[this.currentSessionId!] = entry;\n }\n entry.agents = agents;\n entry.agentCount = agents.length;\n entry.status = status;\n entry.lastHeartbeatAt = nowIso;\n });\n }\n\n /**\n * Mark the session as closing. Called during shutdown.\n * Stops the heartbeat timer.\n */\n async markClosing(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n await this.atomicUpdate((registry) => {\n const entry = registry[this.currentSessionId!];\n if (!entry) return;\n entry.status = 'closing';\n entry.lastHeartbeatAt = new Date().toISOString();\n });\n }\n\n /**\n * Remove the current session from the registry. Call on clean exit.\n */\n async unregister(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (!this.currentSessionId) return;\n const sid = this.currentSessionId;\n this.currentSessionId = null;\n await this.atomicUpdate((registry) => {\n delete registry[sid];\n });\n }\n\n /**\n * List all non-stale sessions. Prunes stale entries automatically.\n */\n async list(): Promise<SessionRegistryEntry[]> {\n const registry = await this.readAndPrune();\n return Object.values(registry);\n }\n\n /**\n * Get a single session entry by ID. Returns undefined if not found or stale.\n */\n async get(sessionId: string): Promise<SessionRegistryEntry | undefined> {\n const registry = await this.readAndPrune();\n return registry[sessionId];\n }\n\n /**\n * List all sessions for a specific project (by slug).\n */\n async listByProject(projectSlug: string): Promise<SessionRegistryEntry[]> {\n const all = await this.list();\n return all.filter((e) => e.projectSlug === projectSlug);\n }\n\n /**\n * Return the registry file path. Useful for WebUI to watch/read.\n */\n get registryPath(): string {\n return this.filePath;\n }\n\n // ── Internal ────────────────────────────────────────────────────────────\n\n private async heartbeat(): Promise<void> {\n if (!this.currentSessionId) return;\n try {\n const sessionId = this.currentSessionId;\n const nowIso = new Date().toISOString();\n await this.atomicUpdate((registry) => {\n const entry = registry[sessionId];\n if (entry) {\n entry.lastHeartbeatAt = nowIso;\n // Status bound: if closing, don't revert\n if (entry.status !== 'closing') {\n const hasRunning = (entry.agents ?? []).some(\n (a) => a.status === 'running' || a.status === 'streaming',\n );\n entry.status = hasRunning ? 'active' : 'idle';\n }\n return;\n }\n if (this.lastEntry) {\n // Our entry is gone (initial register() dropped on a wedged lock, file\n // reset, or pruned). Re-create it through the locked path so a process\n // that booted into a broken registry still shows up once it heals.\n registry[sessionId] = { ...this.lastEntry, lastHeartbeatAt: nowIso };\n }\n });\n } catch {\n // Best-effort heartbeat — never throw\n }\n }\n\n private async readAndPrune(): Promise<Record<string, SessionRegistryEntry>> {\n try {\n const raw = await fs.readFile(this.filePath, 'utf8');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n const now = Date.now();\n let pruned = false;\n\n for (const [id, entry] of Object.entries(registry)) {\n const heartbeatAge = now - new Date(entry.lastHeartbeatAt).getTime();\n // Cleanly-closed session: drop after a short grace (handles both a fully\n // exited process and one still alive but done) so no dead client lingers.\n if (entry.status === 'closing' && heartbeatAge > CLOSING_GRACE_MS) {\n delete registry[id];\n pruned = true;\n continue;\n }\n if (heartbeatAge > STALE_TIMEOUT_MS && !pidAlive(entry.pid)) {\n entry.status = 'stale';\n // Keep stale entries for 5 minutes so UIs can show \"recently closed\"\n const startedAge = now - new Date(entry.startedAt).getTime();\n if (startedAge > 5 * 60_000) {\n delete registry[id];\n pruned = true;\n }\n }\n }\n\n if (pruned) {\n await this.writeAtomic(registry).catch(() => undefined);\n }\n\n return registry;\n } catch {\n return {};\n }\n }\n\n private async atomicUpdate(\n fn: (registry: Record<string, SessionRegistryEntry>) => void,\n ): Promise<void> {\n const lockPath = `${this.filePath}.lock`;\n const maxRetries = 8;\n const retryDelayMs = 20;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n // Acquire exclusive lock via O_CREAT | O_EXCL\n let lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n if (!lockHandle) {\n // Lock contended. A crashed process can leave its lock file behind\n // forever (the `finally` unlink never ran), which would wedge EVERY\n // future write — the registry silently stops updating. Break the lock\n // when its owner pid is dead or it has been held implausibly long\n // (legit holds are sub-millisecond), then retry the open once.\n if (await this.breakStaleLock(lockPath)) {\n lockHandle = await fs.open(lockPath, 'wx').catch(() => null);\n }\n if (!lockHandle) {\n await new Promise((r) => setTimeout(r, retryDelayMs * (attempt + 1)));\n continue;\n }\n }\n\n try {\n // Stamp the owner pid so other processes can detect a stale lock.\n await lockHandle.writeFile(String(process.pid)).catch(() => undefined);\n const raw = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');\n const registry = JSON.parse(raw) as Record<string, SessionRegistryEntry>;\n fn(registry);\n await this.writeAtomicLocked(registry);\n return; // success\n } finally {\n await lockHandle.close();\n await fs.unlink(lockPath).catch(() => undefined);\n }\n } catch {\n // Best-effort — never throw from registry writes\n return;\n }\n }\n // All retries exhausted — registry update dropped (non-critical)\n }\n\n /**\n * Break a contended lock if it is stale: the recorded owner pid is no longer\n * alive, or the lock is older than {@link STALE_LOCK_MS}. Returns true when the\n * lock was removed (caller should retry acquisition). Best-effort and\n * race-tolerant — a fresh lock (age ~0, live owner) is never broken, so the\n * common concurrent case self-heals on the next heartbeat.\n */\n private async breakStaleLock(lockPath: string): Promise<boolean> {\n try {\n const [stat, content] = await Promise.all([\n fs.stat(lockPath),\n fs.readFile(lockPath, 'utf8').catch(() => ''),\n ]);\n const ageMs = Date.now() - stat.mtimeMs;\n const ownerPid = Number.parseInt(content.trim(), 10);\n const ownerDead =\n Number.isInteger(ownerPid) && ownerPid > 0 && ownerPid !== process.pid && !pidAlive(ownerPid);\n if (ownerDead || ageMs > STALE_LOCK_MS) {\n await fs.unlink(lockPath).catch(() => undefined);\n return true;\n }\n return false;\n } catch {\n // stat failed → the lock vanished underneath us; let the caller retry.\n return true;\n }\n }\n\n private async writeAtomicLocked(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n await this.pruneStaleTempFiles();\n await this.writeAtomicFile(registry);\n }\n\n /** Legacy write without lock — used by heartbeat for performance. */\n private async writeAtomic(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n await this.pruneStaleTempFiles();\n await this.writeAtomicFile(registry);\n }\n\n private async writeAtomicFile(registry: Record<string, SessionRegistryEntry>): Promise<void> {\n const tmp = path.join(\n path.dirname(this.filePath),\n `.${path.basename(this.filePath)}.${randomUUID().slice(0, 8)}.tmp`,\n );\n try {\n await fs.writeFile(tmp, JSON.stringify(registry, null, 2), 'utf8');\n await fs.rename(tmp, this.filePath);\n } catch (err) {\n await fs.unlink(tmp).catch(() => undefined);\n throw err;\n }\n }\n\n private async pruneStaleTempFiles(): Promise<void> {\n try {\n const dir = path.dirname(this.filePath);\n const base = path.basename(this.filePath);\n const now = Date.now();\n const stale: Array<{ name: string; mtimeMs: number }> = [];\n\n for (const name of await fs.readdir(dir)) {\n const isTemp =\n (name.startsWith(`${base}.`) || name.startsWith(`.${base}.`)) && name.endsWith('.tmp');\n if (!isTemp) continue;\n const stat = await fs.stat(path.join(dir, name)).catch(() => null);\n if (!stat) continue;\n if (now - stat.mtimeMs > STALE_TMP_MS) stale.push({ name, mtimeMs: stat.mtimeMs });\n }\n\n stale.sort((a, b) => b.mtimeMs - a.mtimeMs);\n await Promise.all(\n stale.slice(MAX_STALE_TMP_FILES).map(async ({ name }) => {\n await fs.unlink(path.join(dir, name)).catch(() => undefined);\n }),\n );\n } catch {\n // best-effort cleanup must not block registry heartbeats\n }\n }\n}\n\n/** Singleton — created once per process. */\nlet _instance: SessionRegistry | null = null;\n\nexport function getSessionRegistry(globalRoot?: string): SessionRegistry {\n if (!_instance && globalRoot) {\n _instance = new SessionRegistry(globalRoot);\n }\n if (!_instance) {\n throw new Error('SessionRegistry not initialized. Call getSessionRegistry(globalRoot) first.');\n }\n return _instance;\n}\n\nexport function hasSessionRegistry(): boolean {\n return _instance !== null;\n}\n","/**\n * AgentStatusTracker — subscribes to EventBus events and keeps the\n * SessionRegistry updated with live agent status.\n *\n * Created once per process during boot. Listens for:\n * - agent.run.started / agent.run.completed → agent status changes\n * - tool.started / tool.executed → current tool tracking\n * - brain.ask_human → waiting_user status\n * - fleet events (subagent spawn/start/done) → agent entries\n *\n * @module agent-status-tracker\n */\nimport type { EventBus } from './kernel/events.js';\nimport type {\n AgentEntry,\n AgentLiveStatus,\n SessionRegistry,\n} from './session-registry.js';\n\n/** A finished (idle/error) subagent older than this is reaped from the fleet view. */\nconst AGENT_REAP_MS = 30_000;\n/** How often the reaper sweeps for finished subagents. */\nconst AGENT_SWEEP_INTERVAL_MS = 10_000;\n/** Max chars of streamed assistant text kept in the registry (the live tail). */\nconst PARTIAL_TEXT_CAP = 1200;\n/** Min gap between registry flushes triggered purely by streamed text. */\nconst PARTIAL_FLUSH_THROTTLE_MS = 300;\n\nexport interface AgentStatusTrackerOptions {\n events: EventBus;\n registry: SessionRegistry;\n /** Leader agent name shown in the registry. Default: \"leader\". */\n leaderName?: string | undefined;\n /**\n * Best-effort callback fired after each registry write settles. Used to nudge\n * local WebUI servers (FleetNotifier) so cross-process status reaches the map\n * without waiting on their file-watch/poll. Never block or throw.\n */\n onUpdate?: (() => void) | undefined;\n}\n\nexport class AgentStatusTracker {\n private readonly events: EventBus;\n private readonly registry: SessionRegistry;\n private readonly leaderName: string;\n\n // Live agent map: agentId → AgentEntry\n private agents = new Map<string, AgentEntry>();\n\n // Leader tracking\n private leaderStatus: AgentLiveStatus = 'idle';\n private leaderCurrentTool: string | undefined;\n private leaderIterations = 0;\n private leaderToolCalls = 0;\n private leaderCostUsd = 0;\n private leaderTokensIn = 0;\n private leaderTokensOut = 0;\n private leaderCtxPct: number | undefined;\n private leaderModel: string | undefined;\n private leaderPartialText = '';\n\n private unsubscribers: Array<() => void> = [];\n private readonly onUpdate: (() => void) | undefined;\n private sweepTimer: ReturnType<typeof setInterval> | null = null;\n private partialTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(opts: AgentStatusTrackerOptions) {\n this.events = opts.events;\n this.registry = opts.registry;\n this.leaderName = opts.leaderName ?? 'leader';\n this.onUpdate = opts.onUpdate;\n }\n\n start(): void {\n // Leader events\n this.unsubscribers.push(\n this.events.onPattern('agent.run.started', () => {\n this.leaderStatus = 'running';\n this.leaderIterations++;\n this.flush();\n }),\n );\n\n // Capture the leader's model + context fill from each iteration's context.\n this.unsubscribers.push(\n this.events.onPattern('iteration.started', (_e, payload) => {\n const ctx = (payload as { ctx?: { model?: string; tokenCount?: number; maxContext?: number } } | undefined)?.ctx;\n if (!ctx) return;\n if (ctx.model) this.leaderModel = ctx.model;\n if (typeof ctx.tokenCount === 'number' && typeof ctx.maxContext === 'number' && ctx.maxContext > 0) {\n this.leaderCtxPct = Math.round((ctx.tokenCount / ctx.maxContext) * 100);\n }\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.completed', () => {\n this.leaderStatus = 'idle';\n this.leaderCurrentTool = undefined;\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('agent.run.error', () => {\n this.leaderStatus = 'error';\n this.leaderCurrentTool = undefined;\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n // Tool events — track current tool\n this.unsubscribers.push(\n this.events.onPattern('tool.started', (_event, payload) => {\n const p = payload as { name?: string } | undefined;\n if (p?.name) {\n this.leaderCurrentTool = p.name;\n this.leaderToolCalls++;\n }\n this.leaderStatus = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('tool.executed', () => {\n this.leaderCurrentTool = undefined;\n this.flush();\n }),\n );\n\n // Brain ask_human → waiting for user input\n this.unsubscribers.push(\n this.events.onPattern('brain.ask_human', () => {\n this.leaderStatus = 'waiting_user';\n this.flush();\n }),\n );\n\n // Streaming events\n this.unsubscribers.push(\n this.events.onPattern('llm.stream_started', () => {\n this.leaderStatus = 'streaming';\n // A new response is starting — drop the previous turn's live tail.\n this.leaderPartialText = '';\n this.flush();\n }),\n );\n\n // Live assistant text — accumulate the streamed tail so a cross-process\n // watcher sees the response form. Flushed on a throttle, NOT per token\n // (text_delta fires once per chunk → would thrash the shared registry).\n this.unsubscribers.push(\n this.events.onPattern('provider.text_delta', (_e, payload) => {\n const text = (payload as { text?: string } | undefined)?.text;\n if (!text) return;\n this.leaderStatus = 'streaming';\n const next = this.leaderPartialText + text;\n this.leaderPartialText =\n next.length > PARTIAL_TEXT_CAP ? next.slice(next.length - PARTIAL_TEXT_CAP) : next;\n this.schedulePartialFlush();\n }),\n );\n\n // Leader token + cost accounting (per provider call — accumulate).\n this.unsubscribers.push(\n this.events.onPattern('token.accounted', (_e, payload) => {\n const p = payload as\n | { usage?: { input?: number; output?: number }; cost?: { total?: number } }\n | undefined;\n if (!p) return;\n this.leaderTokensIn += p.usage?.input ?? 0;\n this.leaderTokensOut += p.usage?.output ?? 0;\n this.leaderCostUsd += p.cost?.total ?? 0;\n this.flush();\n }),\n );\n\n // ── Subagent tracking ──────────────────────────────────────────────\n // These are the real fleet lifecycle events (emitted by MultiAgentHost /\n // the subagent runner / director). The previous code listened to a\n // `fleet.subagent.*` namespace that nothing emits, so subagents never\n // reached the registry — only the leader showed up.\n const touch = (id: string): AgentEntry => {\n let entry = this.agents.get(id);\n if (!entry) {\n entry = { id, name: id, status: 'idle', iterations: 0, toolCalls: 0, lastActivityAt: new Date().toISOString() };\n this.agents.set(id, entry);\n }\n entry.lastActivityAt = new Date().toISOString();\n return entry;\n };\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.spawned', (_e, payload) => {\n const p = payload as { subagentId?: string; name?: string; model?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.name = p.name?.trim() || entry.name;\n if (p.model) entry.model = p.model;\n entry.status = 'running';\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.ctx_pct', (_e, payload) => {\n const p = payload as { subagentId?: string; load?: number } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n if (typeof p.load === 'number') entry.ctxPct = Math.round(p.load * 100);\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.task_started', (_e, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n entry.iterations++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.tool_executed', (_e, payload) => {\n const p = payload as { subagentId?: string; name?: string } | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n entry.currentTool = p.name;\n entry.toolCalls++;\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.iteration_summary', (_e, payload) => {\n const p = payload as\n | {\n subagentId?: string;\n iteration?: number;\n toolCalls?: number;\n currentTool?: string;\n costUsd?: number;\n partialText?: string;\n }\n | undefined;\n if (!p?.subagentId) return;\n const entry = touch(p.subagentId);\n entry.status = 'running';\n if (typeof p.iteration === 'number') entry.iterations = p.iteration;\n if (typeof p.toolCalls === 'number') entry.toolCalls = p.toolCalls;\n if (typeof p.costUsd === 'number') entry.costUsd = p.costUsd;\n if (p.currentTool) entry.currentTool = p.currentTool;\n // Live streamed tail of THIS subagent's current response (the runner\n // already accumulates it) — capped to the same budget as the leader.\n if (typeof p.partialText === 'string') {\n entry.partialText =\n p.partialText.length > PARTIAL_TEXT_CAP\n ? p.partialText.slice(p.partialText.length - PARTIAL_TEXT_CAP)\n : p.partialText;\n }\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.task_completed', (_e, payload) => {\n const p = payload as\n | { subagentId?: string; status?: string; iterations?: number; toolCalls?: number }\n | undefined;\n if (!p?.subagentId) return;\n // Only update an agent we already know — a completion for an unseen\n // agent isn't worth materialising.\n const entry = this.agents.get(p.subagentId);\n if (!entry) return;\n entry.status = p.status === 'failed' || p.status === 'timeout' ? 'error' : 'idle';\n entry.currentTool = undefined;\n entry.partialText = undefined;\n if (typeof p.iterations === 'number') entry.iterations = p.iterations;\n if (typeof p.toolCalls === 'number') entry.toolCalls = p.toolCalls;\n entry.lastActivityAt = new Date().toISOString();\n this.flush();\n }),\n );\n\n this.unsubscribers.push(\n this.events.onPattern('subagent.stopped', (_e, payload) => {\n const p = payload as { subagentId?: string } | undefined;\n if (!p?.subagentId) return;\n if (this.agents.delete(p.subagentId)) this.flush();\n }),\n );\n\n // Reap finished subagents so the fleet view doesn't fill with dead/idle\n // desks. The leader is synthesised in flush() (never in `this.agents`), so\n // it is never reaped — it represents the live session.\n this.sweepTimer = setInterval(() => this.sweep(), AGENT_SWEEP_INTERVAL_MS);\n if (typeof this.sweepTimer.unref === 'function') this.sweepTimer.unref();\n }\n\n stop(): void {\n for (const unsub of this.unsubscribers) {\n try { unsub(); } catch { /* ignore */ }\n }\n this.unsubscribers = [];\n if (this.sweepTimer) {\n clearInterval(this.sweepTimer);\n this.sweepTimer = null;\n }\n if (this.partialTimer) {\n clearTimeout(this.partialTimer);\n this.partialTimer = null;\n }\n }\n\n /**\n * Coalesce streamed-text flushes: at most one registry write per\n * {@link PARTIAL_FLUSH_THROTTLE_MS} while text streams in, so per-token\n * deltas never thrash the cross-process registry file.\n */\n private schedulePartialFlush(): void {\n if (this.partialTimer) return;\n this.partialTimer = setTimeout(() => {\n this.partialTimer = null;\n this.flush();\n }, PARTIAL_FLUSH_THROTTLE_MS);\n if (typeof this.partialTimer.unref === 'function') this.partialTimer.unref();\n }\n\n /**\n * Remove subagents that have been finished (idle/error) for longer than\n * {@link AGENT_REAP_MS}. Running / streaming / waiting_user agents are kept\n * regardless of age — only *not-working* agents are reaped.\n */\n private sweep(): void {\n const now = Date.now();\n let removed = false;\n for (const [id, a] of this.agents) {\n const finished = a.status !== 'running' && a.status !== 'streaming' && a.status !== 'waiting_user';\n const age = now - Date.parse(a.lastActivityAt);\n if (finished && Number.isFinite(age) && age > AGENT_REAP_MS) {\n this.agents.delete(id);\n removed = true;\n }\n }\n if (removed) this.flush();\n }\n\n private flush(): void {\n const leaderEntry: AgentEntry = {\n id: 'leader',\n name: this.leaderName,\n status: this.leaderStatus,\n currentTool: this.leaderCurrentTool,\n iterations: this.leaderIterations,\n toolCalls: this.leaderToolCalls,\n costUsd: this.leaderCostUsd,\n tokensIn: this.leaderTokensIn,\n tokensOut: this.leaderTokensOut,\n ctxPct: this.leaderCtxPct,\n model: this.leaderModel,\n partialText: this.leaderPartialText || undefined,\n lastActivityAt: new Date().toISOString(),\n };\n\n const allAgents = [leaderEntry, ...this.agents.values()];\n // Nudge local WebUIs only AFTER the write settles, so they re-read fresh\n // data. Best-effort — never let a notifier failure surface here.\n this.registry\n .updateAgents(allAgents)\n .then(() => {\n try {\n this.onUpdate?.();\n } catch {\n /* best-effort */\n }\n })\n .catch(() => undefined);\n }\n}\n","/**\n * FleetNotifier — push-on-write nudge to local WebUI servers.\n *\n * The cross-process source of truth is the file-based SessionRegistry, which\n * every WebUI server already watches (`fs.watch`, ~150ms) and polls (5s). This\n * notifier is a best-effort *latency* optimisation on top: after a process\n * writes its session/agent status to the registry, it sends a tiny\n * fire-and-forget `POST /api/fleet/ping` to every WebUI running against the\n * same project (discovered from `~/.wrongstack/webui-instances.json`). The\n * WebUI responds by re-broadcasting the (already-fresh) registry immediately —\n * so a TUI/REPL agent's activity reaches the Fleet HQ map in ~milliseconds\n * instead of waiting on the watch/poll.\n *\n * Design notes:\n * - **Never the source of truth.** If no WebUI is running, the file system +\n * watch/poll still carry everything. Every failure here is swallowed.\n * - **Coalesced.** Bursts of events (tool calls, deltas) collapse into one POST\n * per ~50ms so we never hammer the WebUI per token.\n * - **Discovery cached** for a couple seconds to avoid a disk read per event.\n * - **Loopback only / self-excluded.** Targets the local instances file; a\n * `0.0.0.0`/`::` bind is dialled on `127.0.0.1`, and the caller's own pid is\n * skipped so a WebUI never pings itself.\n *\n * @module fleet-notifier\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nconst INSTANCES_FILE = 'webui-instances.json';\nconst DISCOVERY_TTL_MS = 2_500;\nconst COALESCE_MS = 50;\nconst POST_TIMEOUT_MS = 500;\n\ninterface InstanceRecordLike {\n pid: number;\n httpPort: number;\n host: string;\n projectRoot: string;\n}\n\nfunction pidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n/** Normalise a project root for cross-process comparison (case-insensitive on Windows). */\nfunction normRoot(root: string): string {\n const resolved = path.resolve(root);\n return process.platform === 'win32' ? resolved.toLowerCase() : resolved;\n}\n\nexport interface FleetNotifierOptions {\n /** WrongStack global dir (`~/.wrongstack`) holding `webui-instances.json`. */\n baseDir: string;\n /** This process's project root — only WebUIs on the same project are pinged. */\n projectRoot: string;\n /** This process's pid, so a WebUI never pings itself. */\n selfPid?: number | undefined;\n /** Injectable POST for tests. Defaults to a timed `fetch`. */\n post?: ((url: string) => Promise<void>) | undefined;\n}\n\nexport class FleetNotifier {\n private readonly baseDir: string;\n private readonly projectRoot: string;\n private readonly selfPid: number;\n private readonly doPost: (url: string) => Promise<void>;\n\n private cache: { at: number; urls: string[] } | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n constructor(opts: FleetNotifierOptions) {\n this.baseDir = opts.baseDir;\n this.projectRoot = normRoot(opts.projectRoot);\n this.selfPid = opts.selfPid ?? process.pid;\n this.doPost = opts.post ?? defaultPost;\n }\n\n /** Coalesced, best-effort nudge. Safe to call on every status change. */\n notify(): void {\n if (this.disposed || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, COALESCE_MS);\n if (typeof this.timer.unref === 'function') this.timer.unref();\n }\n\n /** Resolve same-project WebUI ping URLs (cached briefly). Exposed for tests. */\n async endpoints(): Promise<string[]> {\n const now = Date.now();\n if (this.cache && now - this.cache.at < DISCOVERY_TTL_MS) return this.cache.urls;\n const urls = await this.discover();\n this.cache = { at: now, urls };\n return urls;\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async flush(): Promise<void> {\n const urls = await this.endpoints();\n await Promise.all(urls.map((u) => this.doPost(u).catch(() => undefined)));\n }\n\n private async discover(): Promise<string[]> {\n try {\n const raw = await fs.readFile(path.join(this.baseDir, INSTANCES_FILE), 'utf8');\n const data = JSON.parse(raw) as { instances?: InstanceRecordLike[] };\n const list = Array.isArray(data?.instances) ? data.instances : [];\n return list\n .filter((i) => i && typeof i.httpPort === 'number')\n .filter((i) => i.pid !== this.selfPid)\n .filter((i) => normRoot(i.projectRoot) === this.projectRoot)\n .filter((i) => pidAlive(i.pid))\n .map((i) => {\n const host = i.host === '0.0.0.0' || i.host === '::' || !i.host ? '127.0.0.1' : i.host;\n return `http://${host}:${i.httpPort}/api/fleet/ping`;\n });\n } catch {\n // Missing/corrupt instances file → no WebUIs to notify.\n return [];\n }\n }\n}\n\nasync function defaultPost(url: string): Promise<void> {\n await fetch(url, {\n method: 'POST',\n signal: AbortSignal.timeout(POST_TIMEOUT_MS),\n });\n}\n","import { expectDefined } from '../utils/expect-defined.js';\r\nimport { toErrorMessage } from '../utils/error.js';\nimport * as fsp from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport type { CheckpointInfo, RewindResult, RewindResultExtended, SessionRewinder } from '../types/session-rewinder.js';\r\nimport type { SessionEvent, FileSnapshot } from '../types/session.js';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\nimport { SessionError, ERROR_CODES } from '../types/errors.js';\r\n\r\nexport interface SessionRewinderOptions {\r\n sessionsDir: string;\r\n /** The project root directory; used to validate rewind targets stay inside it. */\r\n projectRoot: string;\r\n}\r\n\r\n/**\r\n * Rewind engine that reads session JSONL files and reverts file system\r\n * changes to any previous checkpoint.\r\n */\r\nexport class DefaultSessionRewinder implements SessionRewinder {\r\n constructor(private readonly sessionsDir: string, private readonly projectRoot: string) {}\r\n\r\n async listCheckpoints(sessionId: string): Promise<CheckpointInfo[]> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n // Build a map of promptIndex -> file snapshot count\r\n const fileCountMap = new Map<number, number>();\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n const e = event as { promptIndex: number; files: FileSnapshot[] };\r\n fileCountMap.set(e.promptIndex, (fileCountMap.get(e.promptIndex) ?? 0) + e.files.length);\r\n }\r\n }\r\n\r\n const checkpoints: CheckpointInfo[] = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n const e = event as { promptIndex: number; promptPreview: string; ts: string };\r\n checkpoints.push({\r\n promptIndex: e.promptIndex,\r\n promptPreview: e.promptPreview,\r\n ts: e.ts,\r\n fileCount: fileCountMap.get(e.promptIndex) ?? 0,\r\n });\r\n }\r\n }\r\n\r\n return checkpoints;\r\n }\r\n\r\n async rewindToCheckpoint(\r\n sessionId: string,\r\n checkpointIndex: number,\r\n ): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n let targetIdx = -1;\r\n for (let i = 0; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n const checkpointEvent = event as { promptIndex: number };\r\n if (checkpointEvent.promptIndex === checkpointIndex) {\r\n targetIdx = i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (targetIdx === -1) {\r\n throw new SessionError({\r\n message: `Checkpoint ${checkpointIndex} not found`,\r\n code: ERROR_CODES.SESSION_NOT_FOUND,\r\n context: { checkpointIndex },\r\n });\r\n }\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (let i = targetIdx + 1; i < events.length; i++) {\r\n const event = expectDefined(events[i]);\r\n if (event.type === 'checkpoint') {\r\n break;\r\n }\r\n if (event.type === 'file_snapshot') {\r\n const snapshotEvent = event as { promptIndex: number; files: FileSnapshot[] };\r\n if (snapshotEvent.promptIndex >= checkpointIndex) {\r\n snapshotsToRevert.push({ promptIndex: snapshotEvent.promptIndex, files: snapshotEvent.files });\r\n }\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert, this.projectRoot);\r\n const removedEvents = events.length - targetIdx - 1;\r\n return { ...result, toPromptIndex: checkpointIndex, removedEvents };\r\n }\r\n\r\n async rewindLastN(sessionId: string, n: number): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const checkpoints: Array<{ promptIndex: number; ts: string }> = [];\r\n for (const event of events) {\r\n if (event.type === 'checkpoint') {\r\n checkpoints.push({ promptIndex: event.promptIndex, ts: event.ts });\r\n }\r\n }\r\n\r\n if (checkpoints.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n checkpoints.sort((a, b) => b.promptIndex - a.promptIndex);\r\n const targetIndex = checkpoints[n]?.promptIndex ?? 0;\r\n\r\n const snapshotsToRevert: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n let shouldRevert = false;\r\n\r\n for (const event of events) {\r\n if (event.type === 'checkpoint' && event.promptIndex === targetIndex) {\r\n shouldRevert = true;\r\n continue;\r\n }\r\n if (shouldRevert && event.type === 'file_snapshot') {\r\n snapshotsToRevert.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n const result = await revertSnapshots(snapshotsToRevert.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: targetIndex, removedEvents: snapshotsToRevert.length };\r\n }\r\n\r\n async rewindToStart(sessionId: string): Promise<RewindResultExtended> {\r\n const file = path.join(this.sessionsDir, `${sessionId}.jsonl`);\r\n const raw = await fsp.readFile(file, 'utf8');\r\n const events = parseEvents(raw);\r\n\r\n const allSnapshots: Array<{ promptIndex: number; files: FileSnapshot[] }> = [];\r\n for (const event of events) {\r\n if (event.type === 'file_snapshot') {\r\n allSnapshots.push({ promptIndex: event.promptIndex, files: event.files });\r\n }\r\n }\r\n\r\n if (allSnapshots.length === 0) {\r\n return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };\r\n }\r\n\r\n const result = await revertSnapshots(allSnapshots.reverse(), this.projectRoot);\r\n return { ...result, toPromptIndex: 0, removedEvents: allSnapshots.length };\r\n }\r\n}\r\n\r\nfunction parseEvents(raw: string): SessionEvent[] {\r\n const lines = raw.split('\\n').filter((l) => l.trim());\r\n const events: SessionEvent[] = [];\r\n\r\n for (const line of lines) {\r\n try {\r\n const parsed = JSON.parse(line);\r\n if (\r\n parsed !== null &&\r\n typeof parsed === 'object' &&\r\n typeof (parsed as { type?: unknown | undefined }).type === 'string' &&\r\n typeof (parsed as { ts?: unknown | undefined }).ts === 'string'\r\n ) {\r\n events.push(parsed as SessionEvent);\r\n }\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n\r\n return events;\r\n}\r\n\r\nasync function revertSnapshots(\r\n snapshots: Array<{ promptIndex: number; files: FileSnapshot[] }>,\r\n projectRoot: string,\r\n): Promise<RewindResult> {\r\n const revertedFiles: string[] = [];\r\n const errors: string[] = [];\r\n\r\n for (const snapshot of snapshots) {\r\n for (const file of snapshot.files) {\r\n try {\r\n // Guard: ensure the target path resolves inside the project root.\r\n // Without this, a maliciously recorded path (e.g., via path traversal\r\n // in a tool call that wasn't caught) could cause rewind to write\r\n // to arbitrary locations.\r\n const absPath = path.resolve(file.path);\r\n const root = path.resolve(projectRoot);\r\n const rel = path.relative(root, absPath);\r\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\r\n errors.push(`${file.path}: path resolves outside project root — skipping`);\r\n continue;\r\n }\r\n\r\n if (file.action === 'deleted') {\r\n // File was deleted — restore it from before\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n } else if (file.action === 'created') {\r\n // File was created — delete it\r\n await fsp.unlink(file.path);\r\n revertedFiles.push(file.path);\r\n } else if (file.action === 'modified') {\r\n // File was modified — restore before content\r\n if (file.before !== null) {\r\n // atomicWrite: torn restore would leave the user with a frankenstein file.\r\n await atomicWrite(file.path, file.before, { mode: 0o644 });\r\n revertedFiles.push(file.path);\r\n }\r\n }\r\n } catch (err) {\r\n errors.push(`${file.path}: ${toErrorMessage(err)}`);\r\n }\r\n }\r\n }\r\n\r\n return { revertedFiles, errors };\r\n}","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport type { TodoItem } from '../core/context.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * On-disk checkpoint for `ctx.todos`. Written atomically every time the\n * todo list changes, read once on session resume. This is the missing\n * piece that lets `wstack resume <id>` rehydrate where the previous run\n * stopped instead of starting with an empty board.\n *\n * Schema is intentionally small — a single JSON object so a future\n * format bump is easy. The `version` field is the only contract; the\n * shape under `todos` mirrors `TodoItem` so reading is a straight assign.\n */\nexport interface TodosCheckpointFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n todos: TodoItem[];\n}\n\nexport type TodosCheckpointDetach = () => Promise<void>;\n\n/** Read a checkpoint from disk. Returns null when the file doesn't\n * exist or is corrupt — callers treat both cases as \"no prior state\".\n */\nexport async function loadTodosCheckpoint(\n filePath: string,\n events?: EventBus,\n traceId?: string,\n): Promise<TodoItem[] | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TodosCheckpointFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.todos)) {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return parsed.todos.filter(\n (t): t is TodoItem =>\n !!t &&\n typeof t.id === 'string' &&\n typeof t.content === 'string' &&\n typeof t.status === 'string' &&\n (t.activeForm === undefined || typeof t.activeForm === 'string'),\n );\n } catch {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'todos',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n}\n\n/** Write the checkpoint atomically. Best-effort: a write failure is\n * logged but does not throw — losing one checkpoint shouldn't bring\n * down the agent run.\n */\nexport async function saveTodosCheckpoint(\n filePath: string,\n sessionId: string,\n todos: readonly TodoItem[],\n events?: EventBus,\n traceId?: string,\n): Promise<void> {\n const t0 = Date.now();\n const payload: TodosCheckpointFile = {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n todos: [...todos],\n };\n try {\n await atomicWrite(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: traceId ?? sessionId,\n store: 'todos',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? sessionId,\n store: 'todos',\n filePath,\n operation: 'save',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n });\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'todos_checkpoint.save_failed',\n message: toErrorMessage(err),\n timestamp: new Date().toISOString(),\n }));\n }\n}\n\n/**\n * Subscribe a `ConversationState` so every `todos_replaced` mutation\n * triggers an atomic write to disk. Returns the unsubscribe function.\n *\n * Writes are debounced by 150ms so a flurry of edits (e.g. the LLM\n * marking three items done in the same tool call) coalesces into one\n * disk hit.\n */\nexport function attachTodosCheckpoint(\n state: ConversationState,\n filePath: string,\n sessionId: string,\n events?: EventBus,\n traceId?: string,\n): TodosCheckpointDetach {\n let timer: NodeJS.Timeout | null = null;\n let pending: readonly TodoItem[] | null = null;\n let writeChain: Promise<void> = Promise.resolve();\n\n const enqueueWrite = (todos: readonly TodoItem[]) => {\n writeChain = writeChain\n .then(() => saveTodosCheckpoint(filePath, sessionId, todos, events, traceId))\n /* v8 ignore start -- defensive: saveTodosCheckpoint swallows its own errors and never rejects */\n .catch((err) => {\n // Log and keep the chain alive — a failed write must not\n // poison the chain and silently stop all subsequent writes.\n const msg = toErrorMessage(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'todos_checkpoint.write_chain_failed',\n sessionId,\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n /* v8 ignore stop */\n return writeChain;\n };\n\n const flush = () => {\n timer = null;\n if (pending) {\n const todos = pending;\n pending = null;\n return enqueueWrite(todos);\n }\n /* v8 ignore next -- defensive: flush is only invoked when a change is pending */\n return writeChain;\n };\n\n const unsubscribe = state.onChange((change) => {\n if (change.kind !== 'todos_replaced') return;\n pending = change.todos;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n void flush();\n }, 150);\n });\n return async () => {\n unsubscribe();\n if (timer) {\n clearTimeout(timer);\n // Flush any pending write before detach so callers can safely\n // unsubscribe at shutdown without losing the last update.\n await flush();\n } else {\n await writeChain;\n }\n };\n}\n","import * as fsp from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport type { EventBus } from '../kernel/events.js';\nimport type { ConversationState } from '../core/conversation-state.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Plan items are the strategic counterpart to todos. Where `ctx.todos`\n * is the moment-to-moment task board the LLM mutates per-turn, a plan\n * captures the higher-level approach — the steps the user (or LLM)\n * laid out before any work began.\n *\n * Plans persist by default (per session) so a resumed session can show\n * \"you were on step 3 of 5\". Todos are derived/transient. Both can\n * coexist: think roadmap (plan) vs. sprint board (todos).\n */\nexport interface PlanItem {\n id: string;\n title: string;\n /** Optional longer-form context or rationale. */\n details?: string | undefined;\n status: 'open' | 'in_progress' | 'done';\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PlanFile {\n version: 1;\n sessionId: string;\n title?: string | undefined;\n updatedAt: string;\n items: PlanItem[];\n}\n\nexport async function loadPlan(filePath: string, events?: EventBus): Promise<PlanFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as PlanFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.items)) {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return parsed;\n } catch {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n });\n return null;\n }\n}\n\n/**\n * Persist a plan. Returns `true` on success, `false` if the write failed\n * (still emits `storage.error` + warns — it does NOT throw, so callers that\n * treat a lost plan-save as non-fatal keep working). `mutatePlan` inspects the\n * result and throws so the plan TOOL can report `ok:false` instead of falsely\n * claiming the plan was persisted.\n */\nexport async function savePlan(filePath: string, plan: PlanFile, events?: EventBus): Promise<boolean> {\n const t0 = Date.now();\n try {\n await atomicWrite(filePath, JSON.stringify(plan, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return true;\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'plan',\n filePath,\n operation: 'save',\n error: toErrorMessage(err),\n recoverable: false,\n });\n console.warn(\n '[plan-store] save failed:',\n toErrorMessage(err),\n );\n return false;\n }\n}\n\n/** Create a new PlanFile when none exists on disk. */\nexport function emptyPlan(sessionId: string, title?: string): PlanFile {\n return {\n version: 1,\n sessionId,\n title,\n updatedAt: new Date().toISOString(),\n items: [],\n };\n}\n\nexport function addPlanItem(\n plan: PlanFile,\n title: string,\n details?: string | undefined,\n): { plan: PlanFile; item: PlanItem } {\n const now = new Date().toISOString();\n const item: PlanItem = {\n id: `plan_${Date.now()}_${randomUUID().slice(0, 6)}`,\n title,\n details,\n status: 'open',\n createdAt: now,\n updatedAt: now,\n };\n return {\n plan: { ...plan, items: [...plan.items, item], updatedAt: now },\n item,\n };\n}\n\nexport function removePlanItem(plan: PlanFile, idOrIndex: string): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n return {\n ...plan,\n items: plan.items.filter((_, i) => i !== idx),\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function setPlanItemStatus(\n plan: PlanFile,\n idOrIndex: string,\n status: PlanItem['status'],\n): PlanFile {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return plan;\n const now = new Date().toISOString();\n const items = plan.items.map((it, i) =>\n i === idx ? { ...it, status, updatedAt: now } : it,\n );\n return { ...plan, items, updatedAt: now };\n}\n\nexport function clearPlan(plan: PlanFile): PlanFile {\n return { ...plan, items: [], updatedAt: new Date().toISOString() };\n}\n\n/** Render the plan as a short markdown-ish string suitable for slash output. */\nexport function formatPlan(plan: PlanFile): string {\n if (plan.items.length === 0) return 'Plan is empty.';\n const lines: string[] = [];\n if (plan.title) lines.push(`# ${plan.title}`);\n plan.items.forEach((it, i) => {\n const mark = it.status === 'done' ? '[x]' : it.status === 'in_progress' ? '[~]' : '[ ]';\n lines.push(`${i + 1}. ${mark} ${it.title}`);\n if (it.details) {\n for (const line of it.details.split('\\n')) lines.push(` ${line}`);\n }\n });\n return lines.join('\\n');\n}\n\nfunction matchIndex(plan: PlanFile, idOrIndex: string): number {\n const asNum = Number.parseInt(idOrIndex, 10);\n if (!Number.isNaN(asNum) && asNum >= 1 && asNum <= plan.items.length) return asNum - 1;\n const byId = plan.items.findIndex((it) => it.id === idOrIndex);\n if (byId !== -1) return byId;\n const lower = idOrIndex.toLowerCase();\n return plan.items.findIndex((it) => it.title.toLowerCase().includes(lower));\n}\n\n/**\n * Promote a plan item to a set of todo items.\n * The plan item is marked 'in_progress' (if not already done) and its\n * title + details become the first todo; additional subtasks are appended.\n * Returns the derived todo list so the caller can pass it to `todoTool`\n * or `ctx.state.replaceTodos()`.\n */\nexport function deriveTodosFromPlanItem(\n plan: PlanFile,\n idOrIndex: string,\n subtasks?: string[] | undefined,\n): { plan: PlanFile; todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> } | null {\n const idx = matchIndex(plan, idOrIndex);\n if (idx === -1) return null;\n\n const item = plan.items[idx];\n /* v8 ignore next -- defensive: matchIndex returns a valid in-range index or -1 (handled above) */\n if (!item) return null;\n\n // Mark the plan item in_progress if it wasn't already done\n let updatedPlan = plan;\n if (item.status !== 'done') {\n updatedPlan = setPlanItemStatus(plan, idOrIndex, 'in_progress');\n }\n\n const todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string | undefined; promotedFromPlan?: string | undefined }> = [];\n\n // First todo from the plan item itself\n todos.push({\n id: `todo_${Date.now()}_plan`,\n content: item.title,\n status: 'in_progress',\n activeForm: item.title,\n promotedFromPlan: item.id,\n });\n\n // Optional subtasks\n if (subtasks && subtasks.length > 0) {\n for (const st of subtasks) {\n todos.push({\n id: `todo_${Date.now()}_${randomUUID().slice(0, 6)}`,\n content: st,\n status: 'pending',\n promotedFromPlan: item.id,\n });\n }\n }\n\n return { plan: updatedPlan, todos };\n}\n\n/**\n * Load, modify, and save the plan file under a file-level lock.\n * Prevents races from parallel tool invocations (e.g. batch_tool_use).\n */\nexport async function mutatePlan(\n filePath: string,\n sessionId: string,\n fn: (plan: PlanFile) => PlanFile | Promise<PlanFile>,\n): Promise<PlanFile> {\n return withFileLock(filePath, async () => {\n const plan = (await loadPlan(filePath)) ?? emptyPlan(sessionId);\n const updated = await fn(plan);\n const persisted = await savePlan(filePath, updated);\n if (!persisted) {\n throw new Error(`Failed to persist plan to ${filePath} — the change was NOT saved.`);\n }\n return updated;\n });\n}\n\n/**\n * Optional: attach a state-listener so meta operations (storing a plan\n * id on ctx.meta) trigger a save. Currently a stub — plans don't live\n * on Context, but this keeps the API surface symmetric with the todos\n * checkpoint so future refactors can flip plans into Context if needed.\n */\nexport function attachPlanCheckpoint(\n _state: ConversationState,\n _filePath: string,\n _sessionId: string,\n): () => void {\n return () => undefined;\n}\n","/**\n * Plan templates — pre-defined plan skeletons for common workflows.\n *\n * Templates are stored in-memory (no disk I/O). Users instantiate them\n * via `/plan template use <name>` or `planTool(action: 'template_use')`.\n * Each template is a function that returns an array of item titles, so\n * dynamic content (dates, project names) can be injected later.\n */\n\nexport interface PlanTemplate {\n name: string;\n description: string;\n category: 'development' | 'release' | 'maintenance' | 'infrastructure';\n items: Array<{\n title: string;\n details?: string | undefined;\n }>;\n}\n\nconst templates: Record<string, PlanTemplate> = {\n 'new-feature': {\n name: 'new-feature',\n description: 'Standard workflow for adding a new feature',\n category: 'development',\n items: [\n { title: 'Write specification / design doc', details: 'Define scope, acceptance criteria, edge cases' },\n { title: 'Set up feature branch', details: 'git checkout -b feature/...' },\n { title: 'Implement core logic', details: 'TDD preferred — write tests first' },\n { title: 'Add unit tests', details: '>= 80% coverage for new code' },\n { title: 'Add integration tests', details: 'End-to-end happy path + error paths' },\n { title: 'Update documentation', details: 'README, API docs, changelog' },\n { title: 'Code review', details: 'Self-review before requesting review' },\n { title: 'Merge and deploy', details: 'CI green, tag release' },\n ],\n },\n 'bug-fix': {\n name: 'bug-fix',\n description: 'Systematic approach to fixing bugs',\n category: 'maintenance',\n items: [\n { title: 'Reproduce the bug', details: 'Minimal reproduction case' },\n { title: 'Root cause analysis', details: 'Trace through logs, debugger' },\n { title: 'Write failing test', details: 'Test must fail before fix' },\n { title: 'Implement fix', details: 'Smallest possible change' },\n { title: 'Verify fix', details: 'Test passes, reproduction no longer fails' },\n { title: 'Regression test', details: 'Ensure no related tests broken' },\n { title: 'Document in changelog', details: 'Brief description + issue link' },\n ],\n },\n 'refactor': {\n name: 'refactor',\n description: 'Safe refactoring workflow',\n category: 'maintenance',\n items: [\n { title: 'Identify refactoring target', details: 'Code smell, performance bottleneck, or tech debt' },\n { title: 'Ensure test coverage', details: 'Existing tests must pass before and after' },\n { title: 'Write characterization tests', details: 'Capture current behavior if tests weak' },\n { title: 'Apply refactoring', details: 'Small steps, frequent commits' },\n { title: 'Run full test suite', details: 'All tests must pass' },\n { title: 'Performance check', details: 'Ensure no regression' },\n { title: 'Code review', details: 'Explain the why, not just the what' },\n ],\n },\n 'release': {\n name: 'release',\n description: 'Preparing a new release',\n category: 'release',\n items: [\n { title: 'Version bump', details: 'package.json, lockfiles, tags' },\n { title: 'Update changelog', details: 'All changes since last release' },\n { title: 'Run full test suite', details: 'Unit + integration + e2e' },\n { title: 'Build artifacts', details: 'Docker images, bundles, binaries' },\n { title: 'Staging smoke tests', details: 'Deploy to staging, verify' },\n { title: 'Production deploy', details: 'Blue-green or canary' },\n { title: 'Post-deploy verification', details: 'Health checks, error rates' },\n { title: 'Announce release', details: 'Slack, email, GitHub release notes' },\n ],\n },\n 'security-audit': {\n name: 'security-audit',\n description: 'Security review and hardening',\n category: 'infrastructure',\n items: [\n { title: 'Dependency audit', details: 'npm audit, Snyk, Dependabot alerts' },\n { title: 'Secret scan', details: 'git-secrets, truffleHog, manual review' },\n { title: 'Access control review', details: 'IAM, roles, least privilege' },\n { title: 'Input validation audit', details: 'SQL injection, XSS, path traversal' },\n { title: 'Authentication review', details: 'Session management, MFA, password policy' },\n { title: 'Logging and monitoring', details: 'PII in logs, audit trails' },\n { title: 'Incident response plan', details: 'Runbooks, contacts, escalation' },\n ],\n },\n 'onboarding': {\n name: 'onboarding',\n description: 'New developer onboarding checklist',\n category: 'infrastructure',\n items: [\n { title: 'Repository access', details: 'GitHub/GitLab permissions' },\n { title: 'Local environment setup', details: 'Docker, dependencies, env files' },\n { title: 'Run tests locally', details: 'Verify green suite' },\n { title: 'Read architecture docs', details: 'ADR, README, onboarding guide' },\n { title: 'First commit', details: 'Docs fix or small improvement' },\n { title: 'Pair programming session', details: 'Walk through codebase with buddy' },\n { title: 'Deploy to staging', details: 'Verify CI/CD access' },\n ],\n },\n};\n\nexport function listPlanTemplates(): PlanTemplate[] {\n return Object.values(templates);\n}\n\nexport function getPlanTemplate(name: string): PlanTemplate | undefined {\n return templates[name];\n}\n\nexport function formatPlanTemplates(): string {\n const cats = new Map<PlanTemplate['category'], PlanTemplate[]>();\n for (const t of Object.values(templates)) {\n const arr = cats.get(t.category) ?? [];\n arr.push(t);\n cats.set(t.category, arr);\n }\n\n const lines: string[] = ['Available plan templates:'];\n for (const [cat, items] of cats) {\n lines.push(`\\n${cat}:`);\n for (const t of items) {\n lines.push(` ${t.name.padEnd(18)} — ${t.description}`);\n }\n }\n return lines.join('\\n');\n}\n","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport type { TaskItem } from '../utils/task-format.js';\n\n// ---------------------------------------------------------------------------\n// Task file persistence — one JSON file per session in\n// `<projectSessions>/<sessionId>.tasks.json`.\n//\n// Low-level load/save are exported for read-only consumers. Mutating callers\n// should use `mutateTasks` which wraps the entire read-modify-write cycle\n// under a file-level lock, preventing races from parallel tool invocations.\n// ---------------------------------------------------------------------------\n\nexport interface TaskFile {\n version: 1;\n sessionId: string;\n updatedAt: string;\n tasks: TaskItem[];\n}\n\nexport function emptyTaskFile(sessionId: string): TaskFile {\n return {\n version: 1,\n sessionId,\n updatedAt: new Date().toISOString(),\n tasks: [],\n };\n}\n\n/** Read the task file. Returns null when the file doesn't exist. */\nexport async function loadTasks(\n filePath: string,\n events?: EventBus,\n traceId?: string,\n): Promise<TaskFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: true,\n });\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as TaskFile;\n if (parsed?.version !== 1 || !Array.isArray(parsed.tasks)) {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return parsed;\n } catch {\n events?.emit('storage.read', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n ...(traceId !== undefined && { traceId }),\n });\n return null;\n }\n}\n\n/**\n * Write the task file atomically. Prefer `mutateTasks` for read-modify-write\n * cycles — this low-level function does NOT acquire a lock.\n */\n/**\n * Persist the task file. Returns `true` on success, `false` if the write\n * failed (still emits `storage.error` + warns — does NOT throw). `mutateTasks`\n * inspects the result and throws so the task TOOL can report `ok:false`\n * instead of falsely claiming the tasks were saved.\n */\nexport async function saveTasks(\n filePath: string,\n tasks: TaskFile,\n events?: EventBus,\n traceId?: string,\n): Promise<boolean> {\n const t0 = Date.now();\n try {\n tasks.updatedAt = new Date().toISOString();\n await atomicWrite(filePath, JSON.stringify(tasks, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n ...(traceId !== undefined && { traceId }),\n });\n return true;\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: traceId ?? '~boot~',\n store: 'tasks',\n filePath,\n operation: 'save',\n outcome: 'failure',\n error: toErrorMessage(err),\n recoverable: false,\n ...(traceId !== undefined && { traceId }),\n });\n console.warn(\n '[task-store] save failed:',\n toErrorMessage(err),\n );\n return false;\n }\n}\n\n/**\n * Load, modify, and save the task file under a file-level lock.\n * `fn` receives the current TaskFile (or a fresh empty one) and must\n * return the mutated TaskFile (mutating in-place is fine — the returned\n * reference is what gets saved).\n *\n * This is the primary API for any code path that reads *and then writes*\n * the task file — it prevents races from parallel `batch_tool_use` calls.\n */\nexport async function mutateTasks(\n filePath: string,\n sessionId: string,\n fn: (file: TaskFile) => TaskFile | Promise<TaskFile>,\n events?: EventBus,\n traceId?: string,\n): Promise<TaskFile> {\n return withFileLock(filePath, async () => {\n const file = (await loadTasks(filePath, events, traceId)) ?? emptyTaskFile(sessionId);\n const updated = await fn(file);\n const persisted = await saveTasks(filePath, updated, events, traceId);\n if (!persisted) {\n throw new Error(`Failed to persist tasks to ${filePath} — the change was NOT saved.`);\n }\n return updated;\n });\n}\n","import * as fsp from 'node:fs/promises';\nimport { hostname } from 'node:os';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Director state checkpoint — written incrementally throughout a fleet\n * run so a crashed director can be inspected (and eventually resumed)\n * instead of leaving only a final `fleet.json` manifest after `shutdown()`.\n *\n * Schema is JSON-friendly and deliberately denormalized. Each mutation\n * triggers an atomic-write of the whole file — small payloads (typically\n * < 10 KB even with dozens of subagents) make this cheap.\n */\nexport interface DirectorSubagentState {\n id: string;\n name?: string | undefined;\n role?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n spawnedAt: string;\n}\n\nexport interface DirectorTaskState {\n taskId: string;\n subagentId?: string | undefined;\n description?: string | undefined;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'stopped' | 'timeout';\n assignedAt?: string | undefined;\n completedAt?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n durationMs?: number | undefined;\n error?: string | undefined;\n}\n\nexport interface DirectorStateSnapshot {\n version: 1;\n directorRunId: string;\n updatedAt: string;\n spawnCount: number;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n subagents: DirectorSubagentState[];\n tasks: DirectorTaskState[];\n /** Aggregated usage snapshot. Optional — populated by the Director on save when available. */\n usage?: unknown | undefined;\n}\n\nexport async function loadDirectorState(filePath: string): Promise<DirectorStateSnapshot | null> {\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n try {\n const parsed = JSON.parse(raw) as DirectorStateSnapshot;\n if (parsed?.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Lock file entry written when a director starts. Prevents two directors\n * from resuming the same run — the second one sees the lock and refuses\n * rather than corrupting the checkpoint by writing concurrently.\n */\nexport interface DirectorStateLock {\n pid: number;\n hostname: string;\n startedAt: string;\n}\n\n/**\n * Write a lock file to claim this checkpoint. Returns false if the lock\n * is already held by a live process; returns true if the lock was acquired\n * (either the file didn't exist, or the previous holder is dead).\n */\nexport async function acquireDirectorStateLock(\n lockPath: string,\n processId = process.pid,\n): Promise<boolean> {\n let existing: string | undefined;\n try {\n existing = await fsp.readFile(lockPath, 'utf8');\n } catch {\n // No lock file — we're safe to claim\n }\n\n if (existing) {\n try {\n const lock = JSON.parse(existing) as DirectorStateLock;\n // Check if the process is still alive\n try {\n process.kill(lock.pid, 0);\n // Signal success means the process is alive — another director\n // owns this checkpoint. Refuse.\n return false;\n } catch {\n // ESRCH means the process is dead — stale lock. We'll overwrite.\n }\n } catch {\n // Malformed lock — treat as stale.\n }\n }\n\n const lock: DirectorStateLock = {\n pid: processId,\n hostname: hostname(),\n startedAt: new Date().toISOString(),\n };\n await atomicWrite(lockPath, JSON.stringify(lock), { mode: 0o600 });\n return true;\n}\n\n/**\n * Remove the lock file. Call this on graceful Director.shutdown() so the\n * next director run can claim the checkpoint without stale-lock checks.\n */\nexport async function releaseDirectorStateLock(lockPath: string): Promise<void> {\n try {\n await fsp.unlink(lockPath);\n } catch {\n // ignore\n }\n}\n\n/**\n * In-memory accumulator with atomic-write checkpoint. The Director keeps\n * an instance, mutates it on every spawn/assign/complete/fail event, and\n * the instance debounces writes so a burst of activity collapses into a\n * single disk hit.\n *\n * Supports crash recovery: use `loadDirectorState()` to read an existing\n * checkpoint, then call `DirectorStateCheckpoint.resume(snapshot)` to\n * re-attach to a fleet mid-flight. The lock mechanism ensures no two\n * directors can claim the same checkpoint.\n */\nexport class DirectorStateCheckpoint {\n private snapshot: DirectorStateSnapshot;\n private readonly filePath: string;\n private readonly lockPath: string;\n private timer: NodeJS.Timeout | null = null;\n private readonly debounceMs: number;\n private writing = false;\n private rewriteRequested = false;\n\n constructor(\n filePath: string,\n init: {\n directorRunId: string;\n maxSpawns?: number | undefined;\n spawnDepth: number;\n maxSpawnDepth: number;\n directorBudget?: {\n maxCostUsd?: number | undefined;\n } | undefined;\n },\n debounceMs = 250,\n ) {\n this.filePath = filePath;\n // Lock file lives alongside the checkpoint — `<path>.lock`\n this.lockPath = `${filePath}.lock`;\n this.debounceMs = debounceMs;\n this.snapshot = {\n version: 1,\n directorRunId: init.directorRunId,\n updatedAt: new Date().toISOString(),\n spawnCount: 0,\n maxSpawns: init.maxSpawns,\n spawnDepth: init.spawnDepth,\n maxSpawnDepth: init.maxSpawnDepth,\n directorBudget: init.directorBudget,\n subagents: [],\n tasks: [],\n };\n }\n\n /**\n * Attempt to acquire the lock for this checkpoint. Call this before\n * resuming a crashed director run. If it returns false, another\n * director process is still running this fleet — do not resume.\n */\n async acquireLock(): Promise<boolean> {\n return acquireDirectorStateLock(this.lockPath);\n }\n\n /**\n * Release the lock on graceful shutdown. Call `flush()` first to ensure\n * the final checkpoint state is on disk before removing the lock.\n * Without this, the next resume will see a stale-lock and refuse.\n */\n async releaseLock(): Promise<void> {\n return releaseDirectorStateLock(this.lockPath);\n }\n\n /**\n * Resume from a snapshot previously loaded via `loadDirectorState()`.\n * Use this when `--resume <runId>` is triggered — the snapshot has\n * the full fleet state (subagents, tasks) from before the crash; the\n * checkpoint continues from there.\n */\n resume(snapshot: DirectorStateSnapshot): void {\n this.snapshot = snapshot;\n }\n\n current(): DirectorStateSnapshot {\n return this.snapshot;\n }\n\n recordSpawn(sub: DirectorSubagentState, spawnCount: number): void {\n this.snapshot = {\n ...this.snapshot,\n spawnCount,\n subagents: [...this.snapshot.subagents.filter((s) => s.id !== sub.id), sub],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskAssigned(task: DirectorTaskState): void {\n const exists = this.snapshot.tasks.some((t) => t.taskId === task.taskId);\n this.snapshot = {\n ...this.snapshot,\n tasks: exists\n ? this.snapshot.tasks.map((t) => (t.taskId === task.taskId ? { ...t, ...task } : t))\n : [...this.snapshot.tasks, task],\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n recordTaskStatus(\n taskId: string,\n patch: Partial<DirectorTaskState> & { status: DirectorTaskState['status'] },\n ): void {\n this.snapshot = {\n ...this.snapshot,\n tasks: this.snapshot.tasks.map((t) =>\n t.taskId === taskId ? { ...t, ...patch } : t,\n ),\n };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n setUsage(usage: unknown): void {\n this.snapshot = { ...this.snapshot, usage };\n this.bumpUpdatedAt();\n this.schedule();\n }\n\n /** Force a synchronous flush — used by Director.shutdown(). */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n await this.persist();\n // If a rewrite was requested while we waited, persist() scheduled\n // a follow-up write. Loop until no more rewrites are requested so\n // shutdown doesn't return before the most recent state lands on disk.\n /* v8 ignore start -- concurrency-defensive: persist()'s finally clears the flag in single-threaded flow */\n while (this.rewriteRequested) {\n this.rewriteRequested = false;\n await this.persist();\n }\n /* v8 ignore stop */\n }\n\n private bumpUpdatedAt(): void {\n this.snapshot = { ...this.snapshot, updatedAt: new Date().toISOString() };\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.persist();\n }, this.debounceMs);\n }\n\n private async persist(): Promise<void> {\n if (this.writing) {\n // A write is already in flight — defer to a follow-up flush so the\n // most recent state still lands. Without this guard, simultaneous\n // burst mutations can drop the latest snapshot if rename races.\n this.rewriteRequested = true;\n return;\n }\n this.writing = true;\n try {\n await atomicWrite(this.filePath, JSON.stringify(this.snapshot, null, 2), {\n mode: 0o600,\n });\n } catch (err) {\n console.warn(\n '[director-state] checkpoint write failed:',\n toErrorMessage(err),\n );\n } finally {\n this.writing = false;\n /* v8 ignore start -- concurrency-defensive: rewriteRequested is only set by an overlapping persist() */\n if (this.rewriteRequested) {\n this.rewriteRequested = false;\n this.schedule();\n }\n /* v8 ignore stop */\n }\n }\n}\n","import * as fsp from 'node:fs/promises';\nimport type { EventBus } from '../kernel/events.js';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { color } from '../utils/color.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport { FsError, ERROR_CODES } from '../types/errors.js';\n\n/**\n * Long-running autonomous mission. A goal survives across sessions and\n * drives the EternalAutonomyEngine — every iteration of the engine\n * consults the goal to choose what to do next.\n *\n * Storage: `~/.wrongstack/projects/<hash>/goal.json`. Persistent and\n * project-scoped on purpose: the goal belongs to the codebase, not the\n * REPL session.\n */\n\nexport interface JournalEntry {\n /** ISO timestamp of the iteration. */\n at: string;\n /** Sequential iteration counter (1-based, monotonically increasing). */\n iteration: number;\n /** Source that produced the action ('todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel'). */\n source: 'todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel';\n /** Short one-line description of what the iteration set out to do. */\n task: string;\n /** Outcome status. */\n status: 'success' | 'failure' | 'aborted' | 'skipped';\n /** Optional free-form note (error message, summary, etc.). */\n note?: string | undefined;\n /** Optional token usage delta for this iteration. */\n tokens?: { input: number; output: number } | undefined;\n /** Optional USD cost delta for this iteration (provider-estimated). */\n costUsd?: number | undefined;\n}\n\nexport interface GoalFile {\n version: 1;\n /** The raw mission statement as entered by the user. */\n goal: string;\n /**\n * LLM-refined version of the goal — unambiguous, with concrete\n * deliverables and acceptance criteria.\n */\n refinedGoal?: string | undefined;\n /**\n * Concrete, verifiable deliverables extracted from the refined goal.\n */\n deliverables?: string[] | undefined;\n /**\n * Estimated completion 0-100. Updated by the engine after each\n * iteration. Null means \"not yet assessed\".\n */\n progress?: number | undefined;\n /** Human-readable note explaining the current progress estimate. */\n progressNote?: string | undefined;\n /**\n * Time-series of progress measurements for trend analysis.\n * Last 200 entries retained. Use `recordProgress()` to append.\n */\n progressHistory?: ProgressSnapshot[] | undefined;\n /**\n * Computed trend from recent progress measurements.\n * 'accelerating' | 'steady' | 'stalling' | undefined.\n */\n progressTrend?: 'accelerating' | 'steady' | 'stalling' | undefined;\n /** When the goal was first set or last replaced. */\n setAt: string;\n /** Updated on every iteration completion. */\n lastActivityAt: string;\n /** Total iterations the engine has run against this goal (cumulative). */\n iterations: number;\n /** Engine lifecycle state — 'running' means another process owns this goal. */\n engineState: 'idle' | 'running' | 'stopped';\n /**\n * Mission-level lifecycle.\n */\n goalState?: 'active' | 'paused' | 'completed' | 'abandoned' | undefined;\n /**\n * Per-todo attempt counter.\n */\n todoAttempts?: Record<string, number>;\n /** Bounded ring buffer of recent iterations (newest last). */\n journal: JournalEntry[];\n}\n\n/** Cap on persisted journal entries — older entries are evicted FIFO. */\nexport const MAX_JOURNAL_ENTRIES = 500;\n\n/**\n * Resolve the goal file path for a given project root.\n *\n * SINGLE canonical location: the per-project directory that\n * `resolveWstackPaths()` uses for everything else (sessions, memory, specs) —\n * `~/.wrongstack/projects/<slug>/goal.json`. This is the same path the `/goal`\n * slash command writes via `opts.paths.projectGoal`, so every reader/writer\n * (the eternal/parallel autonomy engines, the CLI autonomy commands, the TUI\n * F9 panel, and `/goal` itself) now agree on one file.\n *\n * Previously this returned a SEPARATE hash-based dir (`projects/<hash>/`), which\n * disagreed with `/goal` and littered the home dir with thousands of stray\n * `<hash>/goal.json` directories that held nothing else.\n */\nexport function goalFilePath(projectRoot: string): string {\n return resolveWstackPaths({ projectRoot }).projectGoal;\n}\n\nexport async function loadGoal(filePath: string, events?: EventBus): Promise<GoalFile | null> {\n const t0 = Date.now();\n let raw: string;\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return null; // file doesn't exist — not an error\n }\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n error: toErrorMessage(err),\n recoverable: false,\n });\n throw err; // permission errors etc. should surface\n }\n try {\n const parsed = JSON.parse(raw) as GoalFile;\n if (parsed?.version !== 1 || typeof parsed.goal !== 'string' || !Array.isArray(parsed.journal)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.invalid_schema',\n path: filePath,\n message: 'invalid schema — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'invalid_schema',\n });\n return null;\n }\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n return parsed;\n } catch {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'goal_store.parse_failed',\n path: filePath,\n message: 'JSON parse failed — consider deleting and re-creating',\n timestamp: new Date().toISOString(),\n }));\n events?.emit('storage.read', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'load',\n outcome: 'failure',\n durationMs: Date.now() - t0,\n error: 'parse_failed',\n });\n return null;\n }\n}\n\nexport async function saveGoal(filePath: string, goal: GoalFile, events?: EventBus): Promise<void> {\n const t0 = Date.now();\n try {\n await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 0o600 });\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'save',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'save',\n error: toErrorMessage(err),\n recoverable: false,\n });\n throw new FsError({\n message: toErrorMessage(err),\n code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,\n path: filePath,\n cause: err,\n });\n }\n}\n\n/**\n * Atomically load, modify, and save a goal file under a file lock.\n * Prevents lost-update races when the autonomy engine and CLI /goal commands\n * write concurrently (both eternal and parallel engines may run simultaneously).\n *\n * `fn` receives the current GoalFile (or `null` if no goal exists yet)\n * and must return the updated GoalFile (or `null` to delete).\n */\nexport async function updateGoal(\n filePath: string,\n fn: (current: GoalFile | null) => GoalFile | null,\n events?: EventBus,\n): Promise<void> {\n const t0 = Date.now();\n await withFileLock(filePath, async () => {\n const current = await loadGoal(filePath, events);\n const next = fn(current);\n if (next) {\n await saveGoal(filePath, next, events);\n } else {\n try {\n await fsp.unlink(filePath);\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'delete',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n } catch (err) {\n events?.emit('storage.error', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'delete',\n error: toErrorMessage(err),\n recoverable: true,\n });\n // best-effort — file may not exist\n }\n }\n events?.emit('storage.write', {\n sessionId: '~boot~',\n store: 'goal',\n filePath,\n operation: 'update',\n outcome: 'success',\n durationMs: Date.now() - t0,\n });\n });\n}\n\nexport function emptyGoal(goal: string): GoalFile {\n const now = new Date().toISOString();\n return {\n version: 1,\n goal,\n setAt: now,\n lastActivityAt: now,\n iterations: 0,\n engineState: 'idle',\n goalState: 'active',\n todoAttempts: {},\n journal: [],\n };\n}\n\n/**\n * Set progress estimate on a goal. Returns a new GoalFile.\n * Clamps progress to 0-100.\n */\nexport function setProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? clamped + '% complete',\n };\n}\n\n/**\n * Append a journal entry, bumping iteration counters and trimming the\n * ring buffer. Returns a new GoalFile — does not mutate the argument.\n */\nexport function appendJournal(goal: GoalFile, entry: Omit<JournalEntry, 'iteration' | 'at'>): GoalFile {\n const iteration = goal.iterations + 1;\n const at = new Date().toISOString();\n const full: JournalEntry = { ...entry, iteration, at };\n const journal = [...goal.journal, full];\n const trimmed = journal.length > MAX_JOURNAL_ENTRIES\n ? journal.slice(journal.length - MAX_JOURNAL_ENTRIES)\n : journal;\n return {\n ...goal,\n iterations: iteration,\n lastActivityAt: at,\n journal: trimmed,\n };\n}\n\n/**\n * Aggregate cumulative cost + tokens across all journal entries.\n */\nexport function summarizeUsage(goal: GoalFile): {\n totalCostUsd: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n iterationsWithUsage: number;\n} {\n let totalCostUsd = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let iterationsWithUsage = 0;\n for (const e of goal.journal) {\n if (typeof e.costUsd === 'number') totalCostUsd += e.costUsd;\n if (e.tokens) {\n totalInputTokens += e.tokens.input;\n totalOutputTokens += e.tokens.output;\n }\n if (typeof e.costUsd === 'number' || e.tokens) iterationsWithUsage++;\n }\n return { totalCostUsd, totalInputTokens, totalOutputTokens, iterationsWithUsage };\n}\n\nconst DOLLAR = '\\u0024';\n\n/** Format the goal + recent journal as a human-readable status block. */\nexport function formatGoal(goal: GoalFile, journalLimit = 10): string {\n const lines: string[] = [];\n\n // Header — show refined goal, with original as annotation if different\n const displayGoal = goal.refinedGoal || goal.goal;\n lines.push(color.bold('Goal') + ': ' + displayGoal);\n if (goal.refinedGoal && goal.refinedGoal !== goal.goal) {\n const snippet = goal.goal.length > 60 ? goal.goal.slice(0, 60) + '…' : goal.goal;\n lines.push(color.dim(' (original: \"' + snippet + '\")'));\n }\n\n // Progress bar (20-segment)\n if (typeof goal.progress === 'number') {\n const pct = Math.min(100, Math.max(0, Math.round(goal.progress)));\n const filled = Math.round(pct / 5);\n const empty = 20 - filled;\n const bar = color.green('█'.repeat(filled)) + color.dim('░'.repeat(empty));\n lines.push('Progress: ' + bar + ' ' + color.bold(pct + '%'));\n if (goal.progressNote) {\n lines.push(' ' + color.dim(goal.progressNote));\n }\n // Trend indicator\n if (goal.progressTrend) {\n const trendIcon = goal.progressTrend === 'accelerating' ? '🚀'\n : goal.progressTrend === 'stalling' ? '⚠️'\n : '➡️';\n lines.push(' Trend: ' + trendIcon + ' ' + goal.progressTrend);\n }\n }\n\n // Deliverables checklist\n if (goal.deliverables && goal.deliverables.length > 0) {\n lines.push('');\n lines.push(color.bold('Deliverables:'));\n for (const d of goal.deliverables) {\n const done = /^\\[[x✓]\\]|✅|\\(done\\)/i.test(d);\n const marker = done ? color.green('✓') : color.dim('○');\n lines.push(' ' + marker + ' ' + d);\n }\n }\n\n lines.push('');\n lines.push('Set: ' + goal.setAt);\n lines.push('Last activity: ' + goal.lastActivityAt);\n lines.push('Iterations: ' + goal.iterations);\n const stateLabel = goal.goalState ?? 'active';\n lines.push('State: ' + stateLabel + (goal.iterations > 0 ? ' (iteration #' + goal.iterations + ')' : ''));\n lines.push('Engine: ' + goal.engineState);\n const usage = summarizeUsage(goal);\n if (usage.iterationsWithUsage > 0) {\n const spent = 'Spent: ' + DOLLAR + usage.totalCostUsd.toFixed(4)\n + ' (in ' + usage.totalInputTokens + ' / out ' + usage.totalOutputTokens\n + ' tokens across ' + usage.iterationsWithUsage + ' iterations)';\n lines.push(spent);\n }\n if (goal.journal.length > 0) {\n lines.push('');\n lines.push('Recent journal (last ' + Math.min(journalLimit, goal.journal.length) + '):');\n const tail = goal.journal.slice(-journalLimit);\n for (const e of tail) {\n const mark = e.status === 'success' ? '✓' : e.status === 'failure' ? '✗' : e.status === 'aborted' ? '⊘' : '·';\n const note = e.note ? ' — ' + e.note : '';\n const cost = typeof e.costUsd === 'number' ? ' (' + DOLLAR + e.costUsd.toFixed(4) + ')' : '';\n lines.push(' #' + e.iteration + ' ' + mark + ' [' + e.source + '] ' + e.task + cost + note);\n }\n }\n return lines.join('\\n');\n}\n\n/** A single progress measurement at a point in time. */\nexport interface ProgressSnapshot {\n at: string;\n progress: number;\n note?: string | undefined;\n}\n\n/**\n * Parse [PROGRESS: N%] from agent final text.\n * Supports formats:\n * [PROGRESS: 45%]\n * [PROGRESS: 45%] — 3/5 deliverables done\n * [progress: 100%]\n * Returns null if no match.\n */\nexport function parseProgressFromText(text: string): { progress: number; note?: string } | null {\n const re = /\\[progress:\\s*(\\d{1,3})%\\]\\s*(?:[—-]\\s*(.+))?/i;\n const m = text.match(re);\n if (!m) return null;\n // Regex match guarantees capture group 1 exists, but use ?? fallback to\n // satisfy noUncheckedIndexedAccess without a non-null assertion.\n const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? '0', 10)));\n const note = m[2]?.trim() || undefined;\n return note === undefined ? { progress } : { progress, note };\n}\n\n/**\n * Record a progress measurement. Returns a new GoalFile with:\n * - progress + progressNote updated\n * - progressHistory appended (last 200 entries kept)\n * - progress trend computed (accelerating/steady/stalling)\n */\nexport function recordProgress(\n goal: GoalFile,\n progress: number,\n note?: string,\n): GoalFile {\n const clamped = Math.min(100, Math.max(0, progress));\n const history = [...(goal.progressHistory ?? []), { at: new Date().toISOString(), progress: clamped, note }];\n // Keep last 200 snapshots\n const trimmed = history.length > 200 ? history.slice(-200) : history;\n\n return {\n ...goal,\n progress: clamped,\n progressNote: note ?? `${clamped}% complete`,\n progressHistory: trimmed,\n progressTrend: computeTrend(trimmed),\n };\n}\n\n/** Max progress history entries to retain. */\nexport const MAX_PROGRESS_HISTORY = 200;\n\nfunction computeTrend(history: ProgressSnapshot[]): 'accelerating' | 'steady' | 'stalling' | undefined {\n if (history.length < 3) return undefined;\n const recent = history.slice(-5);\n const deltas: number[] = [];\n for (let i = 1; i < recent.length; i++) {\n deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));\n }\n /* v8 ignore next -- unreachable: history.length>=3 guard above guarantees >=2 deltas */\n if (deltas.length < 2) return undefined;\n const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n if (avgDelta > 2) return 'accelerating';\n if (avgDelta < -1) return 'stalling';\n return 'steady';\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, ensureDir } from '../utils/atomic-write.js';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\n\nexport interface PromptEntry {\n id: string;\n title: string;\n content: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PromptStore {\n list(): Promise<PromptEntry[]>;\n get(id: string): Promise<PromptEntry | null>;\n save(entry: PromptEntry): Promise<void>;\n delete(id: string): Promise<boolean>;\n find(query: string): Promise<PromptEntry[]>;\n}\n\ninterface RawPromptFile {\n version: 1;\n entry: PromptEntry;\n}\n\nexport class DefaultPromptStore implements PromptStore {\n private readonly dir: string;\n\n constructor(paths: WstackPaths) {\n this.dir = paths.globalPrompts;\n }\n\n async list(): Promise<PromptEntry[]> {\n await ensureDir(this.dir);\n const entries: PromptEntry[] = [];\n try {\n const files = await fs.readdir(this.dir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const raw: RawPromptFile = JSON.parse(\n await fs.readFile(path.join(this.dir, file), 'utf8'),\n );\n entries.push(raw.entry);\n } catch {\n // skip corrupt files\n }\n }\n } catch {\n // dir doesn't exist yet\n }\n return entries.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n async get(id: string): Promise<PromptEntry | null> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n const raw: RawPromptFile = JSON.parse(await fs.readFile(file, 'utf8'));\n return raw.entry;\n } catch {\n return null;\n }\n }\n\n async save(entry: PromptEntry): Promise<void> {\n await ensureDir(this.dir);\n const file = path.join(this.dir, `${entry.id}.json`);\n const raw: RawPromptFile = { version: 1, entry };\n await atomicWrite(file, JSON.stringify(raw, null, 2));\n }\n\n async delete(id: string): Promise<boolean> {\n const file = path.join(this.dir, `${id}.json`);\n try {\n await fs.unlink(file);\n return true;\n } catch {\n return false;\n }\n }\n\n async find(query: string): Promise<PromptEntry[]> {\n const all = await this.list();\n const lower = query.toLowerCase();\n return all.filter(\n (e) =>\n e.title.toLowerCase().includes(lower) ||\n e.content.toLowerCase().includes(lower) ||\n e.tags.some((t) => t.toLowerCase().includes(lower)),\n );\n }\n\n /** Create a new entry and return it. Does NOT persist — call save() afterwards. */\n createNew(title: string, content: string, tags: string[] = []): PromptEntry {\n const now = new Date().toISOString();\n return {\n id: randomUUID().slice(0, 8),\n title,\n content,\n tags,\n createdAt: now,\n updatedAt: now,\n };\n }\n}","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { WstackPaths } from '../utils/wstack-paths.js';\nimport type { SyncCategory, SyncConfig } from '../types/config.js';\nimport { FsError, WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport const ALL_SYNC_CATEGORIES: SyncCategory[] = ['settings', 'skills', 'prompts', 'memory', 'history'];\n\nexport interface SyncResult {\n ok: boolean;\n action: 'push' | 'pull';\n categories: SyncCategory[];\n committedAt?: string | undefined;\n message: string;\n}\n\ninterface SyncStateFile {\n version: 1;\n sha: string;\n lastSyncedAt: string;\n localRev: string;\n}\n\n/**\n * CloudSync — push/pull user-selected ~/.wrongstack categories to a\n * private GitHub repo. No git CLI needed; uses GitHub REST API via fetch.\n * The token is stored encrypted via SecretVault (field named `githubToken`\n * so the vault walker picks it up automatically).\n */\nexport class CloudSync {\n private readonly statePath: string;\n private state: SyncStateFile | null = null;\n\n constructor(\n private readonly paths: WstackPaths,\n private readonly getConfig: () => SyncConfig | null,\n private readonly setConfig: (c: SyncConfig) => Promise<void>,\n ) {\n this.statePath = path.join(paths.globalRoot, 'sync-state.json');\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n async status(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) {\n return 'CloudSync: disabled. Run `/sync enable` to activate.';\n }\n const last = this.state?.lastSyncedAt;\n const since = last ? timeAgo(last) : 'never';\n return [\n `CloudSync: enabled`,\n ` repo: ${cfg.repo}`,\n ` categories: ${cfg.categories.join(', ')}`,\n ` last sync: ${since}`,\n ].join('\\n');\n }\n\n async enable(_repo: string, _categories: SyncCategory[]): Promise<string> {\n // Persisted by the slash command via configStore.update.\n return 'Enable via /sync enable.';\n }\n\n async disable(): Promise<string> {\n const cfg = this.getConfig();\n if (!cfg) return 'CloudSync is not configured.';\n const next = { ...cfg, enabled: false };\n await this.setConfig(next);\n return 'CloudSync disabled. Local data kept.';\n }\n\n async push(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'push', categories: [], message: 'Not enabled.' };\n\n const parts = cfg.repo.split('/');\n const owner = expectDefined(parts[0]);\n const repoName = expectDefined(parts[1]);\n const branch = 'main';\n const baseTreeSha = this.state?.sha;\n\n const { treeEntries, rev } = await this.buildLocalTree(cfg.categories);\n const newTreeSha = await this.createGitTree(token, owner, repoName, treeEntries, baseTreeSha);\n\n const commitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n baseTreeSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n\n try {\n await this.updateRef(token, owner, repoName, branch, commitSha);\n } catch (err) {\n // 422 = not a fast forward — remote branch moved. Fetch latest SHA and retry.\n if (err instanceof Error && err.message.includes('422')) {\n const remote = await this.getRef(token, owner, repoName, branch);\n const currentSha = remote.object.sha;\n const rebasedCommitSha = await this.createCommit(\n token, owner, repoName, newTreeSha,\n currentSha,\n `Sync ${cfg.categories.join(', ')} — ${new Date().toISOString()}`,\n );\n await this.updateRef(token, owner, repoName, branch, rebasedCommitSha);\n } else {\n throw err;\n }\n }\n\n const syncState: SyncStateFile = {\n version: 1,\n sha: commitSha,\n lastSyncedAt: new Date().toISOString(),\n localRev: rev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'push',\n categories: cfg.categories,\n committedAt: commitSha,\n message: `Pushed ${cfg.categories.join(', ')} to ${cfg.repo}. Commit: ${commitSha.slice(0, 7)}`,\n };\n }\n\n async pull(token: string): Promise<SyncResult> {\n const cfg = this.getConfig();\n if (!cfg?.enabled) return { ok: false, action: 'pull', categories: [], message: 'Not enabled.' };\n\n const pullParts = cfg.repo.split('/');\n const owner = expectDefined(pullParts[0]);\n const repoName = expectDefined(pullParts[1]);\n\n const branchData = await this.getRef(token, owner, repoName, 'main');\n const currentSha = branchData.object.sha;\n\n const commitData = await this.getCommit(token, owner, repoName, currentSha);\n const treeSha = commitData.tree.sha;\n\n const treeEntries = await this.getTreeEntries(token, owner, repoName, treeSha);\n\n for (const entry of treeEntries) {\n if (entry.type !== 'blob') continue;\n\n // Paths look like \"data/{category}/...\" — extract the category\n const segments = entry.path.split('/');\n if (segments[0] !== 'data' || !segments[1]) continue;\n const cat = segments[1] as SyncCategory;\n if (!['settings', 'skills', 'prompts', 'memory', 'history'].includes(cat)) continue;\n\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n\n // Reconstruct relative path under the category dir. Remote trees are\n // untrusted input: a compromised sync repo could contain paths like\n // data/skills/../../config.json. Keep every write inside the selected\n // category root, and only allow subpaths for directory-backed categories.\n const rel = segments.slice(2).join('/');\n const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);\n\n const blobData = await this.getBlob(token, owner, repoName, entry.sha);\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.writeFile(destPath, Buffer.from(blobData, 'base64'));\n }\n\n const localRev = await this.hashLocalCategories(cfg.categories);\n const syncState: SyncStateFile = {\n version: 1,\n sha: currentSha,\n lastSyncedAt: new Date().toISOString(),\n localRev,\n };\n await fs.writeFile(this.statePath, JSON.stringify(syncState, null, 2), 'utf8');\n this.state = syncState;\n\n return {\n ok: true,\n action: 'pull',\n categories: cfg.categories,\n committedAt: currentSha,\n message: `Pulled ${cfg.categories.join(', ')} from ${cfg.repo}. Commit: ${currentSha.slice(0, 7)}`,\n };\n }\n\n async hasLocalChanges(): Promise<boolean> {\n if (!this.state) return true;\n const cfg = this.getConfig();\n if (!cfg) return true;\n const current = await this.hashLocalCategories(cfg.categories);\n return current !== this.state.localRev;\n }\n\n async loadState(): Promise<void> {\n try {\n const raw = await fs.readFile(this.statePath, 'utf8');\n this.state = JSON.parse(raw) as SyncStateFile;\n } catch {\n this.state = null;\n }\n }\n\n // ── GitHub API helpers ──────────────────────────────────────────────\n\n private async githubFetch(\n token: string,\n owner: string,\n repo: string,\n method: 'GET' | 'POST' | 'PUT' | 'PATCH',\n pathSegment: string,\n body?: unknown | undefined,\n ): Promise<unknown> {\n const url = `https://api.github.com/repos/${owner}/${repo}${pathSegment}`;\n const init: RequestInit = {\n signal: AbortSignal.timeout(15_000),\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Content-Type': 'application/json',\n },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new WrongStackError({\n message: `GitHub API ${method} ${pathSegment} failed (${res.status}): ${errText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { method, pathSegment, status: res.status, repo: `${owner}/${repo}` },\n });\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : {};\n }\n\n private async getRef(token: string, owner: string, repo: string, ref: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/refs/heads/${ref}`)) as {\n object: { sha: string };\n };\n }\n\n private async updateRef(token: string, owner: string, repo: string, ref: string, sha: string) {\n await this.githubFetch(token, owner, repo, 'PATCH', `/git/refs/heads/${ref}`, {\n sha,\n force: false,\n });\n }\n\n private async getCommit(token: string, owner: string, repo: string, sha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/commits/${sha}`)) as {\n tree: { sha: string };\n message: string;\n };\n }\n\n private async getTreeEntries(token: string, owner: string, repo: string, treeSha: string) {\n return (await this.githubFetch(token, owner, repo, 'GET', `/git/trees/${treeSha}?recursive=1`)) as Array<{\n path: string;\n sha: string;\n type: 'blob' | 'tree';\n }>;\n }\n\n private async createCommit(\n token: string, owner: string, repo: string,\n treeSha: string, parentSha?: string | undefined, message = 'sync',\n ) {\n const body: Record<string, unknown> = { message, tree: treeSha };\n if (parentSha) body.parents = [parentSha];\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/commits', body)) as { sha: string };\n return result.sha;\n }\n\n private async createGitTree(\n token: string, owner: string, repo: string,\n entries: Array<{ path: string; content: string; mode: string }>,\n baseTreeSha?: string | undefined,\n ): Promise<string> {\n const tree = entries.map((e) => ({\n path: e.path,\n mode: e.mode,\n type: 'blob',\n content: e.content,\n }));\n const body: Record<string, unknown> = { tree };\n if (baseTreeSha) body.base_tree = baseTreeSha;\n const result = (await this.githubFetch(token, owner, repo, 'POST', '/git/trees', body)) as { sha: string };\n return result.sha;\n }\n\n private async getBlob(token: string, owner: string, repo: string, sha: string): Promise<string> {\n const result = (await this.githubFetch(token, owner, repo, 'GET', `/git/blobs/${sha}`)) as { content: string };\n return result.content;\n }\n\n // ── Local file helpers ──────────────────────────────────────────────\n\n private async buildLocalTree(categories: SyncCategory[]): Promise<{\n treeEntries: Array<{ path: string; content: string; mode: string }>;\n rev: string;\n }> {\n const entries: Array<{ path: string; content: string; mode: string }> = [];\n const hashes: string[] = [];\n\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file, 'utf8');\n const rel = path.relative(localPath, file).replace(/\\\\/g, '/');\n entries.push({ path: `data/${cat}/${rel}`, content, mode: '100644' });\n hashes.push(content);\n }\n } else {\n const content = await fs.readFile(localPath, 'utf8');\n entries.push({ path: `data/${cat}`, content, mode: '100644' });\n hashes.push(content);\n }\n } catch {\n // skip missing files/dirs\n }\n }\n\n const rev = createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n return { treeEntries: entries, rev };\n }\n\n private async hashLocalCategories(categories: SyncCategory[]): Promise<string> {\n const hashes: string[] = [];\n for (const cat of categories) {\n const localPath = this.categoryToPath(cat);\n if (!localPath) continue;\n try {\n const stat = await fs.stat(localPath);\n if (stat.isDirectory()) {\n const files = await this.walkDir(localPath, localPath);\n for (const file of files) {\n const content = await fs.readFile(file);\n hashes.push(content.toString('base64') + file);\n }\n } else {\n const content = await fs.readFile(localPath);\n hashes.push(content.toString('base64') + localPath);\n }\n } catch {\n // skip\n }\n }\n return createHash('sha256').update(hashes.join('')).digest('hex').slice(0, 12);\n }\n\n private categoryToPath(cat: SyncCategory): string | null {\n switch (cat) {\n case 'settings': return this.paths.globalConfig;\n case 'skills': return this.paths.globalSkills;\n case 'prompts': return this.paths.globalPrompts;\n case 'memory': return this.paths.globalMemory;\n case 'history': return this.paths.historyFile;\n /* v8 ignore next -- unreachable: SyncCategory is exhaustively matched above */\n default: return null;\n }\n }\n\n private async walkDir(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await this.walkDir(full, base)));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n\nfunction resolvePulledCategoryPath(\n cat: SyncCategory,\n localPath: string,\n rel: string,\n remotePath: string,\n): string {\n const directoryBacked = cat === 'skills' || cat === 'prompts';\n if (!directoryBacked) {\n if (rel) throw new FsError({\n message: `Refusing nested CloudSync path for file category: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'nested_file_category', category: cat },\n });\n return localPath;\n }\n\n if (!rel) return localPath;\n const normalizedRel = path.normalize(rel);\n const traversesUp = normalizedRel === '..' || normalizedRel.startsWith(`..${path.sep}`);\n if (path.isAbsolute(normalizedRel) || traversesUp) {\n throw new FsError({\n message: `Refusing CloudSync path traversal: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'path_traversal', normalizedRel },\n });\n }\n\n const dest = path.resolve(localPath, normalizedRel);\n const root = path.resolve(localPath);\n const relative = path.relative(root, dest);\n /* v8 ignore start -- unreachable: the normalizedRel '..' guard above already rejects traversal */\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new FsError({\n message: `Refusing CloudSync path outside category root: ${remotePath}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: remotePath,\n context: { reason: 'outside_category_root', category: cat },\n });\n }\n /* v8 ignore stop */\n return dest;\n}\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n","import type { SessionEvent, SessionWriter } from '../types/session.js';\n\nexport type AuditLevel = 'minimal' | 'standard' | 'full';\n\n/**\n * Configuration for sampling high-volume events inside the bridge.\n * This allows callers (CLI, TUI, WebUI, plugins) to tune how aggressively\n * noisy events like tool progress are persisted.\n */\nexport interface ToolProgressSamplingOptions {\n /**\n * How often to persist 'log' and 'partial_output' progress events.\n * - 1 = every message (no sampling)\n * - 8 = keep the first message + every 8th after that (default)\n */\n sampleRate?: number | undefined;\n}\n\nexport interface SessionSamplingOptions {\n /** Controls sampling behavior for `tool_progress` events (only relevant at auditLevel 'full'). */\n toolProgress?: ToolProgressSamplingOptions | undefined;\n}\n\nexport interface SessionEventBridgeOptions {\n /** Sampling rules for high-volume audit events. */\n sampling?: SessionSamplingOptions | undefined;\n}\n\n/**\n * Small, safe helper that wraps a SessionWriter and enforces the\n * configured auditLevel.\n *\n * All appends are best-effort. Failures are swallowed (with optional\n * diagnostics) so they never crash the agent loop.\n */\nexport interface SessionEventBridge {\n /** Append an event if allowed by the current audit level. */\n append(event: SessionEvent): Promise<void>;\n /** Batch-append events allowed by the current audit level. */\n appendBatch(events: SessionEvent[]): Promise<void>;\n\n /** Current audit level. Reflects the latest {@link setAuditLevel} value. */\n readonly level: AuditLevel;\n\n /**\n * Change the audit level on a live bridge. Subsequent appends are filtered\n * by the new level — used by the TUI `/settings` picker to apply an\n * `auditLevel` change to the running session without a restart.\n */\n setAuditLevel(level: AuditLevel): void;\n\n /** Returns true if an event of this type should be written at the current level. */\n allows(type: SessionEvent['type']): boolean;\n}\n\n/** Core events that are always written regardless of auditLevel. */\nconst CORE_RECONSTRUCT_EVENTS = new Set<SessionEvent['type']>([\n 'session_start',\n 'session_resumed',\n 'user_input',\n 'llm_response',\n 'tool_result',\n 'checkpoint',\n 'file_snapshot',\n 'rewound',\n 'in_flight_start',\n 'in_flight_end',\n 'session_end',\n]);\n\n/**\n * Events that are considered \"standard\" audit detail.\n * These are lightweight and high-value for forensics.\n */\nconst STANDARD_AUDIT_EVENTS = new Set<SessionEvent['type']>([\n 'llm_request',\n 'tool_use',\n 'tool_call_start',\n 'tool_call_end',\n 'compaction',\n 'error',\n 'message_truncated',\n 'provider_retry',\n 'provider_error',\n]);\n\n/**\n * Events that are only allowed at 'full' audit level because they can be\n * very high volume (e.g. streaming tool output).\n */\nconst FULL_ONLY_EVENTS = new Set<SessionEvent['type']>([\n 'tool_progress',\n]);\n\n/**\n * \"full\" level allows everything (including potentially heavy events\n * that plugins or future code may emit).\n */\nfunction isAllowed(type: SessionEvent['type'], level: AuditLevel): boolean {\n if (CORE_RECONSTRUCT_EVENTS.has(type)) return true;\n if (level === 'minimal') return false;\n\n if (STANDARD_AUDIT_EVENTS.has(type)) return true;\n if (level === 'standard') return false;\n\n // 'full' level events (high volume)\n if (FULL_ONLY_EVENTS.has(type)) {\n return level === 'full';\n }\n\n // 'full' — allow everything else\n return true;\n}\n\n/**\n * Create a safe, audit-level-aware bridge around a SessionWriter.\n *\n * The bridge can also apply sampling for high-volume events (e.g. `tool_progress`)\n * when `auditLevel` is set to `'full'`.\n *\n * @example\n * const bridge = createSessionEventBridge(sessionWriter, 'full', {\n * sampling: {\n * toolProgress: { sampleRate: 5 } // more aggressive sampling\n * }\n * });\n */\nexport function createSessionEventBridge(\n writer:\n | SessionWriter\n | (() => SessionWriter | undefined | null)\n | undefined\n | null,\n level: AuditLevel = 'standard',\n options: SessionEventBridgeOptions = {},\n): SessionEventBridge {\n // Mutable so setAuditLevel() can re-tune a live bridge in place.\n let currentLevel: AuditLevel = level ?? 'standard';\n\n // Accept either a writer instance or a getter. A getter lets long-lived\n // hosts (CLI/TUI/WebUI) resolve the CURRENT writer on every append — when\n // the user resumes another session mid-run, audit events follow the swap\n // instead of being silently dropped into the old, closed writer.\n const resolveWriter: () => SessionWriter | undefined | null =\n typeof writer === 'function' ? writer : () => writer;\n\n // Internal sampling state for high-volume events (e.g. tool_progress).\n // Keyed by tool call id (or name as fallback) to keep sampling per-call.\n const progressCounters = new Map<string, number>();\n\n const toolProgressConfig = options.sampling?.toolProgress ?? {};\n const TOOL_PROGRESS_SAMPLE_RATE = toolProgressConfig.sampleRate ?? 8;\n\n /**\n * Decide whether a high-volume event should be sampled in.\n * Currently only implements sampling for 'tool_progress'.\n */\n function shouldSample(event: SessionEvent): boolean {\n if (event.type !== 'tool_progress') return true;\n\n const progEvent = event as Extract<SessionEvent, { type: 'tool_progress' }>;\n const innerType = progEvent.event?.type;\n\n // Always let through high-signal structured events\n if (innerType === 'warning' || innerType === 'metric' || innerType === 'file_changed') {\n return true;\n }\n\n // Sample noisy text streams (log / partial_output)\n if (innerType === 'log' || innerType === 'partial_output') {\n const key = progEvent.id || progEvent.name;\n const count = (progressCounters.get(key) || 0) + 1;\n progressCounters.set(key, count);\n\n // Always keep the first message + every Nth after that\n return count === 1 || (count % TOOL_PROGRESS_SAMPLE_RATE === 0);\n }\n\n return true;\n }\n\n return {\n get level() {\n return currentLevel;\n },\n\n setAuditLevel(next) {\n currentLevel = next ?? 'standard';\n },\n\n allows(type) {\n return isAllowed(type, currentLevel);\n },\n\n async append(event) {\n const target = resolveWriter();\n if (!target) return;\n if (!isAllowed(event.type, currentLevel)) return;\n\n // Apply sampling for high-volume events (only at 'full' level)\n if (!shouldSample(event)) return;\n\n try {\n await target.append(event);\n } catch (_err) {\n // Best-effort: never let session logging break the agent.\n // The existing FileSessionWriter already does throttled warnings,\n // but we keep this wrapper silent by default to avoid log spam.\n // Callers that care can listen to EventBus 'session.damaged' etc.\n }\n },\n\n async appendBatch(events) {\n const target = resolveWriter();\n if (!target || events.length === 0) return;\n const allowed = events.filter(\n (e) => isAllowed(e.type, currentLevel) && shouldSample(e),\n );\n if (allowed.length === 0) return;\n try {\n await target.appendBatch(allowed);\n } catch {\n // best-effort — same contract as append()\n }\n },\n };\n}\n\n/** Convenience re-export of the allowed core set for tests/docs. */\nexport { CORE_RECONSTRUCT_EVENTS, STANDARD_AUDIT_EVENTS };\n\n/**\n * Safely extract the auditLevel from a (possibly partial) Config object.\n * Falls back to 'standard' if not present or invalid.\n */\nexport function resolveAuditLevel(\n cfg?: { session?: { auditLevel?: AuditLevel | undefined } | undefined } | null,\n): AuditLevel {\n const raw = cfg?.session?.auditLevel;\n if (raw === 'minimal' || raw === 'standard' || raw === 'full') {\n return raw;\n }\n return 'standard';\n}\n\n/**\n * Fully resolves the session logging configuration with sensible defaults.\n * This is the recommended way for the CLI / TUI / WebUI to read session config.\n */\nexport function resolveSessionLoggingConfig(\n cfg?: {\n session?: {\n auditLevel?: AuditLevel | undefined;\n sampling?: {\n toolProgress?: { sampleRate?: number | undefined };\n };\n };\n } | null,\n): {\n auditLevel: AuditLevel;\n sampling: {\n toolProgress: { sampleRate: number };\n };\n} {\n const session = cfg?.session ?? {};\n\n const auditLevel = resolveAuditLevel(cfg);\n\n const toolProgressSampleRate =\n session.sampling?.toolProgress?.sampleRate ?? 8;\n\n return {\n auditLevel,\n sampling: {\n toolProgress: {\n sampleRate: Math.max(1, Math.floor(toolProgressSampleRate)),\n },\n },\n };\n}"]}
|