@rolepod/uiproof 0.6.0 → 0.6.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/rolepod-uiproof.ts","../../src/cli/doctor.ts","../../src/cli/install_mobile.ts","../../src/cli/replay.ts","../../src/artifact/ArtifactStore.ts","../../src/util/log.ts","../../src/util/errors.ts","../../src/engine/AppiumEngine.ts","../../src/engine/a11y/uiautomator2.ts","../../src/engine/a11y/xcuitest.ts","../../src/engine/PlaywrightEngine.ts","../../src/engine/a11y/normalize.ts","../../src/engine/factory.ts","../../src/session/SessionRegistry.ts","../../src/tools/composite/verify_ui_flow.ts","../../src/schema/tools.ts","../../src/replay/minimize.ts","../../src/util/manifest.ts","../../src/tools/result.ts","../../src/server.ts","../../src/tools/atomic/browser_click.ts","../../src/tools/atomic/browser_close.ts","../../src/tools/atomic/browser_console.ts","../../src/tools/atomic/browser_drag.ts","../../src/tools/atomic/browser_evaluate.ts","../../src/tools/atomic/browser_fill_form.ts","../../src/tools/atomic/browser_handle_dialog.ts","../../src/tools/atomic/browser_hover.ts","../../src/tools/atomic/browser_key.ts","../../src/tools/atomic/browser_navigate.ts","../../src/tools/atomic/browser_network.ts","../../src/tools/atomic/browser_open.ts","../../src/tools/atomic/browser_pages.ts","../../src/tools/atomic/browser_screenshot.ts","../../src/tools/atomic/browser_scroll.ts","../../src/tools/atomic/browser_set_env.ts","../../src/tools/atomic/browser_snapshot.ts","../../src/tools/atomic/browser_switch_page.ts","../../src/tools/atomic/browser_type.ts","../../src/tools/atomic/browser_upload_file.ts","../../src/tools/atomic/browser_wait_for.ts","../../src/tools/composite/audit_a11y.ts","../../src/tools/composite/extract_ui_state.ts","../../src/tools/composite/scaffold_e2e.ts","../../src/tools/composite/visual_diff.ts","../../src/tools/metadata.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { runDoctor } from \"../src/cli/doctor.js\";\nimport { runInstallMobile } from \"../src/cli/install_mobile.js\";\nimport { runReplay } from \"../src/cli/replay.js\";\nimport { buildServer, SERVER_VERSION } from \"../src/server.js\";\nimport { log } from \"../src/util/log.js\";\n\nconst HELP = `rolepod-uiproof ${SERVER_VERSION}\n\nUsage:\n rolepod-uiproof Start the MCP server on stdio (default)\n rolepod-uiproof doctor Health check (Node, Playwright, Appium, SDKs)\n rolepod-uiproof install:mobile Print mobile setup checklist (iOS / Android)\n rolepod-uiproof replay <file> Re-run a verify_ui_flow replay bundle\n rolepod-uiproof --version Print version\n rolepod-uiproof --help This help\n`;\n\nasync function main(): Promise<void> {\n const [, , sub, ...rest] = process.argv;\n\n switch (sub) {\n case undefined:\n case \"serve\":\n return startServer();\n case \"doctor\":\n process.exit(await runDoctor());\n return;\n case \"install:mobile\":\n case \"install\":\n process.exit(runInstallMobile());\n return;\n case \"replay\": {\n const target = rest[0];\n if (!target) {\n process.stderr.write(\"Usage: rolepod-uiproof replay <bundle.json>\\n\");\n process.exit(2);\n }\n process.exit(await runReplay(target));\n return;\n }\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${SERVER_VERSION}\\n`);\n return;\n case \"--help\":\n case \"-h\":\n case \"help\":\n process.stdout.write(HELP);\n return;\n default:\n process.stderr.write(`Unknown subcommand: ${sub}\\n${HELP}`);\n process.exit(2);\n }\n}\n\nasync function startServer(): Promise<void> {\n const server = buildServer();\n const transport = new StdioServerTransport();\n\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(\"shutting down\", { signal });\n await server.shutdown().catch((err: unknown) =>\n log.error(\"shutdown failed\", { err: String(err) }),\n );\n process.exit(0);\n };\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n\n await server.mcp.connect(transport);\n log.info(\"rolepod-uiproof connected on stdio\");\n}\n\nmain().catch((err: unknown) => {\n log.error(\"fatal startup error\", {\n err: err instanceof Error ? err.stack : String(err),\n });\n process.exit(1);\n});\n","import { existsSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { homedir, platform as osPlatform } from \"node:os\";\n\ntype Check = {\n name: string;\n status: \"ok\" | \"warn\" | \"fail\";\n detail: string;\n};\n\n/**\n * `rolepod-uiproof doctor` — diagnose local environment readiness. Exits\n * with code 0 if every check is `ok` or `warn`, 1 if any `fail`.\n */\nexport async function runDoctor(): Promise<number> {\n const checks: Check[] = [];\n\n // Node version\n const major = Number(process.versions.node.split(\".\")[0]);\n checks.push({\n name: \"Node ≥20\",\n status: major >= 20 ? \"ok\" : \"fail\",\n detail: process.versions.node,\n });\n\n // Playwright Chromium install (looks under the default cache directory)\n checks.push(checkPlaywrightChromium());\n\n // webdriverio (optional)\n checks.push(await checkWebdriverIO());\n\n // Appium server reachable\n checks.push(await checkAppiumServer());\n\n // Xcode (macOS only, for iOS testing — roadmap v0.3)\n if (osPlatform() === \"darwin\") {\n checks.push(checkXcode());\n }\n\n // Android SDK (roadmap v0.3)\n checks.push(checkAndroidSdk());\n\n // SeleniumEngine status — explicitly roadmap v0.4\n checks.push({\n name: \"SeleniumEngine (roadmap v0.4)\",\n status: \"warn\",\n detail:\n \"Not implemented — deferred to v0.4 (legacy Selenium grid support, opt-in via ROLEPOD_MCP_WEB_ENGINE=selenium).\",\n });\n\n // Artifact dir writable\n checks.push(checkArtifactDir());\n\n print(checks);\n const failed = checks.some((c) => c.status === \"fail\");\n return failed ? 1 : 0;\n}\n\nfunction checkPlaywrightChromium(): Check {\n const candidates = [\n join(homedir(), \"Library\", \"Caches\", \"ms-playwright\"),\n join(homedir(), \".cache\", \"ms-playwright\"),\n process.env.PLAYWRIGHT_BROWSERS_PATH,\n ].filter((x): x is string => typeof x === \"string\");\n for (const base of candidates) {\n if (existsSync(base)) {\n return {\n name: \"Playwright Chromium installed\",\n status: \"ok\",\n detail: base,\n };\n }\n }\n return {\n name: \"Playwright Chromium installed\",\n status: \"fail\",\n detail: \"Run: npx playwright install chromium\",\n };\n}\n\nasync function checkWebdriverIO(): Promise<Check> {\n try {\n const url = await import.meta.resolve?.(\"webdriverio\");\n return {\n name: \"webdriverio (mobile client, v0.3)\",\n status: \"ok\",\n detail: url ?? \"resolved\",\n };\n } catch {\n return {\n name: \"webdriverio (mobile client, v0.3)\",\n status: \"warn\",\n detail:\n \"Not installed — web works fine without it. Mobile is roadmap v0.3. For mobile: npm i webdriverio\",\n };\n }\n}\n\nasync function checkAppiumServer(): Promise<Check> {\n const host = process.env.APPIUM_HOST ?? \"127.0.0.1\";\n const port = Number(process.env.APPIUM_PORT ?? 4723);\n const path = process.env.APPIUM_BASE_PATH ?? \"/\";\n const url = `http://${host}:${port}${path.endsWith(\"/\") ? path : path + \"/\"}status`;\n try {\n const ctrl = new AbortController();\n const timeout = setTimeout(() => ctrl.abort(), 1500);\n const res = await fetch(url, { signal: ctrl.signal });\n clearTimeout(timeout);\n return {\n name: \"Appium server (roadmap v0.3)\",\n status: res.ok ? \"ok\" : \"warn\",\n detail: `${url} → HTTP ${res.status}`,\n };\n } catch {\n return {\n name: \"Appium server (roadmap v0.3)\",\n status: \"warn\",\n detail: `Not reachable at ${url} — mobile sessions need a running Appium daemon. Web sessions are unaffected.`,\n };\n }\n}\n\nfunction checkXcode(): Check {\n const path = \"/Applications/Xcode.app\";\n if (existsSync(path)) {\n return { name: \"Xcode (iOS, roadmap v0.3)\", status: \"ok\", detail: path };\n }\n return {\n name: \"Xcode (iOS, roadmap v0.3)\",\n status: \"warn\",\n detail:\n \"Install Xcode via the App Store; required for iOS simulators. Not needed for web targets.\",\n };\n}\n\nfunction checkAndroidSdk(): Check {\n const candidates = [\n process.env.ANDROID_HOME,\n process.env.ANDROID_SDK_ROOT,\n join(homedir(), \"Library\", \"Android\", \"sdk\"),\n join(homedir(), \"Android\", \"Sdk\"),\n ].filter((x): x is string => typeof x === \"string\");\n for (const path of candidates) {\n if (existsSync(path)) {\n return { name: \"Android SDK (roadmap v0.3)\", status: \"ok\", detail: path };\n }\n }\n return {\n name: \"Android SDK (roadmap v0.3)\",\n status: \"warn\",\n detail:\n \"Set ANDROID_HOME — needed only for Android testing. Not needed for web or iOS targets.\",\n };\n}\n\nfunction checkArtifactDir(): Check {\n const dir = resolve(process.cwd(), \".rolepod-uiproof\");\n // Directory does not need to exist yet; only the parent does.\n return {\n name: \"Artifact root writable\",\n status: \"ok\",\n detail: `Will be created at: ${dir}/artifacts/{run_id}/`,\n };\n}\n\nfunction print(checks: Check[]): void {\n const icon = (s: Check[\"status\"]) => (s === \"ok\" ? \"✓\" : s === \"warn\" ? \"•\" : \"✗\");\n for (const c of checks) {\n // Doctor output is user-facing CLI; stdout is appropriate here\n // because this subcommand never speaks MCP on the same channel.\n process.stdout.write(` ${icon(c.status)} ${c.name.padEnd(30)} ${c.detail}\\n`);\n }\n}\n","import { platform as osPlatform } from \"node:os\";\n\nexport function runInstallMobile(): number {\n const os = osPlatform();\n const lines: string[] = [];\n\n lines.push(\"rolepod-uiproof install:mobile — setup checklist\\n\");\n lines.push(\"Mobile support is OPTIONAL. Skip if you only target the web.\\n\");\n\n lines.push(\"1. Install the Node client:\");\n lines.push(\" npm install webdriverio\\n\");\n\n lines.push(\"2. Install the Appium server (2.x):\");\n lines.push(\" npm install -g appium\");\n lines.push(\" appium driver install xcuitest # iOS\");\n lines.push(\" appium driver install uiautomator2 # Android\");\n lines.push(\" appium # leave running\\n\");\n\n if (os === \"darwin\") {\n lines.push(\"3. iOS — macOS host required:\");\n lines.push(\" • Install Xcode + Command Line Tools\");\n lines.push(\" • Open Xcode → Settings → Platforms → install an iOS Simulator\");\n lines.push(\" • `xcrun simctl list devices` confirms a device is available\\n\");\n } else {\n lines.push(\"3. iOS: not supported on this OS (macOS host required).\\n\");\n }\n\n lines.push(\"4. Android — any host:\");\n lines.push(\" • Install Android Studio OR command-line tools\");\n lines.push(\" • Set ANDROID_HOME to the SDK location\");\n lines.push(\" • `adb devices` confirms an emulator or device is reachable\\n\");\n\n lines.push(\"5. Verify:\");\n lines.push(\" npx rolepod-uiproof doctor\\n\");\n\n lines.push(\"Environment overrides (optional):\");\n lines.push(\" APPIUM_HOST default: 127.0.0.1\");\n lines.push(\" APPIUM_PORT default: 4723\");\n lines.push(\" APPIUM_BASE_PATH default: /\");\n\n for (const l of lines) process.stdout.write(l + \"\\n\");\n return 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { ArtifactStore } from \"../artifact/ArtifactStore.js\";\nimport { createMobileEngine, createWebEngine } from \"../engine/factory.js\";\nimport { SessionRegistry } from \"../session/SessionRegistry.js\";\nimport { verifyUiFlowTool } from \"../tools/composite/verify_ui_flow.js\";\nimport type { ToolContext } from \"../tools/types.js\";\n\n/**\n * `rolepod-uiproof replay <bundle.json>` — re-runs a verify_ui_flow\n * replay bundle deterministically, with no agent in the loop. Exit\n * code 0 = passed, 1 = failed or error.\n */\nexport async function runReplay(bundlePath: string): Promise<number> {\n const abs = resolve(bundlePath);\n const raw = await readFile(abs, \"utf8\");\n const bundle = JSON.parse(raw) as Record<string, unknown>;\n if (bundle.version !== 1) {\n process.stderr.write(`Unsupported replay bundle version: ${bundle.version}\\n`);\n return 1;\n }\n\n const webEngine = createWebEngine();\n const registry = new SessionRegistry({ idleTimeoutMs: 0 });\n registry.register(\"web\", webEngine);\n const mobileEngine = createMobileEngine();\n registry.register(\"ios\", mobileEngine);\n registry.register(\"android\", mobileEngine);\n const store = new ArtifactStore();\n const ctx: ToolContext = { registry, store };\n\n try {\n const handler = verifyUiFlowTool.build(ctx);\n const result = await handler({\n mode: \"assert\",\n open: (bundle.open as Record<string, unknown>) ?? {},\n steps:\n (bundle.steps as Array<{ kind: string }> | undefined) ?? [],\n expect:\n (bundle.expect as Array<{ kind: string }> | undefined) ?? [],\n capture: [\"screenshot\"],\n close_on_finish: true,\n minimize: false,\n } as Parameters<ReturnType<typeof verifyUiFlowTool.build>>[0]);\n const body = result.structuredContent as Record<string, unknown>;\n process.stdout.write(JSON.stringify(body, null, 2) + \"\\n\");\n return body.passed === true ? 0 : 1;\n } finally {\n await registry.shutdown().catch(() => undefined);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { log } from \"../util/log.js\";\n\n/**\n * Writes run artifacts. In **standalone** mode (default) — and in v0.4 and\n * earlier — runs live under `./.rolepod-uiproof/artifacts/{prefix}_{ts}_{uuid}/`.\n *\n * In **with-parent** mode — activated automatically when the env var\n * `ROLEPOD_PARENT=1` is set by the parent `rolepod` plugin's SessionStart\n * hook — runs live under `./.rolepod/evidence/{ts}-rolepod-uiproof-{skill}/`,\n * per the Extension Protocol v1 evidence-path convention. Parent's\n * `check-work` skill aggregates manifest.json files from this directory.\n *\n * Baselines for `visual_diff` always live in `./.rolepod-uiproof/baselines/`\n * regardless of mode — they are user-curated configuration, not per-run\n * evidence.\n */\nexport type ReplayStep = Record<string, unknown>;\n\nexport type ReplayBundle = {\n version: 1;\n run_id: string;\n recorded_at: string;\n open: Record<string, unknown>;\n steps: ReplayStep[];\n expect: ReplayStep[];\n};\n\nexport type ArtifactPaths = {\n screenshots: string[];\n replay_bundle?: string;\n};\n\nexport type ArtifactMode = \"standalone\" | \"with-parent\";\n\nexport type StartRunOptions = {\n /**\n * Skill name as it appears in marketplace (`verify-ui`, `audit-a11y`,\n * `visual-diff`, `scaffold-e2e`, `check-errors`). REQUIRED when emitting\n * a manifest.json (Extension Protocol v1) so parent's `check-work` can\n * route artifacts to the right phase.\n *\n * In `with-parent` mode the run dirname is derived from this field; if\n * omitted the `prefix` argument is used as a fallback (legacy).\n */\n skill?: string;\n};\n\nexport type StartRunResult = {\n runId: string;\n runDir: string;\n skill: string;\n mode: ArtifactMode;\n};\n\nexport class ArtifactStore {\n readonly rootDir: string;\n readonly mode: ArtifactMode;\n private readonly baselineRoot: string;\n\n constructor(\n opts: { rootDir?: string; mode?: ArtifactMode } = {},\n ) {\n const detectedParent = process.env.ROLEPOD_PARENT === \"1\";\n this.mode = opts.mode ?? (detectedParent ? \"with-parent\" : \"standalone\");\n\n if (opts.rootDir !== undefined) {\n this.rootDir = opts.rootDir;\n } else if (this.mode === \"with-parent\") {\n this.rootDir = resolve(process.cwd(), \".rolepod\", \"evidence\");\n } else {\n this.rootDir = resolve(process.cwd(), \".rolepod-uiproof\", \"artifacts\");\n }\n\n // Baselines are config, not evidence — always live in the standalone\n // location so visual_diff sees the same set across modes.\n this.baselineRoot = resolve(process.cwd(), \".rolepod-uiproof\", \"baselines\");\n }\n\n /**\n * Allocate a fresh run dir and ensure it exists.\n *\n * - standalone: `./.rolepod-uiproof/artifacts/{prefix}_{ts}_{uuid}/`\n * - with-parent: `./.rolepod/evidence/{ts}-rolepod-uiproof-{skill}/`\n *\n * `prefix` is preserved for back-compat with v0.5 callers; new callers\n * should also pass `opts.skill` so the with-parent path can be derived\n * unambiguously and the manifest can be emitted with the canonical\n * skill name.\n */\n async startRun(\n prefix = \"run\",\n opts: StartRunOptions = {},\n ): Promise<StartRunResult> {\n const ts = this.timestampSlug();\n const skill = opts.skill ?? prefix;\n\n let runId: string;\n if (this.mode === \"with-parent\") {\n // Parent expects a flat, sortable dirname. Append a short uuid only\n // when two runs of the same skill could collide within one second.\n runId = `${ts}-rolepod-uiproof-${skill}`;\n } else {\n runId = `${prefix}_${ts}_${randomUUID().slice(0, 8)}`;\n }\n\n const runDir = resolve(this.rootDir, runId);\n await mkdir(runDir, { recursive: true });\n log.debug(\"artifact run started\", {\n run_id: runId,\n dir: runDir,\n mode: this.mode,\n skill,\n });\n return { runId, runDir, skill, mode: this.mode };\n }\n\n async writeScreenshot(\n runDir: string,\n buf: Buffer,\n name: string,\n ): Promise<string> {\n const path = resolve(runDir, `${name}.png`);\n await writeFile(path, buf);\n return path;\n }\n\n async writeReplayBundle(\n runDir: string,\n bundle: ReplayBundle,\n name = \"replay.json\",\n ): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, JSON.stringify(bundle, null, 2), \"utf8\");\n return path;\n }\n\n async writeReport(runDir: string, name: string, body: string): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, body, \"utf8\");\n return path;\n }\n\n async writeBytes(runDir: string, name: string, buf: Buffer): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, buf);\n return path;\n }\n\n async ensureDir(absDir: string): Promise<string> {\n await mkdir(absDir, { recursive: true });\n return absDir;\n }\n\n /** Root for stored visual baselines: `./.rolepod-uiproof/baselines/`. */\n get baselineDir(): string {\n return this.baselineRoot;\n }\n\n private timestampSlug(): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return (\n `${d.getUTCFullYear()}` +\n pad(d.getUTCMonth() + 1) +\n pad(d.getUTCDate()) +\n \"T\" +\n pad(d.getUTCHours()) +\n pad(d.getUTCMinutes()) +\n pad(d.getUTCSeconds())\n );\n }\n}\n","/**\n * Stdio MCP servers MUST NOT write logs to stdout — stdout carries\n * JSON-RPC. All diagnostic output goes to stderr.\n *\n * Reference: MCP TypeScript SDK README, \"Logging on stdio servers\".\n */\n\nfunction emit(level: \"info\" | \"warn\" | \"error\" | \"debug\", msg: string, extra?: unknown): void {\n const line = JSON.stringify({\n ts: new Date().toISOString(),\n level,\n msg,\n ...(extra !== undefined ? { extra } : {}),\n });\n process.stderr.write(line + \"\\n\");\n}\n\nexport const log = {\n info: (msg: string, extra?: unknown) => emit(\"info\", msg, extra),\n warn: (msg: string, extra?: unknown) => emit(\"warn\", msg, extra),\n error: (msg: string, extra?: unknown) => emit(\"error\", msg, extra),\n debug: (msg: string, extra?: unknown) => {\n if (process.env.ROLEPOD_MCP_DEBUG) emit(\"debug\", msg, extra);\n },\n};\n","/**\n * Structured error types surfaced to MCP clients. Each carries enough\n * context for the Lead agent to recover (typically: re-snapshot, then retry).\n *\n * Snapshot freshness rule: any state-changing call invalidates the current\n * ref index; a stale ref returns `stale_ref` with the last valid snapshot\n * timestamp so the Lead can re-snapshot and retry.\n */\n\nexport type ErrorCode =\n | \"stale_ref\"\n | \"unknown_ref\"\n | \"unknown_session\"\n | \"unsupported_platform\"\n | \"unsupported_engine\"\n | \"not_implemented_in_v01\"\n | \"not_implemented_in_v02\"\n | \"invalid_input\"\n | \"engine_error\";\n\nexport class RolepodMcpError extends Error {\n override readonly name = \"RolepodMcpError\";\n constructor(\n readonly code: ErrorCode,\n message: string,\n readonly detail?: Record<string, unknown>,\n ) {\n super(message);\n }\n\n toJSON(): { code: ErrorCode; message: string; detail?: Record<string, unknown> } {\n return {\n code: this.code,\n message: this.message,\n ...(this.detail ? { detail: this.detail } : {}),\n };\n }\n}\n\nexport class StaleRefError extends RolepodMcpError {\n constructor(sessionId: string, ref: string, lastValidSnapshotAt: string | null) {\n super(\"stale_ref\", `Ref \"${ref}\" is stale — re-snapshot before retrying.`, {\n session_id: sessionId,\n ref,\n last_valid_snapshot_at: lastValidSnapshotAt,\n });\n }\n}\n\nexport class UnknownRefError extends RolepodMcpError {\n constructor(sessionId: string, ref: string) {\n super(\"unknown_ref\", `Ref \"${ref}\" was not found in the current snapshot.`, {\n session_id: sessionId,\n ref,\n });\n }\n}\n\nexport class UnknownSessionError extends RolepodMcpError {\n constructor(sessionId: string) {\n super(\"unknown_session\", `No open session with id \"${sessionId}\".`, {\n session_id: sessionId,\n });\n }\n}\n\nexport class UnsupportedPlatformError extends RolepodMcpError {\n constructor(platform: string) {\n super(\n \"unsupported_platform\",\n `Platform \"${platform}\" is not supported in v0.1 — only \"web\" is implemented. Mobile (ios/android) ships in v0.3.`,\n { platform },\n );\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n RolepodMcpError,\n UnknownRefError,\n UnknownSessionError,\n UnsupportedPlatformError,\n} from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport {\n parseUiAutomator2Tree,\n type AndroidRefMeta,\n} from \"./a11y/uiautomator2.js\";\nimport { parseXcuiTestTree, type IosRefMeta } from \"./a11y/xcuitest.js\";\nimport type {\n A11ySnapshot,\n Direction,\n Engine,\n OpenOptions,\n Platform,\n Session,\n WaitCondition,\n} from \"./Engine.js\";\n\ntype MobileRefMeta = IosRefMeta | AndroidRefMeta;\n\n/**\n * Minimal subset of the webdriverio `Browser` surface that AppiumEngine\n * relies on. We type only what we use so that consumers without\n * `webdriverio` installed still typecheck.\n */\ntype WdioElement = {\n click(): Promise<void>;\n clearValue(): Promise<void>;\n setValue(value: string): Promise<void>;\n isEnabled(): Promise<boolean>;\n};\n\ntype WdioBrowser = {\n sessionId: string;\n capabilities: Record<string, unknown>;\n getPageSource(): Promise<string>;\n saveScreenshot(filepath?: string): Promise<Buffer>;\n takeScreenshot(): Promise<string>; // base64\n pressKeyCode?: (code: number) => Promise<void>;\n $(selector: string): Promise<WdioElement> & WdioElement;\n execute<T = unknown>(script: string, ...args: unknown[]): Promise<T>;\n deleteSession(): Promise<void>;\n pause(ms: number): Promise<void>;\n};\n\ntype WdioRemote = (\n opts: Record<string, unknown>,\n) => Promise<WdioBrowser>;\n\ntype MobileSession = {\n readonly id: string;\n readonly platform: \"ios\" | \"android\";\n readonly driver: WdioBrowser;\n};\n\ntype SessionInternals = {\n session: MobileSession;\n refIndex: Map<string, MobileRefMeta>;\n snapshotGeneration: number;\n refGeneration: number;\n lastSnapshotAt: string | null;\n};\n\n/**\n * AppiumEngine — v0.3 mobile support via Appium 2.x + webdriverio.\n *\n * webdriverio is an `optionalDependency` (brief D-020). The engine\n * lazy-imports it; if missing, every public method throws a structured\n * `engine_error` with installation guidance.\n *\n * Smoke tests run against a real simulator only when one is reachable;\n * unit tests for AT normalization use fixture XML strings (see\n * `tests/unit/`).\n */\nexport class AppiumEngine implements Engine {\n readonly id = \"appium\" as const;\n\n private readonly sessions = new Map<string, SessionInternals>();\n private wdioCache: WdioRemote | null = null;\n\n async open(opts: OpenOptions): Promise<Session> {\n if (opts.platform !== \"ios\" && opts.platform !== \"android\") {\n throw new UnsupportedPlatformError(opts.platform);\n }\n const remote = await this.loadWdio();\n const caps = this.buildCapabilities(opts);\n const driver = await remote({\n hostname: process.env.APPIUM_HOST ?? \"127.0.0.1\",\n port: Number(process.env.APPIUM_PORT ?? 4723),\n path: process.env.APPIUM_BASE_PATH ?? \"/\",\n capabilities: caps,\n });\n\n const sessionId = randomUUID();\n const session: MobileSession = { id: sessionId, platform: opts.platform, driver };\n this.sessions.set(sessionId, {\n session,\n refIndex: new Map(),\n snapshotGeneration: 0,\n refGeneration: -1,\n lastSnapshotAt: null,\n });\n log.info(\"mobile session opened\", {\n session_id: sessionId,\n platform: opts.platform,\n remote_session: driver.sessionId,\n });\n return { id: sessionId, platform: opts.platform };\n }\n\n async close(session: Session): Promise<void> {\n const s = this.requireSession(session.id);\n await s.session.driver.deleteSession().catch((err: unknown) =>\n log.warn(\"appium deleteSession failed\", { session_id: session.id, err: String(err) }),\n );\n this.sessions.delete(session.id);\n log.info(\"mobile session closed\", { session_id: session.id });\n }\n\n async snapshot(session: Session, _mode?: \"visible\" | \"full\"): Promise<A11ySnapshot> {\n void _mode;\n const s = this.requireSession(session.id);\n const xml = await s.session.driver.getPageSource();\n const normalized =\n s.session.platform === \"ios\"\n ? parseXcuiTestTree(xml)\n : parseUiAutomator2Tree(xml);\n\n s.snapshotGeneration += 1;\n s.refGeneration = s.snapshotGeneration;\n s.refIndex = normalized.refIndex as Map<string, MobileRefMeta>;\n s.lastSnapshotAt = new Date().toISOString();\n\n return {\n session_id: session.id,\n platform: s.session.platform,\n url_or_screen: this.screenIdentifier(s),\n taken_at: s.lastSnapshotAt,\n tree: normalized.tree,\n };\n }\n\n async click(session: Session, ref: string): Promise<void> {\n const s = this.requireSession(session.id);\n const el = await this.resolveElement(s, ref);\n await el.click();\n this.invalidateRefs(s);\n }\n\n async type(\n session: Session,\n ref: string,\n text: string,\n opts?: { clearFirst?: boolean },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const el = await this.resolveElement(s, ref);\n if (opts?.clearFirst) await el.clearValue();\n await el.setValue(text);\n this.invalidateRefs(s);\n }\n\n async key(session: Session, key: string): Promise<void> {\n const s = this.requireSession(session.id);\n if (s.session.platform === \"android\" && s.session.driver.pressKeyCode) {\n const code = ANDROID_KEY_CODES[key];\n if (code !== undefined) {\n await s.session.driver.pressKeyCode(code);\n this.invalidateRefs(s);\n return;\n }\n }\n throw new RolepodMcpError(\n \"not_implemented_in_v02\",\n `Mobile key(\"${key}\") is partially supported in v0.3 — only well-known Android keycodes are mapped. iOS hardware keys land later.`,\n { platform: s.session.platform, key },\n );\n }\n\n async scroll(\n session: Session,\n dir: Direction,\n amount = 400,\n _ref?: string,\n ): Promise<void> {\n void _ref;\n const s = this.requireSession(session.id);\n // Mobile scroll is fiddly across drivers — fall back to a touch\n // gesture via execute(). Most consumers will prefer a `wait_for`\n // followed by a `click` on a ref that scrolls into view.\n const action =\n s.session.platform === \"ios\"\n ? \"mobile: swipe\"\n : \"mobile: scrollGesture\";\n const params =\n s.session.platform === \"ios\"\n ? { direction: dir }\n : { left: 100, top: 200, width: 400, height: 600, direction: dir, percent: amount / 1000 };\n await s.session.driver\n .execute(action, params)\n .catch((err: unknown) => log.warn(\"scroll gesture failed\", { err: String(err) }));\n this.invalidateRefs(s);\n }\n\n async waitFor(\n session: Session,\n cond: WaitCondition,\n timeoutMs = 10_000,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (cond.kind === \"idle\") {\n await s.session.driver.pause(cond.ms);\n this.invalidateRefs(s);\n return;\n }\n const snap = await this.snapshot(session);\n const matched =\n cond.kind === \"text_visible\"\n ? treeIncludesText(snap.tree, cond.text)\n : cond.kind === \"ref_exists\"\n ? treeIncludesText(snap.tree, cond.query)\n : false;\n if (matched) return;\n await s.session.driver.pause(250);\n }\n throw new RolepodMcpError(\n \"engine_error\",\n `wait_for ${cond.kind} timed out after ${timeoutMs}ms`,\n { condition: cond, timeout_ms: timeoutMs },\n );\n }\n\n async screenshot(session: Session, _fullPage?: boolean): Promise<Buffer> {\n void _fullPage;\n const s = this.requireSession(session.id);\n const b64 = await s.session.driver.takeScreenshot();\n return Buffer.from(b64, \"base64\");\n }\n\n async navigate(_session: Session, _url: string): Promise<void> {\n throw new UnsupportedPlatformError(_session.platform);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 cross-platform additions — mobile stubs.\n // These ship as `not_implemented_in_v05` until the mobile gesture work lands.\n // -------------------------------------------------------------------------\n\n async hover(_session: Session, _ref: string): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"hover is not yet implemented for mobile (Appium). Use long-press via custom gesture if needed.\",\n );\n }\n\n async drag(_session: Session, _fromRef: string, _toRef: string): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"drag is not yet implemented for mobile (Appium). Use the W3C Actions API directly if needed.\",\n );\n }\n\n async fillForm(\n session: Session,\n fields: { ref: string; value: string | boolean; kind?: string }[],\n ): Promise<void> {\n // Naive port: iterate type() per field. select/checkbox/radio not\n // applicable in native mobile in the same way; treat all as text input.\n for (const f of fields) {\n const v = typeof f.value === \"boolean\" ? String(f.value) : f.value;\n await this.type(session, f.ref, v);\n }\n }\n\n async uploadFile(\n _session: Session,\n _ref: string,\n _filePath: string,\n ): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"upload_file is not supported on mobile (Appium).\",\n );\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n private async loadWdio(): Promise<WdioRemote> {\n if (this.wdioCache) return this.wdioCache;\n try {\n // Avoid TypeScript pulling the (optional) module into static types.\n const mod = (await import(/* @vite-ignore */ \"webdriverio\")) as unknown as {\n remote: WdioRemote;\n };\n this.wdioCache = mod.remote;\n return mod.remote;\n } catch {\n throw new RolepodMcpError(\n \"engine_error\",\n \"Mobile support needs webdriverio (and a running Appium server). Run `npx rolepod-uiproof install:mobile` for the setup checklist.\",\n );\n }\n }\n\n private buildCapabilities(opts: OpenOptions): Record<string, unknown> {\n const caps: Record<string, unknown> = {};\n if (opts.platform === \"ios\") {\n caps.platformName = \"iOS\";\n caps[\"appium:automationName\"] = \"XCUITest\";\n if (opts.device) caps[\"appium:deviceName\"] = opts.device;\n if (opts.bundle_id) caps[\"appium:bundleId\"] = opts.bundle_id;\n } else {\n caps.platformName = \"Android\";\n caps[\"appium:automationName\"] = \"UiAutomator2\";\n if (opts.emulator) caps[\"appium:avd\"] = opts.emulator;\n if (opts.app_package) caps[\"appium:appPackage\"] = opts.app_package;\n if (opts.app_activity) caps[\"appium:appActivity\"] = opts.app_activity;\n }\n if (opts.locale) caps[\"appium:language\"] = opts.locale;\n return caps;\n }\n\n private screenIdentifier(s: SessionInternals): string {\n const caps = s.session.driver.capabilities as Record<string, unknown>;\n return String(\n caps[\"appium:bundleId\"] ??\n caps[\"appium:appPackage\"] ??\n caps.platformName ??\n s.session.platform,\n );\n }\n\n private requireSession(sessionId: string): SessionInternals {\n const s = this.sessions.get(sessionId);\n if (!s) throw new UnknownSessionError(sessionId);\n return s;\n }\n\n private async resolveElement(s: SessionInternals, ref: string): Promise<WdioElement> {\n if (s.refGeneration !== s.snapshotGeneration) {\n throw new RolepodMcpError(\n \"stale_ref\",\n `Ref \"${ref}\" is stale — re-snapshot before retrying.`,\n {\n session_id: s.session.id,\n ref,\n last_valid_snapshot_at: s.lastSnapshotAt,\n },\n );\n }\n const meta = s.refIndex.get(ref);\n if (!meta) throw new UnknownRefError(s.session.id, ref);\n const selector = this.toSelector(meta);\n return s.session.driver.$(selector);\n }\n\n private toSelector(meta: MobileRefMeta): string {\n if (meta.kind === \"ios\") {\n if (meta.accessibilityId) return `~${meta.accessibilityId}`;\n const chain = `**/${meta.type}[${meta.classChainIndex}]`;\n return `-ios class chain:${chain}`;\n }\n if (meta.resourceId) {\n return `-android uiautomator:new UiSelector().resourceId(\"${escape(meta.resourceId)}\")`;\n }\n if (meta.contentDesc) return `~${meta.contentDesc}`;\n if (meta.text) {\n return `-android uiautomator:new UiSelector().text(\"${escape(meta.text)}\")`;\n }\n return `-android uiautomator:new UiSelector().className(\"${meta.androidClass}\").instance(${meta.classIndex - 1})`;\n }\n\n private invalidateRefs(s: SessionInternals): void {\n s.snapshotGeneration += 1;\n }\n}\n\nconst ANDROID_KEY_CODES: Record<string, number> = {\n Enter: 66,\n Tab: 61,\n Escape: 111,\n Back: 4,\n Home: 3,\n Menu: 82,\n Search: 84,\n Backspace: 67,\n ArrowUp: 19,\n ArrowDown: 20,\n ArrowLeft: 21,\n ArrowRight: 22,\n};\n\nfunction escape(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction treeIncludesText(node: { name?: string; value?: string; children?: unknown[] }, text: string): boolean {\n const target = text.toLowerCase();\n const visit = (n: { name?: string; value?: string; children?: unknown[] }): boolean => {\n if ((n.name && n.name.toLowerCase().includes(target)) ||\n (n.value && n.value.toLowerCase().includes(target))) return true;\n if (!n.children) return false;\n for (const c of n.children as Array<{ name?: string; value?: string; children?: unknown[] }>) {\n if (visit(c)) return true;\n }\n return false;\n };\n return visit(node);\n}\n\n// Helper so we don't accidentally export this typo'd internal name.\nfunction _platformGuard(p: Platform): void {\n void p;\n}\nvoid _platformGuard;\n","/**\n * UIAutomator2 (Android via Appium) accessibility-tree normalizer.\n *\n * Parses the Appium XML page source returned by\n * `driver.getPageSource()`. UIAutomator2 markup is rooted at\n * `<hierarchy>` and uses Android class names as tag names\n * (e.g. `android.widget.Button`), with attributes such as\n * `resource-id`, `content-desc`, `text`, `bounds`, `enabled`, etc.\n *\n * Inspired by alumnium-hq/alumnium's UIAutomator2AccessibilityTree\n * (MIT) — see UPSTREAM_TRACKING.md. Original implementation; no\n * verbatim copy.\n */\nimport { XMLParser } from \"fast-xml-parser\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\nexport type AndroidRefMeta = {\n kind: \"android\";\n resourceId?: string;\n contentDesc?: string;\n text?: string;\n androidClass: string;\n /** 1-based index among siblings of the same android class. */\n classIndex: number;\n};\n\nexport type AndroidNormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, AndroidRefMeta>;\n};\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n alwaysCreateTextNode: false,\n preserveOrder: true,\n});\n\ntype RawNode = Record<string, RawNode[] | undefined> & { \":@\"?: Record<string, string> };\n\nexport function parseUiAutomator2Tree(xmlString: string): AndroidNormalizedSnapshot {\n const refIndex = new Map<string, AndroidRefMeta>();\n let counter = 0;\n const nextRef = (): string => `e${++counter}`;\n\n let raw: RawNode[] = [];\n try {\n raw = parser.parse(xmlString) as RawNode[];\n } catch {\n raw = [];\n }\n\n const visit = (node: RawNode, siblingOcc: Map<string, number>): A11yNode | null => {\n const tagName = firstTagName(node);\n if (!tagName) return null;\n const attrs = node[\":@\"] ?? {};\n const childrenRaw = (node[tagName] as RawNode[]) ?? [];\n\n const idx = (siblingOcc.get(tagName) ?? 0) + 1;\n siblingOcc.set(tagName, idx);\n\n const ref = nextRef();\n refIndex.set(ref, {\n kind: \"android\",\n resourceId: attrs[\"@resource-id\"],\n contentDesc: attrs[\"@content-desc\"],\n text: attrs[\"@text\"],\n androidClass: tagName,\n classIndex: idx,\n });\n\n const role = simplifyAndroidClass(tagName);\n\n const a11y: A11yNode = { ref, role };\n const name = attrs[\"@content-desc\"] ?? attrs[\"@text\"];\n if (name) a11y.name = name;\n if (attrs[\"@text\"] && attrs[\"@text\"] !== name) a11y.value = attrs[\"@text\"];\n\n const state: A11yNode[\"state\"] = {};\n if (attrs[\"@enabled\"] === \"false\") state.disabled = true;\n if (attrs[\"@focused\"] === \"true\") state.focused = true;\n if (attrs[\"@selected\"] === \"true\") state.selected = true;\n if (Object.keys(state).length > 0) a11y.state = state;\n\n if (childrenRaw.length > 0) {\n const siblings = new Map<string, number>();\n const children: A11yNode[] = [];\n for (const child of childrenRaw) {\n const built = visit(child, siblings);\n if (built) children.push(built);\n }\n if (children.length > 0) a11y.children = children;\n }\n return a11y;\n };\n\n const hierarchy =\n raw.find((n) => Object.keys(n).some((k) => k === \"hierarchy\")) ?? raw[0];\n if (!hierarchy) {\n return {\n tree: { ref: \"e0\", role: \"RootWebArea\" },\n refIndex,\n };\n }\n const top = visit(hierarchy, new Map());\n if (top) return { tree: top, refIndex };\n return { tree: { ref: \"e0\", role: \"RootWebArea\" }, refIndex };\n}\n\nfunction firstTagName(node: RawNode): string | null {\n for (const key of Object.keys(node)) {\n if (key === \":@\") continue;\n // skip XML declarations (`<?xml ... ?>`) and processing instructions\n if (key.startsWith(\"?\")) continue;\n return key;\n }\n return null;\n}\n\n/** Map `android.widget.Button` → `Button`, fall back to the full class. */\nfunction simplifyAndroidClass(cls: string): string {\n const last = cls.split(\".\").pop();\n return last ?? cls;\n}\n","/**\n * XCUITest (iOS via Appium) accessibility-tree normalizer.\n *\n * Parses the Appium XML page source returned by\n * `driver.getPageSource()` and produces a unified `A11yNode` tree plus\n * a `refIndex` whose entries carry enough information for the engine to\n * resolve `ref → element` later (via accessibility id, name, or class\n * chain).\n *\n * Inspired by alumnium-hq/alumnium's XCUITestAccessibilityTree (MIT) —\n * see UPSTREAM_TRACKING.md. Original implementation; no verbatim copy.\n */\nimport { XMLParser } from \"fast-xml-parser\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\nexport type IosRefMeta = {\n kind: \"ios\";\n /** Accessibility id when present — primary locator. */\n accessibilityId?: string;\n name?: string;\n label?: string;\n type: string;\n /** 1-based class-chain index among siblings of the same `type`. */\n classChainIndex: number;\n};\n\nexport type IosNormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, IosRefMeta>;\n};\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n alwaysCreateTextNode: false,\n preserveOrder: true,\n});\n\ntype RawNode = Record<string, RawNode[] | undefined> & { \":@\"?: Record<string, string> };\n\nexport function parseXcuiTestTree(xmlString: string): IosNormalizedSnapshot {\n const refIndex = new Map<string, IosRefMeta>();\n let counter = 0;\n const nextRef = (): string => `e${++counter}`;\n\n let raw: RawNode[] = [];\n try {\n raw = parser.parse(xmlString) as RawNode[];\n } catch {\n raw = [];\n }\n\n const visit = (node: RawNode, classChainOcc: Map<string, number>): A11yNode | null => {\n const tagName = firstTagName(node);\n if (!tagName) return null;\n const attrs = node[\":@\"] ?? {};\n const childrenRaw = (node[tagName] as RawNode[]) ?? [];\n\n const idx = (classChainOcc.get(tagName) ?? 0) + 1;\n classChainOcc.set(tagName, idx);\n\n const ref = nextRef();\n refIndex.set(ref, {\n kind: \"ios\",\n accessibilityId: attrs[\"@name\"],\n name: attrs[\"@name\"],\n label: attrs[\"@label\"],\n type: tagName,\n classChainIndex: idx,\n });\n\n const role = tagName.startsWith(\"XCUIElementType\")\n ? tagName.slice(\"XCUIElementType\".length).toLowerCase()\n : tagName;\n\n const a11y: A11yNode = { ref, role };\n const name = attrs[\"@label\"] ?? attrs[\"@name\"];\n if (name) a11y.name = name;\n if (attrs[\"@value\"]) a11y.value = attrs[\"@value\"];\n\n const state: A11yNode[\"state\"] = {};\n if (attrs[\"@enabled\"] === \"false\") state.disabled = true;\n if (attrs[\"@selected\"] === \"true\") state.selected = true;\n if (Object.keys(state).length > 0) a11y.state = state;\n\n if (childrenRaw.length > 0) {\n const siblings = new Map<string, number>();\n const children: A11yNode[] = [];\n for (const child of childrenRaw) {\n const built = visit(child, siblings);\n if (built) children.push(built);\n }\n if (children.length > 0) a11y.children = children;\n }\n return a11y;\n };\n\n const topLevel: A11yNode[] = [];\n const rootOcc = new Map<string, number>();\n for (const node of raw) {\n const built = visit(node, rootOcc);\n if (built) topLevel.push(built);\n }\n\n if (topLevel.length === 1) {\n return { tree: topLevel[0]!, refIndex };\n }\n const rootRef = nextRef();\n refIndex.set(rootRef, {\n kind: \"ios\",\n type: \"XCUIElementTypeApplication\",\n classChainIndex: 1,\n });\n const root: A11yNode = { ref: rootRef, role: \"application\" };\n if (topLevel.length > 0) root.children = topLevel;\n return { tree: root, refIndex };\n}\n\nfunction firstTagName(node: RawNode): string | null {\n for (const key of Object.keys(node)) {\n if (key === \":@\") continue;\n // skip XML declarations (`<?xml ... ?>`) and processing instructions\n if (key.startsWith(\"?\")) continue;\n return key;\n }\n return null;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { resolve as resolvePath, isAbsolute } from \"node:path\";\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type Page,\n type Locator,\n type ConsoleMessage,\n type Request,\n type Response,\n type Dialog,\n} from \"playwright\";\nimport {\n RolepodMcpError,\n UnknownRefError,\n UnsupportedPlatformError,\n} from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport {\n parseAriaSnapshot,\n type RefMeta,\n} from \"./a11y/normalize.js\";\nimport type {\n A11ySnapshot,\n Direction,\n Engine,\n FillField,\n OpenOptions,\n Session,\n WaitCondition,\n} from \"./Engine.js\";\n\ntype WebSession = Session & {\n readonly platform: \"web\";\n readonly browser: Browser;\n readonly context: BrowserContext;\n /** Main (initial) page. Subsequent popups land in SessionInternals.pages. */\n readonly mainPage: Page;\n};\n\nexport type ConsoleEntry = {\n level: \"error\" | \"warning\" | \"info\" | \"log\" | \"debug\" | \"trace\";\n text: string;\n ts: string;\n /** Best-effort file:line if Playwright provides it. */\n location?: string;\n};\n\nexport type NetworkEntry = {\n id: number;\n url: string;\n method: string;\n status?: number;\n failure?: string;\n resource_type: string;\n ts: string;\n duration_ms?: number;\n};\n\ntype DialogArming = {\n action: \"accept\" | \"dismiss\" | \"accept_with_text\";\n text?: string;\n expiresAt: number;\n resolve: (handled: boolean) => void;\n};\n\ntype SessionInternals = {\n session: WebSession;\n refIndex: Map<string, RefMeta>;\n snapshotGeneration: number;\n refGeneration: number;\n lastSnapshotAt: string | null;\n\n // v0.5 additions\n pages: Page[];\n activePageIndex: number;\n consoleBuffer: ConsoleEntry[];\n networkBuffer: NetworkEntry[];\n networkInflight: Map<string, { id: number; startedAt: number; resourceType: string }>;\n networkNextId: number;\n dialogArming: DialogArming | null;\n captureOpts: NonNullable<OpenOptions[\"capture\"]> | undefined;\n traceStarted: boolean;\n};\n\nconst CONSOLE_BUFFER_CAP = 1000;\nconst NETWORK_BUFFER_CAP = 1000;\n\n// CDP network condition presets. Numbers match Chrome DevTools UI exactly.\nconst NETWORK_PRESETS = {\n offline: { offline: true, downloadThroughput: 0, uploadThroughput: 0, latency: 0 },\n \"slow-3g\": {\n offline: false,\n // 500 Kbps down / 500 Kbps up / 400ms RTT\n downloadThroughput: (500 * 1024) / 8,\n uploadThroughput: (500 * 1024) / 8,\n latency: 400,\n },\n \"fast-3g\": {\n offline: false,\n downloadThroughput: (1.5 * 1024 * 1024) / 8,\n uploadThroughput: (750 * 1024) / 8,\n latency: 150,\n },\n \"slow-4g\": {\n offline: false,\n downloadThroughput: (4 * 1024 * 1024) / 8,\n uploadThroughput: (3 * 1024 * 1024) / 8,\n latency: 100,\n },\n \"fast-4g\": {\n offline: false,\n downloadThroughput: (9 * 1024 * 1024) / 8,\n uploadThroughput: (4.5 * 1024 * 1024) / 8,\n latency: 60,\n },\n \"no-throttling\": {\n offline: false,\n downloadThroughput: -1,\n uploadThroughput: -1,\n latency: 0,\n },\n} as const;\n\nfunction pushRing<T>(buf: T[], entry: T, cap: number): void {\n buf.push(entry);\n if (buf.length > cap) buf.splice(0, buf.length - cap);\n}\n\nfunction mapConsoleLevel(t: string): ConsoleEntry[\"level\"] {\n switch (t) {\n case \"error\":\n return \"error\";\n case \"warning\":\n return \"warning\";\n case \"info\":\n return \"info\";\n case \"debug\":\n return \"debug\";\n case \"trace\":\n return \"trace\";\n default:\n return \"log\";\n }\n}\n\nfunction formatConsoleLocation(msg: ConsoleMessage): string | undefined {\n try {\n const loc = msg.location();\n if (!loc?.url) return undefined;\n return `${loc.url}:${loc.lineNumber}:${loc.columnNumber}`;\n } catch {\n return undefined;\n }\n}\n\nfunction findNetworkEntry(\n buf: NetworkEntry[],\n req: Request,\n): NetworkEntry | undefined {\n // Walk back-to-front — most recent match wins (handles redirects /\n // duplicate URLs with separate ids).\n const url = req.url();\n const method = req.method();\n for (let i = buf.length - 1; i >= 0; i--) {\n const e = buf[i];\n if (!e) continue;\n if (e.url === url && e.method === method && e.status === undefined && !e.failure) {\n return e;\n }\n }\n return undefined;\n}\n\n/**\n * PlaywrightEngine — v0.1 web-only implementation backed by Playwright's\n * Chromium / Firefox / WebKit drivers and the built-in\n * `page.accessibility.snapshot()` API.\n *\n * The interface contract (Engine.ts) is shared with AppiumEngine and the\n * optional SeleniumEngine.\n */\nexport class PlaywrightEngine implements Engine {\n readonly id = \"playwright\" as const;\n\n private readonly sessions = new Map<string, SessionInternals>();\n\n async open(opts: OpenOptions): Promise<Session> {\n if (opts.platform !== \"web\") {\n throw new UnsupportedPlatformError(opts.platform);\n }\n\n const browserName = opts.browser ?? \"chromium\";\n const launcher =\n browserName === \"firefox\"\n ? firefox\n : browserName === \"webkit\"\n ? webkit\n : chromium;\n\n const headless = opts.headless ?? (process.env.CI ? true : false);\n const browser = await launcher.launch({ headless });\n\n const contextOptions: Parameters<typeof browser.newContext>[0] = {};\n if (opts.viewport) contextOptions.viewport = opts.viewport;\n if (opts.user_agent) contextOptions.userAgent = opts.user_agent;\n if (opts.locale) contextOptions.locale = opts.locale;\n\n // Wire capture lifecycle. Playwright requires recordHar / recordVideo\n // to be set at context creation; trace is start/stop-based.\n if (opts.capture?.har) {\n contextOptions.recordHar = { path: opts.capture.har.path };\n }\n if (opts.capture?.video) {\n contextOptions.recordVideo = {\n dir: opts.capture.video.dir,\n size:\n opts.capture.video.sizeWidth && opts.capture.video.sizeHeight\n ? {\n width: opts.capture.video.sizeWidth,\n height: opts.capture.video.sizeHeight,\n }\n : undefined,\n };\n }\n\n const context = await browser.newContext(contextOptions);\n\n if (opts.capture?.trace) {\n await context.tracing.start({\n screenshots: true,\n snapshots: true,\n sources: false,\n });\n }\n\n const page = await context.newPage();\n const sessionId = randomUUID();\n\n const internals: SessionInternals = {\n session: {\n id: sessionId,\n platform: \"web\",\n browser,\n context,\n mainPage: page,\n },\n refIndex: new Map(),\n snapshotGeneration: 0,\n refGeneration: -1,\n lastSnapshotAt: null,\n pages: [page],\n activePageIndex: 0,\n consoleBuffer: [],\n networkBuffer: [],\n networkInflight: new Map(),\n networkNextId: 1,\n dialogArming: null,\n captureOpts: opts.capture,\n traceStarted: !!opts.capture?.trace,\n };\n\n this.attachPageListeners(internals, page);\n context.on(\"page\", (newPage) => {\n internals.pages.push(newPage);\n this.attachPageListeners(internals, newPage);\n });\n\n if (opts.url) {\n await page.goto(opts.url, { waitUntil: \"domcontentloaded\" });\n }\n\n this.sessions.set(sessionId, internals);\n log.info(\"session opened\", {\n session_id: sessionId,\n browser: browserName,\n url: opts.url ?? null,\n capture: opts.capture\n ? Object.keys(opts.capture).filter(\n (k) => opts.capture![k as keyof typeof opts.capture],\n )\n : [],\n });\n return { id: sessionId, platform: \"web\" };\n }\n\n async close(session: Session): Promise<void> {\n const s = this.requireSession(session.id);\n\n // Stop tracing before context closes — trace.zip is written here.\n if (s.traceStarted && s.captureOpts?.trace) {\n const tracePath = resolvePath(s.captureOpts.trace.artifactDir, \"trace.zip\");\n await s.session.context.tracing\n .stop({ path: tracePath })\n .catch((err: unknown) => {\n log.warn(\"trace stop failed\", {\n session_id: session.id,\n err: String(err),\n });\n });\n }\n\n await s.session.context.close().catch((err: unknown) => {\n log.warn(\"context close failed\", { session_id: session.id, err: String(err) });\n });\n await s.session.browser.close().catch((err: unknown) => {\n log.warn(\"browser close failed\", { session_id: session.id, err: String(err) });\n });\n this.sessions.delete(session.id);\n log.info(\"session closed\", { session_id: session.id });\n }\n\n async snapshot(\n session: Session,\n mode: \"visible\" | \"full\" = \"visible\",\n ): Promise<A11ySnapshot> {\n const s = this.requireSession(session.id);\n // Playwright 1.60 removed `page.accessibility`. The ai-mode aria\n // snapshot is the supported successor — it carries `[ref=eN]` markers\n // that the `aria-ref=` locator can resolve back to elements.\n const ariaYaml = await this.activePage(s).ariaSnapshot({ mode: \"ai\" });\n const { tree, refIndex } = parseAriaSnapshot(ariaYaml);\n void mode; // depth control will route here once we expose `depth` to callers.\n\n s.snapshotGeneration += 1;\n s.refGeneration = s.snapshotGeneration;\n s.refIndex = refIndex;\n s.lastSnapshotAt = new Date().toISOString();\n\n return {\n session_id: session.id,\n platform: \"web\",\n url_or_screen: this.activePage(s).url(),\n taken_at: s.lastSnapshotAt,\n tree,\n };\n }\n\n async click(\n session: Session,\n ref: string,\n opts?: { button?: \"left\" | \"right\" | \"middle\" },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n await locator.click(opts?.button ? { button: opts.button } : undefined);\n this.invalidateRefs(s);\n }\n\n async type(\n session: Session,\n ref: string,\n text: string,\n opts?: { clearFirst?: boolean },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n if (opts?.clearFirst) await locator.fill(\"\");\n await locator.fill(text);\n this.invalidateRefs(s);\n }\n\n async key(session: Session, key: string): Promise<void> {\n const s = this.requireSession(session.id);\n await this.activePage(s).keyboard.press(key);\n this.invalidateRefs(s);\n }\n\n async scroll(\n session: Session,\n dir: Direction,\n amount = 400,\n ref?: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const dx = dir === \"left\" ? -amount : dir === \"right\" ? amount : 0;\n const dy = dir === \"up\" ? -amount : dir === \"down\" ? amount : 0;\n if (ref) {\n const locator = this.resolveLocator(s, ref);\n await locator.evaluate(\n (el, [x, y]) => el.scrollBy(x as number, y as number),\n [dx, dy],\n );\n } else {\n await this.activePage(s).mouse.wheel(dx, dy);\n }\n this.invalidateRefs(s);\n }\n\n async waitFor(\n session: Session,\n cond: WaitCondition,\n timeoutMs = 10_000,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const page = this.activePage(s);\n switch (cond.kind) {\n case \"text_visible\":\n await page\n .getByText(cond.text, { exact: false })\n .first()\n .waitFor({ state: \"visible\", timeout: timeoutMs });\n break;\n case \"ref_exists\":\n await page\n .getByRole(\"button\", { name: cond.query })\n .first()\n .waitFor({ state: \"attached\", timeout: timeoutMs });\n break;\n case \"url_matches\":\n await page.waitForURL(new RegExp(cond.pattern), { timeout: timeoutMs });\n break;\n case \"idle\":\n await page.waitForLoadState(\"networkidle\", { timeout: timeoutMs });\n await page.waitForTimeout(cond.ms);\n break;\n }\n this.invalidateRefs(s);\n }\n\n async screenshot(session: Session, fullPage = false): Promise<Buffer> {\n const s = this.requireSession(session.id);\n return this.activePage(s).screenshot({ fullPage });\n }\n\n async navigate(session: Session, url: string): Promise<void> {\n const s = this.requireSession(session.id);\n if (s.session.platform !== \"web\") {\n throw new UnsupportedPlatformError(s.session.platform);\n }\n await this.activePage(s).goto(url, { waitUntil: \"domcontentloaded\" });\n this.invalidateRefs(s);\n }\n\n /**\n * Composite-only escape hatch — exposes the raw Playwright Page so a\n * composite tool that genuinely needs page-level APIs (axe-core,\n * `getByText`, etc.) can use them without bloating the Engine interface\n * with web-specific verbs. Throws if the session is not web.\n */\n getPageForSession(sessionId: string): Page {\n const s = this.requireSession(sessionId);\n if (s.session.platform !== \"web\") {\n throw new UnsupportedPlatformError(s.session.platform);\n }\n return this.activePage(s);\n }\n\n /** Increment generation; the next ref-using call will see them as stale. */\n bumpGeneration(sessionId: string): void {\n const s = this.requireSession(sessionId);\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 — input additions\n // -------------------------------------------------------------------------\n\n async hover(session: Session, ref: string): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n await locator.hover();\n // Hover does not modify DOM in the same way click does; keep refs valid.\n }\n\n async drag(\n session: Session,\n fromRef: string,\n toRef: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const from = this.resolveLocator(s, fromRef);\n const to = this.resolveLocator(s, toRef);\n await from.dragTo(to);\n this.invalidateRefs(s);\n }\n\n async fillForm(session: Session, fields: FillField[]): Promise<void> {\n const s = this.requireSession(session.id);\n for (const field of fields) {\n const locator = this.resolveLocator(s, field.ref);\n const kind = field.kind;\n if (kind === \"checkbox\" || kind === \"radio\") {\n const checked = typeof field.value === \"boolean\"\n ? field.value\n : field.value === \"true\" || field.value === \"on\";\n await locator.setChecked(checked);\n } else if (kind === \"select\") {\n await locator.selectOption(String(field.value));\n } else {\n // input / textarea / contenteditable\n await locator.fill(String(field.value));\n }\n }\n this.invalidateRefs(s);\n }\n\n async uploadFile(\n session: Session,\n ref: string,\n filePath: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n if (!isAbsolute(filePath)) {\n throw new RolepodMcpError(\n \"invalid_input\",\n `upload_file requires an absolute path; got \"${filePath}\".`,\n { file_path: filePath },\n );\n }\n const locator = this.resolveLocator(s, ref);\n await locator.setInputFiles(filePath);\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 — web-only extensions (not on Engine interface; tools cast to\n // PlaywrightEngine before calling).\n // -------------------------------------------------------------------------\n\n /**\n * Pre-arm a one-shot dialog handler for the next dialog raised on the\n * active page. Returns when either the dialog fires (and is handled)\n * or the timeout elapses. The caller is expected to trigger the\n * dialog (via click etc.) AFTER arming.\n */\n async handleDialog(\n sessionId: string,\n opts: {\n action: \"accept\" | \"dismiss\" | \"accept_with_text\";\n text?: string;\n timeoutMs?: number;\n },\n ): Promise<{ handled: boolean }> {\n const s = this.requireSession(sessionId);\n const timeoutMs = opts.timeoutMs ?? 30_000;\n const expiresAt = Date.now() + timeoutMs;\n\n // If a previous arming is still pending, treat the new call as a\n // replacement.\n if (s.dialogArming) {\n s.dialogArming.resolve(false);\n }\n\n return new Promise<{ handled: boolean }>((resolve) => {\n const arming: DialogArming = {\n action: opts.action,\n text: opts.text,\n expiresAt,\n resolve: (handled) => {\n s.dialogArming = null;\n resolve({ handled });\n },\n };\n s.dialogArming = arming;\n\n // Timeout safety\n const timer = setTimeout(() => {\n if (s.dialogArming === arming) {\n s.dialogArming = null;\n resolve({ handled: false });\n }\n }, timeoutMs);\n timer.unref?.();\n });\n }\n\n getConsole(\n sessionId: string,\n opts?: {\n levels?: ConsoleEntry[\"level\"][];\n contains?: string;\n clear?: boolean;\n limit?: number;\n },\n ): ConsoleEntry[] {\n const s = this.requireSession(sessionId);\n const levels = opts?.levels;\n const contains = opts?.contains;\n const limit = opts?.limit ?? 50;\n let entries = s.consoleBuffer;\n if (levels && levels.length > 0) {\n entries = entries.filter((e) => levels.includes(e.level));\n }\n if (contains) {\n entries = entries.filter((e) => e.text.includes(contains));\n }\n const result = entries.slice(-limit);\n if (opts?.clear) s.consoleBuffer = [];\n return result;\n }\n\n getNetwork(\n sessionId: string,\n opts?: {\n urlPattern?: string;\n patternKind?: \"substring\" | \"regex\";\n method?: string;\n statusRange?: { min: number; max: number };\n onlyFailed?: boolean;\n clear?: boolean;\n limit?: number;\n },\n ): NetworkEntry[] {\n const s = this.requireSession(sessionId);\n let entries = s.networkBuffer;\n if (opts?.urlPattern) {\n if (opts.patternKind === \"regex\") {\n const re = new RegExp(opts.urlPattern);\n entries = entries.filter((e) => re.test(e.url));\n } else {\n entries = entries.filter((e) => e.url.includes(opts.urlPattern!));\n }\n }\n if (opts?.method) {\n const m = opts.method.toUpperCase();\n entries = entries.filter((e) => e.method.toUpperCase() === m);\n }\n if (opts?.statusRange) {\n const { min, max } = opts.statusRange;\n entries = entries.filter(\n (e) =>\n e.status !== undefined && e.status >= min && e.status <= max,\n );\n }\n if (opts?.onlyFailed) {\n entries = entries.filter(\n (e) => !!e.failure || (e.status !== undefined && e.status >= 400),\n );\n }\n const limit = opts?.limit ?? 50;\n const result = entries.slice(-limit);\n if (opts?.clear) s.networkBuffer = [];\n return result;\n }\n\n /**\n * Read the consoleBuffer/networkBuffer directly without filtering —\n * used by verify_ui_flow expect evaluators.\n */\n peekBuffers(sessionId: string): {\n console: ConsoleEntry[];\n network: NetworkEntry[];\n } {\n const s = this.requireSession(sessionId);\n return { console: s.consoleBuffer, network: s.networkBuffer };\n }\n\n /**\n * Runtime mutation of context-level emulation. CPU + network throttle\n * use CDP and only work on chromium; everything else is cross-browser.\n */\n async setEnv(\n sessionId: string,\n opts: {\n viewport?: { width: number; height: number };\n offline?: boolean;\n geolocation?: { latitude: number; longitude: number; accuracy?: number };\n colorScheme?: \"light\" | \"dark\" | \"no-preference\";\n reducedMotion?: \"reduce\" | \"no-preference\";\n extraHeaders?: Record<string, string>;\n networkThrottle?:\n | \"offline\"\n | \"slow-3g\"\n | \"fast-3g\"\n | \"slow-4g\"\n | \"fast-4g\"\n | \"no-throttling\";\n cpuThrottle?: number;\n },\n ): Promise<void> {\n const s = this.requireSession(sessionId);\n const page = this.activePage(s);\n const ctx = s.session.context;\n\n if (opts.viewport) {\n await page.setViewportSize(opts.viewport);\n }\n if (opts.offline !== undefined) {\n await ctx.setOffline(opts.offline);\n }\n if (opts.geolocation) {\n await ctx.setGeolocation(opts.geolocation);\n }\n if (opts.extraHeaders) {\n await ctx.setExtraHTTPHeaders(opts.extraHeaders);\n }\n if (opts.colorScheme || opts.reducedMotion) {\n await page.emulateMedia({\n ...(opts.colorScheme ? { colorScheme: opts.colorScheme } : {}),\n ...(opts.reducedMotion ? { reducedMotion: opts.reducedMotion } : {}),\n });\n }\n if (opts.networkThrottle || opts.cpuThrottle !== undefined) {\n const browserName = ctx.browser()?.browserType().name();\n if (browserName !== \"chromium\") {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `networkThrottle / cpuThrottle require chromium (CDP-backed); current browser is \"${browserName}\".`,\n );\n }\n const cdp = await ctx.newCDPSession(page);\n try {\n if (opts.networkThrottle) {\n const preset = NETWORK_PRESETS[opts.networkThrottle];\n await cdp.send(\"Network.enable\");\n await cdp.send(\"Network.emulateNetworkConditions\", preset);\n }\n if (opts.cpuThrottle !== undefined) {\n await cdp.send(\"Emulation.setCPUThrottlingRate\", {\n rate: opts.cpuThrottle,\n });\n }\n } finally {\n await cdp.detach().catch(() => undefined);\n }\n }\n this.invalidateRefs(s);\n }\n\n /**\n * Execute a JavaScript function in the page context. ALWAYS gated by\n * the tool layer (`ROLEPOD_ALLOW_EVAL=1`); this method does not enforce\n * the env check.\n */\n async evaluate(\n sessionId: string,\n script: string,\n args?: unknown[],\n ): Promise<unknown> {\n const s = this.requireSession(sessionId);\n const page = this.activePage(s);\n // Script body runs inside `(async () => { ... })()` in the page context.\n // Caller can `return await fetch(...)` etc. `args` is exposed as a global\n // `args` array.\n return page.evaluate(\n ({ src, a }) =>\n // eslint-disable-next-line no-new-func\n new Function(\"args\", `return (async () => { ${src} })();`)(a),\n { src: script, a: args ?? [] },\n );\n }\n\n listPages(sessionId: string): {\n index: number;\n url: string;\n title_promise: Promise<string>;\n active: boolean;\n }[] {\n const s = this.requireSession(sessionId);\n return s.pages.map((p, i) => ({\n index: i,\n url: p.url(),\n title_promise: p.title(),\n active: i === s.activePageIndex,\n }));\n }\n\n async switchPage(sessionId: string, index: number): Promise<void> {\n const s = this.requireSession(sessionId);\n if (index < 0 || index >= s.pages.length) {\n throw new RolepodMcpError(\n \"invalid_input\",\n `Page index ${index} out of range (have ${s.pages.length} page(s)).`,\n { index, available: s.pages.length },\n );\n }\n s.activePageIndex = index;\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // Internal helpers\n // -------------------------------------------------------------------------\n\n private activePage(s: SessionInternals): Page {\n return s.pages[s.activePageIndex] ?? s.session.mainPage;\n }\n\n private attachPageListeners(s: SessionInternals, page: Page): void {\n page.on(\"console\", (msg: ConsoleMessage) => {\n const level = mapConsoleLevel(msg.type());\n pushRing(\n s.consoleBuffer,\n {\n level,\n text: msg.text(),\n ts: new Date().toISOString(),\n location: formatConsoleLocation(msg),\n },\n CONSOLE_BUFFER_CAP,\n );\n });\n\n page.on(\"request\", (req: Request) => {\n const id = s.networkNextId++;\n s.networkInflight.set(req.url() + \"::\" + req.method() + \"::\" + id, {\n id,\n startedAt: Date.now(),\n resourceType: req.resourceType(),\n });\n // Optimistic entry — will be updated on response/failed.\n pushRing(\n s.networkBuffer,\n {\n id,\n url: req.url(),\n method: req.method(),\n resource_type: req.resourceType(),\n ts: new Date().toISOString(),\n },\n NETWORK_BUFFER_CAP,\n );\n });\n\n page.on(\"response\", (res: Response) => {\n const req = res.request();\n const entry = findNetworkEntry(s.networkBuffer, req);\n if (entry) {\n entry.status = res.status();\n entry.duration_ms = Date.now() - new Date(entry.ts).getTime();\n }\n });\n\n page.on(\"requestfailed\", (req: Request) => {\n const entry = findNetworkEntry(s.networkBuffer, req);\n if (entry) {\n entry.failure = req.failure()?.errorText ?? \"request failed\";\n }\n });\n\n page.on(\"dialog\", (dialog: Dialog) => {\n void this.handlePageDialog(s, dialog);\n });\n }\n\n private async handlePageDialog(\n s: SessionInternals,\n dialog: Dialog,\n ): Promise<void> {\n const arm = s.dialogArming;\n if (!arm || Date.now() > arm.expiresAt) {\n // Nothing armed → auto-dismiss so the page does not hang.\n await dialog.dismiss().catch(() => undefined);\n if (arm) arm.resolve(false);\n return;\n }\n try {\n if (arm.action === \"accept\") {\n await dialog.accept();\n } else if (arm.action === \"accept_with_text\") {\n await dialog.accept(arm.text ?? \"\");\n } else {\n await dialog.dismiss();\n }\n arm.resolve(true);\n } catch (err) {\n log.warn(\"dialog handle failed\", {\n session_id: s.session.id,\n err: String(err),\n });\n arm.resolve(false);\n }\n }\n\n private requireSession(sessionId: string): SessionInternals {\n const s = this.sessions.get(sessionId);\n if (!s) {\n throw new RolepodMcpError(\n \"unknown_session\",\n `No open session with id \"${sessionId}\".`,\n { session_id: sessionId },\n );\n }\n return s;\n }\n\n private resolveLocator(s: SessionInternals, ref: string): Locator {\n if (s.refGeneration !== s.snapshotGeneration) {\n throw new RolepodMcpError(\n \"stale_ref\",\n `Ref \"${ref}\" is stale — re-snapshot before retrying.`,\n {\n session_id: s.session.id,\n ref,\n last_valid_snapshot_at: s.lastSnapshotAt,\n },\n );\n }\n const meta = s.refIndex.get(ref);\n if (!meta) throw new UnknownRefError(s.session.id, ref);\n // The synthetic refs (`s1`, `s2`, ...) we issue for the wrapper root\n // are not real elements; the Lead should never click them.\n if (meta.ref.startsWith(\"s\")) {\n throw new UnknownRefError(s.session.id, ref);\n }\n return this.activePage(s).locator(`aria-ref=${meta.ref}`);\n }\n\n private invalidateRefs(s: SessionInternals): void {\n s.snapshotGeneration += 1;\n }\n\n /**\n * Test / shutdown helper. Closes every open session.\n */\n async shutdown(): Promise<void> {\n const ids = [...this.sessions.keys()];\n await Promise.all(\n ids.map((id) => this.close({ id, platform: \"web\" }).catch(() => undefined)),\n );\n }\n}\n","import yaml from \"js-yaml\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\n/**\n * Unified accessibility-tree normalization.\n *\n * Implements the Chromium path by parsing Playwright 1.60's\n * `page.ariaSnapshot({ mode: \"ai\" })` YAML output. Each leaf carries a\n * stable `[ref=eN]` marker that Playwright resolves back to a real\n * locator via `page.locator(\"aria-ref=eN\")`.\n *\n * Mobile A11y normalizers (XCUITest / UIAutomator2) are alumnium-inspired\n * — see THIRD_PARTY.md + UPSTREAM_TRACKING.md.\n */\n\n/** Locator metadata for ref → driver resolution. Never sent to the Lead. */\nexport type WebRefMeta = {\n kind: \"web\";\n /** The `eN` ref string. Used as `page.locator(\"aria-ref=\" + ref)`. */\n ref: string;\n};\n\nexport type RefMeta = WebRefMeta;\n\nexport type NormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, RefMeta>;\n};\n\ntype YamlValue = string | YamlArray | YamlObject;\ntype YamlArray = YamlValue[];\ntype YamlObject = { [key: string]: YamlValue | null };\n\nconst KEY_RE = /^(?<role>\\S+?)(?:\\s+\"(?<name>(?:[^\"\\\\]|\\\\.)*)\")?(?<rest>(?:\\s+\\[[^\\]]+\\])*)\\s*$/;\nconst ATTR_RE = /\\[([^=\\]]+)(?:=([^\\]]+))?\\]/g;\n\ntype ParsedKey = {\n role: string;\n name?: string;\n attrs: Record<string, string>;\n};\n\nfunction parseKey(key: string): ParsedKey {\n const trimmed = key.trim();\n const m = KEY_RE.exec(trimmed);\n if (!m) {\n return { role: trimmed, attrs: {} };\n }\n const groups = m.groups!;\n const out: ParsedKey = { role: groups.role!, attrs: {} };\n if (groups.name !== undefined) out.name = unescapeQuoted(groups.name);\n const rest = groups.rest ?? \"\";\n for (const attrMatch of rest.matchAll(ATTR_RE)) {\n const [, k, v] = attrMatch;\n if (k) out.attrs[k] = v ?? \"true\";\n }\n return out;\n}\n\nfunction unescapeQuoted(s: string): string {\n return s.replace(/\\\\(.)/g, \"$1\");\n}\n\n/**\n * Parse a Playwright ai-mode aria snapshot string and produce the unified\n * A11yNode tree plus a refIndex for locator resolution.\n */\nexport function parseAriaSnapshot(snapshotYaml: string): NormalizedSnapshot {\n const refIndex = new Map<string, RefMeta>();\n let synthCounter = 0;\n const nextSynthRef = (): string => `s${++synthCounter}`;\n\n const consumeNode = (value: YamlValue): A11yNode | null => {\n // Object with one key like { 'link \"Home\" [ref=e3]': [...] | \"text\" }\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const keys = Object.keys(value);\n if (keys.length !== 1) return null;\n const key = keys[0]!;\n // Pseudo-keys like `/url` carry hyperlink metadata, not real nodes.\n if (key.startsWith(\"/\")) return null;\n const inner = value[key];\n if (typeof inner === \"string\") return buildNode(key, null, inner);\n if (Array.isArray(inner)) return buildNode(key, inner, undefined);\n return buildNode(key, null, undefined);\n }\n // Bare string like `link \"Home\" [ref=e3]` or `text \"hello\"`\n if (typeof value === \"string\") {\n return buildNode(value, null, undefined);\n }\n return null;\n };\n\n const buildNode = (\n key: string,\n rawChildren: YamlValue | null | undefined,\n inlineText: string | undefined,\n ): A11yNode => {\n const parsed = parseKey(key);\n const ref = parsed.attrs.ref ?? nextSynthRef();\n refIndex.set(ref, { kind: \"web\", ref });\n\n const node: A11yNode = {\n ref,\n role: parsed.role,\n };\n if (parsed.name !== undefined) node.name = parsed.name;\n if (inlineText !== undefined) {\n node.value = inlineText;\n } else if (parsed.attrs.level) {\n node.value = parsed.attrs.level;\n }\n\n const state: A11yNode[\"state\"] = {};\n if (\"disabled\" in parsed.attrs) state.disabled = parsed.attrs.disabled !== \"false\";\n if (\"focused\" in parsed.attrs) state.focused = parsed.attrs.focused !== \"false\";\n if (\"selected\" in parsed.attrs) state.selected = parsed.attrs.selected !== \"false\";\n if (\"expanded\" in parsed.attrs) state.expanded = parsed.attrs.expanded !== \"false\";\n if (Object.keys(state).length > 0) node.state = state;\n\n if (Array.isArray(rawChildren)) {\n const children: A11yNode[] = [];\n for (const child of rawChildren) {\n const built = consumeNode(child);\n if (built) children.push(built);\n }\n if (children.length > 0) node.children = children;\n }\n return node;\n };\n\n let loaded: YamlValue;\n try {\n loaded = (yaml.load(snapshotYaml) as YamlValue) ?? [];\n } catch {\n loaded = [];\n }\n\n const topLevel: A11yNode[] = [];\n if (Array.isArray(loaded)) {\n for (const entry of loaded) {\n const node = consumeNode(entry);\n if (node) topLevel.push(node);\n }\n } else if (loaded && typeof loaded === \"object\") {\n const node = consumeNode(loaded);\n if (node) topLevel.push(node);\n } else if (typeof loaded === \"string\" && loaded.length > 0) {\n const node = consumeNode(loaded);\n if (node) topLevel.push(node);\n }\n\n // The composite needs a single root. Wrap when there are 0 or >1 entries.\n if (topLevel.length === 1) {\n return { tree: topLevel[0]!, refIndex };\n }\n const rootRef = nextSynthRef();\n refIndex.set(rootRef, { kind: \"web\", ref: rootRef });\n const root: A11yNode = { ref: rootRef, role: \"RootWebArea\" };\n if (topLevel.length > 0) root.children = topLevel;\n return { tree: root, refIndex };\n}\n","import { RolepodMcpError } from \"../util/errors.js\";\nimport { AppiumEngine } from \"./AppiumEngine.js\";\nimport { PlaywrightEngine } from \"./PlaywrightEngine.js\";\nimport type { Engine } from \"./Engine.js\";\n\n/**\n * Engine selection happens once at server startup. v0.3 wires\n * Playwright for `web` and Appium for `ios`/`android`. The\n * `ROLEPOD_MCP_WEB_ENGINE` env var (D-012) only governs the *web*\n * engine; mobile always routes to Appium.\n */\nexport function createWebEngine(): Engine {\n const choice = (process.env.ROLEPOD_MCP_WEB_ENGINE ?? \"playwright\").toLowerCase();\n switch (choice) {\n case \"playwright\":\n return new PlaywrightEngine();\n case \"selenium\":\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"SeleniumEngine ships in v0.4 — set ROLEPOD_MCP_WEB_ENGINE=playwright until then.\",\n { requested: choice },\n );\n default:\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `Unknown web engine \"${choice}\" — supported: playwright.`,\n { requested: choice },\n );\n }\n}\n\nexport function createMobileEngine(): Engine {\n return new AppiumEngine();\n}\n\n/** Back-compat alias for v0.1 callers. */\nexport function createEngine(): Engine {\n return createWebEngine();\n}\n","import { UnknownSessionError, UnsupportedPlatformError } from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport type { Engine, OpenOptions, Platform, Session } from \"../engine/Engine.js\";\n\n/**\n * Routes sessions to the correct engine and enforces idle-timeout cleanup.\n *\n * v0.1: only PlaywrightEngine is wired up, so every `platform: 'web'`\n * request goes there. AppiumEngine (v0.3) will register against the\n * `ios`/`android` platform keys without touching tool code.\n */\nexport class SessionRegistry {\n private readonly enginesByPlatform = new Map<Platform, Engine>();\n private readonly engineBySession = new Map<string, Engine>();\n private readonly platformBySession = new Map<string, Platform>();\n private readonly lastActivity = new Map<string, number>();\n private readonly idleTimeoutMs: number;\n private idleTimer: NodeJS.Timeout | null = null;\n\n constructor(opts: { idleTimeoutMs?: number } = {}) {\n this.idleTimeoutMs = opts.idleTimeoutMs ?? 5 * 60 * 1000;\n }\n\n /** Register an engine as the handler for a given platform. */\n register(platform: Platform, engine: Engine): void {\n this.enginesByPlatform.set(platform, engine);\n }\n\n async open(opts: OpenOptions): Promise<Session> {\n const engine = this.enginesByPlatform.get(opts.platform);\n if (!engine) throw new UnsupportedPlatformError(opts.platform);\n const session = await engine.open(opts);\n this.engineBySession.set(session.id, engine);\n this.platformBySession.set(session.id, session.platform);\n this.touch(session.id);\n this.ensureIdleSweep();\n return session;\n }\n\n engineFor(sessionId: string): Engine {\n const engine = this.engineBySession.get(sessionId);\n if (!engine) throw new UnknownSessionError(sessionId);\n this.touch(sessionId);\n return engine;\n }\n\n async close(session: Session): Promise<void> {\n const engine = this.engineBySession.get(session.id);\n if (!engine) throw new UnknownSessionError(session.id);\n await engine.close(session);\n this.engineBySession.delete(session.id);\n this.platformBySession.delete(session.id);\n this.lastActivity.delete(session.id);\n }\n\n /** Look up the platform recorded for an open session. */\n platformOf(sessionId: string): Platform {\n const platform = this.platformBySession.get(sessionId);\n if (!platform) throw new UnknownSessionError(sessionId);\n return platform;\n }\n\n async shutdown(): Promise<void> {\n if (this.idleTimer) {\n clearInterval(this.idleTimer);\n this.idleTimer = null;\n }\n const closes: Array<Promise<void>> = [];\n for (const [sessionId, engine] of this.engineBySession) {\n const platform = this.platformFor(sessionId);\n closes.push(\n engine\n .close({ id: sessionId, platform })\n .catch((err: unknown) =>\n log.warn(\"shutdown close failed\", { sessionId, err: String(err) }),\n ),\n );\n }\n await Promise.all(closes);\n this.engineBySession.clear();\n this.platformBySession.clear();\n this.lastActivity.clear();\n }\n\n private touch(sessionId: string): void {\n this.lastActivity.set(sessionId, Date.now());\n }\n\n private platformFor(sessionId: string): Platform {\n return this.platformBySession.get(sessionId) ?? \"web\";\n }\n\n private ensureIdleSweep(): void {\n if (this.idleTimer || this.idleTimeoutMs <= 0) return;\n const interval = Math.max(30_000, Math.floor(this.idleTimeoutMs / 4));\n this.idleTimer = setInterval(() => {\n const cutoff = Date.now() - this.idleTimeoutMs;\n for (const [sessionId, lastSeen] of this.lastActivity) {\n if (lastSeen < cutoff) {\n const engine = this.engineBySession.get(sessionId);\n if (!engine) {\n this.lastActivity.delete(sessionId);\n continue;\n }\n log.info(\"idle session sweep — closing\", { sessionId });\n engine\n .close({ id: sessionId, platform: this.platformFor(sessionId) })\n .catch((err: unknown) =>\n log.warn(\"idle close failed\", { sessionId, err: String(err) }),\n )\n .finally(() => {\n this.engineBySession.delete(sessionId);\n this.lastActivity.delete(sessionId);\n });\n }\n }\n }, interval);\n this.idleTimer.unref();\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n ToolNames,\n verifyUiFlowShape,\n type A11yNode,\n type VerifyUiFlowInput,\n} from \"../../schema/tools.js\";\nimport type {\n A11ySnapshot,\n Engine,\n OpenOptions,\n Session,\n} from \"../../engine/Engine.js\";\nimport { ddmin } from \"../../replay/minimize.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest, type ManifestArtifact } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolContext, ToolModule } from \"../types.js\";\n\n/**\n * Composite `verify_ui_flow` — drive a session through steps and evaluate\n * expectations against the resulting state.\n *\n * - `mode: 'assert'` (default): pass = \"expected feature works\".\n * - `mode: 'reproduce'`: pass = \"expected bug surfaced\". When `minimize`\n * is true (default) and the initial run reproduces, the composite\n * performs a linear delta-removal pass over `steps` to find a smaller\n * sequence that still reproduces. See D-025.\n */\nexport const verifyUiFlowTool: ToolModule<typeof verifyUiFlowShape> = {\n name: ToolNames.verifyUiFlow,\n description:\n \"Open a session, run UI steps, evaluate assertions, and save evidence. Set mode='reproduce' for bug reproduction with optional step minimization.\",\n inputShape: verifyUiFlowShape,\n build(ctx) {\n return safeHandler(async (args: VerifyUiFlowInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"verify\",\n { skill: \"verify-ui\" },\n );\n\n const initial = await runFlow(ctx, args, args.steps, runDir, {\n captureEvidence: true,\n bundleName: \"replay.json\",\n });\n\n const result: Record<string, unknown> = {\n run_id: runId,\n mode: args.mode,\n passed: initial.passed,\n evidence_paths: initial.evidence,\n };\n if (initial.failedAtStep !== undefined) result.failed_at_step = initial.failedAtStep;\n if (initial.failureReason !== undefined) result.failure_reason = initial.failureReason;\n if (initial.finalUrl !== undefined) result.final_url_or_screen = initial.finalUrl;\n\n if (args.mode === \"reproduce\" && initial.passed && args.minimize) {\n const min = await minimize(ctx, args, args.steps, runDir);\n result.minimized = {\n original_step_count: args.steps.length,\n minimized_step_count: min.steps.length,\n minimal_steps: min.steps,\n steps_removed: min.removed,\n replay_bundle: min.replayPath,\n attempts: min.attempts,\n };\n }\n\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: initial.passed ? \"pass\" : \"fail\",\n summary: buildVerifySummary(args, initial),\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: flattenVerifyEvidence(initial.evidence),\n metadata: {\n mode: args.mode,\n step_count: args.steps.length,\n expect_count: args.expect.length,\n ...(initial.finalUrl !== undefined ? { final_url: initial.finalUrl } : {}),\n },\n });\n if (manifestPath) result.manifest = manifestPath;\n\n return ok(result);\n });\n },\n};\n\nfunction buildVerifySummary(\n args: VerifyUiFlowInput,\n outcome: RunOutcome,\n): string {\n const stepCount = args.steps.length;\n const expectCount = args.expect.length;\n if (outcome.passed) {\n return `${stepCount} step(s), ${expectCount} expect(s) passed`;\n }\n if (outcome.failedAtStep !== undefined) {\n return `failed at step ${outcome.failedAtStep}: ${outcome.failureReason ?? \"unknown\"}`;\n }\n return `failed: ${outcome.failureReason ?? \"unknown\"}`;\n}\n\nfunction flattenVerifyEvidence(ev: Evidence): ManifestArtifact[] {\n const out: ManifestArtifact[] = [];\n for (const s of ev.screenshots) out.push({ type: \"screenshot\", path: s });\n if (ev.replay_bundle) out.push({ type: \"replay_bundle\", path: ev.replay_bundle });\n if (ev.console) out.push({ type: \"console\", path: ev.console });\n if (ev.a11y_tree) out.push({ type: \"a11y_tree\", path: ev.a11y_tree });\n if (ev.har) out.push({ type: \"har\", path: ev.har });\n if (ev.trace) out.push({ type: \"trace\", path: ev.trace });\n if (ev.video) for (const v of ev.video) out.push({ type: \"video\", path: v });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Core single-run logic — shared by the initial run and every minimization\n// attempt.\n// ---------------------------------------------------------------------------\n\ntype Evidence = {\n screenshots: string[];\n replay_bundle?: string;\n console?: string;\n a11y_tree?: string;\n har?: string;\n trace?: string;\n video?: string[];\n};\n\ntype RunOutcome = {\n passed: boolean;\n failedAtStep?: number;\n failureReason?: string;\n finalUrl?: string;\n evidence: Evidence;\n};\n\nfunction buildCaptureOptions(\n captures: Set<string>,\n runDir: string,\n): OpenOptions[\"capture\"] | undefined {\n const cap: NonNullable<OpenOptions[\"capture\"]> = {};\n if (captures.has(\"har\")) {\n cap.har = { path: resolvePath(runDir, \"network.har\") };\n }\n if (captures.has(\"video\")) {\n cap.video = { dir: resolvePath(runDir, \"videos\") };\n }\n if (captures.has(\"trace\")) {\n cap.trace = { artifactDir: runDir };\n }\n return Object.keys(cap).length > 0 ? cap : undefined;\n}\n\nasync function runFlow(\n ctx: ToolContext,\n args: VerifyUiFlowInput,\n steps: VerifyUiFlowInput[\"steps\"],\n runDir: string,\n opts: { captureEvidence: boolean; bundleName: string },\n): Promise<RunOutcome> {\n const evidence: Evidence = { screenshots: [] };\n const captures = new Set<string>(args.capture ?? [\"screenshot\"]);\n let passed = false;\n let failedAtStep: number | undefined;\n let failureReason: string | undefined;\n let finalSnapshot: A11ySnapshot | undefined;\n\n // Build OpenOptions enriched with capture lifecycle requests. The\n // engine wires recordHar / recordVideo / tracing at context creation.\n const openOpts: OpenOptions = { ...args.open };\n const captureCfg = buildCaptureOptions(captures, runDir);\n if (captureCfg) {\n openOpts.capture = captureCfg;\n }\n\n const session = await ctx.registry.open(openOpts);\n const engine = ctx.registry.engineFor(session.id);\n const sessionHandle: Session = { id: session.id, platform: session.platform };\n\n try {\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const beforeSnap = await engine.snapshot(sessionHandle);\n try {\n await runStep(engine, sessionHandle, step, beforeSnap);\n } catch (err) {\n failedAtStep = i;\n failureReason = `Step ${i} (${step.kind}) failed: ${describeError(err)}`;\n throw err;\n }\n }\n\n finalSnapshot = await engine.snapshot(sessionHandle);\n const failures: string[] = [];\n for (let i = 0; i < args.expect.length; i++) {\n const expectation = args.expect[i]!;\n if (!evaluateExpect(expectation, finalSnapshot, engine, session.id)) {\n failures.push(`expect[${i}] ${describeExpect(expectation)}`);\n }\n }\n if (failures.length === 0) {\n passed = true;\n } else {\n failureReason = `Expectations failed: ${failures.join(\"; \")}`;\n }\n } catch (err) {\n if (!failureReason) failureReason = describeError(err);\n passed = false;\n } finally {\n if (opts.captureEvidence) {\n if (captures.has(\"screenshot\")) {\n try {\n const buf = await engine.screenshot(sessionHandle, true);\n const p = await ctx.store.writeScreenshot(runDir, buf, \"final\");\n evidence.screenshots.push(p);\n } catch (err) {\n failureReason ??= `screenshot capture failed: ${describeError(err)}`;\n }\n }\n\n if (captures.has(\"console\") && engine instanceof PlaywrightEngine) {\n try {\n const messages = engine.peekBuffers(session.id).console;\n evidence.console = await ctx.store.writeReport(\n runDir,\n \"console.json\",\n JSON.stringify(\n {\n count: messages.length,\n by_level: countByLevel(messages),\n messages,\n },\n null,\n 2,\n ),\n );\n } catch (err) {\n failureReason ??= `console capture failed: ${describeError(err)}`;\n }\n }\n\n if (captures.has(\"a11y_tree\") && finalSnapshot) {\n try {\n evidence.a11y_tree = await ctx.store.writeReport(\n runDir,\n \"a11y_tree.json\",\n JSON.stringify(finalSnapshot, null, 2),\n );\n } catch (err) {\n failureReason ??= `a11y_tree capture failed: ${describeError(err)}`;\n }\n }\n\n try {\n evidence.replay_bundle = await ctx.store.writeReplayBundle(\n runDir,\n {\n version: 1,\n run_id: runDir.split(\"/\").pop() ?? \"run\",\n recorded_at: new Date().toISOString(),\n open: args.open as unknown as Record<string, unknown>,\n steps: steps as unknown as Record<string, unknown>[],\n expect: args.expect as unknown as Record<string, unknown>[],\n },\n opts.bundleName,\n );\n } catch {\n /* swallow — replay bundle is best-effort */\n }\n }\n if (args.close_on_finish) {\n await ctx.registry.close(sessionHandle).catch(() => undefined);\n }\n }\n\n // HAR / video / trace artifacts are flushed by the engine on context close.\n // Surface their paths now that the close has completed (if captureEvidence\n // was requested).\n if (opts.captureEvidence) {\n if (captureCfg?.har) evidence.har = captureCfg.har.path;\n if (captureCfg?.trace) {\n evidence.trace = resolvePath(captureCfg.trace.artifactDir, \"trace.zip\");\n }\n if (captureCfg?.video) {\n try {\n const files = await readdir(captureCfg.video.dir).catch(() => [] as string[]);\n evidence.video = files\n .filter((f) => f.endsWith(\".webm\"))\n .map((f) => resolvePath(captureCfg.video!.dir, f));\n } catch {\n /* swallow — video is best-effort */\n }\n }\n }\n\n const out: RunOutcome = { passed, evidence };\n if (failedAtStep !== undefined) out.failedAtStep = failedAtStep;\n if (failureReason !== undefined) out.failureReason = failureReason;\n if (finalSnapshot) out.finalUrl = finalSnapshot.url_or_screen;\n return out;\n}\n\nfunction countByLevel(\n messages: { level: string }[],\n): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const m of messages) {\n counts[m.level] = (counts[m.level] ?? 0) + 1;\n }\n return counts;\n}\n\n// ---------------------------------------------------------------------------\n// Linear delta-removal — naive but bounded by the step count.\n// ---------------------------------------------------------------------------\n\ntype MinimizeResult = {\n steps: VerifyUiFlowInput[\"steps\"];\n removed: number[];\n attempts: number;\n replayPath: string | undefined;\n};\n\nasync function minimize(\n ctx: ToolContext,\n args: VerifyUiFlowInput,\n initialSteps: VerifyUiFlowInput[\"steps\"],\n runDir: string,\n): Promise<MinimizeResult> {\n // Tag each step with its original index so we can report what was removed.\n type Tagged = { step: VerifyUiFlowInput[\"steps\"][number]; origIndex: number };\n const tagged: Tagged[] = initialSteps.map((step, origIndex) => ({ step, origIndex }));\n let attempts = 0;\n\n const predicate = async (subset: Tagged[]): Promise<boolean> => {\n attempts += 1;\n const outcome = await runFlow(\n ctx,\n args,\n subset.map((t) => t.step),\n runDir,\n { captureEvidence: false, bundleName: \"minimize-tmp.json\" },\n );\n return outcome.passed;\n };\n\n const minimal = await ddmin(tagged, predicate);\n const remainingIdx = new Set(minimal.map((t) => t.origIndex));\n const removed = tagged\n .map((t) => t.origIndex)\n .filter((i) => !remainingIdx.has(i));\n\n // One final capture run with the minimized sequence to anchor evidence.\n let replayPath: string | undefined;\n if (minimal.length !== initialSteps.length) {\n const finalRun = await runFlow(\n ctx,\n args,\n minimal.map((t) => t.step),\n runDir,\n { captureEvidence: true, bundleName: \"replay-minimized.json\" },\n );\n replayPath = finalRun.evidence.replay_bundle;\n }\n return {\n steps: minimal.map((t) => t.step),\n removed: removed.sort((a, b) => a - b),\n attempts,\n replayPath,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Step + expect evaluation helpers (shared with mode='assert').\n// ---------------------------------------------------------------------------\n\nasync function runStep(\n engine: Engine,\n session: Session,\n step: VerifyUiFlowInput[\"steps\"][number],\n snap: A11ySnapshot,\n): Promise<void> {\n switch (step.kind) {\n case \"click\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.click(session, ref);\n return;\n }\n case \"type\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.type(\n session,\n ref,\n step.text,\n step.clear_first ? { clearFirst: true } : undefined,\n );\n return;\n }\n case \"key\":\n await engine.key(session, step.key);\n return;\n case \"wait_for\":\n await engine.waitFor(session, step.condition);\n return;\n case \"navigate\":\n await engine.navigate(session, step.url);\n return;\n case \"hover\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.hover(session, ref);\n return;\n }\n case \"drag\": {\n const fromRef = findRefByQuery(snap.tree, step.from_query);\n if (!fromRef) throw missingQuery(step.from_query);\n const toRef = findRefByQuery(snap.tree, step.to_query);\n if (!toRef) throw missingQuery(step.to_query);\n await engine.drag(session, fromRef, toRef);\n return;\n }\n case \"fill_form\": {\n const resolved = step.fields.map((f) => {\n const ref = findRefByQuery(snap.tree, f.query);\n if (!ref) throw missingQuery(f.query);\n return f.kind !== undefined\n ? { ref, value: f.value, kind: f.kind }\n : { ref, value: f.value };\n });\n await engine.fillForm(session, resolved);\n return;\n }\n case \"upload\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.uploadFile(session, ref, step.file_path);\n return;\n }\n case \"dialog\": {\n requirePlaywright(engine, \"dialog\");\n // Fire and forget — the next step (the dialog trigger) will resolve\n // the handler. We register synchronously inside handleDialog.\n void engine\n .handleDialog(session.id, {\n action: step.action,\n ...(step.text !== undefined ? { text: step.text } : {}),\n })\n .catch(() => undefined);\n return;\n }\n case \"set_env\": {\n requirePlaywright(engine, \"set_env\");\n await engine.setEnv(session.id, {\n ...(step.viewport !== undefined ? { viewport: step.viewport } : {}),\n ...(step.offline !== undefined ? { offline: step.offline } : {}),\n ...(step.geolocation !== undefined\n ? { geolocation: step.geolocation }\n : {}),\n ...(step.color_scheme !== undefined\n ? { colorScheme: step.color_scheme }\n : {}),\n ...(step.reduced_motion !== undefined\n ? { reducedMotion: step.reduced_motion }\n : {}),\n ...(step.extra_headers !== undefined\n ? { extraHeaders: step.extra_headers }\n : {}),\n ...(step.network_throttle !== undefined\n ? { networkThrottle: step.network_throttle }\n : {}),\n ...(step.cpu_throttle !== undefined\n ? { cpuThrottle: step.cpu_throttle }\n : {}),\n });\n return;\n }\n case \"switch_page\": {\n requirePlaywright(engine, \"switch_page\");\n await engine.switchPage(session.id, step.index);\n return;\n }\n case \"evaluate\": {\n requirePlaywright(engine, \"evaluate\");\n if (process.env.ROLEPOD_ALLOW_EVAL !== \"1\") {\n throw new RolepodMcpError(\n \"engine_error\",\n \"verify_ui_flow step kind 'evaluate' is disabled. Restart the rolepod-uiproof MCP server with ROLEPOD_ALLOW_EVAL=1 to enable.\",\n );\n }\n await engine.evaluate(session.id, step.script);\n return;\n }\n }\n}\n\nfunction requirePlaywright(\n engine: Engine,\n stepKind: string,\n): asserts engine is PlaywrightEngine {\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `verify_ui_flow step kind \"${stepKind}\" is web-only and requires PlaywrightEngine.`,\n );\n }\n}\n\nfunction evaluateExpect(\n exp: VerifyUiFlowInput[\"expect\"][number],\n snap: A11ySnapshot,\n engine: Engine,\n sessionId: string,\n): boolean {\n switch (exp.kind) {\n case \"text_visible\":\n return treeHasText(snap.tree, exp.text);\n case \"text_absent\":\n return !treeHasText(snap.tree, exp.text);\n case \"url_matches\":\n return new RegExp(exp.pattern).test(snap.url_or_screen);\n case \"ref_in_state\": {\n const node = findNodeByQuery(snap.tree, exp.query);\n if (!node) return false;\n switch (exp.state) {\n case \"visible\":\n return true;\n case \"enabled\":\n return node.state?.disabled !== true;\n case \"focused\":\n return node.state?.focused === true;\n }\n }\n case \"no_console_errors\": {\n if (!(engine instanceof PlaywrightEngine)) return true; // mobile = no console\n const msgs = engine.peekBuffers(sessionId).console.filter(\n (m) => m.level === \"error\",\n );\n const excludes = exp.exclude_patterns ?? [];\n const remaining = msgs.filter(\n (m) => !excludes.some((p) => m.text.includes(p)),\n );\n return remaining.length === 0;\n }\n case \"no_failed_requests\": {\n if (!(engine instanceof PlaywrightEngine)) return true;\n const reqs = engine.peekBuffers(sessionId).network.filter((r) => {\n if (r.failure) return true;\n if (r.status === undefined) return false;\n if (exp.allow_4xx) return r.status >= 500;\n return r.status >= 400;\n });\n const excludes = exp.exclude_patterns ?? [];\n const remaining = reqs.filter(\n (r) => !excludes.some((p) => r.url.includes(p)),\n );\n return remaining.length === 0;\n }\n case \"request_made\": {\n if (!(engine instanceof PlaywrightEngine)) return false;\n const re = new RegExp(exp.url_pattern);\n const wantMethod = exp.method?.toUpperCase();\n const matches = engine.peekBuffers(sessionId).network.filter((r) => {\n if (!re.test(r.url)) return false;\n if (wantMethod && r.method.toUpperCase() !== wantMethod) return false;\n return true;\n });\n const min = exp.min_count ?? 1;\n return matches.length >= min;\n }\n case \"response_status\": {\n if (!(engine instanceof PlaywrightEngine)) return false;\n const re = new RegExp(exp.url_pattern);\n const match = engine\n .peekBuffers(sessionId)\n .network.find((r) => re.test(r.url) && r.status === exp.status);\n return match !== undefined;\n }\n }\n}\n\nfunction describeExpect(exp: VerifyUiFlowInput[\"expect\"][number]): string {\n switch (exp.kind) {\n case \"text_visible\":\n return `text_visible \"${exp.text}\"`;\n case \"text_absent\":\n return `text_absent \"${exp.text}\"`;\n case \"url_matches\":\n return `url_matches /${exp.pattern}/`;\n case \"ref_in_state\":\n return `ref_in_state \"${exp.query}\" → ${exp.state}`;\n case \"no_console_errors\":\n return \"no_console_errors\";\n case \"no_failed_requests\":\n return \"no_failed_requests\";\n case \"request_made\":\n return `request_made ${exp.method ?? \"\"} ${exp.url_pattern}`.trim();\n case \"response_status\":\n return `response_status ${exp.url_pattern} = ${exp.status}`;\n }\n}\n\nfunction missingQuery(query: string): RolepodMcpError {\n return new RolepodMcpError(\n \"invalid_input\",\n `No element matched query \"${query}\" in the current snapshot.`,\n { query },\n );\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nfunction findRefByQuery(tree: A11yNode, query: string): string | null {\n const node = findNodeByQuery(tree, query);\n return node ? node.ref : null;\n}\n\nfunction findNodeByQuery(tree: A11yNode, query: string): A11yNode | null {\n const target = query.toLowerCase();\n const visit = (node: A11yNode): A11yNode | null => {\n if (\n (node.name && node.name.toLowerCase().includes(target)) ||\n (node.value && node.value.toLowerCase().includes(target))\n ) {\n return node;\n }\n if (node.children) {\n for (const c of node.children) {\n const hit = visit(c);\n if (hit) return hit;\n }\n }\n return null;\n };\n return visit(tree);\n}\n\nfunction treeHasText(tree: A11yNode, text: string): boolean {\n const target = text.toLowerCase();\n const visit = (node: A11yNode): boolean => {\n if (\n (node.name && node.name.toLowerCase().includes(target)) ||\n (node.value && node.value.toLowerCase().includes(target))\n ) {\n return true;\n }\n return node.children?.some(visit) ?? false;\n };\n return visit(tree);\n}\n","import { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Shared building blocks\n// ---------------------------------------------------------------------------\n\nexport const platformSchema = z.enum([\"web\", \"ios\", \"android\"]);\nexport const browserSchema = z.enum([\"chromium\", \"firefox\", \"webkit\"]);\n\nexport const viewportSchema = z.object({\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nexport const bboxSchema = z.object({\n x: z.number(),\n y: z.number(),\n w: z.number(),\n h: z.number(),\n});\n\nexport const a11yStateSchema = z.object({\n focused: z.boolean().optional(),\n selected: z.boolean().optional(),\n expanded: z.boolean().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type A11yNode = {\n ref: string;\n role: string;\n name?: string;\n value?: string;\n state?: z.infer<typeof a11yStateSchema>;\n bbox?: z.infer<typeof bboxSchema>;\n children?: A11yNode[];\n};\n\nexport const a11yNodeSchema: z.ZodType<A11yNode> = z.lazy(() =>\n z.object({\n ref: z.string(),\n role: z.string(),\n name: z.string().optional(),\n value: z.string().optional(),\n state: a11yStateSchema.optional(),\n bbox: bboxSchema.optional(),\n children: z.array(a11yNodeSchema).optional(),\n }),\n);\n\nexport const waitConditionSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"text_visible\"), text: z.string() }),\n z.object({ kind: z.literal(\"ref_exists\"), query: z.string() }),\n z.object({ kind: z.literal(\"url_matches\"), pattern: z.string() }),\n z.object({ kind: z.literal(\"idle\"), ms: z.number().int().positive() }),\n]);\n\n// ---------------------------------------------------------------------------\n// Atomic tools — input shapes\n//\n// NOTE: MCP SDK's `registerTool({ inputSchema })` expects a Zod *raw shape*\n// (a plain object whose values are Zod schemas), NOT a `z.object(...)`. We\n// export both the raw shape (for the SDK) and a derived `z.object` (for\n// internal parsing / type inference).\n// ---------------------------------------------------------------------------\n\nexport const browserOpenShape = {\n platform: platformSchema.default(\"web\"),\n url: z.string().url().optional(),\n browser: browserSchema.optional(),\n viewport: viewportSchema.optional(),\n // mobile fields kept for forward compat; v0.1 only handles platform='web'\n bundle_id: z.string().optional(),\n device: z.string().optional(),\n app_package: z.string().optional(),\n app_activity: z.string().optional(),\n emulator: z.string().optional(),\n headless: z.boolean().optional(),\n user_agent: z.string().optional(),\n locale: z.string().optional(),\n} as const;\nexport const browserOpenSchema = z.object(browserOpenShape);\nexport type BrowserOpenInput = z.infer<typeof browserOpenSchema>;\n\nexport const browserCloseShape = {\n session_id: z.string().min(1),\n} as const;\nexport const browserCloseSchema = z.object(browserCloseShape);\nexport type BrowserCloseInput = z.infer<typeof browserCloseSchema>;\n\nexport const browserSnapshotShape = {\n session_id: z.string().min(1),\n mode: z.enum([\"visible\", \"full\"]).optional(),\n} as const;\nexport const browserSnapshotSchema = z.object(browserSnapshotShape);\nexport type BrowserSnapshotInput = z.infer<typeof browserSnapshotSchema>;\n\nexport const browserClickShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n button: z.enum([\"left\", \"right\", \"middle\"]).optional(),\n} as const;\nexport const browserClickSchema = z.object(browserClickShape);\nexport type BrowserClickInput = z.infer<typeof browserClickSchema>;\n\nexport const browserTypeShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n text: z.string(),\n clear_first: z.boolean().optional(),\n} as const;\nexport const browserTypeSchema = z.object(browserTypeShape);\nexport type BrowserTypeInput = z.infer<typeof browserTypeSchema>;\n\nexport const browserKeyShape = {\n session_id: z.string().min(1),\n key: z.string().min(1),\n} as const;\nexport const browserKeySchema = z.object(browserKeyShape);\nexport type BrowserKeyInput = z.infer<typeof browserKeySchema>;\n\nexport const browserScrollShape = {\n session_id: z.string().min(1),\n direction: z.enum([\"up\", \"down\", \"left\", \"right\"]),\n amount: z.number().int().positive().optional(),\n ref: z.string().min(1).optional(),\n} as const;\nexport const browserScrollSchema = z.object(browserScrollShape);\nexport type BrowserScrollInput = z.infer<typeof browserScrollSchema>;\n\nexport const browserWaitForShape = {\n session_id: z.string().min(1),\n condition: waitConditionSchema,\n timeout_ms: z.number().int().positive().optional(),\n} as const;\nexport const browserWaitForSchema = z.object(browserWaitForShape);\nexport type BrowserWaitForInput = z.infer<typeof browserWaitForSchema>;\n\nexport const browserScreenshotShape = {\n session_id: z.string().min(1),\n full_page: z.boolean().optional(),\n} as const;\nexport const browserScreenshotSchema = z.object(browserScreenshotShape);\nexport type BrowserScreenshotInput = z.infer<typeof browserScreenshotSchema>;\n\nexport const browserNavigateShape = {\n session_id: z.string().min(1),\n url: z.string().url(),\n} as const;\nexport const browserNavigateSchema = z.object(browserNavigateShape);\nexport type BrowserNavigateInput = z.infer<typeof browserNavigateSchema>;\n\n// ---------------------------------------------------------------------------\n// v0.5 atomic additions\n// ---------------------------------------------------------------------------\n\nexport const browserHoverShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n} as const;\nexport const browserHoverSchema = z.object(browserHoverShape);\nexport type BrowserHoverInput = z.infer<typeof browserHoverSchema>;\n\nexport const browserDragShape = {\n session_id: z.string().min(1),\n from_ref: z.string().min(1),\n to_ref: z.string().min(1),\n} as const;\nexport const browserDragSchema = z.object(browserDragShape);\nexport type BrowserDragInput = z.infer<typeof browserDragSchema>;\n\nexport const fillFieldKindSchema = z.enum([\n \"input\",\n \"select\",\n \"checkbox\",\n \"radio\",\n]);\n\nexport const fillFormFieldSchema = z.object({\n ref: z.string().min(1),\n value: z.union([z.string(), z.boolean()]),\n kind: fillFieldKindSchema.optional(),\n});\n\nexport const browserFillFormShape = {\n session_id: z.string().min(1),\n fields: z.array(fillFormFieldSchema).min(1),\n} as const;\nexport const browserFillFormSchema = z.object(browserFillFormShape);\nexport type BrowserFillFormInput = z.infer<typeof browserFillFormSchema>;\n\nexport const browserUploadFileShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n file_path: z.string().min(1),\n} as const;\nexport const browserUploadFileSchema = z.object(browserUploadFileShape);\nexport type BrowserUploadFileInput = z.infer<typeof browserUploadFileSchema>;\n\nexport const dialogActionSchema = z.enum([\n \"accept\",\n \"dismiss\",\n \"accept_with_text\",\n]);\n\nexport const browserHandleDialogShape = {\n session_id: z.string().min(1),\n action: dialogActionSchema,\n /** Only used when action='accept_with_text'. */\n text: z.string().optional(),\n /**\n * Arming behavior: registers a one-shot handler for the NEXT dialog\n * raised on the page. Call this BEFORE the action that triggers the\n * dialog (e.g. before clicking the button that calls `confirm()`).\n * Default 30s if no dialog appears, handler is auto-removed.\n */\n timeout_ms: z.number().int().positive().optional(),\n} as const;\nexport const browserHandleDialogSchema = z.object(browserHandleDialogShape);\nexport type BrowserHandleDialogInput = z.infer<typeof browserHandleDialogSchema>;\n\nexport const consoleLevelSchema = z.enum([\n \"error\",\n \"warning\",\n \"info\",\n \"log\",\n \"debug\",\n \"trace\",\n]);\n\nexport const browserConsoleShape = {\n session_id: z.string().min(1),\n /** Filter to only these levels. Default: errors+warnings. */\n levels: z.array(consoleLevelSchema).optional(),\n /** Substring match on message text. */\n contains: z.string().optional(),\n /** Drop all buffered messages after returning. */\n clear: z.boolean().default(false),\n /** Cap on returned messages (artifact still holds full ring buffer). */\n limit: z.number().int().positive().max(1000).default(50),\n} as const;\nexport const browserConsoleSchema = z.object(browserConsoleShape);\nexport type BrowserConsoleInput = z.infer<typeof browserConsoleSchema>;\n\nexport const browserNetworkShape = {\n session_id: z.string().min(1),\n /** Substring or regex (per `pattern_kind`) match on URL. */\n url_pattern: z.string().optional(),\n pattern_kind: z.enum([\"substring\", \"regex\"]).default(\"substring\"),\n method: z.string().optional(),\n /** Inclusive range — e.g. `{min: 400, max: 599}` for any error response. */\n status_range: z\n .object({\n min: z.number().int().min(100).max(599),\n max: z.number().int().min(100).max(599),\n })\n .optional(),\n only_failed: z.boolean().default(false),\n /** Write the full HAR file for this session to artifacts/{runId}/network.har. */\n export_har: z.boolean().default(false),\n /** Drop buffered entries after returning. */\n clear: z.boolean().default(false),\n limit: z.number().int().positive().max(1000).default(50),\n} as const;\nexport const browserNetworkSchema = z.object(browserNetworkShape);\nexport type BrowserNetworkInput = z.infer<typeof browserNetworkSchema>;\n\nexport const networkPresetSchema = z.enum([\n \"offline\",\n \"slow-3g\",\n \"fast-3g\",\n \"slow-4g\",\n \"fast-4g\",\n \"no-throttling\",\n]);\n\nexport const geolocationSchema = z.object({\n latitude: z.number().min(-90).max(90),\n longitude: z.number().min(-180).max(180),\n accuracy: z.number().nonnegative().optional(),\n});\n\n/**\n * Runtime environment mutation. Merges resize+emulate. Fields here are\n * the ones Playwright supports changing AFTER context creation. Things\n * that must be set at context-creation time (user_agent, locale,\n * timezone) live on `browser_open` and cannot be changed mid-session.\n *\n * `network_throttle` and `cpu_throttle` are chromium-only (CDP-backed).\n */\nexport const browserSetEnvShape = {\n session_id: z.string().min(1),\n viewport: viewportSchema.optional(),\n offline: z.boolean().optional(),\n geolocation: geolocationSchema.optional(),\n color_scheme: z.enum([\"light\", \"dark\", \"no-preference\"]).optional(),\n reduced_motion: z.enum([\"reduce\", \"no-preference\"]).optional(),\n extra_headers: z.record(z.string(), z.string()).optional(),\n network_throttle: networkPresetSchema.optional(),\n /** CPU slowdown multiplier (1 = no throttle, 4 = 4x slower). Chromium only. */\n cpu_throttle: z.number().min(1).max(20).optional(),\n} as const;\nexport const browserSetEnvSchema = z.object(browserSetEnvShape);\nexport type BrowserSetEnvInput = z.infer<typeof browserSetEnvSchema>;\n\n/**\n * Execute JavaScript in the page context. GATED: server must be started\n * with env `ROLEPOD_ALLOW_EVAL=1`, otherwise the tool returns an\n * `eval_disabled` error. Equivalent to arbitrary code execution — only\n * enable for trusted automation scenarios.\n *\n * `script` is the body of an async function whose return value is sent\n * back as `result`. Use `args` to pass JSON-serialisable values.\n */\nexport const browserEvaluateShape = {\n session_id: z.string().min(1),\n script: z.string().min(1),\n args: z.array(z.unknown()).optional(),\n} as const;\nexport const browserEvaluateSchema = z.object(browserEvaluateShape);\nexport type BrowserEvaluateInput = z.infer<typeof browserEvaluateSchema>;\n\n/**\n * Multi-page support. A session owns one browser context, which may\n * have multiple pages (e.g. when an OAuth popup or `target=\"_blank\"`\n * link opens). The active page index is sticky — all subsequent\n * tool calls operate on it until `switch_page` changes it.\n */\nexport const browserPagesShape = {\n session_id: z.string().min(1),\n} as const;\nexport const browserPagesSchema = z.object(browserPagesShape);\nexport type BrowserPagesInput = z.infer<typeof browserPagesSchema>;\n\nexport const browserSwitchPageShape = {\n session_id: z.string().min(1),\n index: z.number().int().nonnegative(),\n} as const;\nexport const browserSwitchPageSchema = z.object(browserSwitchPageShape);\nexport type BrowserSwitchPageInput = z.infer<typeof browserSwitchPageSchema>;\n\n// ---------------------------------------------------------------------------\n// Composite verify_ui_flow\n//\n// Both `mode: 'assert'` and `mode: 'reproduce'` are implemented (D-025).\n// When mode='reproduce' && passed && minimize, the composite runs a\n// classic ddmin pass over `steps` and adds a `minimized` block to the\n// output carrying the surviving step list and a `replay-minimized.json`\n// artifact path.\n// ---------------------------------------------------------------------------\n\nexport const verifyFillFieldSchema = z.object({\n query: z.string(),\n value: z.union([z.string(), z.boolean()]),\n kind: fillFieldKindSchema.optional(),\n});\n\nexport const verifyStepSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"click\"), query: z.string() }),\n z.object({\n kind: z.literal(\"type\"),\n query: z.string(),\n text: z.string(),\n clear_first: z.boolean().optional(),\n }),\n z.object({ kind: z.literal(\"key\"), key: z.string() }),\n z.object({ kind: z.literal(\"wait_for\"), condition: waitConditionSchema }),\n z.object({ kind: z.literal(\"navigate\"), url: z.string().url() }),\n // v0.5 additions\n z.object({ kind: z.literal(\"hover\"), query: z.string() }),\n z.object({\n kind: z.literal(\"drag\"),\n from_query: z.string(),\n to_query: z.string(),\n }),\n z.object({\n kind: z.literal(\"fill_form\"),\n fields: z.array(verifyFillFieldSchema).min(1),\n }),\n z.object({\n kind: z.literal(\"upload\"),\n query: z.string(),\n file_path: z.string().min(1),\n }),\n z.object({\n kind: z.literal(\"dialog\"),\n action: dialogActionSchema,\n text: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"set_env\"),\n viewport: viewportSchema.optional(),\n offline: z.boolean().optional(),\n geolocation: geolocationSchema.optional(),\n color_scheme: z.enum([\"light\", \"dark\", \"no-preference\"]).optional(),\n reduced_motion: z.enum([\"reduce\", \"no-preference\"]).optional(),\n extra_headers: z.record(z.string(), z.string()).optional(),\n network_throttle: networkPresetSchema.optional(),\n cpu_throttle: z.number().min(1).max(20).optional(),\n }),\n z.object({\n kind: z.literal(\"switch_page\"),\n index: z.number().int().nonnegative(),\n }),\n z.object({ kind: z.literal(\"evaluate\"), script: z.string().min(1) }),\n]);\n\nexport const verifyExpectSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"text_visible\"), text: z.string() }),\n z.object({ kind: z.literal(\"text_absent\"), text: z.string() }),\n z.object({ kind: z.literal(\"url_matches\"), pattern: z.string() }),\n z.object({\n kind: z.literal(\"ref_in_state\"),\n query: z.string(),\n state: z.enum([\"visible\", \"enabled\", \"focused\"]),\n }),\n // v0.5 additions\n z.object({\n kind: z.literal(\"no_console_errors\"),\n exclude_patterns: z.array(z.string()).optional(),\n }),\n z.object({\n kind: z.literal(\"no_failed_requests\"),\n exclude_patterns: z.array(z.string()).optional(),\n /** When true, only 5xx counts as a failure. Default false (4xx + 5xx). */\n allow_4xx: z.boolean().optional(),\n }),\n z.object({\n kind: z.literal(\"request_made\"),\n url_pattern: z.string(),\n method: z.string().optional(),\n min_count: z.number().int().positive().optional(),\n }),\n z.object({\n kind: z.literal(\"response_status\"),\n url_pattern: z.string(),\n status: z.number().int().min(100).max(599),\n }),\n]);\n\nexport const captureKindSchema = z.enum([\n \"screenshot\",\n \"har\",\n \"console\",\n \"a11y_tree\",\n \"video\",\n \"trace\",\n]);\n\nexport const verifyUiFlowShape = {\n mode: z.enum([\"assert\", \"reproduce\"]).default(\"assert\"),\n open: browserOpenSchema,\n steps: z.array(verifyStepSchema).default([]),\n expect: z.array(verifyExpectSchema).default([]),\n capture: z.array(captureKindSchema).optional(),\n close_on_finish: z.boolean().default(true),\n /**\n * Only consulted when `mode='reproduce'`. When true (default) and the\n * initial run reproduces the bug, the composite tries to remove each\n * step in turn and re-runs to find a smaller reproducer.\n */\n minimize: z.boolean().default(true),\n} as const;\nexport const verifyUiFlowSchema = z.object(verifyUiFlowShape);\nexport type VerifyUiFlowInput = z.infer<typeof verifyUiFlowSchema>;\n\n// ---------------------------------------------------------------------------\n// audit_a11y\n// ---------------------------------------------------------------------------\n\nexport const wcagLevelSchema = z.enum([\"wcag-a\", \"wcag-aa\", \"wcag-aaa\"]);\nexport const a11ySeveritySchema = z.enum([\n \"critical\",\n \"serious\",\n \"moderate\",\n \"minor\",\n]);\nexport const auditScopeSchema = z.union([\n z.literal(\"page\"),\n z.object({ ref: z.string().min(1) }),\n]);\n\nexport const auditA11yShape = {\n open: browserOpenSchema,\n level: wcagLevelSchema.default(\"wcag-aa\"),\n scope: auditScopeSchema.default(\"page\"),\n report_format: z.enum([\"json\", \"markdown\"]).default(\"json\"),\n close_on_finish: z.boolean().default(true),\n} as const;\nexport const auditA11ySchema = z.object(auditA11yShape);\nexport type AuditA11yInput = z.infer<typeof auditA11ySchema>;\n\n// ---------------------------------------------------------------------------\n// visual_diff\n// ---------------------------------------------------------------------------\n\nexport const visualDiffShape = {\n open: browserOpenSchema,\n baseline_id: z.string().min(1),\n viewport: viewportSchema.optional(),\n threshold_pct: z.number().min(0).max(1).default(0.1),\n close_on_finish: z.boolean().default(true),\n /** Pixel sensitivity for pixelmatch (0 = strict, 1 = lax). Default 0.1. */\n pixel_threshold: z.number().min(0).max(1).default(0.1),\n} as const;\nexport const visualDiffSchema = z.object(visualDiffShape);\nexport type VisualDiffInput = z.infer<typeof visualDiffSchema>;\n\n// ---------------------------------------------------------------------------\n// scaffold_e2e\n// ---------------------------------------------------------------------------\n\nexport const e2eFrameworkSchema = z.enum([\n \"playwright-test\",\n \"vitest+playwright\",\n \"pytest+selenium\",\n]);\n\nexport const scaffoldE2eShape = {\n framework: e2eFrameworkSchema,\n scenario_nl: z.string().min(1),\n url: z.string().url(),\n recorded_bundle: z.string().min(1).optional(),\n /** Override the generated test file name. */\n filename: z.string().min(1).optional(),\n} as const;\nexport const scaffoldE2eSchema = z.object(scaffoldE2eShape);\nexport type ScaffoldE2eInput = z.infer<typeof scaffoldE2eSchema>;\n\n// ---------------------------------------------------------------------------\n// extract_ui_state — used internally by other shipped skills (not user-facing).\n// ---------------------------------------------------------------------------\n\nexport const extractUiStateShape = {\n session_id: z.string().min(1).optional(),\n open: browserOpenSchema.optional(),\n question_nl: z.string().min(1),\n close_on_finish: z.boolean().default(false),\n} as const;\nexport const extractUiStateSchema = z.object(extractUiStateShape);\nexport type ExtractUiStateInput = z.infer<typeof extractUiStateSchema>;\n\n// ---------------------------------------------------------------------------\n// Tool name registry — single source of truth for tool naming.\n// All names are prefixed `rolepod_*` per brief 03-tool-surface.md.\n// ---------------------------------------------------------------------------\n\nexport const ToolNames = {\n browserOpen: \"rolepod_browser_open\",\n browserClose: \"rolepod_browser_close\",\n browserSnapshot: \"rolepod_browser_snapshot\",\n browserClick: \"rolepod_browser_click\",\n browserType: \"rolepod_browser_type\",\n browserKey: \"rolepod_browser_key\",\n browserScroll: \"rolepod_browser_scroll\",\n browserWaitFor: \"rolepod_browser_wait_for\",\n browserScreenshot: \"rolepod_browser_screenshot\",\n browserNavigate: \"rolepod_browser_navigate\",\n // v0.5 atomics\n browserHover: \"rolepod_browser_hover\",\n browserDrag: \"rolepod_browser_drag\",\n browserFillForm: \"rolepod_browser_fill_form\",\n browserUploadFile: \"rolepod_browser_upload_file\",\n browserHandleDialog: \"rolepod_browser_handle_dialog\",\n browserConsole: \"rolepod_browser_console\",\n browserNetwork: \"rolepod_browser_network\",\n browserSetEnv: \"rolepod_browser_set_env\",\n browserEvaluate: \"rolepod_browser_evaluate\",\n browserPages: \"rolepod_browser_pages\",\n browserSwitchPage: \"rolepod_browser_switch_page\",\n // composite\n verifyUiFlow: \"rolepod_verify_ui_flow\",\n auditA11y: \"rolepod_audit_a11y\",\n visualDiff: \"rolepod_visual_diff\",\n scaffoldE2e: \"rolepod_scaffold_e2e\",\n extractUiState: \"rolepod_extract_ui_state\",\n} as const;\n\nexport type ToolName = (typeof ToolNames)[keyof typeof ToolNames];\n","/**\n * Classic delta-debugging minimization (`ddmin`) — Zeller & Hildebrandt,\n * 2002. Given a sequence `input` and a predicate `reproduces(subset)`\n * that returns true when the subset still triggers the target outcome,\n * returns a 1-minimal subset.\n *\n * The algorithm is bounded by `O(N log N)` predicate calls in the\n * common case and `O(N²)` in the worst case — but each call is an\n * expensive browser run, so the caller is encouraged to cap the run\n * count separately if needed.\n */\nexport type DdminPredicate<T> = (subset: T[]) => Promise<boolean>;\n\nexport async function ddmin<T>(input: T[], reproduces: DdminPredicate<T>): Promise<T[]> {\n let current = [...input];\n let n = 2;\n while (current.length >= 2) {\n const chunkSize = Math.max(1, Math.floor(current.length / n));\n let reduced = false;\n\n // Try removing each chunk (delta) one at a time.\n for (let i = 0; i < current.length; i += chunkSize) {\n const complement = [\n ...current.slice(0, i),\n ...current.slice(i + chunkSize),\n ];\n if (complement.length === 0) continue;\n if (await reproduces(complement)) {\n current = complement;\n n = Math.max(n - 1, 2);\n reduced = true;\n break;\n }\n }\n if (reduced) continue;\n\n // No single delta worked — increase granularity.\n if (n >= current.length) break;\n n = Math.min(n * 2, current.length);\n }\n return current;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Extension Protocol v1 — manifest.json schema.\n *\n * Parent `rolepod` plugin's `check-work` skill scans `.rolepod/evidence/`\n * for `manifest.json` files and aggregates them into the verify report.\n * uiproof writes one of these in BOTH standalone and with-parent modes —\n * uniform tooling surface, and a user who later installs the parent gets\n * historic artifacts already in the right shape.\n */\nexport const ROLEPOD_PROTOCOL_VERSION = \"rolepod/v1\" as const;\n\nexport type ManifestPhase = \"verify\" | \"debug\" | \"build\" | \"review\";\nexport type ManifestStatus = \"pass\" | \"fail\" | \"warn\";\n\nexport type ManifestArtifact = {\n type: string;\n path: string;\n};\n\nexport type ManifestInput = {\n runDir: string;\n skill: string;\n phase: ManifestPhase;\n status: ManifestStatus;\n summary: string;\n startedAt: string;\n finishedAt: string;\n artifacts: ManifestArtifact[];\n metadata?: Record<string, unknown>;\n};\n\nexport type Manifest = {\n protocol: typeof ROLEPOD_PROTOCOL_VERSION;\n plugin: \"rolepod-uiproof\";\n skill: string;\n phase: ManifestPhase;\n status: ManifestStatus;\n summary: string;\n started_at: string;\n finished_at: string;\n artifacts: ManifestArtifact[];\n metadata: Record<string, unknown>;\n};\n\n/**\n * Write the manifest.json next to the run's other artifacts. Best-effort:\n * any IO failure is logged but never thrown — a missing manifest must not\n * fail an otherwise-successful composite tool call.\n */\nexport async function writeManifest(input: ManifestInput): Promise<string | undefined> {\n const manifest: Manifest = {\n protocol: ROLEPOD_PROTOCOL_VERSION,\n plugin: \"rolepod-uiproof\",\n skill: input.skill,\n phase: input.phase,\n status: input.status,\n summary: input.summary,\n started_at: input.startedAt,\n finished_at: input.finishedAt,\n artifacts: input.artifacts,\n metadata: input.metadata ?? {},\n };\n const path = resolve(input.runDir, \"manifest.json\");\n try {\n await writeFile(path, JSON.stringify(manifest, null, 2), \"utf8\");\n return path;\n } catch (err) {\n log.warn(\"manifest write failed\", {\n run_dir: input.runDir,\n skill: input.skill,\n err: String(err),\n });\n return undefined;\n }\n}\n","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { RolepodMcpError } from \"../util/errors.js\";\n\n/**\n * Pack a successful tool result into the MCP wire format. The same value\n * is emitted both as a text content block (for the Lead to read) and as\n * `structuredContent` (for any client that prefers typed JSON).\n */\nexport function ok(value: unknown): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify(value, null, 2) }],\n structuredContent: value as Record<string, unknown>,\n };\n}\n\n/**\n * Pack a structured error. RolepodMcpError surfaces a stable error code +\n * detail bag; anything else degrades to \"engine_error\" with the message.\n */\nexport function failure(err: unknown): CallToolResult {\n if (err instanceof RolepodMcpError) {\n const payload = err.toJSON();\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n structuredContent: payload as unknown as Record<string, unknown>,\n };\n }\n const message = err instanceof Error ? err.message : String(err);\n const payload = { code: \"engine_error\" as const, message };\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n structuredContent: payload as unknown as Record<string, unknown>,\n };\n}\n\n/** Wrap a handler so any thrown error is converted to a structured failure. */\nexport function safeHandler<Args>(\n fn: (args: Args) => Promise<CallToolResult>,\n): (args: Args) => Promise<CallToolResult> {\n return async (args: Args) => {\n try {\n return await fn(args);\n } catch (err) {\n return failure(err);\n }\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ArtifactStore } from \"./artifact/ArtifactStore.js\";\nimport { createMobileEngine, createWebEngine } from \"./engine/factory.js\";\nimport { SessionRegistry } from \"./session/SessionRegistry.js\";\nimport { browserClickTool } from \"./tools/atomic/browser_click.js\";\nimport { browserCloseTool } from \"./tools/atomic/browser_close.js\";\nimport { browserConsoleTool } from \"./tools/atomic/browser_console.js\";\nimport { browserDragTool } from \"./tools/atomic/browser_drag.js\";\nimport { browserEvaluateTool } from \"./tools/atomic/browser_evaluate.js\";\nimport { browserFillFormTool } from \"./tools/atomic/browser_fill_form.js\";\nimport { browserHandleDialogTool } from \"./tools/atomic/browser_handle_dialog.js\";\nimport { browserHoverTool } from \"./tools/atomic/browser_hover.js\";\nimport { browserKeyTool } from \"./tools/atomic/browser_key.js\";\nimport { browserNavigateTool } from \"./tools/atomic/browser_navigate.js\";\nimport { browserNetworkTool } from \"./tools/atomic/browser_network.js\";\nimport { browserOpenTool } from \"./tools/atomic/browser_open.js\";\nimport { browserPagesTool } from \"./tools/atomic/browser_pages.js\";\nimport { browserScreenshotTool } from \"./tools/atomic/browser_screenshot.js\";\nimport { browserScrollTool } from \"./tools/atomic/browser_scroll.js\";\nimport { browserSetEnvTool } from \"./tools/atomic/browser_set_env.js\";\nimport { browserSnapshotTool } from \"./tools/atomic/browser_snapshot.js\";\nimport { browserSwitchPageTool } from \"./tools/atomic/browser_switch_page.js\";\nimport { browserTypeTool } from \"./tools/atomic/browser_type.js\";\nimport { browserUploadFileTool } from \"./tools/atomic/browser_upload_file.js\";\nimport { browserWaitForTool } from \"./tools/atomic/browser_wait_for.js\";\nimport { auditA11yTool } from \"./tools/composite/audit_a11y.js\";\nimport { extractUiStateTool } from \"./tools/composite/extract_ui_state.js\";\nimport { scaffoldE2eTool } from \"./tools/composite/scaffold_e2e.js\";\nimport { verifyUiFlowTool } from \"./tools/composite/verify_ui_flow.js\";\nimport { visualDiffTool } from \"./tools/composite/visual_diff.js\";\nimport { toolMetadata } from \"./tools/metadata.js\";\nimport type { ToolContext } from \"./tools/types.js\";\nimport { log } from \"./util/log.js\";\n\nexport const SERVER_NAME = \"rolepod-uiproof\";\nexport const SERVER_VERSION = \"0.6.0\";\n\n/**\n * Extension Protocol version this build implements. Compared against the\n * parent-supplied `ROLEPOD_PROTOCOL` env var at server start.\n */\nexport const SUPPORTED_PROTOCOL = \"v1\" as const;\n\n/**\n * Warn (don't fail) when the parent `rolepod` plugin signals a protocol\n * version we don't implement. Skipping the check would let a parent on a\n * future v2 silently get mis-shaped evidence; throwing would break older\n * parents that haven't set the env var at all.\n */\nfunction checkProtocolCompat(): void {\n const requested = process.env.ROLEPOD_PROTOCOL;\n if (!requested) return; // not running with a protocol-aware parent\n if (requested !== SUPPORTED_PROTOCOL) {\n // eslint-disable-next-line no-console\n console.warn(\n `rolepod protocol mismatch: expected ${SUPPORTED_PROTOCOL}, got ${requested}. ` +\n `Manifest will still be written in ${SUPPORTED_PROTOCOL} shape — parent may not parse it correctly.`,\n );\n }\n}\n\nexport type ServerHandle = {\n mcp: McpServer;\n registry: SessionRegistry;\n store: ArtifactStore;\n shutdown(): Promise<void>;\n};\n\n/**\n * Build the MCP server with every v0.1 tool registered. Caller is\n * responsible for choosing a transport (stdio for production, in-memory\n * for tests) and invoking `mcp.connect(transport)`.\n */\nexport function buildServer(\n opts: { artifactRoot?: string; idleTimeoutMs?: number } = {},\n): ServerHandle {\n checkProtocolCompat();\n\n const webEngine = createWebEngine();\n const registry = new SessionRegistry({ idleTimeoutMs: opts.idleTimeoutMs });\n registry.register(\"web\", webEngine);\n // Mobile engines are lazy — the webdriverio import only fires when an\n // `ios`/`android` session is actually opened. So registering Appium\n // unconditionally is safe for web-only installs.\n const mobileEngine = createMobileEngine();\n registry.register(\"ios\", mobileEngine);\n registry.register(\"android\", mobileEngine);\n\n const storeOpts: ConstructorParameters<typeof ArtifactStore>[0] = {};\n if (opts.artifactRoot !== undefined) storeOpts.rootDir = opts.artifactRoot;\n const store = new ArtifactStore(storeOpts);\n\n const ctx: ToolContext = { registry, store };\n\n const mcp = new McpServer({\n name: SERVER_NAME,\n version: SERVER_VERSION,\n });\n\n const tools = [\n // atomic (v0.1-v0.4)\n browserOpenTool,\n browserCloseTool,\n browserSnapshotTool,\n browserClickTool,\n browserTypeTool,\n browserKeyTool,\n browserScrollTool,\n browserWaitForTool,\n browserScreenshotTool,\n browserNavigateTool,\n // atomic (v0.5)\n browserHoverTool,\n browserDragTool,\n browserFillFormTool,\n browserUploadFileTool,\n browserHandleDialogTool,\n browserConsoleTool,\n browserNetworkTool,\n browserSetEnvTool,\n browserEvaluateTool,\n browserPagesTool,\n browserSwitchPageTool,\n // composite\n verifyUiFlowTool,\n auditA11yTool,\n visualDiffTool,\n scaffoldE2eTool,\n extractUiStateTool,\n ] as const;\n\n for (const t of tools) {\n const meta = toolMetadata[t.name as keyof typeof toolMetadata];\n mcp.registerTool(\n t.name,\n {\n title: meta?.title,\n description: t.description,\n inputSchema: t.inputShape,\n annotations: meta?.annotations,\n },\n t.build(ctx) as Parameters<typeof mcp.registerTool>[2],\n );\n }\n\n log.info(\"rolepod-uiproof server built\", {\n version: SERVER_VERSION,\n protocol: SUPPORTED_PROTOCOL,\n mode: store.mode,\n tools: tools.map((t) => t.name),\n });\n\n return {\n mcp,\n registry,\n store,\n async shutdown() {\n await registry.shutdown();\n await mcp.close().catch(() => undefined);\n },\n };\n}\n","import { browserClickShape, ToolNames, type BrowserClickInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserClickTool: ToolModule<typeof browserClickShape> = {\n name: ToolNames.browserClick,\n description:\n \"Click the element identified by `ref` from the most recent snapshot. Invalidates all refs on success.\",\n inputShape: browserClickShape,\n build(ctx) {\n return safeHandler(async (args: BrowserClickInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.click(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.ref,\n args.button ? { button: args.button } : undefined,\n );\n return ok({ clicked: true });\n });\n },\n};\n","import { browserCloseShape, ToolNames, type BrowserCloseInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserCloseTool: ToolModule<typeof browserCloseShape> = {\n name: ToolNames.browserClose,\n description: \"Close an open session and free its browser / driver resources.\",\n inputShape: browserCloseShape,\n build(ctx) {\n return safeHandler(async (args: BrowserCloseInput) => {\n const platform = ctx.registry.platformOf(args.session_id);\n await ctx.registry.close({ id: args.session_id, platform });\n return ok({ closed: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserConsoleShape,\n ToolNames,\n type BrowserConsoleInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserConsoleTool: ToolModule<typeof browserConsoleShape> = {\n name: ToolNames.browserConsole,\n description:\n \"List console messages emitted by the active page since the session opened (or since the last `clear`). Filters: `levels` (default: errors+warnings), substring `contains`, and `limit` (default 50, max 1000). Set `clear: true` to drain the buffer after returning. Read-only.\",\n inputShape: browserConsoleShape,\n build(ctx) {\n return safeHandler(async (args: BrowserConsoleInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"console is web-only and requires PlaywrightEngine.\",\n );\n }\n // Default: errors + warnings only (token-conscious).\n const levels: BrowserConsoleInput[\"levels\"] =\n args.levels && args.levels.length > 0\n ? args.levels\n : [\"error\", \"warning\"];\n const messages = engine.getConsole(args.session_id, {\n levels,\n ...(args.contains !== undefined ? { contains: args.contains } : {}),\n clear: args.clear,\n limit: args.limit,\n });\n return ok({\n count: messages.length,\n messages,\n });\n });\n },\n};\n","import {\n browserDragShape,\n ToolNames,\n type BrowserDragInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserDragTool: ToolModule<typeof browserDragShape> = {\n name: ToolNames.browserDrag,\n description:\n \"Drag the element identified by `from_ref` onto the element identified by `to_ref`. Both refs come from the most recent snapshot. Invalidates all refs on success.\",\n inputShape: browserDragShape,\n build(ctx) {\n return safeHandler(async (args: BrowserDragInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.drag(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.from_ref,\n args.to_ref,\n );\n return ok({ dragged: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserEvaluateShape,\n ToolNames,\n type BrowserEvaluateInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\n/**\n * Gating: this tool executes ARBITRARY JavaScript in the page context,\n * which can read DOM state, mutate it, or exfiltrate data. It is disabled\n * by default and only registers a working handler when the server was\n * started with the env var `ROLEPOD_ALLOW_EVAL=1`. Otherwise the tool is\n * still listed (so callers can discover the capability) but every call\n * returns an `eval_disabled` error.\n */\nexport const browserEvaluateTool: ToolModule<typeof browserEvaluateShape> = {\n name: ToolNames.browserEvaluate,\n description:\n \"Execute JavaScript in the active page's context. The `script` is the body of an async function — use `return` for the result and reference inputs via the implicit `args` array. DISABLED unless the MCP server was launched with `ROLEPOD_ALLOW_EVAL=1`; intended for trusted automation setups only (state seeding, computed-style reads, synthetic event dispatch).\",\n inputShape: browserEvaluateShape,\n build(ctx) {\n const allowed = process.env.ROLEPOD_ALLOW_EVAL === \"1\";\n return safeHandler(async (args: BrowserEvaluateInput) => {\n if (!allowed) {\n throw new RolepodMcpError(\n \"engine_error\",\n \"browser_evaluate is disabled. Restart the rolepod-uiproof MCP server with the env var ROLEPOD_ALLOW_EVAL=1 to enable arbitrary JavaScript execution in the page context.\",\n );\n }\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"evaluate is web-only and requires PlaywrightEngine.\",\n );\n }\n const result = await engine.evaluate(\n args.session_id,\n args.script,\n args.args,\n );\n return ok({ result });\n });\n },\n};\n","import {\n browserFillFormShape,\n ToolNames,\n type BrowserFillFormInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserFillFormTool: ToolModule<typeof browserFillFormShape> = {\n name: ToolNames.browserFillForm,\n description:\n \"Batch-fill multiple form fields (inputs, selects, checkboxes, radios) in one call. Each field needs a `ref` from the latest snapshot and a `value`; pass `kind` to disambiguate non-input controls. Token-efficient alternative to a sequence of `type` calls. Invalidates all refs on success.\",\n inputShape: browserFillFormShape,\n build(ctx) {\n return safeHandler(async (args: BrowserFillFormInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.fillForm(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.fields,\n );\n return ok({ filled: args.fields.length });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserHandleDialogShape,\n ToolNames,\n type BrowserHandleDialogInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserHandleDialogTool: ToolModule<\n typeof browserHandleDialogShape\n> = {\n name: ToolNames.browserHandleDialog,\n description:\n \"Pre-arm a one-shot handler for the NEXT JavaScript dialog (`alert`/`confirm`/`prompt`/`beforeunload`) on the active page. Call this BEFORE the action that triggers the dialog (e.g. before clicking the button that calls `confirm()`). Returns when the dialog fires or the timeout (default 30s) elapses. Un-armed dialogs are auto-dismissed so the page does not hang.\",\n inputShape: browserHandleDialogShape,\n build(ctx) {\n return safeHandler(async (args: BrowserHandleDialogInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"handle_dialog is web-only and requires PlaywrightEngine.\",\n );\n }\n const { handled } = await engine.handleDialog(args.session_id, {\n action: args.action,\n ...(args.text !== undefined ? { text: args.text } : {}),\n ...(args.timeout_ms !== undefined ? { timeoutMs: args.timeout_ms } : {}),\n });\n return ok({ handled, action: args.action });\n });\n },\n};\n","import {\n browserHoverShape,\n ToolNames,\n type BrowserHoverInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserHoverTool: ToolModule<typeof browserHoverShape> = {\n name: ToolNames.browserHover,\n description:\n \"Hover the pointer over the element identified by `ref`. Refs remain valid afterwards (read-mostly).\",\n inputShape: browserHoverShape,\n build(ctx) {\n return safeHandler(async (args: BrowserHoverInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.hover(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.ref,\n );\n return ok({ hovered: true });\n });\n },\n};\n","import { browserKeyShape, ToolNames, type BrowserKeyInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserKeyTool: ToolModule<typeof browserKeyShape> = {\n name: ToolNames.browserKey,\n description:\n \"Press a single key (e.g. 'Enter', 'Tab', 'Escape'). Invalidates all refs on success.\",\n inputShape: browserKeyShape,\n build(ctx) {\n return safeHandler(async (args: BrowserKeyInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.key({ id: args.session_id, platform: ctx.registry.platformOf(args.session_id) }, args.key);\n return ok({ pressed: true });\n });\n },\n};\n","import {\n browserNavigateShape,\n ToolNames,\n type BrowserNavigateInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserNavigateTool: ToolModule<typeof browserNavigateShape> = {\n name: ToolNames.browserNavigate,\n description:\n \"Navigate the session to a new URL (web only). Invalidates all refs on success.\",\n inputShape: browserNavigateShape,\n build(ctx) {\n return safeHandler(async (args: BrowserNavigateInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.navigate({ id: args.session_id, platform: ctx.registry.platformOf(args.session_id) }, args.url);\n return ok({ navigated: true, url: args.url });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserNetworkShape,\n ToolNames,\n type BrowserNetworkInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserNetworkTool: ToolModule<typeof browserNetworkShape> = {\n name: ToolNames.browserNetwork,\n description:\n \"List network requests captured on the active page. Filters: `url_pattern` (substring or regex via `pattern_kind`), `method`, `status_range`, `only_failed`. Set `export_har: true` to require the session to have been opened with HAR recording — see `verify_ui_flow` capture=[\\\"har\\\"] or call `browser_open` with capture.har=true. Read-only unless `clear: true`.\",\n inputShape: browserNetworkShape,\n build(ctx) {\n return safeHandler(async (args: BrowserNetworkInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"network is web-only and requires PlaywrightEngine.\",\n );\n }\n const requests = engine.getNetwork(args.session_id, {\n ...(args.url_pattern !== undefined ? { urlPattern: args.url_pattern } : {}),\n patternKind: args.pattern_kind,\n ...(args.method !== undefined ? { method: args.method } : {}),\n ...(args.status_range !== undefined\n ? { statusRange: args.status_range }\n : {}),\n onlyFailed: args.only_failed,\n clear: args.clear,\n limit: args.limit,\n });\n const failed = requests.filter(\n (r) => !!r.failure || (r.status !== undefined && r.status >= 400),\n ).length;\n return ok({\n count: requests.length,\n failed_count: failed,\n requests,\n // HAR file lives wherever the session was opened with\n // `capture.har.path`. We don't echo it here to avoid leaking\n // filesystem paths into untrusted logs; the verify_ui_flow run\n // result surfaces it in `evidence_paths.har`.\n har_recording: args.export_har\n ? \"HAR is written at session close to the path passed via capture.har at open time.\"\n : undefined,\n });\n });\n },\n};\n","import { browserOpenShape, ToolNames, type BrowserOpenInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserOpenTool: ToolModule<typeof browserOpenShape> = {\n name: ToolNames.browserOpen,\n description:\n \"Open a new browser or mobile session against a target. v0.1 supports platform='web' only; mobile lands in v0.3.\",\n inputShape: browserOpenShape,\n build(ctx) {\n return safeHandler(async (args: BrowserOpenInput) => {\n const session = await ctx.registry.open(args);\n return ok({ session_id: session.id, platform: session.platform });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserPagesShape,\n ToolNames,\n type BrowserPagesInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserPagesTool: ToolModule<typeof browserPagesShape> = {\n name: ToolNames.browserPages,\n description:\n \"List all pages currently open in the session's browser context — typically just the main page, plus any popups, OAuth windows, or `target=_blank` tabs that the page itself opened. Each entry carries `{ index, url, title, active }`. Read-only.\",\n inputShape: browserPagesShape,\n build(ctx) {\n return safeHandler(async (args: BrowserPagesInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"pages is web-only and requires PlaywrightEngine.\",\n );\n }\n const raw = engine.listPages(args.session_id);\n // Resolve titles (best-effort — closed pages reject).\n const pages = await Promise.all(\n raw.map(async (p) => ({\n index: p.index,\n url: p.url,\n title: await p.title_promise.catch(() => \"\"),\n active: p.active,\n })),\n );\n return ok({ count: pages.length, pages });\n });\n },\n};\n","import {\n browserScreenshotShape,\n ToolNames,\n type BrowserScreenshotInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserScreenshotTool: ToolModule<typeof browserScreenshotShape> = {\n name: ToolNames.browserScreenshot,\n description:\n \"Capture a screenshot and save under ./.rolepod-uiproof/artifacts/{run_id}/. Set `full_page: true` for full-page capture; default is viewport only. Read-only (does NOT invalidate refs).\",\n inputShape: browserScreenshotShape,\n build(ctx) {\n return safeHandler(async (args: BrowserScreenshotInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const { runId, runDir } = await ctx.store.startRun(\"snap\");\n const buf = await engine.screenshot(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.full_page ?? false,\n );\n const path = await ctx.store.writeScreenshot(runDir, buf, \"shot\");\n return ok({\n run_id: runId,\n path,\n width: undefined,\n height: undefined,\n bytes: buf.byteLength,\n });\n });\n },\n};\n","import { browserScrollShape, ToolNames, type BrowserScrollInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserScrollTool: ToolModule<typeof browserScrollShape> = {\n name: ToolNames.browserScroll,\n description:\n \"Scroll the page (or a specific scrollable element when `ref` is set) by `amount` pixels in `direction`. Invalidates all refs on success.\",\n inputShape: browserScrollShape,\n build(ctx) {\n return safeHandler(async (args: BrowserScrollInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.scroll(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.direction,\n args.amount,\n args.ref,\n );\n return ok({ scrolled: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserSetEnvShape,\n ToolNames,\n type BrowserSetEnvInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSetEnvTool: ToolModule<typeof browserSetEnvShape> = {\n name: ToolNames.browserSetEnv,\n description:\n \"Mutate session environment at runtime: viewport, offline state, geolocation, color_scheme (`light`/`dark`), reduced_motion, extra HTTP headers, network throttle preset (`slow-3g`/`fast-3g`/`slow-4g`/`fast-4g`/`offline`/`no-throttling`), and CPU throttle multiplier. `network_throttle` and `cpu_throttle` are chromium-only (CDP). `user_agent`, `locale`, and `timezone` cannot be changed mid-session — set them at `browser_open` time. Invalidates all refs.\",\n inputShape: browserSetEnvShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSetEnvInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"set_env is web-only and requires PlaywrightEngine.\",\n );\n }\n await engine.setEnv(args.session_id, {\n ...(args.viewport !== undefined ? { viewport: args.viewport } : {}),\n ...(args.offline !== undefined ? { offline: args.offline } : {}),\n ...(args.geolocation !== undefined\n ? { geolocation: args.geolocation }\n : {}),\n ...(args.color_scheme !== undefined\n ? { colorScheme: args.color_scheme }\n : {}),\n ...(args.reduced_motion !== undefined\n ? { reducedMotion: args.reduced_motion }\n : {}),\n ...(args.extra_headers !== undefined\n ? { extraHeaders: args.extra_headers }\n : {}),\n ...(args.network_throttle !== undefined\n ? { networkThrottle: args.network_throttle }\n : {}),\n ...(args.cpu_throttle !== undefined\n ? { cpuThrottle: args.cpu_throttle }\n : {}),\n });\n return ok({ applied: true });\n });\n },\n};\n","import {\n browserSnapshotShape,\n ToolNames,\n type BrowserSnapshotInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSnapshotTool: ToolModule<typeof browserSnapshotShape> = {\n name: ToolNames.browserSnapshot,\n description:\n \"Return the current accessibility tree with stable refs (e1, e2, …). Refs are valid only until the next state-changing call (D-010).\",\n inputShape: browserSnapshotShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSnapshotInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const snap = await engine.snapshot(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.mode,\n );\n return ok({\n session_id: snap.session_id,\n url_or_screen: snap.url_or_screen,\n tree: snap.tree,\n taken_at: snap.taken_at,\n });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserSwitchPageShape,\n ToolNames,\n type BrowserSwitchPageInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSwitchPageTool: ToolModule<typeof browserSwitchPageShape> = {\n name: ToolNames.browserSwitchPage,\n description:\n \"Set the active page for subsequent tool calls. Use `browser_pages` to discover indexes. Switching invalidates all refs because each page has its own DOM. Page 0 is the main page; popups land at higher indexes in the order they opened.\",\n inputShape: browserSwitchPageShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSwitchPageInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"switch_page is web-only and requires PlaywrightEngine.\",\n );\n }\n await engine.switchPage(args.session_id, args.index);\n return ok({ active_index: args.index });\n });\n },\n};\n","import { browserTypeShape, ToolNames, type BrowserTypeInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserTypeTool: ToolModule<typeof browserTypeShape> = {\n name: ToolNames.browserType,\n description:\n \"Type `text` into the element identified by `ref`. Set `clear_first: true` to replace the existing value. Invalidates all refs on success.\",\n inputShape: browserTypeShape,\n build(ctx) {\n return safeHandler(async (args: BrowserTypeInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.type(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.ref,\n args.text,\n args.clear_first ? { clearFirst: true } : undefined,\n );\n return ok({ typed: true });\n });\n },\n};\n","import {\n browserUploadFileShape,\n ToolNames,\n type BrowserUploadFileInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserUploadFileTool: ToolModule<typeof browserUploadFileShape> = {\n name: ToolNames.browserUploadFile,\n description:\n \"Attach a local file to the `<input type=file>` element identified by `ref`. `file_path` MUST be an absolute path on the host filesystem. Invalidates all refs on success.\",\n inputShape: browserUploadFileShape,\n build(ctx) {\n return safeHandler(async (args: BrowserUploadFileInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.uploadFile(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.ref,\n args.file_path,\n );\n return ok({ uploaded: true, file_path: args.file_path });\n });\n },\n};\n","import {\n browserWaitForShape,\n ToolNames,\n type BrowserWaitForInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserWaitForTool: ToolModule<typeof browserWaitForShape> = {\n name: ToolNames.browserWaitFor,\n description:\n \"Wait until a condition holds: text_visible, ref_exists, url_matches, or idle. Defaults to a 10s timeout. Invalidates all refs on success.\",\n inputShape: browserWaitForShape,\n build(ctx) {\n return safeHandler(async (args: BrowserWaitForInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const start = Date.now();\n await engine.waitFor(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.condition,\n args.timeout_ms,\n );\n return ok({ matched: true, waited_ms: Date.now() - start });\n });\n },\n};\n","import AxeBuilder from \"@axe-core/playwright\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n auditA11yShape,\n ToolNames,\n type AuditA11yInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport {\n writeManifest,\n type ManifestArtifact,\n type ManifestStatus,\n} from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nconst TAGS_BY_LEVEL: Record<AuditA11yInput[\"level\"], string[]> = {\n \"wcag-a\": [\"wcag2a\", \"wcag21a\"],\n \"wcag-aa\": [\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\"],\n \"wcag-aaa\": [\n \"wcag2a\",\n \"wcag2aa\",\n \"wcag2aaa\",\n \"wcag21a\",\n \"wcag21aa\",\n \"wcag21aaa\",\n ],\n};\n\nconst AXE_TO_SEVERITY: Record<string, \"critical\" | \"serious\" | \"moderate\" | \"minor\"> = {\n critical: \"critical\",\n serious: \"serious\",\n moderate: \"moderate\",\n minor: \"minor\",\n};\n\nexport const auditA11yTool: ToolModule<typeof auditA11yShape> = {\n name: ToolNames.auditA11y,\n description:\n \"Run an accessibility audit on the page using axe-core. Returns issues grouped by severity with WCAG references and fix suggestions. v0.2: scope='page' only.\",\n inputShape: auditA11yShape,\n build(ctx) {\n return safeHandler(async (args: AuditA11yInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"audit\",\n { skill: \"audit-a11y\" },\n );\n const session = await ctx.registry.open(args.open);\n const engine = ctx.registry.engineFor(session.id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"audit_a11y currently requires PlaywrightEngine (mobile a11y audit lands later).\",\n );\n }\n const page = engine.getPageForSession(session.id);\n\n let reportPath: string | undefined;\n let issues: Array<Record<string, unknown>> = [];\n let scopeTagged = false;\n try {\n // Tag the scope element so axe-core can include it via CSS.\n if (args.scope !== \"page\") {\n // refresh refIndex so the supplied ref is meaningful\n await engine.snapshot({ id: session.id, platform: \"web\" });\n const ref = args.scope.ref;\n const locator = page.locator(`aria-ref=${ref}`);\n if ((await locator.count()) === 0) {\n throw new RolepodMcpError(\n \"unknown_ref\",\n `Ref \"${ref}\" not found in the current snapshot.`,\n { session_id: session.id, ref },\n );\n }\n await locator\n .first()\n .evaluate((el) => el.setAttribute(\"data-rolepod-axe-scope\", \"true\"));\n scopeTagged = true;\n }\n\n const builder = new AxeBuilder({ page }).withTags(TAGS_BY_LEVEL[args.level]);\n if (scopeTagged) builder.include(\"[data-rolepod-axe-scope]\");\n const results = await builder.analyze();\n issues = results.violations.flatMap((v) =>\n v.nodes.map((n, idx) => ({\n wcag_ref: pickWcagRef(v.tags) ?? v.id,\n severity: AXE_TO_SEVERITY[v.impact ?? \"minor\"] ?? \"minor\",\n ref: `${v.id}#${idx}`,\n description: v.help,\n fix_suggestion: v.helpUrl,\n target: n.target.join(\" \"),\n })),\n );\n\n const payload = {\n run_id: runId,\n level: args.level,\n counts: countBySeverity(issues),\n issues,\n };\n if (args.report_format === \"markdown\") {\n reportPath = await ctx.store.writeReport(\n runDir,\n \"report.md\",\n renderMarkdown(payload),\n );\n } else {\n reportPath = await ctx.store.writeReport(\n runDir,\n \"report.json\",\n JSON.stringify(payload, null, 2),\n );\n }\n } finally {\n if (scopeTagged) {\n await page\n .locator(\"[data-rolepod-axe-scope]\")\n .first()\n .evaluate((el) => el.removeAttribute(\"data-rolepod-axe-scope\"))\n .catch(() => undefined);\n }\n if (args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n\n const counts = countBySeverity(issues);\n const status = a11yStatus(counts);\n const artifacts: ManifestArtifact[] = reportPath\n ? [{ type: \"report\", path: reportPath }]\n : [];\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status,\n summary: buildAuditSummary(args.level, counts, status),\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts,\n metadata: {\n level: args.level,\n scope: args.scope,\n counts,\n report_format: args.report_format,\n },\n });\n\n return ok({\n run_id: runId,\n counts,\n issues,\n report_path: reportPath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n });\n },\n};\n\n/**\n * Graduated status mapping for a11y audits — keeps `warn` signal that a\n * strict pass/fail would discard.\n *\n * critical + serious > 0 → fail (blocking issues)\n * moderate + minor > 0 → warn (worth surfacing, not blocking)\n * no issues → pass\n */\nfunction a11yStatus(counts: Record<string, number>): ManifestStatus {\n if ((counts.critical ?? 0) + (counts.serious ?? 0) > 0) return \"fail\";\n if ((counts.moderate ?? 0) + (counts.minor ?? 0) > 0) return \"warn\";\n return \"pass\";\n}\n\nfunction buildAuditSummary(\n level: string,\n counts: Record<string, number>,\n status: ManifestStatus,\n): string {\n const total =\n (counts.critical ?? 0) +\n (counts.serious ?? 0) +\n (counts.moderate ?? 0) +\n (counts.minor ?? 0);\n if (status === \"pass\") return `${level}: 0 issues`;\n return `${level}: ${total} issue(s) — critical=${counts.critical ?? 0}, serious=${counts.serious ?? 0}, moderate=${counts.moderate ?? 0}, minor=${counts.minor ?? 0}`;\n}\n\nfunction pickWcagRef(tags: string[]): string | undefined {\n return tags.find((t) => /^wcag\\d/.test(t));\n}\n\nfunction countBySeverity(\n issues: Array<Record<string, unknown>>,\n): Record<string, number> {\n const out: Record<string, number> = {\n critical: 0,\n serious: 0,\n moderate: 0,\n minor: 0,\n };\n for (const i of issues) {\n const s = String(i.severity);\n out[s] = (out[s] ?? 0) + 1;\n }\n return out;\n}\n\nfunction renderMarkdown(p: {\n run_id: string;\n level: string;\n counts: Record<string, number>;\n issues: Array<Record<string, unknown>>;\n}): string {\n const header = `# A11y audit — ${p.run_id}\\n\\nLevel: \\`${p.level}\\`\\n\\n## Counts\\n\\n- critical: ${p.counts.critical}\\n- serious: ${p.counts.serious}\\n- moderate: ${p.counts.moderate}\\n- minor: ${p.counts.minor}\\n\\n## Issues\\n\\n`;\n const body = p.issues\n .map(\n (i) =>\n `### ${i.severity} — ${i.description}\\n\\n- WCAG: ${i.wcag_ref}\\n- Target: \\`${i.target}\\`\\n- Fix: ${i.fix_suggestion}\\n`,\n )\n .join(\"\\n\");\n return header + body;\n}\n","import {\n extractUiStateShape,\n ToolNames,\n type A11yNode,\n type ExtractUiStateInput,\n} from \"../../schema/tools.js\";\nimport type { Session } from \"../../engine/Engine.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\n/**\n * Returns the most-relevant accessibility-tree subtree plus the refs\n * matched by the question. **No LLM is invoked** — the Lead interprets\n * the returned subtree.\n */\nexport const extractUiStateTool: ToolModule<typeof extractUiStateShape> = {\n name: ToolNames.extractUiState,\n description:\n \"Return the AT-tree subtree most likely to answer a natural-language question, plus matched refs. No LLM is called — the Lead does the interpretation.\",\n inputShape: extractUiStateShape,\n build(ctx) {\n return safeHandler(async (args: ExtractUiStateInput) => {\n let session: Session;\n let openedHere = false;\n if (args.session_id) {\n const platform = ctx.registry.platformOf(args.session_id);\n session = { id: args.session_id, platform };\n } else if (args.open) {\n session = await ctx.registry.open(args.open);\n openedHere = true;\n } else {\n throw new RolepodMcpError(\n \"invalid_input\",\n \"Provide either `session_id` (existing session) or `open` (to start one).\",\n );\n }\n\n try {\n const engine = ctx.registry.engineFor(session.id);\n const snap = await engine.snapshot(session);\n const tokens = tokenize(args.question_nl);\n const matches = scoreTree(snap.tree, tokens);\n const top = matches[0];\n const subtree = top\n ? (top.subtree as A11yNode)\n : snap.tree;\n const matchedRefs = matches.slice(0, 8).map((m) => m.ref);\n\n let confidence: \"high\" | \"medium\" | \"low\" = \"low\";\n if (top) {\n if (top.score >= tokens.length && tokens.length > 0) confidence = \"high\";\n else if (top.score >= Math.max(1, Math.ceil(tokens.length / 2)))\n confidence = \"medium\";\n }\n\n return ok({\n snapshot_ref: snap.taken_at,\n confidence,\n matched_refs: matchedRefs,\n value: subtree,\n url_or_screen: snap.url_or_screen,\n });\n } finally {\n if (openedHere && args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n });\n },\n};\n\nfunction tokenize(q: string): string[] {\n return q\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .split(/\\s+/)\n .filter((t) => t.length >= 2);\n}\n\ntype ScoredMatch = {\n ref: string;\n score: number;\n subtree: A11yNode;\n};\n\nfunction scoreTree(root: A11yNode, tokens: string[]): ScoredMatch[] {\n const matches: ScoredMatch[] = [];\n const visit = (node: A11yNode, ancestors: A11yNode[]): void => {\n const hay = `${node.name ?? \"\"} ${node.value ?? \"\"}`.toLowerCase();\n let score = 0;\n for (const t of tokens) if (hay.includes(t)) score += 1;\n if (score > 0) {\n // surface the matching node plus one ancestor for context\n const subtree = ancestors.length > 0 ? ancestors[ancestors.length - 1]! : node;\n matches.push({ ref: node.ref, score, subtree });\n }\n if (node.children) {\n for (const c of node.children) visit(c, [...ancestors, node]);\n }\n };\n visit(root, []);\n matches.sort((a, b) => b.score - a.score);\n return matches;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport {\n scaffoldE2eShape,\n ToolNames,\n type ScaffoldE2eInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\ntype Step = { kind: string; [k: string]: unknown };\ntype Expect = { kind: string; [k: string]: unknown };\ntype ReplayShape = {\n version: number;\n open?: { url?: string };\n steps?: Step[];\n expect?: Expect[];\n};\n\nexport const scaffoldE2eTool: ToolModule<typeof scaffoldE2eShape> = {\n name: ToolNames.scaffoldE2e,\n description:\n \"Generate a runnable e2e test file (playwright-test, vitest+playwright, or pytest+selenium) from a scenario description and optional replay bundle from a prior verify_ui_flow run.\",\n inputShape: scaffoldE2eShape,\n build(ctx) {\n return safeHandler(async (args: ScaffoldE2eInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"scaffold\",\n { skill: \"scaffold-e2e\" },\n );\n const slug = slugify(args.scenario_nl);\n const bundle = args.recorded_bundle\n ? await loadReplay(args.recorded_bundle)\n : null;\n const ctxObj = { args, slug, bundle };\n\n let body: string;\n let language: \"typescript\" | \"python\";\n let filename: string;\n let dependencies: string[];\n let setupNotes: string;\n\n switch (args.framework) {\n case \"playwright-test\":\n body = renderPlaywrightTest(ctxObj);\n language = \"typescript\";\n filename = args.filename ?? `${slug}.spec.ts`;\n dependencies = [\"@playwright/test\"];\n setupNotes =\n \"Install: `npm i -D @playwright/test && npx playwright install`. Run: `npx playwright test`.\";\n break;\n case \"vitest+playwright\":\n body = renderVitestPlaywright(ctxObj);\n language = \"typescript\";\n filename = args.filename ?? `${slug}.test.ts`;\n dependencies = [\"vitest\", \"playwright\"];\n setupNotes =\n \"Install: `npm i -D vitest playwright && npx playwright install chromium`. Run: `npx vitest`.\";\n break;\n case \"pytest+selenium\":\n body = renderPytestSelenium(ctxObj);\n language = \"python\";\n filename = args.filename ?? `test_${slug}.py`;\n dependencies = [\"pytest\", \"selenium\"];\n setupNotes =\n \"Install: `pip install pytest selenium`. Ensure a Chrome driver is on PATH. Run: `pytest`.\";\n break;\n default:\n throw new RolepodMcpError(\n \"invalid_input\",\n `Unknown framework \"${args.framework}\".`,\n );\n }\n\n const path = await ctx.store.writeReport(runDir, filename, body);\n\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"build\",\n status: \"pass\",\n summary: `generated ${args.framework} test \"${filename}\" from ${bundle ? \"replay bundle\" : \"scenario\"}`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: [{ type: \"test_file\", path }],\n metadata: {\n framework: args.framework,\n language,\n from_replay_bundle: Boolean(bundle),\n },\n });\n\n return ok({\n run_id: runId,\n test_file_path: path,\n language,\n dependencies,\n setup_notes: setupNotes,\n from_replay_bundle: Boolean(bundle),\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n });\n },\n};\n\nasync function loadReplay(bundlePath: string): Promise<ReplayShape> {\n const raw = await readFile(resolve(bundlePath), \"utf8\");\n return JSON.parse(raw) as ReplayShape;\n}\n\nfunction slugify(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 40) || \"scenario\"\n );\n}\n\ntype RenderCtx = {\n args: ScaffoldE2eInput;\n slug: string;\n bundle: ReplayShape | null;\n};\n\nfunction renderPlaywrightTest(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(playwrightStepLine).join(\"\\n\")\n : ` // TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(playwrightExpectLine).join(\"\\n\")\n : ` // TODO: add expectations`;\n return [\n `import { test, expect } from \"@playwright/test\";`,\n ``,\n `test(${JSON.stringify(c.args.scenario_nl)}, async ({ page }) => {`,\n ` await page.goto(${JSON.stringify(url)});`,\n stepLines,\n expectLines,\n `});`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction renderVitestPlaywright(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(playwrightStepLine).join(\"\\n\")\n : ` // TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(playwrightExpectLine).join(\"\\n\")\n : ` // TODO: add expectations`;\n return [\n `import { test } from \"vitest\";`,\n `import { chromium, expect } from \"playwright/test\";`,\n ``,\n `test(${JSON.stringify(c.args.scenario_nl)}, async () => {`,\n ` const browser = await chromium.launch();`,\n ` const page = await browser.newPage();`,\n ` try {`,\n ` await page.goto(${JSON.stringify(url)});`,\n indent(stepLines, 2),\n indent(expectLines, 2),\n ` } finally {`,\n ` await browser.close();`,\n ` }`,\n `});`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction renderPytestSelenium(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(seleniumStepLine).join(\"\\n\")\n : ` # TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(seleniumExpectLine).join(\"\\n\")\n : ` # TODO: add expectations`;\n return [\n `import pytest`,\n `from selenium import webdriver`,\n `from selenium.webdriver.common.by import By`,\n `from selenium.webdriver.common.keys import Keys`,\n ``,\n `def test_${slugifyPy(c.args.scenario_nl)}():`,\n ` \"\"\"${c.args.scenario_nl}\"\"\"`,\n ` driver = webdriver.Chrome()`,\n ` try:`,\n ` driver.get(${JSON.stringify(url)})`,\n indent(stepLines, 2),\n indent(expectLines, 2),\n ` finally:`,\n ` driver.quit()`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction playwrightStepLine(step: Step): string {\n switch (step.kind) {\n case \"click\":\n return ` await page.getByText(${JSON.stringify(step.query)}, { exact: false }).first().click();`;\n case \"type\":\n return ` await page.getByRole(\"textbox\", { name: ${JSON.stringify(step.query)} }).fill(${JSON.stringify(step.text)});`;\n case \"key\":\n return ` await page.keyboard.press(${JSON.stringify(step.key)});`;\n case \"navigate\":\n return ` await page.goto(${JSON.stringify(step.url)});`;\n case \"wait_for\":\n return ` // wait_for: ${JSON.stringify(step.condition)} — translate to page.waitForXxx()`;\n case \"hover\":\n return ` await page.getByText(${JSON.stringify(step.query)}, { exact: false }).first().hover();`;\n case \"drag\":\n return [\n ` await page`,\n ` .getByText(${JSON.stringify(step.from_query)}, { exact: false })`,\n ` .first()`,\n ` .dragTo(page.getByText(${JSON.stringify(step.to_query)}, { exact: false }).first());`,\n ].join(\"\\n\");\n case \"fill_form\": {\n const fields = Array.isArray(step.fields) ? (step.fields as Array<{ query: string; value: unknown; kind?: string }>) : [];\n return fields\n .map((f) => {\n const q = JSON.stringify(f.query);\n if (f.kind === \"select\") {\n return ` await page.getByLabel(${q}).selectOption(${JSON.stringify(String(f.value))});`;\n }\n if (f.kind === \"checkbox\" || f.kind === \"radio\") {\n const checked = typeof f.value === \"boolean\"\n ? f.value\n : String(f.value) === \"true\" || String(f.value) === \"on\";\n return ` await page.getByLabel(${q}).setChecked(${checked});`;\n }\n return ` await page.getByLabel(${q}).fill(${JSON.stringify(String(f.value))});`;\n })\n .join(\"\\n\");\n }\n case \"upload\":\n return ` await page.getByLabel(${JSON.stringify(step.query)}).setInputFiles(${JSON.stringify(step.file_path)});`;\n case \"dialog\":\n return [\n ` page.once(\"dialog\", async (dialog) => {`,\n step.action === \"accept\"\n ? ` await dialog.accept();`\n : step.action === \"accept_with_text\"\n ? ` await dialog.accept(${JSON.stringify(step.text ?? \"\")});`\n : ` await dialog.dismiss();`,\n ` });`,\n ].join(\"\\n\");\n case \"set_env\": {\n const lines: string[] = [];\n if (step.viewport && typeof step.viewport === \"object\") {\n const v = step.viewport as { width: number; height: number };\n lines.push(` await page.setViewportSize({ width: ${v.width}, height: ${v.height} });`);\n }\n if (step.offline !== undefined) {\n lines.push(` await page.context().setOffline(${Boolean(step.offline)});`);\n }\n if (step.geolocation) {\n lines.push(` await page.context().setGeolocation(${JSON.stringify(step.geolocation)});`);\n }\n if (step.color_scheme || step.reduced_motion) {\n const opts: Record<string, unknown> = {};\n if (step.color_scheme) opts.colorScheme = step.color_scheme;\n if (step.reduced_motion) opts.reducedMotion = step.reduced_motion;\n lines.push(` await page.emulateMedia(${JSON.stringify(opts)});`);\n }\n if (step.extra_headers) {\n lines.push(` await page.context().setExtraHTTPHeaders(${JSON.stringify(step.extra_headers)});`);\n }\n if (step.network_throttle || step.cpu_throttle !== undefined) {\n lines.push(` // network/cpu throttle requires CDP — see Playwright docs (chromium only)`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : ` // set_env: nothing to apply`;\n }\n case \"switch_page\":\n return ` const allPages = page.context().pages(); /* switch to index ${step.index} */ if (allPages[${step.index}]) await allPages[${step.index}].bringToFront();`;\n case \"evaluate\":\n return ` await page.evaluate(${JSON.stringify(step.script)});`;\n default:\n return ` // unsupported step kind: ${step.kind}`;\n }\n}\n\nfunction playwrightExpectLine(exp: Expect): string {\n switch (exp.kind) {\n case \"text_visible\":\n return ` await expect(page.getByText(${JSON.stringify(exp.text)}, { exact: false }).first()).toBeVisible();`;\n case \"text_absent\":\n return ` await expect(page.getByText(${JSON.stringify(exp.text)}, { exact: false }).first()).toHaveCount(0);`;\n case \"url_matches\":\n return ` await expect(page).toHaveURL(new RegExp(${JSON.stringify(exp.pattern)}));`;\n case \"ref_in_state\":\n return ` // ref_in_state ${JSON.stringify(exp.query)} → ${String(exp.state)} — translate as needed`;\n case \"no_console_errors\":\n return [\n ` // no_console_errors — collect via page.on('console') before the steps, then:`,\n ` // expect(consoleErrors).toEqual([]);`,\n ].join(\"\\n\");\n case \"no_failed_requests\":\n return [\n ` // no_failed_requests — collect via page.on('requestfailed'/'response') before the steps, then:`,\n ` // expect(failedRequests).toEqual([]);`,\n ].join(\"\\n\");\n case \"request_made\":\n return ` await page.waitForRequest(new RegExp(${JSON.stringify(exp.url_pattern)}));`;\n case \"response_status\":\n return ` await page.waitForResponse((r) => new RegExp(${JSON.stringify(exp.url_pattern)}).test(r.url()) && r.status() === ${Number(exp.status)});`;\n default:\n return ` // unsupported expect kind: ${exp.kind}`;\n }\n}\n\nfunction seleniumStepLine(step: Step): string {\n switch (step.kind) {\n case \"click\":\n return ` driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.query))}\\\\\")]\").click()`;\n case \"type\":\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${escapePy(String(step.query))}\\\\\" or @placeholder=\\\\\"${escapePy(String(step.query))}\\\\\"]\").send_keys(${JSON.stringify(step.text)})`;\n case \"key\":\n return ` driver.switch_to.active_element.send_keys(Keys.${pyKeyName(String(step.key))})`;\n case \"navigate\":\n return ` driver.get(${JSON.stringify(step.url)})`;\n case \"wait_for\":\n return ` # wait_for: ${JSON.stringify(step.condition)} — translate to WebDriverWait`;\n case \"hover\":\n return [\n ` from selenium.webdriver.common.action_chains import ActionChains`,\n ` target = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.query))}\\\\\")]\")`,\n ` ActionChains(driver).move_to_element(target).perform()`,\n ].join(\"\\n\");\n case \"drag\":\n return [\n ` from selenium.webdriver.common.action_chains import ActionChains`,\n ` src = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.from_query))}\\\\\")]\")`,\n ` dst = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.to_query))}\\\\\")]\")`,\n ` ActionChains(driver).drag_and_drop(src, dst).perform()`,\n ].join(\"\\n\");\n case \"fill_form\": {\n const fields = Array.isArray(step.fields)\n ? (step.fields as Array<{ query: string; value: unknown; kind?: string }>)\n : [];\n return fields\n .map((f) => {\n const q = escapePy(f.query);\n if (f.kind === \"select\") {\n return [\n ` from selenium.webdriver.support.ui import Select`,\n ` Select(driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\")).select_by_visible_text(${JSON.stringify(String(f.value))})`,\n ].join(\"\\n\");\n }\n if (f.kind === \"checkbox\" || f.kind === \"radio\") {\n const checked =\n typeof f.value === \"boolean\"\n ? f.value\n : String(f.value) === \"true\";\n return ` el = driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\"); el.click() if el.is_selected() != ${checked ? \"True\" : \"False\"} else None`;\n }\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\").send_keys(${JSON.stringify(String(f.value))})`;\n })\n .join(\"\\n\");\n }\n case \"upload\":\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${escapePy(String(step.query))}\\\\\"]\").send_keys(${JSON.stringify(step.file_path)})`;\n case \"dialog\":\n return [\n ` alert = driver.switch_to.alert`,\n step.action === \"accept\"\n ? ` alert.accept()`\n : step.action === \"accept_with_text\"\n ? ` alert.send_keys(${JSON.stringify(step.text ?? \"\")}); alert.accept()`\n : ` alert.dismiss()`,\n ].join(\"\\n\");\n case \"set_env\": {\n const lines: string[] = [];\n if (step.viewport && typeof step.viewport === \"object\") {\n const v = step.viewport as { width: number; height: number };\n lines.push(` driver.set_window_size(${v.width}, ${v.height})`);\n }\n lines.push(` # set_env partially supported in Selenium — see selenium docs for offline/geolocation/colorScheme via CDP`);\n return lines.join(\"\\n\");\n }\n case \"switch_page\":\n return ` driver.switch_to.window(driver.window_handles[${step.index}])`;\n case \"evaluate\":\n return ` driver.execute_script(${JSON.stringify(step.script)})`;\n default:\n return ` # unsupported step kind: ${step.kind}`;\n }\n}\n\nfunction seleniumExpectLine(exp: Expect): string {\n switch (exp.kind) {\n case \"text_visible\":\n return ` assert ${JSON.stringify(exp.text)} in driver.page_source`;\n case \"text_absent\":\n return ` assert ${JSON.stringify(exp.text)} not in driver.page_source`;\n case \"url_matches\":\n return ` import re; assert re.search(${JSON.stringify(exp.pattern)}, driver.current_url)`;\n case \"ref_in_state\":\n return ` # ref_in_state ${JSON.stringify(exp.query)} → ${String(exp.state)}`;\n case \"no_console_errors\":\n return [\n ` # no_console_errors — read browser logs via driver.get_log(\"browser\")`,\n ` errors = [l for l in driver.get_log(\"browser\") if l.get(\"level\") == \"SEVERE\"]`,\n ` assert errors == [], f\"console errors: {errors}\"`,\n ].join(\"\\n\");\n case \"no_failed_requests\":\n return ` # no_failed_requests — selenium has no built-in network capture. Enable selenium-wire or BiDi for this.`;\n case \"request_made\":\n return ` # request_made ${JSON.stringify(exp.url_pattern)} — use selenium-wire (driver.requests) or BiDi`;\n case \"response_status\":\n return ` # response_status ${JSON.stringify(exp.url_pattern)} == ${Number(exp.status)} — use selenium-wire (driver.requests) or BiDi`;\n default:\n return ` # unsupported expect kind: ${exp.kind}`;\n }\n}\n\nfunction slugifyPy(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 40) || \"scenario\"\n );\n}\n\nfunction escapePy(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction pyKeyName(k: string): string {\n const map: Record<string, string> = {\n Enter: \"ENTER\",\n Tab: \"TAB\",\n Escape: \"ESCAPE\",\n Backspace: \"BACK_SPACE\",\n ArrowUp: \"ARROW_UP\",\n ArrowDown: \"ARROW_DOWN\",\n ArrowLeft: \"ARROW_LEFT\",\n ArrowRight: \"ARROW_RIGHT\",\n };\n return map[k] ?? `RETURN # unknown key: ${k}`;\n}\n\nfunction indent(block: string, n: number): string {\n const pad = \" \".repeat(n);\n return block\n .split(\"\\n\")\n .map((l) => (l.length > 0 ? pad + l : l))\n .join(\"\\n\");\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport pixelmatch from \"pixelmatch\";\nimport { PNG } from \"pngjs\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n ToolNames,\n visualDiffShape,\n type VisualDiffInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest, type ManifestArtifact } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const visualDiffTool: ToolModule<typeof visualDiffShape> = {\n name: ToolNames.visualDiff,\n description:\n \"Capture a screenshot and compare against a named baseline under ./.rolepod-uiproof/baselines/. First call for a baseline_id seeds the baseline (passed=true, diff_pct=0). Subsequent calls return the diff percentage and an annotated diff image.\",\n inputShape: visualDiffShape,\n build(ctx) {\n return safeHandler(async (args: VisualDiffInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"vdiff\",\n { skill: \"visual-diff\" },\n );\n const session = await ctx.registry.open({\n ...args.open,\n ...(args.viewport ? { viewport: args.viewport } : {}),\n });\n const engine = ctx.registry.engineFor(session.id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"visual_diff currently requires PlaywrightEngine.\",\n );\n }\n\n try {\n const buf = await engine.screenshot(\n { id: session.id, platform: session.platform },\n true,\n );\n const currentPath = await ctx.store.writeScreenshot(runDir, buf, \"current\");\n\n await ctx.store.ensureDir(ctx.store.baselineDir);\n const baselinePath = resolve(\n ctx.store.baselineDir,\n `${args.baseline_id}.png`,\n );\n\n if (!existsSync(baselinePath)) {\n await ctx.store.writeBytes(\n ctx.store.baselineDir,\n `${args.baseline_id}.png`,\n buf,\n );\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: \"pass\",\n summary: `baseline \"${args.baseline_id}\" seeded from current capture`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: [\n { type: \"baseline\", path: baselinePath },\n { type: \"screenshot\", path: currentPath },\n ],\n metadata: { baseline_id: args.baseline_id, seeded: true },\n });\n return ok({\n run_id: runId,\n baseline_id: args.baseline_id,\n diff_pct: 0,\n passed: true,\n baseline_path: baselinePath,\n current_path: currentPath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n note: \"Baseline did not exist — current capture saved as the new baseline.\",\n });\n }\n\n const [baselineRaw, currentRaw] = await Promise.all([\n readFile(baselinePath),\n readFile(currentPath),\n ]);\n const baseline = PNG.sync.read(baselineRaw);\n const current = PNG.sync.read(currentRaw);\n\n if (baseline.width !== current.width || baseline.height !== current.height) {\n throw new RolepodMcpError(\n \"engine_error\",\n `Dimension mismatch for baseline \"${args.baseline_id}\" — baseline ${baseline.width}x${baseline.height}, current ${current.width}x${current.height}. Delete the baseline or pass a matching viewport.`,\n {\n baseline: { w: baseline.width, h: baseline.height },\n current: { w: current.width, h: current.height },\n },\n );\n }\n\n const diff = new PNG({ width: baseline.width, height: baseline.height });\n const diffPixels = pixelmatch(\n baseline.data,\n current.data,\n diff.data,\n baseline.width,\n baseline.height,\n { threshold: args.pixel_threshold, includeAA: true },\n );\n const total = baseline.width * baseline.height;\n const diffPct = diffPixels / total;\n const passed = diffPct <= args.threshold_pct;\n\n const diffImagePath = await ctx.store.writeBytes(\n runDir,\n \"diff.png\",\n PNG.sync.write(diff),\n );\n\n const artifacts: ManifestArtifact[] = [\n { type: \"baseline\", path: baselinePath },\n { type: \"screenshot\", path: currentPath },\n { type: \"diff\", path: diffImagePath },\n ];\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: passed ? \"pass\" : \"fail\",\n summary: `diff ${(diffPct * 100).toFixed(3)}% vs baseline \"${args.baseline_id}\" (threshold ${(args.threshold_pct * 100).toFixed(3)}%)`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts,\n metadata: {\n baseline_id: args.baseline_id,\n diff_pct: Number(diffPct.toFixed(6)),\n diff_pixels: diffPixels,\n total_pixels: total,\n threshold_pct: args.threshold_pct,\n },\n });\n\n return ok({\n run_id: runId,\n baseline_id: args.baseline_id,\n diff_pct: Number(diffPct.toFixed(6)),\n diff_pixels: diffPixels,\n total_pixels: total,\n passed,\n baseline_path: baselinePath,\n current_path: currentPath,\n diff_image_path: diffImagePath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n } finally {\n if (args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n });\n },\n};\n","import type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ToolNames, type ToolName } from \"../schema/tools.js\";\n\n/**\n * Per-tool display metadata exposed via MCP `registerTool`.\n *\n * - `title`: human-readable label shown in client UIs (Claude Code, Cursor, etc.)\n * - `annotations`: trust-and-safety hints. Per spec these are advisory only —\n * clients still gate on user consent — but they let well-behaved clients\n * auto-approve read-only calls and prompt harder on destructive ones.\n *\n * `destructiveHint`/`idempotentHint` are only meaningful when `readOnlyHint`\n * is false, so we omit them for read-only tools.\n */\nexport type ToolMetadata = {\n title: string;\n annotations: ToolAnnotations;\n};\n\nexport const toolMetadata: Record<ToolName, ToolMetadata> = {\n // ---------- atomic ----------\n [ToolNames.browserOpen]: {\n title: \"Open Browser/Mobile Session\",\n annotations: {\n title: \"Open Browser/Mobile Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserClose]: {\n title: \"Close Session\",\n annotations: {\n title: \"Close Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSnapshot]: {\n title: \"Capture Accessibility Snapshot\",\n annotations: {\n title: \"Capture Accessibility Snapshot\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserClick]: {\n title: \"Click Element\",\n annotations: {\n title: \"Click Element\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserType]: {\n title: \"Type Text\",\n annotations: {\n title: \"Type Text\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserKey]: {\n title: \"Press Key\",\n annotations: {\n title: \"Press Key\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserScroll]: {\n title: \"Scroll Viewport\",\n annotations: {\n title: \"Scroll Viewport\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserWaitFor]: {\n title: \"Wait For Condition\",\n annotations: {\n title: \"Wait For Condition\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserScreenshot]: {\n title: \"Take Screenshot\",\n annotations: {\n title: \"Take Screenshot\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserNavigate]: {\n title: \"Navigate URL\",\n annotations: {\n title: \"Navigate URL\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n\n // ---------- composite ----------\n [ToolNames.verifyUiFlow]: {\n title: \"Verify UI Flow\",\n annotations: {\n title: \"Verify UI Flow\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.auditA11y]: {\n title: \"Audit Accessibility (axe-core)\",\n annotations: {\n title: \"Audit Accessibility (axe-core)\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.visualDiff]: {\n title: \"Visual Diff vs Baseline\",\n annotations: {\n title: \"Visual Diff vs Baseline\",\n // Writes to ./.rolepod-uiproof/{baselines,artifacts}/ but only adds files —\n // never destroys an existing baseline silently.\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.scaffoldE2e]: {\n title: \"Scaffold E2E Test File\",\n annotations: {\n title: \"Scaffold E2E Test File\",\n // Writes a test file to the local repo.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n [ToolNames.extractUiState]: {\n title: \"Extract UI State (NL Query)\",\n annotations: {\n title: \"Extract UI State (NL Query)\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n\n // ---------- v0.5 atomic additions ----------\n [ToolNames.browserHover]: {\n title: \"Hover Element\",\n annotations: {\n title: \"Hover Element\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserDrag]: {\n title: \"Drag Element\",\n annotations: {\n title: \"Drag Element\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserFillForm]: {\n title: \"Fill Form (Batch)\",\n annotations: {\n title: \"Fill Form (Batch)\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserUploadFile]: {\n title: \"Upload File\",\n annotations: {\n title: \"Upload File\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserHandleDialog]: {\n title: \"Pre-arm Dialog Handler\",\n annotations: {\n title: \"Pre-arm Dialog Handler\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n [ToolNames.browserConsole]: {\n title: \"Inspect Console Logs\",\n annotations: {\n title: \"Inspect Console Logs\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserNetwork]: {\n title: \"Inspect Network Requests\",\n annotations: {\n title: \"Inspect Network Requests\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSetEnv]: {\n title: \"Set Browser Environment\",\n annotations: {\n title: \"Set Browser Environment\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserEvaluate]: {\n title: \"Evaluate JavaScript (gated; arbitrary code execution)\",\n annotations: {\n title: \"Evaluate JavaScript\",\n // Arbitrary code execution in the page context. Gated by\n // ROLEPOD_ALLOW_EVAL=1 server-side. Always treat as destructive.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserPages]: {\n title: \"List Open Pages\",\n annotations: {\n title: \"List Open Pages\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSwitchPage]: {\n title: \"Switch Active Page\",\n annotations: {\n title: \"Switch Active Page\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n};\n"],"mappings":";;;AACA,SAAS,4BAA4B;;;ACDrC,SAAS,kBAAkB;AAC3B,SAAS,SAAS,YAAY;AAC9B,SAAS,SAAS,YAAY,kBAAkB;AAYhD,eAAsB,YAA6B;AACjD,QAAM,SAAkB,CAAC;AAGzB,QAAM,QAAQ,OAAO,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;AACxD,SAAO,KAAK;AAAA,IACV,MAAM;AAAA,IACN,QAAQ,SAAS,KAAK,OAAO;AAAA,IAC7B,QAAQ,QAAQ,SAAS;AAAA,EAC3B,CAAC;AAGD,SAAO,KAAK,wBAAwB,CAAC;AAGrC,SAAO,KAAK,MAAM,iBAAiB,CAAC;AAGpC,SAAO,KAAK,MAAM,kBAAkB,CAAC;AAGrC,MAAI,WAAW,MAAM,UAAU;AAC7B,WAAO,KAAK,WAAW,CAAC;AAAA,EAC1B;AAGA,SAAO,KAAK,gBAAgB,CAAC;AAG7B,SAAO,KAAK;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ,CAAC;AAGD,SAAO,KAAK,iBAAiB,CAAC;AAE9B,QAAM,MAAM;AACZ,QAAM,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AACrD,SAAO,SAAS,IAAI;AACtB;AAEA,SAAS,0BAAiC;AACxC,QAAM,aAAa;AAAA,IACjB,KAAK,QAAQ,GAAG,WAAW,UAAU,eAAe;AAAA,IACpD,KAAK,QAAQ,GAAG,UAAU,eAAe;AAAA,IACzC,QAAQ,IAAI;AAAA,EACd,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAClD,aAAW,QAAQ,YAAY;AAC7B,QAAI,WAAW,IAAI,GAAG;AACpB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEA,eAAe,mBAAmC;AAChD,MAAI;AACF,UAAM,MAAM,MAAM,YAAY,UAAU,aAAa;AACrD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QACE;AAAA,IACJ;AAAA,EACF;AACF;AAEA,eAAe,oBAAoC;AACjD,QAAM,OAAO,QAAQ,IAAI,eAAe;AACxC,QAAM,OAAO,OAAO,QAAQ,IAAI,eAAe,IAAI;AACnD,QAAM,OAAO,QAAQ,IAAI,oBAAoB;AAC7C,QAAM,MAAM,UAAU,IAAI,IAAI,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,OAAO,OAAO,GAAG;AAC3E,MAAI;AACF,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,UAAU,WAAW,MAAM,KAAK,MAAM,GAAG,IAAI;AACnD,UAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;AACpD,iBAAa,OAAO;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,IAAI,KAAK,OAAO;AAAA,MACxB,QAAQ,GAAG,GAAG,gBAAW,IAAI,MAAM;AAAA,IACrC;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ,oBAAoB,GAAG;AAAA,IACjC;AAAA,EACF;AACF;AAEA,SAAS,aAAoB;AAC3B,QAAM,OAAO;AACb,MAAI,WAAW,IAAI,GAAG;AACpB,WAAO,EAAE,MAAM,6BAA6B,QAAQ,MAAM,QAAQ,KAAK;AAAA,EACzE;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ;AACF;AAEA,SAAS,kBAAyB;AAChC,QAAM,aAAa;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,IACZ,KAAK,QAAQ,GAAG,WAAW,WAAW,KAAK;AAAA,IAC3C,KAAK,QAAQ,GAAG,WAAW,KAAK;AAAA,EAClC,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAClD,aAAW,QAAQ,YAAY;AAC7B,QAAI,WAAW,IAAI,GAAG;AACpB,aAAO,EAAE,MAAM,8BAA8B,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ;AACF;AAEA,SAAS,mBAA0B;AACjC,QAAM,MAAM,QAAQ,QAAQ,IAAI,GAAG,kBAAkB;AAErD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ,uBAAuB,GAAG;AAAA,EACpC;AACF;AAEA,SAAS,MAAM,QAAuB;AACpC,QAAM,OAAO,CAAC,MAAwB,MAAM,OAAO,WAAM,MAAM,SAAS,WAAM;AAC9E,aAAW,KAAK,QAAQ;AAGtB,YAAQ,OAAO,MAAM,KAAK,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM;AAAA,CAAI;AAAA,EAC/E;AACF;;;AC5KA,SAAS,YAAYA,mBAAkB;AAEhC,SAAS,mBAA2B;AACzC,QAAM,KAAKA,YAAW;AACtB,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,yDAAoD;AAC/D,QAAM,KAAK,gEAAgE;AAE3E,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,gCAAgC;AAE3C,QAAM,KAAK,qCAAqC;AAChD,QAAM,KAAK,4BAA4B;AACvC,QAAM,KAAK,gDAAgD;AAC3D,QAAM,KAAK,oDAAoD;AAC/D,QAAM,KAAK,4DAA4D;AAEvE,MAAI,OAAO,UAAU;AACnB,UAAM,KAAK,oCAA+B;AAC1C,UAAM,KAAK,gDAA2C;AACtD,UAAM,KAAK,yFAAqE;AAChF,UAAM,KAAK,0EAAqE;AAAA,EAClF,OAAO;AACL,UAAM,KAAK,2DAA2D;AAAA,EACxE;AAEA,QAAM,KAAK,6BAAwB;AACnC,QAAM,KAAK,0DAAqD;AAChE,QAAM,KAAK,kDAA6C;AACxD,QAAM,KAAK,yEAAoE;AAE/E,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,mCAAmC;AAE9C,QAAM,KAAK,mCAAmC;AAC9C,QAAM,KAAK,2CAA2C;AACtD,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,mCAAmC;AAE9C,aAAW,KAAK,MAAO,SAAQ,OAAO,MAAM,IAAI,IAAI;AACpD,SAAO;AACT;;;AC1CA,SAAS,gBAAgB;AACzB,SAAS,WAAAC,gBAAe;;;ACDxB,SAAS,kBAAkB;AAC3B,SAAS,OAAO,iBAAiB;AACjC,SAAS,WAAAC,gBAAe;;;ACKxB,SAAS,KAAK,OAA4C,KAAa,OAAuB;AAC5F,QAAM,OAAO,KAAK,UAAU;AAAA,IAC1B,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,EACzC,CAAC;AACD,UAAQ,OAAO,MAAM,OAAO,IAAI;AAClC;AAEO,IAAM,MAAM;AAAA,EACjB,MAAM,CAAC,KAAa,UAAoB,KAAK,QAAQ,KAAK,KAAK;AAAA,EAC/D,MAAM,CAAC,KAAa,UAAoB,KAAK,QAAQ,KAAK,KAAK;AAAA,EAC/D,OAAO,CAAC,KAAa,UAAoB,KAAK,SAAS,KAAK,KAAK;AAAA,EACjE,OAAO,CAAC,KAAa,UAAoB;AACvC,QAAI,QAAQ,IAAI,kBAAmB,MAAK,SAAS,KAAK,KAAK;AAAA,EAC7D;AACF;;;ADiCO,IAAM,gBAAN,MAAoB;AAAA,EAChB;AAAA,EACA;AAAA,EACQ;AAAA,EAEjB,YACE,OAAkD,CAAC,GACnD;AACA,UAAM,iBAAiB,QAAQ,IAAI,mBAAmB;AACtD,SAAK,OAAO,KAAK,SAAS,iBAAiB,gBAAgB;AAE3D,QAAI,KAAK,YAAY,QAAW;AAC9B,WAAK,UAAU,KAAK;AAAA,IACtB,WAAW,KAAK,SAAS,eAAe;AACtC,WAAK,UAAUC,SAAQ,QAAQ,IAAI,GAAG,YAAY,UAAU;AAAA,IAC9D,OAAO;AACL,WAAK,UAAUA,SAAQ,QAAQ,IAAI,GAAG,oBAAoB,WAAW;AAAA,IACvE;AAIA,SAAK,eAAeA,SAAQ,QAAQ,IAAI,GAAG,oBAAoB,WAAW;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,SACJ,SAAS,OACT,OAAwB,CAAC,GACA;AACzB,UAAM,KAAK,KAAK,cAAc;AAC9B,UAAM,QAAQ,KAAK,SAAS;AAE5B,QAAI;AACJ,QAAI,KAAK,SAAS,eAAe;AAG/B,cAAQ,GAAG,EAAE,oBAAoB,KAAK;AAAA,IACxC,OAAO;AACL,cAAQ,GAAG,MAAM,IAAI,EAAE,IAAI,WAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,IACrD;AAEA,UAAM,SAASA,SAAQ,KAAK,SAAS,KAAK;AAC1C,UAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AACvC,QAAI,MAAM,wBAAwB;AAAA,MAChC,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,MAAM,KAAK;AAAA,MACX;AAAA,IACF,CAAC;AACD,WAAO,EAAE,OAAO,QAAQ,OAAO,MAAM,KAAK,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,gBACJ,QACA,KACA,MACiB;AACjB,UAAM,OAAOA,SAAQ,QAAQ,GAAG,IAAI,MAAM;AAC1C,UAAM,UAAU,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBACJ,QACA,QACA,OAAO,eACU;AACjB,UAAM,OAAOA,SAAQ,QAAQ,IAAI;AACjC,UAAM,UAAU,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,MAAM;AAC7D,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,QAAgB,MAAc,MAA+B;AAC7E,UAAM,OAAOA,SAAQ,QAAQ,IAAI;AACjC,UAAM,UAAU,MAAM,MAAM,MAAM;AAClC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,QAAgB,MAAc,KAA8B;AAC3E,UAAM,OAAOA,SAAQ,QAAQ,IAAI;AACjC,UAAM,UAAU,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,QAAiC;AAC/C,UAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AACvC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,gBAAwB;AAC9B,UAAM,IAAI,oBAAI,KAAK;AACnB,UAAM,MAAM,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,WACE,GAAG,EAAE,eAAe,CAAC,KACrB,IAAI,EAAE,YAAY,IAAI,CAAC,IACvB,IAAI,EAAE,WAAW,CAAC,IAClB,MACA,IAAI,EAAE,YAAY,CAAC,IACnB,IAAI,EAAE,cAAc,CAAC,IACrB,IAAI,EAAE,cAAc,CAAC;AAAA,EAEzB;AACF;;;AE1JO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAEzC,YACW,MACT,SACS,QACT;AACA,UAAM,OAAO;AAJJ;AAEA;AAAA,EAGX;AAAA,EALW;AAAA,EAEA;AAAA,EAJO,OAAO;AAAA,EASzB,SAAiF;AAC/E,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;AAYO,IAAM,kBAAN,cAA8B,gBAAgB;AAAA,EACnD,YAAY,WAAmB,KAAa;AAC1C,UAAM,eAAe,QAAQ,GAAG,4CAA4C;AAAA,MAC1E,YAAY;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,sBAAN,cAAkC,gBAAgB;AAAA,EACvD,YAAY,WAAmB;AAC7B,UAAM,mBAAmB,4BAA4B,SAAS,MAAM;AAAA,MAClE,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AACF;AAEO,IAAM,2BAAN,cAAuC,gBAAgB;AAAA,EAC5D,YAAY,UAAkB;AAC5B;AAAA,MACE;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB,EAAE,SAAS;AAAA,IACb;AAAA,EACF;AACF;;;AC1EA,SAAS,cAAAC,mBAAkB;;;ACa3B,SAAS,iBAAiB;AAkB1B,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,eAAe;AACjB,CAAC;AAIM,SAAS,sBAAsB,WAA8C;AAClF,QAAM,WAAW,oBAAI,IAA4B;AACjD,MAAI,UAAU;AACd,QAAM,UAAU,MAAc,IAAI,EAAE,OAAO;AAE3C,MAAI,MAAiB,CAAC;AACtB,MAAI;AACF,UAAM,OAAO,MAAM,SAAS;AAAA,EAC9B,QAAQ;AACN,UAAM,CAAC;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,MAAe,eAAqD;AACjF,UAAM,UAAU,aAAa,IAAI;AACjC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,KAAK,IAAI,KAAK,CAAC;AAC7B,UAAM,cAAe,KAAK,OAAO,KAAmB,CAAC;AAErD,UAAM,OAAO,WAAW,IAAI,OAAO,KAAK,KAAK;AAC7C,eAAW,IAAI,SAAS,GAAG;AAE3B,UAAM,MAAM,QAAQ;AACpB,aAAS,IAAI,KAAK;AAAA,MAChB,MAAM;AAAA,MACN,YAAY,MAAM,cAAc;AAAA,MAChC,aAAa,MAAM,eAAe;AAAA,MAClC,MAAM,MAAM,OAAO;AAAA,MACnB,cAAc;AAAA,MACd,YAAY;AAAA,IACd,CAAC;AAED,UAAM,OAAO,qBAAqB,OAAO;AAEzC,UAAM,OAAiB,EAAE,KAAK,KAAK;AACnC,UAAM,OAAO,MAAM,eAAe,KAAK,MAAM,OAAO;AACpD,QAAI,KAAM,MAAK,OAAO;AACtB,QAAI,MAAM,OAAO,KAAK,MAAM,OAAO,MAAM,KAAM,MAAK,QAAQ,MAAM,OAAO;AAEzE,UAAM,QAA2B,CAAC;AAClC,QAAI,MAAM,UAAU,MAAM,QAAS,OAAM,WAAW;AACpD,QAAI,MAAM,UAAU,MAAM,OAAQ,OAAM,UAAU;AAClD,QAAI,MAAM,WAAW,MAAM,OAAQ,OAAM,WAAW;AACpD,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,EAAG,MAAK,QAAQ;AAEhD,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,WAAW,oBAAI,IAAoB;AACzC,YAAM,WAAuB,CAAC;AAC9B,iBAAW,SAAS,aAAa;AAC/B,cAAM,QAAQ,MAAM,OAAO,QAAQ;AACnC,YAAI,MAAO,UAAS,KAAK,KAAK;AAAA,MAChC;AACA,UAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YACJ,IAAI,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,MAAM,WAAW,CAAC,KAAK,IAAI,CAAC;AACzE,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL,MAAM,EAAE,KAAK,MAAM,MAAM,cAAc;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACA,QAAM,MAAM,MAAM,WAAW,oBAAI,IAAI,CAAC;AACtC,MAAI,IAAK,QAAO,EAAE,MAAM,KAAK,SAAS;AACtC,SAAO,EAAE,MAAM,EAAE,KAAK,MAAM,MAAM,cAAc,GAAG,SAAS;AAC9D;AAEA,SAAS,aAAa,MAA8B;AAClD,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,QAAQ,KAAM;AAElB,QAAI,IAAI,WAAW,GAAG,EAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,KAAqB;AACjD,QAAM,OAAO,IAAI,MAAM,GAAG,EAAE,IAAI;AAChC,SAAO,QAAQ;AACjB;;;AC/GA,SAAS,aAAAC,kBAAiB;AAmB1B,IAAMC,UAAS,IAAID,WAAU;AAAA,EAC3B,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,eAAe;AACjB,CAAC;AAIM,SAAS,kBAAkB,WAA0C;AAC1E,QAAM,WAAW,oBAAI,IAAwB;AAC7C,MAAI,UAAU;AACd,QAAM,UAAU,MAAc,IAAI,EAAE,OAAO;AAE3C,MAAI,MAAiB,CAAC;AACtB,MAAI;AACF,UAAMC,QAAO,MAAM,SAAS;AAAA,EAC9B,QAAQ;AACN,UAAM,CAAC;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,MAAe,kBAAwD;AACpF,UAAM,UAAUC,cAAa,IAAI;AACjC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,KAAK,IAAI,KAAK,CAAC;AAC7B,UAAM,cAAe,KAAK,OAAO,KAAmB,CAAC;AAErD,UAAM,OAAO,cAAc,IAAI,OAAO,KAAK,KAAK;AAChD,kBAAc,IAAI,SAAS,GAAG;AAE9B,UAAM,MAAM,QAAQ;AACpB,aAAS,IAAI,KAAK;AAAA,MAChB,MAAM;AAAA,MACN,iBAAiB,MAAM,OAAO;AAAA,MAC9B,MAAM,MAAM,OAAO;AAAA,MACnB,OAAO,MAAM,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,iBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,OAAO,QAAQ,WAAW,iBAAiB,IAC7C,QAAQ,MAAM,kBAAkB,MAAM,EAAE,YAAY,IACpD;AAEJ,UAAM,OAAiB,EAAE,KAAK,KAAK;AACnC,UAAM,OAAO,MAAM,QAAQ,KAAK,MAAM,OAAO;AAC7C,QAAI,KAAM,MAAK,OAAO;AACtB,QAAI,MAAM,QAAQ,EAAG,MAAK,QAAQ,MAAM,QAAQ;AAEhD,UAAM,QAA2B,CAAC;AAClC,QAAI,MAAM,UAAU,MAAM,QAAS,OAAM,WAAW;AACpD,QAAI,MAAM,WAAW,MAAM,OAAQ,OAAM,WAAW;AACpD,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,EAAG,MAAK,QAAQ;AAEhD,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,WAAW,oBAAI,IAAoB;AACzC,YAAM,WAAuB,CAAC;AAC9B,iBAAW,SAAS,aAAa;AAC/B,cAAM,QAAQ,MAAM,OAAO,QAAQ;AACnC,YAAI,MAAO,UAAS,KAAK,KAAK;AAAA,MAChC;AACA,UAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAuB,CAAC;AAC9B,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,QAAQ,KAAK;AACtB,UAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAI,MAAO,UAAS,KAAK,KAAK;AAAA,EAChC;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,EAAE,MAAM,SAAS,CAAC,GAAI,SAAS;AAAA,EACxC;AACA,QAAM,UAAU,QAAQ;AACxB,WAAS,IAAI,SAAS;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,EACnB,CAAC;AACD,QAAM,OAAiB,EAAE,KAAK,SAAS,MAAM,cAAc;AAC3D,MAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AACzC,SAAO,EAAE,MAAM,MAAM,SAAS;AAChC;AAEA,SAASA,cAAa,MAA8B;AAClD,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,QAAQ,KAAM;AAElB,QAAI,IAAI,WAAW,GAAG,EAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AF/CO,IAAM,eAAN,MAAqC;AAAA,EACjC,KAAK;AAAA,EAEG,WAAW,oBAAI,IAA8B;AAAA,EACtD,YAA+B;AAAA,EAEvC,MAAM,KAAK,MAAqC;AAC9C,QAAI,KAAK,aAAa,SAAS,KAAK,aAAa,WAAW;AAC1D,YAAM,IAAI,yBAAyB,KAAK,QAAQ;AAAA,IAClD;AACA,UAAM,SAAS,MAAM,KAAK,SAAS;AACnC,UAAM,OAAO,KAAK,kBAAkB,IAAI;AACxC,UAAM,SAAS,MAAM,OAAO;AAAA,MAC1B,UAAU,QAAQ,IAAI,eAAe;AAAA,MACrC,MAAM,OAAO,QAAQ,IAAI,eAAe,IAAI;AAAA,MAC5C,MAAM,QAAQ,IAAI,oBAAoB;AAAA,MACtC,cAAc;AAAA,IAChB,CAAC;AAED,UAAM,YAAYC,YAAW;AAC7B,UAAM,UAAyB,EAAE,IAAI,WAAW,UAAU,KAAK,UAAU,OAAO;AAChF,SAAK,SAAS,IAAI,WAAW;AAAA,MAC3B;AAAA,MACA,UAAU,oBAAI,IAAI;AAAA,MAClB,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAI,KAAK,yBAAyB;AAAA,MAChC,YAAY;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,gBAAgB,OAAO;AAAA,IACzB,CAAC;AACD,WAAO,EAAE,IAAI,WAAW,UAAU,KAAK,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,MAAM,SAAiC;AAC3C,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,EAAE,QAAQ,OAAO,cAAc,EAAE;AAAA,MAAM,CAAC,QAC5C,IAAI,KAAK,+BAA+B,EAAE,YAAY,QAAQ,IAAI,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IACtF;AACA,SAAK,SAAS,OAAO,QAAQ,EAAE;AAC/B,QAAI,KAAK,yBAAyB,EAAE,YAAY,QAAQ,GAAG,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,SAAS,SAAkB,OAAmD;AAClF,SAAK;AACL,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,MAAM,MAAM,EAAE,QAAQ,OAAO,cAAc;AACjD,UAAM,aACJ,EAAE,QAAQ,aAAa,QACnB,kBAAkB,GAAG,IACrB,sBAAsB,GAAG;AAE/B,MAAE,sBAAsB;AACxB,MAAE,gBAAgB,EAAE;AACpB,MAAE,WAAW,WAAW;AACxB,MAAE,kBAAiB,oBAAI,KAAK,GAAE,YAAY;AAE1C,WAAO;AAAA,MACL,YAAY,QAAQ;AAAA,MACpB,UAAU,EAAE,QAAQ;AAAA,MACpB,eAAe,KAAK,iBAAiB,CAAC;AAAA,MACtC,UAAU,EAAE;AAAA,MACZ,MAAM,WAAW;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,SAAkB,KAA4B;AACxD,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,KAAK,MAAM,KAAK,eAAe,GAAG,GAAG;AAC3C,UAAM,GAAG,MAAM;AACf,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,KACJ,SACA,KACA,MACA,MACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,KAAK,MAAM,KAAK,eAAe,GAAG,GAAG;AAC3C,QAAI,MAAM,WAAY,OAAM,GAAG,WAAW;AAC1C,UAAM,GAAG,SAAS,IAAI;AACtB,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,IAAI,SAAkB,KAA4B;AACtD,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,QAAI,EAAE,QAAQ,aAAa,aAAa,EAAE,QAAQ,OAAO,cAAc;AACrE,YAAM,OAAO,kBAAkB,GAAG;AAClC,UAAI,SAAS,QAAW;AACtB,cAAM,EAAE,QAAQ,OAAO,aAAa,IAAI;AACxC,aAAK,eAAe,CAAC;AACrB;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,eAAe,GAAG;AAAA,MAClB,EAAE,UAAU,EAAE,QAAQ,UAAU,IAAI;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,SACA,KACA,SAAS,KACT,MACe;AACf,SAAK;AACL,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AAIxC,UAAM,SACJ,EAAE,QAAQ,aAAa,QACnB,kBACA;AACN,UAAM,SACJ,EAAE,QAAQ,aAAa,QACnB,EAAE,WAAW,IAAI,IACjB,EAAE,MAAM,KAAK,KAAK,KAAK,OAAO,KAAK,QAAQ,KAAK,WAAW,KAAK,SAAS,SAAS,IAAK;AAC7F,UAAM,EAAE,QAAQ,OACb,QAAQ,QAAQ,MAAM,EACtB,MAAM,CAAC,QAAiB,IAAI,KAAK,yBAAyB,EAAE,KAAK,OAAO,GAAG,EAAE,CAAC,CAAC;AAClF,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,QACJ,SACA,MACA,YAAY,KACG;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,WAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,UAAI,KAAK,SAAS,QAAQ;AACxB,cAAM,EAAE,QAAQ,OAAO,MAAM,KAAK,EAAE;AACpC,aAAK,eAAe,CAAC;AACrB;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AACxC,YAAM,UACJ,KAAK,SAAS,iBACV,iBAAiB,KAAK,MAAM,KAAK,IAAI,IACrC,KAAK,SAAS,eACZ,iBAAiB,KAAK,MAAM,KAAK,KAAK,IACtC;AACR,UAAI,QAAS;AACb,YAAM,EAAE,QAAQ,OAAO,MAAM,GAAG;AAAA,IAClC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,YAAY,KAAK,IAAI,oBAAoB,SAAS;AAAA,MAClD,EAAE,WAAW,MAAM,YAAY,UAAU;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,SAAkB,WAAsC;AACvE,SAAK;AACL,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,MAAM,MAAM,EAAE,QAAQ,OAAO,eAAe;AAClD,WAAO,OAAO,KAAK,KAAK,QAAQ;AAAA,EAClC;AAAA,EAEA,MAAM,SAAS,UAAmB,MAA6B;AAC7D,UAAM,IAAI,yBAAyB,SAAS,QAAQ;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,UAAmB,MAA6B;AAC1D,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,UAAmB,UAAkB,QAA+B;AAC7E,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,SACA,QACe;AAGf,eAAW,KAAK,QAAQ;AACtB,YAAM,IAAI,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,KAAK,IAAI,EAAE;AAC7D,YAAM,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,UACA,MACA,WACe;AACf,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,WAAgC;AAC5C,QAAI,KAAK,UAAW,QAAO,KAAK;AAChC,QAAI;AAEF,YAAM,MAAO,MAAM;AAAA;AAAA,QAA0B;AAAA,MAAa;AAG1D,WAAK,YAAY,IAAI;AACrB,aAAO,IAAI;AAAA,IACb,QAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,MAA4C;AACpE,UAAM,OAAgC,CAAC;AACvC,QAAI,KAAK,aAAa,OAAO;AAC3B,WAAK,eAAe;AACpB,WAAK,uBAAuB,IAAI;AAChC,UAAI,KAAK,OAAQ,MAAK,mBAAmB,IAAI,KAAK;AAClD,UAAI,KAAK,UAAW,MAAK,iBAAiB,IAAI,KAAK;AAAA,IACrD,OAAO;AACL,WAAK,eAAe;AACpB,WAAK,uBAAuB,IAAI;AAChC,UAAI,KAAK,SAAU,MAAK,YAAY,IAAI,KAAK;AAC7C,UAAI,KAAK,YAAa,MAAK,mBAAmB,IAAI,KAAK;AACvD,UAAI,KAAK,aAAc,MAAK,oBAAoB,IAAI,KAAK;AAAA,IAC3D;AACA,QAAI,KAAK,OAAQ,MAAK,iBAAiB,IAAI,KAAK;AAChD,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,GAA6B;AACpD,UAAM,OAAO,EAAE,QAAQ,OAAO;AAC9B,WAAO;AAAA,MACL,KAAK,iBAAiB,KACpB,KAAK,mBAAmB,KACxB,KAAK,gBACL,EAAE,QAAQ;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,eAAe,WAAqC;AAC1D,UAAM,IAAI,KAAK,SAAS,IAAI,SAAS;AACrC,QAAI,CAAC,EAAG,OAAM,IAAI,oBAAoB,SAAS;AAC/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,GAAqB,KAAmC;AACnF,QAAI,EAAE,kBAAkB,EAAE,oBAAoB;AAC5C,YAAM,IAAI;AAAA,QACR;AAAA,QACA,QAAQ,GAAG;AAAA,QACX;AAAA,UACE,YAAY,EAAE,QAAQ;AAAA,UACtB;AAAA,UACA,wBAAwB,EAAE;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAO,EAAE,SAAS,IAAI,GAAG;AAC/B,QAAI,CAAC,KAAM,OAAM,IAAI,gBAAgB,EAAE,QAAQ,IAAI,GAAG;AACtD,UAAM,WAAW,KAAK,WAAW,IAAI;AACrC,WAAO,EAAE,QAAQ,OAAO,EAAE,QAAQ;AAAA,EACpC;AAAA,EAEQ,WAAW,MAA6B;AAC9C,QAAI,KAAK,SAAS,OAAO;AACvB,UAAI,KAAK,gBAAiB,QAAO,IAAI,KAAK,eAAe;AACzD,YAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,KAAK,eAAe;AACrD,aAAO,oBAAoB,KAAK;AAAA,IAClC;AACA,QAAI,KAAK,YAAY;AACnB,aAAO,qDAAqD,OAAO,KAAK,UAAU,CAAC;AAAA,IACrF;AACA,QAAI,KAAK,YAAa,QAAO,IAAI,KAAK,WAAW;AACjD,QAAI,KAAK,MAAM;AACb,aAAO,+CAA+C,OAAO,KAAK,IAAI,CAAC;AAAA,IACzE;AACA,WAAO,oDAAoD,KAAK,YAAY,eAAe,KAAK,aAAa,CAAC;AAAA,EAChH;AAAA,EAEQ,eAAe,GAA2B;AAChD,MAAE,sBAAsB;AAAA,EAC1B;AACF;AAEA,IAAM,oBAA4C;AAAA,EAChD,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AACd;AAEA,SAAS,OAAO,GAAmB;AACjC,SAAO,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACrD;AAEA,SAAS,iBAAiB,MAA+D,MAAuB;AAC9G,QAAM,SAAS,KAAK,YAAY;AAChC,QAAM,QAAQ,CAAC,MAAwE;AACrF,QAAK,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,SAAS,MAAM,KAC9C,EAAE,SAAS,EAAE,MAAM,YAAY,EAAE,SAAS,MAAM,EAAI,QAAO;AAChE,QAAI,CAAC,EAAE,SAAU,QAAO;AACxB,eAAW,KAAK,EAAE,UAA4E;AAC5F,UAAI,MAAM,CAAC,EAAG,QAAO;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM,IAAI;AACnB;;;AGjaA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,WAAW,aAAa,kBAAkB;AACnD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OASK;;;ACdP,OAAO,UAAU;AAiCjB,IAAM,SAAS;AACf,IAAM,UAAU;AAQhB,SAAS,SAAS,KAAwB;AACxC,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,IAAI,OAAO,KAAK,OAAO;AAC7B,MAAI,CAAC,GAAG;AACN,WAAO,EAAE,MAAM,SAAS,OAAO,CAAC,EAAE;AAAA,EACpC;AACA,QAAM,SAAS,EAAE;AACjB,QAAM,MAAiB,EAAE,MAAM,OAAO,MAAO,OAAO,CAAC,EAAE;AACvD,MAAI,OAAO,SAAS,OAAW,KAAI,OAAO,eAAe,OAAO,IAAI;AACpE,QAAM,OAAO,OAAO,QAAQ;AAC5B,aAAW,aAAa,KAAK,SAAS,OAAO,GAAG;AAC9C,UAAM,CAAC,EAAE,GAAG,CAAC,IAAI;AACjB,QAAI,EAAG,KAAI,MAAM,CAAC,IAAI,KAAK;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,eAAe,GAAmB;AACzC,SAAO,EAAE,QAAQ,UAAU,IAAI;AACjC;AAMO,SAAS,kBAAkB,cAA0C;AAC1E,QAAM,WAAW,oBAAI,IAAqB;AAC1C,MAAI,eAAe;AACnB,QAAM,eAAe,MAAc,IAAI,EAAE,YAAY;AAErD,QAAM,cAAc,CAAC,UAAsC;AAEzD,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,UAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,YAAM,MAAM,KAAK,CAAC;AAElB,UAAI,IAAI,WAAW,GAAG,EAAG,QAAO;AAChC,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,OAAO,UAAU,SAAU,QAAO,UAAU,KAAK,MAAM,KAAK;AAChE,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,UAAU,KAAK,OAAO,MAAS;AAChE,aAAO,UAAU,KAAK,MAAM,MAAS;AAAA,IACvC;AAEA,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,UAAU,OAAO,MAAM,MAAS;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,CAChB,KACA,aACA,eACa;AACb,UAAM,SAAS,SAAS,GAAG;AAC3B,UAAM,MAAM,OAAO,MAAM,OAAO,aAAa;AAC7C,aAAS,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,CAAC;AAEtC,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA,MAAM,OAAO;AAAA,IACf;AACA,QAAI,OAAO,SAAS,OAAW,MAAK,OAAO,OAAO;AAClD,QAAI,eAAe,QAAW;AAC5B,WAAK,QAAQ;AAAA,IACf,WAAW,OAAO,MAAM,OAAO;AAC7B,WAAK,QAAQ,OAAO,MAAM;AAAA,IAC5B;AAEA,UAAM,QAA2B,CAAC;AAClC,QAAI,cAAc,OAAO,MAAO,OAAM,WAAW,OAAO,MAAM,aAAa;AAC3E,QAAI,aAAa,OAAO,MAAO,OAAM,UAAU,OAAO,MAAM,YAAY;AACxE,QAAI,cAAc,OAAO,MAAO,OAAM,WAAW,OAAO,MAAM,aAAa;AAC3E,QAAI,cAAc,OAAO,MAAO,OAAM,WAAW,OAAO,MAAM,aAAa;AAC3E,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,EAAG,MAAK,QAAQ;AAEhD,QAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,YAAM,WAAuB,CAAC;AAC9B,iBAAW,SAAS,aAAa;AAC/B,cAAM,QAAQ,YAAY,KAAK;AAC/B,YAAI,MAAO,UAAS,KAAK,KAAK;AAAA,MAChC;AACA,UAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,aAAU,KAAK,KAAK,YAAY,KAAmB,CAAC;AAAA,EACtD,QAAQ;AACN,aAAS,CAAC;AAAA,EACZ;AAEA,QAAM,WAAuB,CAAC;AAC9B,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,eAAW,SAAS,QAAQ;AAC1B,YAAM,OAAO,YAAY,KAAK;AAC9B,UAAI,KAAM,UAAS,KAAK,IAAI;AAAA,IAC9B;AAAA,EACF,WAAW,UAAU,OAAO,WAAW,UAAU;AAC/C,UAAM,OAAO,YAAY,MAAM;AAC/B,QAAI,KAAM,UAAS,KAAK,IAAI;AAAA,EAC9B,WAAW,OAAO,WAAW,YAAY,OAAO,SAAS,GAAG;AAC1D,UAAM,OAAO,YAAY,MAAM;AAC/B,QAAI,KAAM,UAAS,KAAK,IAAI;AAAA,EAC9B;AAGA,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,EAAE,MAAM,SAAS,CAAC,GAAI,SAAS;AAAA,EACxC;AACA,QAAM,UAAU,aAAa;AAC7B,WAAS,IAAI,SAAS,EAAE,MAAM,OAAO,KAAK,QAAQ,CAAC;AACnD,QAAM,OAAiB,EAAE,KAAK,SAAS,MAAM,cAAc;AAC3D,MAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AACzC,SAAO,EAAE,MAAM,MAAM,SAAS;AAChC;;;ADxEA,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAG3B,IAAM,kBAAkB;AAAA,EACtB,SAAS,EAAE,SAAS,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,SAAS,EAAE;AAAA,EACjF,WAAW;AAAA,IACT,SAAS;AAAA;AAAA,IAET,oBAAqB,MAAM,OAAQ;AAAA,IACnC,kBAAmB,MAAM,OAAQ;AAAA,IACjC,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,oBAAqB,MAAM,OAAO,OAAQ;AAAA,IAC1C,kBAAmB,MAAM,OAAQ;AAAA,IACjC,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,oBAAqB,IAAI,OAAO,OAAQ;AAAA,IACxC,kBAAmB,IAAI,OAAO,OAAQ;AAAA,IACtC,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,oBAAqB,IAAI,OAAO,OAAQ;AAAA,IACxC,kBAAmB,MAAM,OAAO,OAAQ;AAAA,IACxC,SAAS;AAAA,EACX;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,SAAS;AAAA,EACX;AACF;AAEA,SAAS,SAAY,KAAU,OAAU,KAAmB;AAC1D,MAAI,KAAK,KAAK;AACd,MAAI,IAAI,SAAS,IAAK,KAAI,OAAO,GAAG,IAAI,SAAS,GAAG;AACtD;AAEA,SAAS,gBAAgB,GAAkC;AACzD,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,sBAAsB,KAAyC;AACtE,MAAI;AACF,UAAM,MAAM,IAAI,SAAS;AACzB,QAAI,CAAC,KAAK,IAAK,QAAO;AACtB,WAAO,GAAG,IAAI,GAAG,IAAI,IAAI,UAAU,IAAI,IAAI,YAAY;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBACP,KACA,KAC0B;AAG1B,QAAM,MAAM,IAAI,IAAI;AACpB,QAAM,SAAS,IAAI,OAAO;AAC1B,WAAS,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AACxC,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,CAAC,EAAG;AACR,QAAI,EAAE,QAAQ,OAAO,EAAE,WAAW,UAAU,EAAE,WAAW,UAAa,CAAC,EAAE,SAAS;AAChF,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAUO,IAAM,mBAAN,MAAyC;AAAA,EACrC,KAAK;AAAA,EAEG,WAAW,oBAAI,IAA8B;AAAA,EAE9D,MAAM,KAAK,MAAqC;AAC9C,QAAI,KAAK,aAAa,OAAO;AAC3B,YAAM,IAAI,yBAAyB,KAAK,QAAQ;AAAA,IAClD;AAEA,UAAM,cAAc,KAAK,WAAW;AACpC,UAAM,WACJ,gBAAgB,YACZ,UACA,gBAAgB,WACd,SACA;AAER,UAAM,WAAW,KAAK,aAAa,QAAQ,IAAI,KAAK,OAAO;AAC3D,UAAM,UAAU,MAAM,SAAS,OAAO,EAAE,SAAS,CAAC;AAElD,UAAM,iBAA2D,CAAC;AAClE,QAAI,KAAK,SAAU,gBAAe,WAAW,KAAK;AAClD,QAAI,KAAK,WAAY,gBAAe,YAAY,KAAK;AACrD,QAAI,KAAK,OAAQ,gBAAe,SAAS,KAAK;AAI9C,QAAI,KAAK,SAAS,KAAK;AACrB,qBAAe,YAAY,EAAE,MAAM,KAAK,QAAQ,IAAI,KAAK;AAAA,IAC3D;AACA,QAAI,KAAK,SAAS,OAAO;AACvB,qBAAe,cAAc;AAAA,QAC3B,KAAK,KAAK,QAAQ,MAAM;AAAA,QACxB,MACE,KAAK,QAAQ,MAAM,aAAa,KAAK,QAAQ,MAAM,aAC/C;AAAA,UACE,OAAO,KAAK,QAAQ,MAAM;AAAA,UAC1B,QAAQ,KAAK,QAAQ,MAAM;AAAA,QAC7B,IACA;AAAA,MACR;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,QAAQ,WAAW,cAAc;AAEvD,QAAI,KAAK,SAAS,OAAO;AACvB,YAAM,QAAQ,QAAQ,MAAM;AAAA,QAC1B,aAAa;AAAA,QACb,WAAW;AAAA,QACX,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,MAAM,QAAQ,QAAQ;AACnC,UAAM,YAAYC,YAAW;AAE7B,UAAM,YAA8B;AAAA,MAClC,SAAS;AAAA,QACP,IAAI;AAAA,QACJ,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,MACA,UAAU,oBAAI,IAAI;AAAA,MAClB,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,OAAO,CAAC,IAAI;AAAA,MACZ,iBAAiB;AAAA,MACjB,eAAe,CAAC;AAAA,MAChB,eAAe,CAAC;AAAA,MAChB,iBAAiB,oBAAI,IAAI;AAAA,MACzB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,cAAc,CAAC,CAAC,KAAK,SAAS;AAAA,IAChC;AAEA,SAAK,oBAAoB,WAAW,IAAI;AACxC,YAAQ,GAAG,QAAQ,CAAC,YAAY;AAC9B,gBAAU,MAAM,KAAK,OAAO;AAC5B,WAAK,oBAAoB,WAAW,OAAO;AAAA,IAC7C,CAAC;AAED,QAAI,KAAK,KAAK;AACZ,YAAM,KAAK,KAAK,KAAK,KAAK,EAAE,WAAW,mBAAmB,CAAC;AAAA,IAC7D;AAEA,SAAK,SAAS,IAAI,WAAW,SAAS;AACtC,QAAI,KAAK,kBAAkB;AAAA,MACzB,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,KAAK,KAAK,OAAO;AAAA,MACjB,SAAS,KAAK,UACV,OAAO,KAAK,KAAK,OAAO,EAAE;AAAA,QACxB,CAAC,MAAM,KAAK,QAAS,CAA8B;AAAA,MACrD,IACA,CAAC;AAAA,IACP,CAAC;AACD,WAAO,EAAE,IAAI,WAAW,UAAU,MAAM;AAAA,EAC1C;AAAA,EAEA,MAAM,MAAM,SAAiC;AAC3C,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AAGxC,QAAI,EAAE,gBAAgB,EAAE,aAAa,OAAO;AAC1C,YAAM,YAAY,YAAY,EAAE,YAAY,MAAM,aAAa,WAAW;AAC1E,YAAM,EAAE,QAAQ,QAAQ,QACrB,KAAK,EAAE,MAAM,UAAU,CAAC,EACxB,MAAM,CAAC,QAAiB;AACvB,YAAI,KAAK,qBAAqB;AAAA,UAC5B,YAAY,QAAQ;AAAA,UACpB,KAAK,OAAO,GAAG;AAAA,QACjB,CAAC;AAAA,MACH,CAAC;AAAA,IACL;AAEA,UAAM,EAAE,QAAQ,QAAQ,MAAM,EAAE,MAAM,CAAC,QAAiB;AACtD,UAAI,KAAK,wBAAwB,EAAE,YAAY,QAAQ,IAAI,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IAC/E,CAAC;AACD,UAAM,EAAE,QAAQ,QAAQ,MAAM,EAAE,MAAM,CAAC,QAAiB;AACtD,UAAI,KAAK,wBAAwB,EAAE,YAAY,QAAQ,IAAI,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IAC/E,CAAC;AACD,SAAK,SAAS,OAAO,QAAQ,EAAE;AAC/B,QAAI,KAAK,kBAAkB,EAAE,YAAY,QAAQ,GAAG,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,SACJ,SACA,OAA2B,WACJ;AACvB,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AAIxC,UAAM,WAAW,MAAM,KAAK,WAAW,CAAC,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACrE,UAAM,EAAE,MAAM,SAAS,IAAI,kBAAkB,QAAQ;AACrD,SAAK;AAEL,MAAE,sBAAsB;AACxB,MAAE,gBAAgB,EAAE;AACpB,MAAE,WAAW;AACb,MAAE,kBAAiB,oBAAI,KAAK,GAAE,YAAY;AAE1C,WAAO;AAAA,MACL,YAAY,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,eAAe,KAAK,WAAW,CAAC,EAAE,IAAI;AAAA,MACtC,UAAU,EAAE;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MACJ,SACA,KACA,MACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,UAAU,KAAK,eAAe,GAAG,GAAG;AAC1C,UAAM,QAAQ,MAAM,MAAM,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,MAAS;AACtE,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,KACJ,SACA,KACA,MACA,MACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,UAAU,KAAK,eAAe,GAAG,GAAG;AAC1C,QAAI,MAAM,WAAY,OAAM,QAAQ,KAAK,EAAE;AAC3C,UAAM,QAAQ,KAAK,IAAI;AACvB,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,IAAI,SAAkB,KAA4B;AACtD,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,KAAK,WAAW,CAAC,EAAE,SAAS,MAAM,GAAG;AAC3C,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,OACJ,SACA,KACA,SAAS,KACT,KACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,KAAK,QAAQ,SAAS,CAAC,SAAS,QAAQ,UAAU,SAAS;AACjE,UAAM,KAAK,QAAQ,OAAO,CAAC,SAAS,QAAQ,SAAS,SAAS;AAC9D,QAAI,KAAK;AACP,YAAM,UAAU,KAAK,eAAe,GAAG,GAAG;AAC1C,YAAM,QAAQ;AAAA,QACZ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,GAAa,CAAW;AAAA,QACpD,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF,OAAO;AACL,YAAM,KAAK,WAAW,CAAC,EAAE,MAAM,MAAM,IAAI,EAAE;AAAA,IAC7C;AACA,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,QACJ,SACA,MACA,YAAY,KACG;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,OAAO,KAAK,WAAW,CAAC;AAC9B,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,cAAM,KACH,UAAU,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC,EACrC,MAAM,EACN,QAAQ,EAAE,OAAO,WAAW,SAAS,UAAU,CAAC;AACnD;AAAA,MACF,KAAK;AACH,cAAM,KACH,UAAU,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC,EACxC,MAAM,EACN,QAAQ,EAAE,OAAO,YAAY,SAAS,UAAU,CAAC;AACpD;AAAA,MACF,KAAK;AACH,cAAM,KAAK,WAAW,IAAI,OAAO,KAAK,OAAO,GAAG,EAAE,SAAS,UAAU,CAAC;AACtE;AAAA,MACF,KAAK;AACH,cAAM,KAAK,iBAAiB,eAAe,EAAE,SAAS,UAAU,CAAC;AACjE,cAAM,KAAK,eAAe,KAAK,EAAE;AACjC;AAAA,IACJ;AACA,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,WAAW,SAAkB,WAAW,OAAwB;AACpE,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,WAAO,KAAK,WAAW,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC;AAAA,EACnD;AAAA,EAEA,MAAM,SAAS,SAAkB,KAA4B;AAC3D,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,QAAI,EAAE,QAAQ,aAAa,OAAO;AAChC,YAAM,IAAI,yBAAyB,EAAE,QAAQ,QAAQ;AAAA,IACvD;AACA,UAAM,KAAK,WAAW,CAAC,EAAE,KAAK,KAAK,EAAE,WAAW,mBAAmB,CAAC;AACpE,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,WAAyB;AACzC,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,QAAI,EAAE,QAAQ,aAAa,OAAO;AAChC,YAAM,IAAI,yBAAyB,EAAE,QAAQ,QAAQ;AAAA,IACvD;AACA,WAAO,KAAK,WAAW,CAAC;AAAA,EAC1B;AAAA;AAAA,EAGA,eAAe,WAAyB;AACtC,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,SAAkB,KAA4B;AACxD,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,UAAU,KAAK,eAAe,GAAG,GAAG;AAC1C,UAAM,QAAQ,MAAM;AAAA,EAEtB;AAAA,EAEA,MAAM,KACJ,SACA,SACA,OACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,UAAM,OAAO,KAAK,eAAe,GAAG,OAAO;AAC3C,UAAM,KAAK,KAAK,eAAe,GAAG,KAAK;AACvC,UAAM,KAAK,OAAO,EAAE;AACpB,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,SAAS,SAAkB,QAAoC;AACnE,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,eAAW,SAAS,QAAQ;AAC1B,YAAM,UAAU,KAAK,eAAe,GAAG,MAAM,GAAG;AAChD,YAAM,OAAO,MAAM;AACnB,UAAI,SAAS,cAAc,SAAS,SAAS;AAC3C,cAAM,UAAU,OAAO,MAAM,UAAU,YACnC,MAAM,QACN,MAAM,UAAU,UAAU,MAAM,UAAU;AAC9C,cAAM,QAAQ,WAAW,OAAO;AAAA,MAClC,WAAW,SAAS,UAAU;AAC5B,cAAM,QAAQ,aAAa,OAAO,MAAM,KAAK,CAAC;AAAA,MAChD,OAAO;AAEL,cAAM,QAAQ,KAAK,OAAO,MAAM,KAAK,CAAC;AAAA,MACxC;AAAA,IACF;AACA,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,WACJ,SACA,KACA,UACe;AACf,UAAM,IAAI,KAAK,eAAe,QAAQ,EAAE;AACxC,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,+CAA+C,QAAQ;AAAA,QACvD,EAAE,WAAW,SAAS;AAAA,MACxB;AAAA,IACF;AACA,UAAM,UAAU,KAAK,eAAe,GAAG,GAAG;AAC1C,UAAM,QAAQ,cAAc,QAAQ;AACpC,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,aACJ,WACA,MAK+B;AAC/B,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,YAAY,KAAK,IAAI,IAAI;AAI/B,QAAI,EAAE,cAAc;AAClB,QAAE,aAAa,QAAQ,KAAK;AAAA,IAC9B;AAEA,WAAO,IAAI,QAA8B,CAACC,aAAY;AACpD,YAAM,SAAuB;AAAA,QAC3B,QAAQ,KAAK;AAAA,QACb,MAAM,KAAK;AAAA,QACX;AAAA,QACA,SAAS,CAAC,YAAY;AACpB,YAAE,eAAe;AACjB,UAAAA,SAAQ,EAAE,QAAQ,CAAC;AAAA,QACrB;AAAA,MACF;AACA,QAAE,eAAe;AAGjB,YAAM,QAAQ,WAAW,MAAM;AAC7B,YAAI,EAAE,iBAAiB,QAAQ;AAC7B,YAAE,eAAe;AACjB,UAAAA,SAAQ,EAAE,SAAS,MAAM,CAAC;AAAA,QAC5B;AAAA,MACF,GAAG,SAAS;AACZ,YAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,WACE,WACA,MAMgB;AAChB,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,UAAM,SAAS,MAAM;AACrB,UAAM,WAAW,MAAM;AACvB,UAAM,QAAQ,MAAM,SAAS;AAC7B,QAAI,UAAU,EAAE;AAChB,QAAI,UAAU,OAAO,SAAS,GAAG;AAC/B,gBAAU,QAAQ,OAAO,CAAC,MAAM,OAAO,SAAS,EAAE,KAAK,CAAC;AAAA,IAC1D;AACA,QAAI,UAAU;AACZ,gBAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,QAAQ,CAAC;AAAA,IAC3D;AACA,UAAM,SAAS,QAAQ,MAAM,CAAC,KAAK;AACnC,QAAI,MAAM,MAAO,GAAE,gBAAgB,CAAC;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,WACE,WACA,MASgB;AAChB,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,QAAI,UAAU,EAAE;AAChB,QAAI,MAAM,YAAY;AACpB,UAAI,KAAK,gBAAgB,SAAS;AAChC,cAAM,KAAK,IAAI,OAAO,KAAK,UAAU;AACrC,kBAAU,QAAQ,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC;AAAA,MAChD,OAAO;AACL,kBAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,SAAS,KAAK,UAAW,CAAC;AAAA,MAClE;AAAA,IACF;AACA,QAAI,MAAM,QAAQ;AAChB,YAAM,IAAI,KAAK,OAAO,YAAY;AAClC,gBAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,YAAY,MAAM,CAAC;AAAA,IAC9D;AACA,QAAI,MAAM,aAAa;AACrB,YAAM,EAAE,KAAK,IAAI,IAAI,KAAK;AAC1B,gBAAU,QAAQ;AAAA,QAChB,CAAC,MACC,EAAE,WAAW,UAAa,EAAE,UAAU,OAAO,EAAE,UAAU;AAAA,MAC7D;AAAA,IACF;AACA,QAAI,MAAM,YAAY;AACpB,gBAAU,QAAQ;AAAA,QAChB,CAAC,MAAM,CAAC,CAAC,EAAE,WAAY,EAAE,WAAW,UAAa,EAAE,UAAU;AAAA,MAC/D;AAAA,IACF;AACA,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,SAAS,QAAQ,MAAM,CAAC,KAAK;AACnC,QAAI,MAAM,MAAO,GAAE,gBAAgB,CAAC;AACpC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,WAGV;AACA,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,WAAO,EAAE,SAAS,EAAE,eAAe,SAAS,EAAE,cAAc;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OACJ,WACA,MAgBe;AACf,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,UAAM,OAAO,KAAK,WAAW,CAAC;AAC9B,UAAM,MAAM,EAAE,QAAQ;AAEtB,QAAI,KAAK,UAAU;AACjB,YAAM,KAAK,gBAAgB,KAAK,QAAQ;AAAA,IAC1C;AACA,QAAI,KAAK,YAAY,QAAW;AAC9B,YAAM,IAAI,WAAW,KAAK,OAAO;AAAA,IACnC;AACA,QAAI,KAAK,aAAa;AACpB,YAAM,IAAI,eAAe,KAAK,WAAW;AAAA,IAC3C;AACA,QAAI,KAAK,cAAc;AACrB,YAAM,IAAI,oBAAoB,KAAK,YAAY;AAAA,IACjD;AACA,QAAI,KAAK,eAAe,KAAK,eAAe;AAC1C,YAAM,KAAK,aAAa;AAAA,QACtB,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,QAC5D,GAAI,KAAK,gBAAgB,EAAE,eAAe,KAAK,cAAc,IAAI,CAAC;AAAA,MACpE,CAAC;AAAA,IACH;AACA,QAAI,KAAK,mBAAmB,KAAK,gBAAgB,QAAW;AAC1D,YAAM,cAAc,IAAI,QAAQ,GAAG,YAAY,EAAE,KAAK;AACtD,UAAI,gBAAgB,YAAY;AAC9B,cAAM,IAAI;AAAA,UACR;AAAA,UACA,oFAAoF,WAAW;AAAA,QACjG;AAAA,MACF;AACA,YAAM,MAAM,MAAM,IAAI,cAAc,IAAI;AACxC,UAAI;AACF,YAAI,KAAK,iBAAiB;AACxB,gBAAM,SAAS,gBAAgB,KAAK,eAAe;AACnD,gBAAM,IAAI,KAAK,gBAAgB;AAC/B,gBAAM,IAAI,KAAK,oCAAoC,MAAM;AAAA,QAC3D;AACA,YAAI,KAAK,gBAAgB,QAAW;AAClC,gBAAM,IAAI,KAAK,kCAAkC;AAAA,YAC/C,MAAM,KAAK;AAAA,UACb,CAAC;AAAA,QACH;AAAA,MACF,UAAE;AACA,cAAM,IAAI,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,MAC1C;AAAA,IACF;AACA,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SACJ,WACA,QACA,MACkB;AAClB,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,UAAM,OAAO,KAAK,WAAW,CAAC;AAI9B,WAAO,KAAK;AAAA,MACV,CAAC,EAAE,KAAK,EAAE;AAAA;AAAA,QAER,IAAI,SAAS,QAAQ,yBAAyB,GAAG,QAAQ,EAAE,CAAC;AAAA;AAAA,MAC9D,EAAE,KAAK,QAAQ,GAAG,QAAQ,CAAC,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,UAAU,WAKN;AACF,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,WAAO,EAAE,MAAM,IAAI,CAAC,GAAG,OAAO;AAAA,MAC5B,OAAO;AAAA,MACP,KAAK,EAAE,IAAI;AAAA,MACX,eAAe,EAAE,MAAM;AAAA,MACvB,QAAQ,MAAM,EAAE;AAAA,IAClB,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,WAAW,WAAmB,OAA8B;AAChE,UAAM,IAAI,KAAK,eAAe,SAAS;AACvC,QAAI,QAAQ,KAAK,SAAS,EAAE,MAAM,QAAQ;AACxC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,cAAc,KAAK,uBAAuB,EAAE,MAAM,MAAM;AAAA,QACxD,EAAE,OAAO,WAAW,EAAE,MAAM,OAAO;AAAA,MACrC;AAAA,IACF;AACA,MAAE,kBAAkB;AACpB,SAAK,eAAe,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAW,GAA2B;AAC5C,WAAO,EAAE,MAAM,EAAE,eAAe,KAAK,EAAE,QAAQ;AAAA,EACjD;AAAA,EAEQ,oBAAoB,GAAqB,MAAkB;AACjE,SAAK,GAAG,WAAW,CAAC,QAAwB;AAC1C,YAAM,QAAQ,gBAAgB,IAAI,KAAK,CAAC;AACxC;AAAA,QACE,EAAE;AAAA,QACF;AAAA,UACE;AAAA,UACA,MAAM,IAAI,KAAK;AAAA,UACf,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,UAC3B,UAAU,sBAAsB,GAAG;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,GAAG,WAAW,CAAC,QAAiB;AACnC,YAAM,KAAK,EAAE;AACb,QAAE,gBAAgB,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI;AAAA,QACjE;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,cAAc,IAAI,aAAa;AAAA,MACjC,CAAC;AAED;AAAA,QACE,EAAE;AAAA,QACF;AAAA,UACE;AAAA,UACA,KAAK,IAAI,IAAI;AAAA,UACb,QAAQ,IAAI,OAAO;AAAA,UACnB,eAAe,IAAI,aAAa;AAAA,UAChC,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,QAC7B;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,GAAG,YAAY,CAAC,QAAkB;AACrC,YAAM,MAAM,IAAI,QAAQ;AACxB,YAAM,QAAQ,iBAAiB,EAAE,eAAe,GAAG;AACnD,UAAI,OAAO;AACT,cAAM,SAAS,IAAI,OAAO;AAC1B,cAAM,cAAc,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM,EAAE,EAAE,QAAQ;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,SAAK,GAAG,iBAAiB,CAAC,QAAiB;AACzC,YAAM,QAAQ,iBAAiB,EAAE,eAAe,GAAG;AACnD,UAAI,OAAO;AACT,cAAM,UAAU,IAAI,QAAQ,GAAG,aAAa;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,SAAK,GAAG,UAAU,CAAC,WAAmB;AACpC,WAAK,KAAK,iBAAiB,GAAG,MAAM;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,iBACZ,GACA,QACe;AACf,UAAM,MAAM,EAAE;AACd,QAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,WAAW;AAEtC,YAAM,OAAO,QAAQ,EAAE,MAAM,MAAM,MAAS;AAC5C,UAAI,IAAK,KAAI,QAAQ,KAAK;AAC1B;AAAA,IACF;AACA,QAAI;AACF,UAAI,IAAI,WAAW,UAAU;AAC3B,cAAM,OAAO,OAAO;AAAA,MACtB,WAAW,IAAI,WAAW,oBAAoB;AAC5C,cAAM,OAAO,OAAO,IAAI,QAAQ,EAAE;AAAA,MACpC,OAAO;AACL,cAAM,OAAO,QAAQ;AAAA,MACvB;AACA,UAAI,QAAQ,IAAI;AAAA,IAClB,SAAS,KAAK;AACZ,UAAI,KAAK,wBAAwB;AAAA,QAC/B,YAAY,EAAE,QAAQ;AAAA,QACtB,KAAK,OAAO,GAAG;AAAA,MACjB,CAAC;AACD,UAAI,QAAQ,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,eAAe,WAAqC;AAC1D,UAAM,IAAI,KAAK,SAAS,IAAI,SAAS;AACrC,QAAI,CAAC,GAAG;AACN,YAAM,IAAI;AAAA,QACR;AAAA,QACA,4BAA4B,SAAS;AAAA,QACrC,EAAE,YAAY,UAAU;AAAA,MAC1B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,GAAqB,KAAsB;AAChE,QAAI,EAAE,kBAAkB,EAAE,oBAAoB;AAC5C,YAAM,IAAI;AAAA,QACR;AAAA,QACA,QAAQ,GAAG;AAAA,QACX;AAAA,UACE,YAAY,EAAE,QAAQ;AAAA,UACtB;AAAA,UACA,wBAAwB,EAAE;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAO,EAAE,SAAS,IAAI,GAAG;AAC/B,QAAI,CAAC,KAAM,OAAM,IAAI,gBAAgB,EAAE,QAAQ,IAAI,GAAG;AAGtD,QAAI,KAAK,IAAI,WAAW,GAAG,GAAG;AAC5B,YAAM,IAAI,gBAAgB,EAAE,QAAQ,IAAI,GAAG;AAAA,IAC7C;AACA,WAAO,KAAK,WAAW,CAAC,EAAE,QAAQ,YAAY,KAAK,GAAG,EAAE;AAAA,EAC1D;AAAA,EAEQ,eAAe,GAA2B;AAChD,MAAE,sBAAsB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,UAAM,MAAM,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AACpC,UAAM,QAAQ;AAAA,MACZ,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,IAAI,UAAU,MAAM,CAAC,EAAE,MAAM,MAAM,MAAS,CAAC;AAAA,IAC5E;AAAA,EACF;AACF;;;AEx4BO,SAAS,kBAA0B;AACxC,QAAM,UAAU,QAAQ,IAAI,0BAA0B,cAAc,YAAY;AAChF,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,IAAI,iBAAiB;AAAA,IAC9B,KAAK;AACH,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,WAAW,OAAO;AAAA,MACtB;AAAA,IACF;AACE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,uBAAuB,MAAM;AAAA,QAC7B,EAAE,WAAW,OAAO;AAAA,MACtB;AAAA,EACJ;AACF;AAEO,SAAS,qBAA6B;AAC3C,SAAO,IAAI,aAAa;AAC1B;;;ACtBO,IAAM,kBAAN,MAAsB;AAAA,EACV,oBAAoB,oBAAI,IAAsB;AAAA,EAC9C,kBAAkB,oBAAI,IAAoB;AAAA,EAC1C,oBAAoB,oBAAI,IAAsB;AAAA,EAC9C,eAAe,oBAAI,IAAoB;AAAA,EACvC;AAAA,EACT,YAAmC;AAAA,EAE3C,YAAY,OAAmC,CAAC,GAAG;AACjD,SAAK,gBAAgB,KAAK,iBAAiB,IAAI,KAAK;AAAA,EACtD;AAAA;AAAA,EAGA,SAAS,UAAoB,QAAsB;AACjD,SAAK,kBAAkB,IAAI,UAAU,MAAM;AAAA,EAC7C;AAAA,EAEA,MAAM,KAAK,MAAqC;AAC9C,UAAM,SAAS,KAAK,kBAAkB,IAAI,KAAK,QAAQ;AACvD,QAAI,CAAC,OAAQ,OAAM,IAAI,yBAAyB,KAAK,QAAQ;AAC7D,UAAM,UAAU,MAAM,OAAO,KAAK,IAAI;AACtC,SAAK,gBAAgB,IAAI,QAAQ,IAAI,MAAM;AAC3C,SAAK,kBAAkB,IAAI,QAAQ,IAAI,QAAQ,QAAQ;AACvD,SAAK,MAAM,QAAQ,EAAE;AACrB,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,WAA2B;AACnC,UAAM,SAAS,KAAK,gBAAgB,IAAI,SAAS;AACjD,QAAI,CAAC,OAAQ,OAAM,IAAI,oBAAoB,SAAS;AACpD,SAAK,MAAM,SAAS;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,SAAiC;AAC3C,UAAM,SAAS,KAAK,gBAAgB,IAAI,QAAQ,EAAE;AAClD,QAAI,CAAC,OAAQ,OAAM,IAAI,oBAAoB,QAAQ,EAAE;AACrD,UAAM,OAAO,MAAM,OAAO;AAC1B,SAAK,gBAAgB,OAAO,QAAQ,EAAE;AACtC,SAAK,kBAAkB,OAAO,QAAQ,EAAE;AACxC,SAAK,aAAa,OAAO,QAAQ,EAAE;AAAA,EACrC;AAAA;AAAA,EAGA,WAAW,WAA6B;AACtC,UAAM,WAAW,KAAK,kBAAkB,IAAI,SAAS;AACrD,QAAI,CAAC,SAAU,OAAM,IAAI,oBAAoB,SAAS;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAA0B;AAC9B,QAAI,KAAK,WAAW;AAClB,oBAAc,KAAK,SAAS;AAC5B,WAAK,YAAY;AAAA,IACnB;AACA,UAAM,SAA+B,CAAC;AACtC,eAAW,CAAC,WAAW,MAAM,KAAK,KAAK,iBAAiB;AACtD,YAAM,WAAW,KAAK,YAAY,SAAS;AAC3C,aAAO;AAAA,QACL,OACG,MAAM,EAAE,IAAI,WAAW,SAAS,CAAC,EACjC;AAAA,UAAM,CAAC,QACN,IAAI,KAAK,yBAAyB,EAAE,WAAW,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,QACnE;AAAA,MACJ;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,MAAM;AACxB,SAAK,gBAAgB,MAAM;AAC3B,SAAK,kBAAkB,MAAM;AAC7B,SAAK,aAAa,MAAM;AAAA,EAC1B;AAAA,EAEQ,MAAM,WAAyB;AACrC,SAAK,aAAa,IAAI,WAAW,KAAK,IAAI,CAAC;AAAA,EAC7C;AAAA,EAEQ,YAAY,WAA6B;AAC/C,WAAO,KAAK,kBAAkB,IAAI,SAAS,KAAK;AAAA,EAClD;AAAA,EAEQ,kBAAwB;AAC9B,QAAI,KAAK,aAAa,KAAK,iBAAiB,EAAG;AAC/C,UAAM,WAAW,KAAK,IAAI,KAAQ,KAAK,MAAM,KAAK,gBAAgB,CAAC,CAAC;AACpE,SAAK,YAAY,YAAY,MAAM;AACjC,YAAM,SAAS,KAAK,IAAI,IAAI,KAAK;AACjC,iBAAW,CAAC,WAAW,QAAQ,KAAK,KAAK,cAAc;AACrD,YAAI,WAAW,QAAQ;AACrB,gBAAM,SAAS,KAAK,gBAAgB,IAAI,SAAS;AACjD,cAAI,CAAC,QAAQ;AACX,iBAAK,aAAa,OAAO,SAAS;AAClC;AAAA,UACF;AACA,cAAI,KAAK,qCAAgC,EAAE,UAAU,CAAC;AACtD,iBACG,MAAM,EAAE,IAAI,WAAW,UAAU,KAAK,YAAY,SAAS,EAAE,CAAC,EAC9D;AAAA,YAAM,CAAC,QACN,IAAI,KAAK,qBAAqB,EAAE,WAAW,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,UAC/D,EACC,QAAQ,MAAM;AACb,iBAAK,gBAAgB,OAAO,SAAS;AACrC,iBAAK,aAAa,OAAO,SAAS;AAAA,UACpC,CAAC;AAAA,QACL;AAAA,MACF;AAAA,IACF,GAAG,QAAQ;AACX,SAAK,UAAU,MAAM;AAAA,EACvB;AACF;;;ACvHA,SAAS,eAAe;AACxB,SAAS,WAAWC,oBAAmB;;;ACDvC,SAAS,SAAS;AAMX,IAAM,iBAAiB,EAAE,KAAK,CAAC,OAAO,OAAO,SAAS,CAAC;AACvD,IAAM,gBAAgB,EAAE,KAAK,CAAC,YAAY,WAAW,QAAQ,CAAC;AAE9D,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACjC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AACpC,CAAC;AAEM,IAAM,aAAa,EAAE,OAAO;AAAA,EACjC,GAAG,EAAE,OAAO;AAAA,EACZ,GAAG,EAAE,OAAO;AAAA,EACZ,GAAG,EAAE,OAAO;AAAA,EACZ,GAAG,EAAE,OAAO;AACd,CAAC;AAEM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAYM,IAAM,iBAAsC,EAAE;AAAA,EAAK,MACxD,EAAE,OAAO;AAAA,IACP,KAAK,EAAE,OAAO;AAAA,IACd,MAAM,EAAE,OAAO;AAAA,IACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,OAAO,gBAAgB,SAAS;AAAA,IAChC,MAAM,WAAW,SAAS;AAAA,IAC1B,UAAU,EAAE,MAAM,cAAc,EAAE,SAAS;AAAA,EAC7C,CAAC;AACH;AAEO,IAAM,sBAAsB,EAAE,mBAAmB,QAAQ;AAAA,EAC9D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,cAAc,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC9D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,YAAY,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,EAC7D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,aAAa,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,EAChE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACvE,CAAC;AAWM,IAAM,mBAAmB;AAAA,EAC9B,UAAU,eAAe,QAAQ,KAAK;AAAA,EACtC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAC/B,SAAS,cAAc,SAAS;AAAA,EAChC,UAAU,eAAe,SAAS;AAAA;AAAA,EAElC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAC9B;AACO,IAAM,oBAAoB,EAAE,OAAO,gBAAgB;AAGnD,IAAM,oBAAoB;AAAA,EAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAC9B;AACO,IAAM,qBAAqB,EAAE,OAAO,iBAAiB;AAGrD,IAAM,uBAAuB;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,MAAM,EAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,SAAS;AAC7C;AACO,IAAM,wBAAwB,EAAE,OAAO,oBAAoB;AAG3D,IAAM,oBAAoB;AAAA,EAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ,SAAS,QAAQ,CAAC,EAAE,SAAS;AACvD;AACO,IAAM,qBAAqB,EAAE,OAAO,iBAAiB;AAGrD,IAAM,mBAAmB;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrB,MAAM,EAAE,OAAO;AAAA,EACf,aAAa,EAAE,QAAQ,EAAE,SAAS;AACpC;AACO,IAAM,oBAAoB,EAAE,OAAO,gBAAgB;AAGnD,IAAM,kBAAkB;AAAA,EAC7B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AACvB;AACO,IAAM,mBAAmB,EAAE,OAAO,eAAe;AAGjD,IAAM,qBAAqB;AAAA,EAChC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,WAAW,EAAE,KAAK,CAAC,MAAM,QAAQ,QAAQ,OAAO,CAAC;AAAA,EACjD,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC7C,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAClC;AACO,IAAM,sBAAsB,EAAE,OAAO,kBAAkB;AAGvD,IAAM,sBAAsB;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,WAAW;AAAA,EACX,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AACnD;AACO,IAAM,uBAAuB,EAAE,OAAO,mBAAmB;AAGzD,IAAM,yBAAyB;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,WAAW,EAAE,QAAQ,EAAE,SAAS;AAClC;AACO,IAAM,0BAA0B,EAAE,OAAO,sBAAsB;AAG/D,IAAM,uBAAuB;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI;AACtB;AACO,IAAM,wBAAwB,EAAE,OAAO,oBAAoB;AAO3D,IAAM,oBAAoB;AAAA,EAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AACvB;AACO,IAAM,qBAAqB,EAAE,OAAO,iBAAiB;AAGrD,IAAM,mBAAmB;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAC1B;AACO,IAAM,oBAAoB,EAAE,OAAO,gBAAgB;AAGnD,IAAM,sBAAsB,EAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrB,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxC,MAAM,oBAAoB,SAAS;AACrC,CAAC;AAEM,IAAM,uBAAuB;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,QAAQ,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC;AAC5C;AACO,IAAM,wBAAwB,EAAE,OAAO,oBAAoB;AAG3D,IAAM,yBAAyB;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAC7B;AACO,IAAM,0BAA0B,EAAE,OAAO,sBAAsB;AAG/D,IAAM,qBAAqB,EAAE,KAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,2BAA2B;AAAA,EACtC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,QAAQ;AAAA;AAAA,EAER,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1B,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AACnD;AACO,IAAM,4BAA4B,EAAE,OAAO,wBAAwB;AAGnE,IAAM,qBAAqB,EAAE,KAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,sBAAsB;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAE5B,QAAQ,EAAE,MAAM,kBAAkB,EAAE,SAAS;AAAA;AAAA,EAE7C,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE9B,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAEhC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAI,EAAE,QAAQ,EAAE;AACzD;AACO,IAAM,uBAAuB,EAAE,OAAO,mBAAmB;AAGzD,IAAM,sBAAsB;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAE5B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,cAAc,EAAE,KAAK,CAAC,aAAa,OAAO,CAAC,EAAE,QAAQ,WAAW;AAAA,EAChE,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE5B,cAAc,EACX,OAAO;AAAA,IACN,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG;AAAA,IACtC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG;AAAA,EACxC,CAAC,EACA,SAAS;AAAA,EACZ,aAAa,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAEtC,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAErC,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAI,EAAE,QAAQ,EAAE;AACzD;AACO,IAAM,uBAAuB,EAAE,OAAO,mBAAmB;AAGzD,IAAM,sBAAsB,EAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE;AAAA,EACpC,WAAW,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG;AAAA,EACvC,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AAC9C,CAAC;AAUM,IAAM,qBAAqB;AAAA,EAChC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,UAAU,eAAe,SAAS;AAAA,EAClC,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,aAAa,kBAAkB,SAAS;AAAA,EACxC,cAAc,EAAE,KAAK,CAAC,SAAS,QAAQ,eAAe,CAAC,EAAE,SAAS;AAAA,EAClE,gBAAgB,EAAE,KAAK,CAAC,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,EAC7D,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACzD,kBAAkB,oBAAoB,SAAS;AAAA;AAAA,EAE/C,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AACnD;AACO,IAAM,sBAAsB,EAAE,OAAO,kBAAkB;AAYvD,IAAM,uBAAuB;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AACtC;AACO,IAAM,wBAAwB,EAAE,OAAO,oBAAoB;AAS3D,IAAM,oBAAoB;AAAA,EAC/B,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAC9B;AACO,IAAM,qBAAqB,EAAE,OAAO,iBAAiB;AAGrD,IAAM,yBAAyB;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACtC;AACO,IAAM,0BAA0B,EAAE,OAAO,sBAAsB;AAa/D,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,OAAO,EAAE,OAAO;AAAA,EAChB,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxC,MAAM,oBAAoB,SAAS;AACrC,CAAC;AAEM,IAAM,mBAAmB,EAAE,mBAAmB,QAAQ;AAAA,EAC3D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,EACxD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,MAAM;AAAA,IACtB,OAAO,EAAE,OAAO;AAAA,IAChB,MAAM,EAAE,OAAO;AAAA,IACf,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,EACpC,CAAC;AAAA,EACD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,KAAK,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AAAA,EACpD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,UAAU,GAAG,WAAW,oBAAoB,CAAC;AAAA,EACxE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,UAAU,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAAA;AAAA,EAE/D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,EACxD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,MAAM;AAAA,IACtB,YAAY,EAAE,OAAO;AAAA,IACrB,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,WAAW;AAAA,IAC3B,QAAQ,EAAE,MAAM,qBAAqB,EAAE,IAAI,CAAC;AAAA,EAC9C,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,QAAQ;AAAA,IACxB,OAAO,EAAE,OAAO;AAAA,IAChB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,QAAQ;AAAA,IACxB,QAAQ;AAAA,IACR,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,SAAS;AAAA,IACzB,UAAU,eAAe,SAAS;AAAA,IAClC,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC9B,aAAa,kBAAkB,SAAS;AAAA,IACxC,cAAc,EAAE,KAAK,CAAC,SAAS,QAAQ,eAAe,CAAC,EAAE,SAAS;AAAA,IAClE,gBAAgB,EAAE,KAAK,CAAC,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,IAC7D,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACzD,kBAAkB,oBAAoB,SAAS;AAAA,IAC/C,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACnD,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,aAAa;AAAA,IAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACtC,CAAC;AAAA,EACD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,UAAU,GAAG,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AACrE,CAAC;AAEM,IAAM,qBAAqB,EAAE,mBAAmB,QAAQ;AAAA,EAC7D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,cAAc,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC9D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,aAAa,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC7D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,aAAa,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,EAChE,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,cAAc;AAAA,IAC9B,OAAO,EAAE,OAAO;AAAA,IAChB,OAAO,EAAE,KAAK,CAAC,WAAW,WAAW,SAAS,CAAC;AAAA,EACjD,CAAC;AAAA;AAAA,EAED,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,mBAAmB;AAAA,IACnC,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACjD,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,oBAAoB;AAAA,IACpC,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,IAE/C,WAAW,EAAE,QAAQ,EAAE,SAAS;AAAA,EAClC,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,cAAc;AAAA,IAC9B,aAAa,EAAE,OAAO;AAAA,IACtB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,iBAAiB;AAAA,IACjC,aAAa,EAAE,OAAO;AAAA,IACtB,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG;AAAA,EAC3C,CAAC;AACH,CAAC;AAEM,IAAM,oBAAoB,EAAE,KAAK;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,oBAAoB;AAAA,EAC/B,MAAM,EAAE,KAAK,CAAC,UAAU,WAAW,CAAC,EAAE,QAAQ,QAAQ;AAAA,EACtD,MAAM;AAAA,EACN,OAAO,EAAE,MAAM,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC3C,QAAQ,EAAE,MAAM,kBAAkB,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC9C,SAAS,EAAE,MAAM,iBAAiB,EAAE,SAAS;AAAA,EAC7C,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzC,UAAU,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACpC;AACO,IAAM,qBAAqB,EAAE,OAAO,iBAAiB;AAOrD,IAAM,kBAAkB,EAAE,KAAK,CAAC,UAAU,WAAW,UAAU,CAAC;AAChE,IAAM,qBAAqB,EAAE,KAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACM,IAAM,mBAAmB,EAAE,MAAM;AAAA,EACtC,EAAE,QAAQ,MAAM;AAAA,EAChB,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AACrC,CAAC;AAEM,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO,gBAAgB,QAAQ,SAAS;AAAA,EACxC,OAAO,iBAAiB,QAAQ,MAAM;AAAA,EACtC,eAAe,EAAE,KAAK,CAAC,QAAQ,UAAU,CAAC,EAAE,QAAQ,MAAM;AAAA,EAC1D,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAC3C;AACO,IAAM,kBAAkB,EAAE,OAAO,cAAc;AAO/C,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,UAAU,eAAe,SAAS;AAAA,EAClC,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACnD,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEzC,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AACvD;AACO,IAAM,mBAAmB,EAAE,OAAO,eAAe;AAOjD,IAAM,qBAAqB,EAAE,KAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,mBAAmB;AAAA,EAC9B,WAAW;AAAA,EACX,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,KAAK,EAAE,OAAO,EAAE,IAAI;AAAA,EACpB,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA;AAAA,EAE5C,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACvC;AACO,IAAM,oBAAoB,EAAE,OAAO,gBAAgB;AAOnD,IAAM,sBAAsB;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACvC,MAAM,kBAAkB,SAAS;AAAA,EACjC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAC5C;AACO,IAAM,uBAAuB,EAAE,OAAO,mBAAmB;AAQzD,IAAM,YAAY;AAAA,EACvB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAEjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,mBAAmB;AAAA;AAAA,EAEnB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAClB;;;ACnjBA,eAAsB,MAAS,OAAY,YAA6C;AACtF,MAAI,UAAU,CAAC,GAAG,KAAK;AACvB,MAAI,IAAI;AACR,SAAO,QAAQ,UAAU,GAAG;AAC1B,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC;AAC5D,QAAI,UAAU;AAGd,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,WAAW;AAClD,YAAM,aAAa;AAAA,QACjB,GAAG,QAAQ,MAAM,GAAG,CAAC;AAAA,QACrB,GAAG,QAAQ,MAAM,IAAI,SAAS;AAAA,MAChC;AACA,UAAI,WAAW,WAAW,EAAG;AAC7B,UAAI,MAAM,WAAW,UAAU,GAAG;AAChC,kBAAU;AACV,YAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AACrB,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAS;AAGb,QAAI,KAAK,QAAQ,OAAQ;AACzB,QAAI,KAAK,IAAI,IAAI,GAAG,QAAQ,MAAM;AAAA,EACpC;AACA,SAAO;AACT;;;ACzCA,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,WAAAC,gBAAe;AAYjB,IAAM,2BAA2B;AAwCxC,eAAsB,cAAc,OAAmD;AACrF,QAAM,WAAqB;AAAA,IACzB,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM;AAAA,IACf,YAAY,MAAM;AAAA,IAClB,aAAa,MAAM;AAAA,IACnB,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B;AACA,QAAM,OAAOC,SAAQ,MAAM,QAAQ,eAAe;AAClD,MAAI;AACF,UAAMC,WAAU,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,MAAM;AAC/D,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,QAAI,KAAK,yBAAyB;AAAA,MAChC,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,KAAK,OAAO,GAAG;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACtEO,SAAS,GAAG,OAAgC;AACjD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,CAAC;AAAA,IAChE,mBAAmB;AAAA,EACrB;AACF;AAMO,SAAS,QAAQ,KAA8B;AACpD,MAAI,eAAe,iBAAiB;AAClC,UAAMC,WAAU,IAAI,OAAO;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAUA,UAAS,MAAM,CAAC,EAAE,CAAC;AAAA,MAClE,mBAAmBA;AAAA,IACrB;AAAA,EACF;AACA,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,QAAM,UAAU,EAAE,MAAM,gBAAyB,QAAQ;AACzD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,CAAC;AAAA,IAClE,mBAAmB;AAAA,EACrB;AACF;AAGO,SAAS,YACd,IACyC;AACzC,SAAO,OAAO,SAAe;AAC3B,QAAI;AACF,aAAO,MAAM,GAAG,IAAI;AAAA,IACtB,SAAS,KAAK;AACZ,aAAO,QAAQ,GAAG;AAAA,IACpB;AAAA,EACF;AACF;;;AJjBO,IAAM,mBAAyD;AAAA,EACpE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA4B;AACpD,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,QAC/C;AAAA,QACA,EAAE,OAAO,YAAY;AAAA,MACvB;AAEA,YAAM,UAAU,MAAM,QAAQ,KAAK,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC3D,iBAAiB;AAAA,QACjB,YAAY;AAAA,MACd,CAAC;AAED,YAAM,SAAkC;AAAA,QACtC,QAAQ;AAAA,QACR,MAAM,KAAK;AAAA,QACX,QAAQ,QAAQ;AAAA,QAChB,gBAAgB,QAAQ;AAAA,MAC1B;AACA,UAAI,QAAQ,iBAAiB,OAAW,QAAO,iBAAiB,QAAQ;AACxE,UAAI,QAAQ,kBAAkB,OAAW,QAAO,iBAAiB,QAAQ;AACzE,UAAI,QAAQ,aAAa,OAAW,QAAO,sBAAsB,QAAQ;AAEzE,UAAI,KAAK,SAAS,eAAe,QAAQ,UAAU,KAAK,UAAU;AAChE,cAAM,MAAM,MAAM,SAAS,KAAK,MAAM,KAAK,OAAO,MAAM;AACxD,eAAO,YAAY;AAAA,UACjB,qBAAqB,KAAK,MAAM;AAAA,UAChC,sBAAsB,IAAI,MAAM;AAAA,UAChC,eAAe,IAAI;AAAA,UACnB,eAAe,IAAI;AAAA,UACnB,eAAe,IAAI;AAAA,UACnB,UAAU,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,eAAe,MAAM,cAAc;AAAA,QACvC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ,QAAQ,SAAS,SAAS;AAAA,QAClC,SAAS,mBAAmB,MAAM,OAAO;AAAA,QACzC;AAAA,QACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACnC,WAAW,sBAAsB,QAAQ,QAAQ;AAAA,QACjD,UAAU;AAAA,UACR,MAAM,KAAK;AAAA,UACX,YAAY,KAAK,MAAM;AAAA,UACvB,cAAc,KAAK,OAAO;AAAA,UAC1B,GAAI,QAAQ,aAAa,SAAY,EAAE,WAAW,QAAQ,SAAS,IAAI,CAAC;AAAA,QAC1E;AAAA,MACF,CAAC;AACD,UAAI,aAAc,QAAO,WAAW;AAEpC,aAAO,GAAG,MAAM;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAEA,SAAS,mBACP,MACA,SACQ;AACR,QAAM,YAAY,KAAK,MAAM;AAC7B,QAAM,cAAc,KAAK,OAAO;AAChC,MAAI,QAAQ,QAAQ;AAClB,WAAO,GAAG,SAAS,aAAa,WAAW;AAAA,EAC7C;AACA,MAAI,QAAQ,iBAAiB,QAAW;AACtC,WAAO,kBAAkB,QAAQ,YAAY,KAAK,QAAQ,iBAAiB,SAAS;AAAA,EACtF;AACA,SAAO,WAAW,QAAQ,iBAAiB,SAAS;AACtD;AAEA,SAAS,sBAAsB,IAAkC;AAC/D,QAAM,MAA0B,CAAC;AACjC,aAAW,KAAK,GAAG,YAAa,KAAI,KAAK,EAAE,MAAM,cAAc,MAAM,EAAE,CAAC;AACxE,MAAI,GAAG,cAAe,KAAI,KAAK,EAAE,MAAM,iBAAiB,MAAM,GAAG,cAAc,CAAC;AAChF,MAAI,GAAG,QAAS,KAAI,KAAK,EAAE,MAAM,WAAW,MAAM,GAAG,QAAQ,CAAC;AAC9D,MAAI,GAAG,UAAW,KAAI,KAAK,EAAE,MAAM,aAAa,MAAM,GAAG,UAAU,CAAC;AACpE,MAAI,GAAG,IAAK,KAAI,KAAK,EAAE,MAAM,OAAO,MAAM,GAAG,IAAI,CAAC;AAClD,MAAI,GAAG,MAAO,KAAI,KAAK,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM,CAAC;AACxD,MAAI,GAAG,MAAO,YAAW,KAAK,GAAG,MAAO,KAAI,KAAK,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;AAC3E,SAAO;AACT;AAyBA,SAAS,oBACP,UACA,QACoC;AACpC,QAAM,MAA2C,CAAC;AAClD,MAAI,SAAS,IAAI,KAAK,GAAG;AACvB,QAAI,MAAM,EAAE,MAAMC,aAAY,QAAQ,aAAa,EAAE;AAAA,EACvD;AACA,MAAI,SAAS,IAAI,OAAO,GAAG;AACzB,QAAI,QAAQ,EAAE,KAAKA,aAAY,QAAQ,QAAQ,EAAE;AAAA,EACnD;AACA,MAAI,SAAS,IAAI,OAAO,GAAG;AACzB,QAAI,QAAQ,EAAE,aAAa,OAAO;AAAA,EACpC;AACA,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM;AAC7C;AAEA,eAAe,QACb,KACA,MACA,OACA,QACA,MACqB;AACrB,QAAM,WAAqB,EAAE,aAAa,CAAC,EAAE;AAC7C,QAAM,WAAW,IAAI,IAAY,KAAK,WAAW,CAAC,YAAY,CAAC;AAC/D,MAAI,SAAS;AACb,MAAI;AACJ,MAAI;AACJ,MAAI;AAIJ,QAAM,WAAwB,EAAE,GAAG,KAAK,KAAK;AAC7C,QAAM,aAAa,oBAAoB,UAAU,MAAM;AACvD,MAAI,YAAY;AACd,aAAS,UAAU;AAAA,EACrB;AAEA,QAAM,UAAU,MAAM,IAAI,SAAS,KAAK,QAAQ;AAChD,QAAM,SAAS,IAAI,SAAS,UAAU,QAAQ,EAAE;AAChD,QAAM,gBAAyB,EAAE,IAAI,QAAQ,IAAI,UAAU,QAAQ,SAAS;AAE5E,MAAI;AACF,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,aAAa,MAAM,OAAO,SAAS,aAAa;AACtD,UAAI;AACF,cAAM,QAAQ,QAAQ,eAAe,MAAM,UAAU;AAAA,MACvD,SAAS,KAAK;AACZ,uBAAe;AACf,wBAAgB,QAAQ,CAAC,KAAK,KAAK,IAAI,aAAa,cAAc,GAAG,CAAC;AACtE,cAAM;AAAA,MACR;AAAA,IACF;AAEA,oBAAgB,MAAM,OAAO,SAAS,aAAa;AACnD,UAAM,WAAqB,CAAC;AAC5B,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AAC3C,YAAM,cAAc,KAAK,OAAO,CAAC;AACjC,UAAI,CAAC,eAAe,aAAa,eAAe,QAAQ,QAAQ,EAAE,GAAG;AACnE,iBAAS,KAAK,UAAU,CAAC,KAAK,eAAe,WAAW,CAAC,EAAE;AAAA,MAC7D;AAAA,IACF;AACA,QAAI,SAAS,WAAW,GAAG;AACzB,eAAS;AAAA,IACX,OAAO;AACL,sBAAgB,wBAAwB,SAAS,KAAK,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,CAAC,cAAe,iBAAgB,cAAc,GAAG;AACrD,aAAS;AAAA,EACX,UAAE;AACA,QAAI,KAAK,iBAAiB;AACxB,UAAI,SAAS,IAAI,YAAY,GAAG;AAC9B,YAAI;AACF,gBAAM,MAAM,MAAM,OAAO,WAAW,eAAe,IAAI;AACvD,gBAAM,IAAI,MAAM,IAAI,MAAM,gBAAgB,QAAQ,KAAK,OAAO;AAC9D,mBAAS,YAAY,KAAK,CAAC;AAAA,QAC7B,SAAS,KAAK;AACZ,4BAAkB,8BAA8B,cAAc,GAAG,CAAC;AAAA,QACpE;AAAA,MACF;AAEA,UAAI,SAAS,IAAI,SAAS,KAAK,kBAAkB,kBAAkB;AACjE,YAAI;AACF,gBAAM,WAAW,OAAO,YAAY,QAAQ,EAAE,EAAE;AAChD,mBAAS,UAAU,MAAM,IAAI,MAAM;AAAA,YACjC;AAAA,YACA;AAAA,YACA,KAAK;AAAA,cACH;AAAA,gBACE,OAAO,SAAS;AAAA,gBAChB,UAAU,aAAa,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,4BAAkB,2BAA2B,cAAc,GAAG,CAAC;AAAA,QACjE;AAAA,MACF;AAEA,UAAI,SAAS,IAAI,WAAW,KAAK,eAAe;AAC9C,YAAI;AACF,mBAAS,YAAY,MAAM,IAAI,MAAM;AAAA,YACnC;AAAA,YACA;AAAA,YACA,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,UACvC;AAAA,QACF,SAAS,KAAK;AACZ,4BAAkB,6BAA6B,cAAc,GAAG,CAAC;AAAA,QACnE;AAAA,MACF;AAEA,UAAI;AACF,iBAAS,gBAAgB,MAAM,IAAI,MAAM;AAAA,UACvC;AAAA,UACA;AAAA,YACE,SAAS;AAAA,YACT,QAAQ,OAAO,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,YACnC,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,MAAM,KAAK;AAAA,YACX;AAAA,YACA,QAAQ,KAAK;AAAA,UACf;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,KAAK,iBAAiB;AACxB,YAAM,IAAI,SAAS,MAAM,aAAa,EAAE,MAAM,MAAM,MAAS;AAAA,IAC/D;AAAA,EACF;AAKA,MAAI,KAAK,iBAAiB;AACxB,QAAI,YAAY,IAAK,UAAS,MAAM,WAAW,IAAI;AACnD,QAAI,YAAY,OAAO;AACrB,eAAS,QAAQA,aAAY,WAAW,MAAM,aAAa,WAAW;AAAA,IACxE;AACA,QAAI,YAAY,OAAO;AACrB,UAAI;AACF,cAAM,QAAQ,MAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,MAAM,MAAM,CAAC,CAAa;AAC5E,iBAAS,QAAQ,MACd,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,EACjC,IAAI,CAAC,MAAMA,aAAY,WAAW,MAAO,KAAK,CAAC,CAAC;AAAA,MACrD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAkB,EAAE,QAAQ,SAAS;AAC3C,MAAI,iBAAiB,OAAW,KAAI,eAAe;AACnD,MAAI,kBAAkB,OAAW,KAAI,gBAAgB;AACrD,MAAI,cAAe,KAAI,WAAW,cAAc;AAChD,SAAO;AACT;AAEA,SAAS,aACP,UACwB;AACxB,QAAM,SAAiC,CAAC;AACxC,aAAW,KAAK,UAAU;AACxB,WAAO,EAAE,KAAK,KAAK,OAAO,EAAE,KAAK,KAAK,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAaA,eAAe,SACb,KACA,MACA,cACA,QACyB;AAGzB,QAAM,SAAmB,aAAa,IAAI,CAAC,MAAM,eAAe,EAAE,MAAM,UAAU,EAAE;AACpF,MAAI,WAAW;AAEf,QAAM,YAAY,OAAO,WAAuC;AAC9D,gBAAY;AACZ,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACxB;AAAA,MACA,EAAE,iBAAiB,OAAO,YAAY,oBAAoB;AAAA,IAC5D;AACA,WAAO,QAAQ;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM,MAAM,QAAQ,SAAS;AAC7C,QAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5D,QAAM,UAAU,OACb,IAAI,CAAC,MAAM,EAAE,SAAS,EACtB,OAAO,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;AAGrC,MAAI;AACJ,MAAI,QAAQ,WAAW,aAAa,QAAQ;AAC1C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACzB;AAAA,MACA,EAAE,iBAAiB,MAAM,YAAY,wBAAwB;AAAA,IAC/D;AACA,iBAAa,SAAS,SAAS;AAAA,EACjC;AACA,SAAO;AAAA,IACL,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IAChC,SAAS,QAAQ,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACF;AAMA,eAAe,QACb,QACA,SACA,MACA,MACe;AACf,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,SAAS;AACZ,YAAM,MAAM,eAAe,KAAK,MAAM,KAAK,KAAK;AAChD,UAAI,CAAC,IAAK,OAAM,aAAa,KAAK,KAAK;AACvC,YAAM,OAAO,MAAM,SAAS,GAAG;AAC/B;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,MAAM,eAAe,KAAK,MAAM,KAAK,KAAK;AAChD,UAAI,CAAC,IAAK,OAAM,aAAa,KAAK,KAAK;AACvC,YAAM,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,KAAK,cAAc,EAAE,YAAY,KAAK,IAAI;AAAA,MAC5C;AACA;AAAA,IACF;AAAA,IACA,KAAK;AACH,YAAM,OAAO,IAAI,SAAS,KAAK,GAAG;AAClC;AAAA,IACF,KAAK;AACH,YAAM,OAAO,QAAQ,SAAS,KAAK,SAAS;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,OAAO,SAAS,SAAS,KAAK,GAAG;AACvC;AAAA,IACF,KAAK,SAAS;AACZ,YAAM,MAAM,eAAe,KAAK,MAAM,KAAK,KAAK;AAChD,UAAI,CAAC,IAAK,OAAM,aAAa,KAAK,KAAK;AACvC,YAAM,OAAO,MAAM,SAAS,GAAG;AAC/B;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,UAAU,eAAe,KAAK,MAAM,KAAK,UAAU;AACzD,UAAI,CAAC,QAAS,OAAM,aAAa,KAAK,UAAU;AAChD,YAAM,QAAQ,eAAe,KAAK,MAAM,KAAK,QAAQ;AACrD,UAAI,CAAC,MAAO,OAAM,aAAa,KAAK,QAAQ;AAC5C,YAAM,OAAO,KAAK,SAAS,SAAS,KAAK;AACzC;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,WAAW,KAAK,OAAO,IAAI,CAAC,MAAM;AACtC,cAAM,MAAM,eAAe,KAAK,MAAM,EAAE,KAAK;AAC7C,YAAI,CAAC,IAAK,OAAM,aAAa,EAAE,KAAK;AACpC,eAAO,EAAE,SAAS,SACd,EAAE,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK,IACpC,EAAE,KAAK,OAAO,EAAE,MAAM;AAAA,MAC5B,CAAC;AACD,YAAM,OAAO,SAAS,SAAS,QAAQ;AACvC;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAM,MAAM,eAAe,KAAK,MAAM,KAAK,KAAK;AAChD,UAAI,CAAC,IAAK,OAAM,aAAa,KAAK,KAAK;AACvC,YAAM,OAAO,WAAW,SAAS,KAAK,KAAK,SAAS;AACpD;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,wBAAkB,QAAQ,QAAQ;AAGlC,WAAK,OACF,aAAa,QAAQ,IAAI;AAAA,QACxB,QAAQ,KAAK;AAAA,QACb,GAAI,KAAK,SAAS,SAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,MACvD,CAAC,EACA,MAAM,MAAM,MAAS;AACxB;AAAA,IACF;AAAA,IACA,KAAK,WAAW;AACd,wBAAkB,QAAQ,SAAS;AACnC,YAAM,OAAO,OAAO,QAAQ,IAAI;AAAA,QAC9B,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,QACjE,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,QAC9D,GAAI,KAAK,gBAAgB,SACrB,EAAE,aAAa,KAAK,YAAY,IAChC,CAAC;AAAA,QACL,GAAI,KAAK,iBAAiB,SACtB,EAAE,aAAa,KAAK,aAAa,IACjC,CAAC;AAAA,QACL,GAAI,KAAK,mBAAmB,SACxB,EAAE,eAAe,KAAK,eAAe,IACrC,CAAC;AAAA,QACL,GAAI,KAAK,kBAAkB,SACvB,EAAE,cAAc,KAAK,cAAc,IACnC,CAAC;AAAA,QACL,GAAI,KAAK,qBAAqB,SAC1B,EAAE,iBAAiB,KAAK,iBAAiB,IACzC,CAAC;AAAA,QACL,GAAI,KAAK,iBAAiB,SACtB,EAAE,aAAa,KAAK,aAAa,IACjC,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK,eAAe;AAClB,wBAAkB,QAAQ,aAAa;AACvC,YAAM,OAAO,WAAW,QAAQ,IAAI,KAAK,KAAK;AAC9C;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,wBAAkB,QAAQ,UAAU;AACpC,UAAI,QAAQ,IAAI,uBAAuB,KAAK;AAC1C,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,SAAS,QAAQ,IAAI,KAAK,MAAM;AAC7C;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBACP,QACA,UACoC;AACpC,MAAI,EAAE,kBAAkB,mBAAmB;AACzC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,6BAA6B,QAAQ;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,eACP,KACA,MACA,QACA,WACS;AACT,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,YAAY,KAAK,MAAM,IAAI,IAAI;AAAA,IACxC,KAAK;AACH,aAAO,CAAC,YAAY,KAAK,MAAM,IAAI,IAAI;AAAA,IACzC,KAAK;AACH,aAAO,IAAI,OAAO,IAAI,OAAO,EAAE,KAAK,KAAK,aAAa;AAAA,IACxD,KAAK,gBAAgB;AACnB,YAAM,OAAO,gBAAgB,KAAK,MAAM,IAAI,KAAK;AACjD,UAAI,CAAC,KAAM,QAAO;AAClB,cAAQ,IAAI,OAAO;AAAA,QACjB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO,KAAK,OAAO,aAAa;AAAA,QAClC,KAAK;AACH,iBAAO,KAAK,OAAO,YAAY;AAAA,MACnC;AAAA,IACF;AAAA,IACA,KAAK,qBAAqB;AACxB,UAAI,EAAE,kBAAkB,kBAAmB,QAAO;AAClD,YAAM,OAAO,OAAO,YAAY,SAAS,EAAE,QAAQ;AAAA,QACjD,CAAC,MAAM,EAAE,UAAU;AAAA,MACrB;AACA,YAAM,WAAW,IAAI,oBAAoB,CAAC;AAC1C,YAAM,YAAY,KAAK;AAAA,QACrB,CAAC,MAAM,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC;AAAA,MACjD;AACA,aAAO,UAAU,WAAW;AAAA,IAC9B;AAAA,IACA,KAAK,sBAAsB;AACzB,UAAI,EAAE,kBAAkB,kBAAmB,QAAO;AAClD,YAAM,OAAO,OAAO,YAAY,SAAS,EAAE,QAAQ,OAAO,CAAC,MAAM;AAC/D,YAAI,EAAE,QAAS,QAAO;AACtB,YAAI,EAAE,WAAW,OAAW,QAAO;AACnC,YAAI,IAAI,UAAW,QAAO,EAAE,UAAU;AACtC,eAAO,EAAE,UAAU;AAAA,MACrB,CAAC;AACD,YAAM,WAAW,IAAI,oBAAoB,CAAC;AAC1C,YAAM,YAAY,KAAK;AAAA,QACrB,CAAC,MAAM,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,IAAI,SAAS,CAAC,CAAC;AAAA,MAChD;AACA,aAAO,UAAU,WAAW;AAAA,IAC9B;AAAA,IACA,KAAK,gBAAgB;AACnB,UAAI,EAAE,kBAAkB,kBAAmB,QAAO;AAClD,YAAM,KAAK,IAAI,OAAO,IAAI,WAAW;AACrC,YAAM,aAAa,IAAI,QAAQ,YAAY;AAC3C,YAAM,UAAU,OAAO,YAAY,SAAS,EAAE,QAAQ,OAAO,CAAC,MAAM;AAClE,YAAI,CAAC,GAAG,KAAK,EAAE,GAAG,EAAG,QAAO;AAC5B,YAAI,cAAc,EAAE,OAAO,YAAY,MAAM,WAAY,QAAO;AAChE,eAAO;AAAA,MACT,CAAC;AACD,YAAM,MAAM,IAAI,aAAa;AAC7B,aAAO,QAAQ,UAAU;AAAA,IAC3B;AAAA,IACA,KAAK,mBAAmB;AACtB,UAAI,EAAE,kBAAkB,kBAAmB,QAAO;AAClD,YAAM,KAAK,IAAI,OAAO,IAAI,WAAW;AACrC,YAAM,QAAQ,OACX,YAAY,SAAS,EACrB,QAAQ,KAAK,CAAC,MAAM,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,WAAW,IAAI,MAAM;AAChE,aAAO,UAAU;AAAA,IACnB;AAAA,EACF;AACF;AAEA,SAAS,eAAe,KAAkD;AACxE,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,iBAAiB,IAAI,IAAI;AAAA,IAClC,KAAK;AACH,aAAO,gBAAgB,IAAI,IAAI;AAAA,IACjC,KAAK;AACH,aAAO,gBAAgB,IAAI,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,iBAAiB,IAAI,KAAK,YAAO,IAAI,KAAK;AAAA,IACnD,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,gBAAgB,IAAI,UAAU,EAAE,IAAI,IAAI,WAAW,GAAG,KAAK;AAAA,IACpE,KAAK;AACH,aAAO,mBAAmB,IAAI,WAAW,MAAM,IAAI,MAAM;AAAA,EAC7D;AACF;AAEA,SAAS,aAAa,OAAgC;AACpD,SAAO,IAAI;AAAA,IACT;AAAA,IACA,6BAA6B,KAAK;AAAA,IAClC,EAAE,MAAM;AAAA,EACV;AACF;AAEA,SAAS,cAAc,KAAsB;AAC3C,MAAI,eAAe,MAAO,QAAO,IAAI;AACrC,SAAO,OAAO,GAAG;AACnB;AAEA,SAAS,eAAe,MAAgB,OAA8B;AACpE,QAAM,OAAO,gBAAgB,MAAM,KAAK;AACxC,SAAO,OAAO,KAAK,MAAM;AAC3B;AAEA,SAAS,gBAAgB,MAAgB,OAAgC;AACvE,QAAM,SAAS,MAAM,YAAY;AACjC,QAAM,QAAQ,CAAC,SAAoC;AACjD,QACG,KAAK,QAAQ,KAAK,KAAK,YAAY,EAAE,SAAS,MAAM,KACpD,KAAK,SAAS,KAAK,MAAM,YAAY,EAAE,SAAS,MAAM,GACvD;AACA,aAAO;AAAA,IACT;AACA,QAAI,KAAK,UAAU;AACjB,iBAAW,KAAK,KAAK,UAAU;AAC7B,cAAM,MAAM,MAAM,CAAC;AACnB,YAAI,IAAK,QAAO;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM,IAAI;AACnB;AAEA,SAAS,YAAY,MAAgB,MAAuB;AAC1D,QAAM,SAAS,KAAK,YAAY;AAChC,QAAM,QAAQ,CAAC,SAA4B;AACzC,QACG,KAAK,QAAQ,KAAK,KAAK,YAAY,EAAE,SAAS,MAAM,KACpD,KAAK,SAAS,KAAK,MAAM,YAAY,EAAE,SAAS,MAAM,GACvD;AACA,aAAO;AAAA,IACT;AACA,WAAO,KAAK,UAAU,KAAK,KAAK,KAAK;AAAA,EACvC;AACA,SAAO,MAAM,IAAI;AACnB;;;AXxoBA,eAAsB,UAAU,YAAqC;AACnE,QAAM,MAAMC,SAAQ,UAAU;AAC9B,QAAM,MAAM,MAAM,SAAS,KAAK,MAAM;AACtC,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,MAAI,OAAO,YAAY,GAAG;AACxB,YAAQ,OAAO,MAAM,sCAAsC,OAAO,OAAO;AAAA,CAAI;AAC7E,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,gBAAgB;AAClC,QAAM,WAAW,IAAI,gBAAgB,EAAE,eAAe,EAAE,CAAC;AACzD,WAAS,SAAS,OAAO,SAAS;AAClC,QAAM,eAAe,mBAAmB;AACxC,WAAS,SAAS,OAAO,YAAY;AACrC,WAAS,SAAS,WAAW,YAAY;AACzC,QAAM,QAAQ,IAAI,cAAc;AAChC,QAAM,MAAmB,EAAE,UAAU,MAAM;AAE3C,MAAI;AACF,UAAM,UAAU,iBAAiB,MAAM,GAAG;AAC1C,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,MAAM;AAAA,MACN,MAAO,OAAO,QAAoC,CAAC;AAAA,MACnD,OACG,OAAO,SAAiD,CAAC;AAAA,MAC5D,QACG,OAAO,UAAkD,CAAC;AAAA,MAC7D,SAAS,CAAC,YAAY;AAAA,MACtB,iBAAiB;AAAA,MACjB,UAAU;AAAA,IACZ,CAA6D;AAC7D,UAAM,OAAO,OAAO;AACpB,YAAQ,OAAO,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AACzD,WAAO,KAAK,WAAW,OAAO,IAAI;AAAA,EACpC,UAAE;AACA,UAAM,SAAS,SAAS,EAAE,MAAM,MAAM,MAAS;AAAA,EACjD;AACF;;;AgBlDA,SAAS,iBAAiB;;;ACInB,IAAM,mBAAyD;AAAA,EACpE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA4B;AACpD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK;AAAA,QACL,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI;AAAA,MAC1C;AACA,aAAO,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;AChBO,IAAM,mBAAyD;AAAA,EACpE,MAAM,UAAU;AAAA,EAChB,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA4B;AACpD,YAAM,WAAW,IAAI,SAAS,WAAW,KAAK,UAAU;AACxD,YAAM,IAAI,SAAS,MAAM,EAAE,IAAI,KAAK,YAAY,SAAS,CAAC;AAC1D,aAAO,GAAG,EAAE,QAAQ,KAAK,CAAC;AAAA,IAC5B,CAAC;AAAA,EACH;AACF;;;ACLO,IAAM,qBAA6D;AAAA,EACxE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA8B;AACtD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SACJ,KAAK,UAAU,KAAK,OAAO,SAAS,IAChC,KAAK,SACL,CAAC,SAAS,SAAS;AACzB,YAAM,WAAW,OAAO,WAAW,KAAK,YAAY;AAAA,QAClD;AAAA,QACA,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,QACjE,OAAO,KAAK;AAAA,QACZ,OAAO,KAAK;AAAA,MACd,CAAC;AACD,aAAO,GAAG;AAAA,QACR,OAAO,SAAS;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;ACjCO,IAAM,kBAAuD;AAAA,EAClE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA2B;AACnD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX;AAAA,UACE,IAAI,KAAK;AAAA,UACT,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU;AAAA,QACnD;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;ACTO,IAAM,sBAA+D;AAAA,EAC1E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,UAAM,UAAU,QAAQ,IAAI,uBAAuB;AACnD,WAAO,YAAY,OAAO,SAA+B;AACvD,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,OAAO,CAAC;AAAA,IACtB,CAAC;AAAA,EACH;AACF;;;ACvCO,IAAM,sBAA+D;AAAA,EAC1E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA+B;AACvD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX;AAAA,UACE,IAAI,KAAK;AAAA,UACT,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU;AAAA,QACnD;AAAA,QACA,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,QAAQ,KAAK,OAAO,OAAO,CAAC;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;;;AChBO,IAAM,0BAET;AAAA,EACF,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAAmC;AAC3D,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,aAAa,KAAK,YAAY;AAAA,QAC7D,QAAQ,KAAK;AAAA,QACb,GAAI,KAAK,SAAS,SAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,QACrD,GAAI,KAAK,eAAe,SAAY,EAAE,WAAW,KAAK,WAAW,IAAI,CAAC;AAAA,MACxE,CAAC;AACD,aAAO,GAAG,EAAE,SAAS,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AACF;;;AC1BO,IAAM,mBAAyD;AAAA,EACpE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA4B;AACpD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX;AAAA,UACE,IAAI,KAAK;AAAA,UACT,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU;AAAA,QACnD;AAAA,QACA,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;ACtBO,IAAM,iBAAqD;AAAA,EAChE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA0B;AAClD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO,IAAI,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE,GAAG,KAAK,GAAG;AACtG,aAAO,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;ACRO,IAAM,sBAA+D;AAAA,EAC1E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA+B;AACvD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO,SAAS,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE,GAAG,KAAK,GAAG;AAC3G,aAAO,GAAG,EAAE,WAAW,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AACF;;;ACVO,IAAM,qBAA6D;AAAA,EACxE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA8B;AACtD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,WAAW,OAAO,WAAW,KAAK,YAAY;AAAA,QAClD,GAAI,KAAK,gBAAgB,SAAY,EAAE,YAAY,KAAK,YAAY,IAAI,CAAC;AAAA,QACzE,aAAa,KAAK;AAAA,QAClB,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC3D,GAAI,KAAK,iBAAiB,SACtB,EAAE,aAAa,KAAK,aAAa,IACjC,CAAC;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,OAAO,KAAK;AAAA,MACd,CAAC;AACD,YAAM,SAAS,SAAS;AAAA,QACtB,CAAC,MAAM,CAAC,CAAC,EAAE,WAAY,EAAE,WAAW,UAAa,EAAE,UAAU;AAAA,MAC/D,EAAE;AACF,aAAO,GAAG;AAAA,QACR,OAAO,SAAS;AAAA,QAChB,cAAc;AAAA,QACd;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,eAAe,KAAK,aAChB,qFACA;AAAA,MACN,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AChDO,IAAM,kBAAuD;AAAA,EAClE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA2B;AACnD,YAAM,UAAU,MAAM,IAAI,SAAS,KAAK,IAAI;AAC5C,aAAO,GAAG,EAAE,YAAY,QAAQ,IAAI,UAAU,QAAQ,SAAS,CAAC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;;;ACLO,IAAM,mBAAyD;AAAA,EACpE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA4B;AACpD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,MAAM,OAAO,UAAU,KAAK,UAAU;AAE5C,YAAM,QAAQ,MAAM,QAAQ;AAAA,QAC1B,IAAI,IAAI,OAAO,OAAO;AAAA,UACpB,OAAO,EAAE;AAAA,UACT,KAAK,EAAE;AAAA,UACP,OAAO,MAAM,EAAE,cAAc,MAAM,MAAM,EAAE;AAAA,UAC3C,QAAQ,EAAE;AAAA,QACZ,EAAE;AAAA,MACJ;AACA,aAAO,GAAG,EAAE,OAAO,MAAM,QAAQ,MAAM,CAAC;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;;;AC7BO,IAAM,wBAAmE;AAAA,EAC9E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAAiC;AACzD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,EAAE,OAAO,OAAO,IAAI,MAAM,IAAI,MAAM,SAAS,MAAM;AACzD,YAAM,MAAM,MAAM,OAAO;AAAA,QACvB,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK,aAAa;AAAA,MACpB;AACA,YAAM,OAAO,MAAM,IAAI,MAAM,gBAAgB,QAAQ,KAAK,MAAM;AAChE,aAAO,GAAG;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,OAAO,IAAI;AAAA,MACb,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AC3BO,IAAM,oBAA2D;AAAA,EACtE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA6B;AACrD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,UAAU,KAAK,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH;AACF;;;ACXO,IAAM,oBAA2D;AAAA,EACtE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA6B;AACrD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,OAAO,KAAK,YAAY;AAAA,QACnC,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,QACjE,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,QAC9D,GAAI,KAAK,gBAAgB,SACrB,EAAE,aAAa,KAAK,YAAY,IAChC,CAAC;AAAA,QACL,GAAI,KAAK,iBAAiB,SACtB,EAAE,aAAa,KAAK,aAAa,IACjC,CAAC;AAAA,QACL,GAAI,KAAK,mBAAmB,SACxB,EAAE,eAAe,KAAK,eAAe,IACrC,CAAC;AAAA,QACL,GAAI,KAAK,kBAAkB,SACvB,EAAE,cAAc,KAAK,cAAc,IACnC,CAAC;AAAA,QACL,GAAI,KAAK,qBAAqB,SAC1B,EAAE,iBAAiB,KAAK,iBAAiB,IACzC,CAAC;AAAA,QACL,GAAI,KAAK,iBAAiB,SACtB,EAAE,aAAa,KAAK,aAAa,IACjC,CAAC;AAAA,MACP,CAAC;AACD,aAAO,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;;;ACzCO,IAAM,sBAA+D;AAAA,EAC1E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA+B;AACvD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO,MAAM,OAAO;AAAA,QACxB,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK;AAAA,MACP;AACA,aAAO,GAAG;AAAA,QACR,YAAY,KAAK;AAAA,QACjB,eAAe,KAAK;AAAA,QACpB,MAAM,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AClBO,IAAM,wBAAmE;AAAA,EAC9E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAAiC;AACzD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,WAAW,KAAK,YAAY,KAAK,KAAK;AACnD,aAAO,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC;AAAA,IACxC,CAAC;AAAA,EACH;AACF;;;ACxBO,IAAM,kBAAuD;AAAA,EAClE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA2B;AACnD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,cAAc,EAAE,YAAY,KAAK,IAAI;AAAA,MAC5C;AACA,aAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAAA,IAC3B,CAAC;AAAA,EACH;AACF;;;ACbO,IAAM,wBAAmE;AAAA,EAC9E,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAAiC;AACzD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,OAAO;AAAA,QACX;AAAA,UACE,IAAI,KAAK;AAAA,UACT,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU;AAAA,QACnD;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,UAAU,MAAM,WAAW,KAAK,UAAU,CAAC;AAAA,IACzD,CAAC;AAAA,EACH;AACF;;;ACnBO,IAAM,qBAA6D;AAAA,EACxE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA8B;AACtD,YAAM,SAAS,IAAI,SAAS,UAAU,KAAK,UAAU;AACrD,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,OAAO;AAAA,QACX,EAAE,IAAI,KAAK,YAAY,UAAU,IAAI,SAAS,WAAW,KAAK,UAAU,EAAE;AAAA,QAC1E,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,aAAO,GAAG,EAAE,SAAS,MAAM,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC;AAAA,IAC5D,CAAC;AAAA,EACH;AACF;;;ACzBA,OAAO,gBAAgB;AAgBvB,IAAM,gBAA2D;AAAA,EAC/D,UAAU,CAAC,UAAU,SAAS;AAAA,EAC9B,WAAW,CAAC,UAAU,WAAW,WAAW,UAAU;AAAA,EACtD,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,kBAAiF;AAAA,EACrF,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AACT;AAEO,IAAM,gBAAmD;AAAA,EAC9D,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAAyB;AACjD,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,QAC/C;AAAA,QACA,EAAE,OAAO,aAAa;AAAA,MACxB;AACA,YAAM,UAAU,MAAM,IAAI,SAAS,KAAK,KAAK,IAAI;AACjD,YAAM,SAAS,IAAI,SAAS,UAAU,QAAQ,EAAE;AAChD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,OAAO,kBAAkB,QAAQ,EAAE;AAEhD,UAAI;AACJ,UAAI,SAAyC,CAAC;AAC9C,UAAI,cAAc;AAClB,UAAI;AAEF,YAAI,KAAK,UAAU,QAAQ;AAEzB,gBAAM,OAAO,SAAS,EAAE,IAAI,QAAQ,IAAI,UAAU,MAAM,CAAC;AACzD,gBAAM,MAAM,KAAK,MAAM;AACvB,gBAAM,UAAU,KAAK,QAAQ,YAAY,GAAG,EAAE;AAC9C,cAAK,MAAM,QAAQ,MAAM,MAAO,GAAG;AACjC,kBAAM,IAAI;AAAA,cACR;AAAA,cACA,QAAQ,GAAG;AAAA,cACX,EAAE,YAAY,QAAQ,IAAI,IAAI;AAAA,YAChC;AAAA,UACF;AACA,gBAAM,QACH,MAAM,EACN,SAAS,CAAC,OAAO,GAAG,aAAa,0BAA0B,MAAM,CAAC;AACrE,wBAAc;AAAA,QAChB;AAEA,cAAM,UAAU,IAAI,WAAW,EAAE,KAAK,CAAC,EAAE,SAAS,cAAc,KAAK,KAAK,CAAC;AAC3E,YAAI,YAAa,SAAQ,QAAQ,0BAA0B;AAC3D,cAAM,UAAU,MAAM,QAAQ,QAAQ;AACtC,iBAAS,QAAQ,WAAW;AAAA,UAAQ,CAAC,MACnC,EAAE,MAAM,IAAI,CAAC,GAAG,SAAS;AAAA,YACvB,UAAU,YAAY,EAAE,IAAI,KAAK,EAAE;AAAA,YACnC,UAAU,gBAAgB,EAAE,UAAU,OAAO,KAAK;AAAA,YAClD,KAAK,GAAG,EAAE,EAAE,IAAI,GAAG;AAAA,YACnB,aAAa,EAAE;AAAA,YACf,gBAAgB,EAAE;AAAA,YAClB,QAAQ,EAAE,OAAO,KAAK,GAAG;AAAA,UAC3B,EAAE;AAAA,QACJ;AAEA,cAAM,UAAU;AAAA,UACd,QAAQ;AAAA,UACR,OAAO,KAAK;AAAA,UACZ,QAAQ,gBAAgB,MAAM;AAAA,UAC9B;AAAA,QACF;AACA,YAAI,KAAK,kBAAkB,YAAY;AACrC,uBAAa,MAAM,IAAI,MAAM;AAAA,YAC3B;AAAA,YACA;AAAA,YACA,eAAe,OAAO;AAAA,UACxB;AAAA,QACF,OAAO;AACL,uBAAa,MAAM,IAAI,MAAM;AAAA,YAC3B;AAAA,YACA;AAAA,YACA,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,UACjC;AAAA,QACF;AAAA,MACF,UAAE;AACA,YAAI,aAAa;AACf,gBAAM,KACH,QAAQ,0BAA0B,EAClC,MAAM,EACN,SAAS,CAAC,OAAO,GAAG,gBAAgB,wBAAwB,CAAC,EAC7D,MAAM,MAAM,MAAS;AAAA,QAC1B;AACA,YAAI,KAAK,iBAAiB;AACxB,gBAAM,IAAI,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QACzD;AAAA,MACF;AAEA,YAAM,SAAS,gBAAgB,MAAM;AACrC,YAAM,SAAS,WAAW,MAAM;AAChC,YAAM,YAAgC,aAClC,CAAC,EAAE,MAAM,UAAU,MAAM,WAAW,CAAC,IACrC,CAAC;AACL,YAAM,eAAe,MAAM,cAAc;AAAA,QACvC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,SAAS,kBAAkB,KAAK,OAAO,QAAQ,MAAM;AAAA,QACrD;AAAA,QACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACnC;AAAA,QACA,UAAU;AAAA,UACR,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,UACZ;AAAA,UACA,eAAe,KAAK;AAAA,QACtB;AAAA,MACF,CAAC;AAED,aAAO,GAAG;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,MACnD,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAUA,SAAS,WAAW,QAAgD;AAClE,OAAK,OAAO,YAAY,MAAM,OAAO,WAAW,KAAK,EAAG,QAAO;AAC/D,OAAK,OAAO,YAAY,MAAM,OAAO,SAAS,KAAK,EAAG,QAAO;AAC7D,SAAO;AACT;AAEA,SAAS,kBACP,OACA,QACA,QACQ;AACR,QAAM,SACH,OAAO,YAAY,MACnB,OAAO,WAAW,MAClB,OAAO,YAAY,MACnB,OAAO,SAAS;AACnB,MAAI,WAAW,OAAQ,QAAO,GAAG,KAAK;AACtC,SAAO,GAAG,KAAK,KAAK,KAAK,6BAAwB,OAAO,YAAY,CAAC,aAAa,OAAO,WAAW,CAAC,cAAc,OAAO,YAAY,CAAC,WAAW,OAAO,SAAS,CAAC;AACrK;AAEA,SAAS,YAAY,MAAoC;AACvD,SAAO,KAAK,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,CAAC;AAC3C;AAEA,SAAS,gBACP,QACwB;AACxB,QAAM,MAA8B;AAAA,IAClC,UAAU;AAAA,IACV,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACA,aAAW,KAAK,QAAQ;AACtB,UAAM,IAAI,OAAO,EAAE,QAAQ;AAC3B,QAAI,CAAC,KAAK,IAAI,CAAC,KAAK,KAAK;AAAA,EAC3B;AACA,SAAO;AACT;AAEA,SAAS,eAAe,GAKb;AACT,QAAM,SAAS,uBAAkB,EAAE,MAAM;AAAA;AAAA,WAAgB,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA,cAAkC,EAAE,OAAO,QAAQ;AAAA,aAAgB,EAAE,OAAO,OAAO;AAAA,cAAiB,EAAE,OAAO,QAAQ;AAAA,WAAc,EAAE,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AACjN,QAAM,OAAO,EAAE,OACZ;AAAA,IACC,CAAC,MACC,OAAO,EAAE,QAAQ,WAAM,EAAE,WAAW;AAAA;AAAA,UAAe,EAAE,QAAQ;AAAA,cAAiB,EAAE,MAAM;AAAA,SAAc,EAAE,cAAc;AAAA;AAAA,EACxH,EACC,KAAK,IAAI;AACZ,SAAO,SAAS;AAClB;;;AC9MO,IAAM,qBAA6D;AAAA,EACxE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA8B;AACtD,UAAI;AACJ,UAAI,aAAa;AACjB,UAAI,KAAK,YAAY;AACnB,cAAM,WAAW,IAAI,SAAS,WAAW,KAAK,UAAU;AACxD,kBAAU,EAAE,IAAI,KAAK,YAAY,SAAS;AAAA,MAC5C,WAAW,KAAK,MAAM;AACpB,kBAAU,MAAM,IAAI,SAAS,KAAK,KAAK,IAAI;AAC3C,qBAAa;AAAA,MACf,OAAO;AACL,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,IAAI,SAAS,UAAU,QAAQ,EAAE;AAChD,cAAM,OAAO,MAAM,OAAO,SAAS,OAAO;AAC1C,cAAM,SAAS,SAAS,KAAK,WAAW;AACxC,cAAM,UAAU,UAAU,KAAK,MAAM,MAAM;AAC3C,cAAM,MAAM,QAAQ,CAAC;AACrB,cAAM,UAAU,MACX,IAAI,UACL,KAAK;AACT,cAAM,cAAc,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AAExD,YAAI,aAAwC;AAC5C,YAAI,KAAK;AACP,cAAI,IAAI,SAAS,OAAO,UAAU,OAAO,SAAS,EAAG,cAAa;AAAA,mBACzD,IAAI,SAAS,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,SAAS,CAAC,CAAC;AAC5D,yBAAa;AAAA,QACjB;AAEA,eAAO,GAAG;AAAA,UACR,cAAc,KAAK;AAAA,UACnB;AAAA,UACA,cAAc;AAAA,UACd,OAAO;AAAA,UACP,eAAe,KAAK;AAAA,QACtB,CAAC;AAAA,MACH,UAAE;AACA,YAAI,cAAc,KAAK,iBAAiB;AACtC,gBAAM,IAAI,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QACzD;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,SAAS,GAAqB;AACrC,SAAO,EACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AAChC;AAQA,SAAS,UAAU,MAAgB,QAAiC;AAClE,QAAM,UAAyB,CAAC;AAChC,QAAM,QAAQ,CAAC,MAAgB,cAAgC;AAC7D,UAAM,MAAM,GAAG,KAAK,QAAQ,EAAE,IAAI,KAAK,SAAS,EAAE,GAAG,YAAY;AACjE,QAAI,QAAQ;AACZ,eAAW,KAAK,OAAQ,KAAI,IAAI,SAAS,CAAC,EAAG,UAAS;AACtD,QAAI,QAAQ,GAAG;AAEb,YAAM,UAAU,UAAU,SAAS,IAAI,UAAU,UAAU,SAAS,CAAC,IAAK;AAC1E,cAAQ,KAAK,EAAE,KAAK,KAAK,KAAK,OAAO,QAAQ,CAAC;AAAA,IAChD;AACA,QAAI,KAAK,UAAU;AACjB,iBAAW,KAAK,KAAK,SAAU,OAAM,GAAG,CAAC,GAAG,WAAW,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF;AACA,QAAM,MAAM,CAAC,CAAC;AACd,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACxC,SAAO;AACT;;;ACxGA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,WAAAC,gBAAe;AAoBjB,IAAM,kBAAuD;AAAA,EAClE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA2B;AACnD,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,QAC/C;AAAA,QACA,EAAE,OAAO,eAAe;AAAA,MAC1B;AACA,YAAM,OAAO,QAAQ,KAAK,WAAW;AACrC,YAAM,SAAS,KAAK,kBAChB,MAAM,WAAW,KAAK,eAAe,IACrC;AACJ,YAAM,SAAS,EAAE,MAAM,MAAM,OAAO;AAEpC,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAI;AAEJ,cAAQ,KAAK,WAAW;AAAA,QACtB,KAAK;AACH,iBAAO,qBAAqB,MAAM;AAClC,qBAAW;AACX,qBAAW,KAAK,YAAY,GAAG,IAAI;AACnC,yBAAe,CAAC,kBAAkB;AAClC,uBACE;AACF;AAAA,QACF,KAAK;AACH,iBAAO,uBAAuB,MAAM;AACpC,qBAAW;AACX,qBAAW,KAAK,YAAY,GAAG,IAAI;AACnC,yBAAe,CAAC,UAAU,YAAY;AACtC,uBACE;AACF;AAAA,QACF,KAAK;AACH,iBAAO,qBAAqB,MAAM;AAClC,qBAAW;AACX,qBAAW,KAAK,YAAY,QAAQ,IAAI;AACxC,yBAAe,CAAC,UAAU,UAAU;AACpC,uBACE;AACF;AAAA,QACF;AACE,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,sBAAsB,KAAK,SAAS;AAAA,UACtC;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM,IAAI,MAAM,YAAY,QAAQ,UAAU,IAAI;AAE/D,YAAM,eAAe,MAAM,cAAc;AAAA,QACvC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS,aAAa,KAAK,SAAS,UAAU,QAAQ,UAAU,SAAS,kBAAkB,UAAU;AAAA,QACrG;AAAA,QACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACnC,WAAW,CAAC,EAAE,MAAM,aAAa,KAAK,CAAC;AAAA,QACvC,UAAU;AAAA,UACR,WAAW,KAAK;AAAA,UAChB;AAAA,UACA,oBAAoB,QAAQ,MAAM;AAAA,QACpC;AAAA,MACF,CAAC;AAED,aAAO,GAAG;AAAA,QACR,QAAQ;AAAA,QACR,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,oBAAoB,QAAQ,MAAM;AAAA,QAClC,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,MACnD,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,eAAe,WAAW,YAA0C;AAClE,QAAM,MAAM,MAAMC,UAASC,SAAQ,UAAU,GAAG,MAAM;AACtD,SAAO,KAAK,MAAM,GAAG;AACvB;AAEA,SAAS,QAAQ,GAAmB;AAClC,SACE,EACG,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE,KAAK;AAEvB;AAQA,SAAS,qBAAqB,GAAsB;AAClD,QAAM,MAAM,EAAE,QAAQ,MAAM,OAAO,EAAE,KAAK;AAC1C,QAAM,YAAY,EAAE,QAAQ,OAAO,SAC/B,EAAE,OAAO,MAAM,IAAI,kBAAkB,EAAE,KAAK,IAAI,IAChD,mCAAmC,EAAE,KAAK,WAAW;AACzD,QAAM,cAAc,EAAE,QAAQ,QAAQ,SAClC,EAAE,OAAO,OAAO,IAAI,oBAAoB,EAAE,KAAK,IAAI,IACnD;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,KAAK,UAAU,EAAE,KAAK,WAAW,CAAC;AAAA,IAC1C,qBAAqB,KAAK,UAAU,GAAG,CAAC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,uBAAuB,GAAsB;AACpD,QAAM,MAAM,EAAE,QAAQ,MAAM,OAAO,EAAE,KAAK;AAC1C,QAAM,YAAY,EAAE,QAAQ,OAAO,SAC/B,EAAE,OAAO,MAAM,IAAI,kBAAkB,EAAE,KAAK,IAAI,IAChD,qCAAqC,EAAE,KAAK,WAAW;AAC3D,QAAM,cAAc,EAAE,QAAQ,QAAQ,SAClC,EAAE,OAAO,OAAO,IAAI,oBAAoB,EAAE,KAAK,IAAI,IACnD;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,KAAK,UAAU,EAAE,KAAK,WAAW,CAAC;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAuB,KAAK,UAAU,GAAG,CAAC;AAAA,IAC1C,OAAO,WAAW,CAAC;AAAA,IACnB,OAAO,aAAa,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,qBAAqB,GAAsB;AAClD,QAAM,MAAM,EAAE,QAAQ,MAAM,OAAO,EAAE,KAAK;AAC1C,QAAM,YAAY,EAAE,QAAQ,OAAO,SAC/B,EAAE,OAAO,MAAM,IAAI,gBAAgB,EAAE,KAAK,IAAI,IAC9C,oCAAoC,EAAE,KAAK,WAAW;AAC1D,QAAM,cAAc,EAAE,QAAQ,QAAQ,SAClC,EAAE,OAAO,OAAO,IAAI,kBAAkB,EAAE,KAAK,IAAI,IACjD;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,UAAU,EAAE,KAAK,WAAW,CAAC;AAAA,IACzC,UAAU,EAAE,KAAK,WAAW;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,sBAAsB,KAAK,UAAU,GAAG,CAAC;AAAA,IACzC,OAAO,WAAW,CAAC;AAAA,IACnB,OAAO,aAAa,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,mBAAmB,MAAoB;AAC9C,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,0BAA0B,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IAC7D,KAAK;AACH,aAAO,6CAA6C,KAAK,UAAU,KAAK,KAAK,CAAC,YAAY,KAAK,UAAU,KAAK,IAAI,CAAC;AAAA,IACrH,KAAK;AACH,aAAO,+BAA+B,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,IAChE,KAAK;AACH,aAAO,qBAAqB,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,IACtD,KAAK;AACH,aAAO,kBAAkB,KAAK,UAAU,KAAK,SAAS,CAAC;AAAA,IACzD,KAAK;AACH,aAAO,0BAA0B,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IAC7D,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA,kBAAkB,KAAK,UAAU,KAAK,UAAU,CAAC;AAAA,QACjD;AAAA,QACA,8BAA8B,KAAK,UAAU,KAAK,QAAQ,CAAC;AAAA,MAC7D,EAAE,KAAK,IAAI;AAAA,IACb,KAAK,aAAa;AAChB,YAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,IAAK,KAAK,SAAqE,CAAC;AACxH,aAAO,OACJ,IAAI,CAAC,MAAM;AACV,cAAM,IAAI,KAAK,UAAU,EAAE,KAAK;AAChC,YAAI,EAAE,SAAS,UAAU;AACvB,iBAAO,2BAA2B,CAAC,kBAAkB,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,QACtF;AACA,YAAI,EAAE,SAAS,cAAc,EAAE,SAAS,SAAS;AAC/C,gBAAM,UAAU,OAAO,EAAE,UAAU,YAC/B,EAAE,QACF,OAAO,EAAE,KAAK,MAAM,UAAU,OAAO,EAAE,KAAK,MAAM;AACtD,iBAAO,2BAA2B,CAAC,gBAAgB,OAAO;AAAA,QAC5D;AACA,eAAO,2BAA2B,CAAC,UAAU,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,MAC9E,CAAC,EACA,KAAK,IAAI;AAAA,IACd;AAAA,IACA,KAAK;AACH,aAAO,2BAA2B,KAAK,UAAU,KAAK,KAAK,CAAC,mBAAmB,KAAK,UAAU,KAAK,SAAS,CAAC;AAAA,IAC/G,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA,KAAK,WAAW,WACZ,+BACA,KAAK,WAAW,qBACd,2BAA2B,KAAK,UAAU,KAAK,QAAQ,EAAE,CAAC,OAC1D;AAAA,QACN;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK,WAAW;AACd,YAAM,QAAkB,CAAC;AACzB,UAAI,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACtD,cAAM,IAAI,KAAK;AACf,cAAM,KAAK,yCAAyC,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM;AAAA,MACxF;AACA,UAAI,KAAK,YAAY,QAAW;AAC9B,cAAM,KAAK,qCAAqC,QAAQ,KAAK,OAAO,CAAC,IAAI;AAAA,MAC3E;AACA,UAAI,KAAK,aAAa;AACpB,cAAM,KAAK,yCAAyC,KAAK,UAAU,KAAK,WAAW,CAAC,IAAI;AAAA,MAC1F;AACA,UAAI,KAAK,gBAAgB,KAAK,gBAAgB;AAC5C,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,aAAc,MAAK,cAAc,KAAK;AAC/C,YAAI,KAAK,eAAgB,MAAK,gBAAgB,KAAK;AACnD,cAAM,KAAK,6BAA6B,KAAK,UAAU,IAAI,CAAC,IAAI;AAAA,MAClE;AACA,UAAI,KAAK,eAAe;AACtB,cAAM,KAAK,8CAA8C,KAAK,UAAU,KAAK,aAAa,CAAC,IAAI;AAAA,MACjG;AACA,UAAI,KAAK,oBAAoB,KAAK,iBAAiB,QAAW;AAC5D,cAAM,KAAK,mFAA8E;AAAA,MAC3F;AACA,aAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAAA,IAC/C;AAAA,IACA,KAAK;AACH,aAAO,iEAAiE,KAAK,KAAK,oBAAoB,KAAK,KAAK,qBAAqB,KAAK,KAAK;AAAA,IACjJ,KAAK;AACH,aAAO,yBAAyB,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IAC7D;AACE,aAAO,+BAA+B,KAAK,IAAI;AAAA,EACnD;AACF;AAEA,SAAS,qBAAqB,KAAqB;AACjD,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,iCAAiC,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IAClE,KAAK;AACH,aAAO,iCAAiC,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IAClE,KAAK;AACH,aAAO,6CAA6C,KAAK,UAAU,IAAI,OAAO,CAAC;AAAA,IACjF,KAAK;AACH,aAAO,qBAAqB,KAAK,UAAU,IAAI,KAAK,CAAC,WAAM,OAAO,IAAI,KAAK,CAAC;AAAA,IAC9E,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO,0CAA0C,KAAK,UAAU,IAAI,WAAW,CAAC;AAAA,IAClF,KAAK;AACH,aAAO,kDAAkD,KAAK,UAAU,IAAI,WAAW,CAAC,qCAAqC,OAAO,IAAI,MAAM,CAAC;AAAA,IACjJ;AACE,aAAO,iCAAiC,IAAI,IAAI;AAAA,EACpD;AACF;AAEA,SAAS,iBAAiB,MAAoB;AAC5C,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,+DAA+D,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,IACpG,KAAK;AACH,aAAO,0DAA0D,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC,0BAA0B,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC,oBAAoB,KAAK,UAAU,KAAK,IAAI,CAAC;AAAA,IAClM,KAAK;AACH,aAAO,sDAAsD,UAAU,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,IAC1F,KAAK;AACH,aAAO,kBAAkB,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,IACnD,KAAK;AACH,aAAO,mBAAmB,KAAK,UAAU,KAAK,SAAS,CAAC;AAAA,IAC1D,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA,wEAAwE,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,QACpG;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA,qEAAqE,SAAS,OAAO,KAAK,UAAU,CAAC,CAAC;AAAA,QACtG,qEAAqE,SAAS,OAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,QACpG;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK,aAAa;AAChB,YAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,IACnC,KAAK,SACN,CAAC;AACL,aAAO,OACJ,IAAI,CAAC,MAAM;AACV,cAAM,IAAI,SAAS,EAAE,KAAK;AAC1B,YAAI,EAAE,SAAS,UAAU;AACvB,iBAAO;AAAA,YACL;AAAA,YACA,iEAAiE,CAAC,kCAAkC,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,UACrI,EAAE,KAAK,IAAI;AAAA,QACb;AACA,YAAI,EAAE,SAAS,cAAc,EAAE,SAAS,SAAS;AAC/C,gBAAM,UACJ,OAAO,EAAE,UAAU,YACf,EAAE,QACF,OAAO,EAAE,KAAK,MAAM;AAC1B,iBAAO,+DAA+D,CAAC,6CAA6C,UAAU,SAAS,OAAO;AAAA,QAChJ;AACA,eAAO,0DAA0D,CAAC,oBAAoB,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,MACvH,CAAC,EACA,KAAK,IAAI;AAAA,IACd;AAAA,IACA,KAAK;AACH,aAAO,0DAA0D,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC,oBAAoB,KAAK,UAAU,KAAK,SAAS,CAAC;AAAA,IACjJ,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA,KAAK,WAAW,WACZ,uBACA,KAAK,WAAW,qBACd,uBAAuB,KAAK,UAAU,KAAK,QAAQ,EAAE,CAAC,sBACtD;AAAA,MACR,EAAE,KAAK,IAAI;AAAA,IACb,KAAK,WAAW;AACd,YAAM,QAAkB,CAAC;AACzB,UAAI,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACtD,cAAM,IAAI,KAAK;AACf,cAAM,KAAK,8BAA8B,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG;AAAA,MAClE;AACA,YAAM,KAAK,oHAA+G;AAC1H,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IACA,KAAK;AACH,aAAO,qDAAqD,KAAK,KAAK;AAAA,IACxE,KAAK;AACH,aAAO,6BAA6B,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IACjE;AACE,aAAO,gCAAgC,KAAK,IAAI;AAAA,EACpD;AACF;AAEA,SAAS,mBAAmB,KAAqB;AAC/C,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,cAAc,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IAC/C,KAAK;AACH,aAAO,cAAc,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IAC/C,KAAK;AACH,aAAO,mCAAmC,KAAK,UAAU,IAAI,OAAO,CAAC;AAAA,IACvE,KAAK;AACH,aAAO,sBAAsB,KAAK,UAAU,IAAI,KAAK,CAAC,WAAM,OAAO,IAAI,KAAK,CAAC;AAAA,IAC/E,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,sBAAsB,KAAK,UAAU,IAAI,WAAW,CAAC;AAAA,IAC9D,KAAK;AACH,aAAO,yBAAyB,KAAK,UAAU,IAAI,WAAW,CAAC,OAAO,OAAO,IAAI,MAAM,CAAC;AAAA,IAC1F;AACE,aAAO,kCAAkC,IAAI,IAAI;AAAA,EACrD;AACF;AAEA,SAAS,UAAU,GAAmB;AACpC,SACE,EACG,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE,KAAK;AAEvB;AAEA,SAAS,SAAS,GAAmB;AACnC,SAAO,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACrD;AAEA,SAAS,UAAU,GAAmB;AACpC,QAAM,MAA8B;AAAA,IAClC,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AACA,SAAO,IAAI,CAAC,KAAK,0BAA0B,CAAC;AAC9C;AAEA,SAAS,OAAO,OAAe,GAAmB;AAChD,QAAM,MAAM,IAAI,OAAO,CAAC;AACxB,SAAO,MACJ,MAAM,IAAI,EACV,IAAI,CAAC,MAAO,EAAE,SAAS,IAAI,MAAM,IAAI,CAAE,EACvC,KAAK,IAAI;AACd;;;ACzcA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,WAAAC,gBAAe;AACxB,OAAO,gBAAgB;AACvB,SAAS,WAAW;AAYb,IAAM,iBAAqD;AAAA,EAChE,MAAM,UAAU;AAAA,EAChB,aACE;AAAA,EACF,YAAY;AAAA,EACZ,MAAM,KAAK;AACT,WAAO,YAAY,OAAO,SAA0B;AAClD,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,QAC/C;AAAA,QACA,EAAE,OAAO,cAAc;AAAA,MACzB;AACA,YAAM,UAAU,MAAM,IAAI,SAAS,KAAK;AAAA,QACtC,GAAG,KAAK;AAAA,QACR,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MACrD,CAAC;AACD,YAAM,SAAS,IAAI,SAAS,UAAU,QAAQ,EAAE;AAChD,UAAI,EAAE,kBAAkB,mBAAmB;AACzC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,MAAM,MAAM,OAAO;AAAA,UACvB,EAAE,IAAI,QAAQ,IAAI,UAAU,QAAQ,SAAS;AAAA,UAC7C;AAAA,QACF;AACA,cAAM,cAAc,MAAM,IAAI,MAAM,gBAAgB,QAAQ,KAAK,SAAS;AAE1E,cAAM,IAAI,MAAM,UAAU,IAAI,MAAM,WAAW;AAC/C,cAAM,eAAeC;AAAA,UACnB,IAAI,MAAM;AAAA,UACV,GAAG,KAAK,WAAW;AAAA,QACrB;AAEA,YAAI,CAACC,YAAW,YAAY,GAAG;AAC7B,gBAAM,IAAI,MAAM;AAAA,YACd,IAAI,MAAM;AAAA,YACV,GAAG,KAAK,WAAW;AAAA,YACnB;AAAA,UACF;AACA,gBAAMC,gBAAe,MAAM,cAAc;AAAA,YACvC;AAAA,YACA;AAAA,YACA,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS,aAAa,KAAK,WAAW;AAAA,YACtC;AAAA,YACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,YACnC,WAAW;AAAA,cACT,EAAE,MAAM,YAAY,MAAM,aAAa;AAAA,cACvC,EAAE,MAAM,cAAc,MAAM,YAAY;AAAA,YAC1C;AAAA,YACA,UAAU,EAAE,aAAa,KAAK,aAAa,QAAQ,KAAK;AAAA,UAC1D,CAAC;AACD,iBAAO,GAAG;AAAA,YACR,QAAQ;AAAA,YACR,aAAa,KAAK;AAAA,YAClB,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,eAAe;AAAA,YACf,cAAc;AAAA,YACd,GAAIA,gBAAe,EAAE,UAAUA,cAAa,IAAI,CAAC;AAAA,YACjD,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAEA,cAAM,CAAC,aAAa,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,UAClDC,UAAS,YAAY;AAAA,UACrBA,UAAS,WAAW;AAAA,QACtB,CAAC;AACD,cAAM,WAAW,IAAI,KAAK,KAAK,WAAW;AAC1C,cAAM,UAAU,IAAI,KAAK,KAAK,UAAU;AAExC,YAAI,SAAS,UAAU,QAAQ,SAAS,SAAS,WAAW,QAAQ,QAAQ;AAC1E,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,oCAAoC,KAAK,WAAW,qBAAgB,SAAS,KAAK,IAAI,SAAS,MAAM,aAAa,QAAQ,KAAK,IAAI,QAAQ,MAAM;AAAA,YACjJ;AAAA,cACE,UAAU,EAAE,GAAG,SAAS,OAAO,GAAG,SAAS,OAAO;AAAA,cAClD,SAAS,EAAE,GAAG,QAAQ,OAAO,GAAG,QAAQ,OAAO;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAEA,cAAM,OAAO,IAAI,IAAI,EAAE,OAAO,SAAS,OAAO,QAAQ,SAAS,OAAO,CAAC;AACvE,cAAM,aAAa;AAAA,UACjB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,KAAK;AAAA,UACL,SAAS;AAAA,UACT,SAAS;AAAA,UACT,EAAE,WAAW,KAAK,iBAAiB,WAAW,KAAK;AAAA,QACrD;AACA,cAAM,QAAQ,SAAS,QAAQ,SAAS;AACxC,cAAM,UAAU,aAAa;AAC7B,cAAM,SAAS,WAAW,KAAK;AAE/B,cAAM,gBAAgB,MAAM,IAAI,MAAM;AAAA,UACpC;AAAA,UACA;AAAA,UACA,IAAI,KAAK,MAAM,IAAI;AAAA,QACrB;AAEA,cAAM,YAAgC;AAAA,UACpC,EAAE,MAAM,YAAY,MAAM,aAAa;AAAA,UACvC,EAAE,MAAM,cAAc,MAAM,YAAY;AAAA,UACxC,EAAE,MAAM,QAAQ,MAAM,cAAc;AAAA,QACtC;AACA,cAAM,eAAe,MAAM,cAAc;AAAA,UACvC;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,QAAQ,SAAS,SAAS;AAAA,UAC1B,SAAS,SAAS,UAAU,KAAK,QAAQ,CAAC,CAAC,kBAAkB,KAAK,WAAW,iBAAiB,KAAK,gBAAgB,KAAK,QAAQ,CAAC,CAAC;AAAA,UAClI;AAAA,UACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,UACnC;AAAA,UACA,UAAU;AAAA,YACR,aAAa,KAAK;AAAA,YAClB,UAAU,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,YACnC,aAAa;AAAA,YACb,cAAc;AAAA,YACd,eAAe,KAAK;AAAA,UACtB;AAAA,QACF,CAAC;AAED,eAAO,GAAG;AAAA,UACR,QAAQ;AAAA,UACR,aAAa,KAAK;AAAA,UAClB,UAAU,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,UACnC,aAAa;AAAA,UACb,cAAc;AAAA,UACd;AAAA,UACA,eAAe;AAAA,UACf,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,QACnD,CAAC;AAAA,MACH,UAAE;AACA,YAAI,KAAK,iBAAiB;AACxB,gBAAM,IAAI,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QACzD;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjJO,IAAM,eAA+C;AAAA;AAAA,EAE1D,CAAC,UAAU,WAAW,GAAG;AAAA,IACvB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,YAAY,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,eAAe,GAAG;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,YAAY,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,WAAW,GAAG;AAAA,IACvB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,UAAU,GAAG;AAAA,IACtB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,aAAa,GAAG;AAAA,IACzB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,cAAc,GAAG;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,iBAAiB,GAAG;AAAA,IAC7B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,eAAe,GAAG;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,CAAC,UAAU,YAAY,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,SAAS,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,UAAU,GAAG;AAAA,IACtB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA;AAAA;AAAA,MAGP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,WAAW,GAAG;AAAA,IACvB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA;AAAA,MAEP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,cAAc,GAAG;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,CAAC,UAAU,YAAY,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,WAAW,GAAG;AAAA,IACvB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,eAAe,GAAG;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,iBAAiB,GAAG;AAAA,IAC7B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,mBAAmB,GAAG;AAAA,IAC/B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,cAAc,GAAG;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,cAAc,GAAG;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,aAAa,GAAG;AAAA,IACzB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,eAAe,GAAG;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA;AAAA;AAAA,MAGP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,YAAY,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,CAAC,UAAU,iBAAiB,GAAG;AAAA,IAC7B,OAAO;AAAA,IACP,aAAa;AAAA,MACX,OAAO;AAAA,MACP,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA,IACjB;AAAA,EACF;AACF;;;A1BhPO,IAAM,cAAc;AACpB,IAAM,iBAAiB;AAMvB,IAAM,qBAAqB;AAQlC,SAAS,sBAA4B;AACnC,QAAM,YAAY,QAAQ,IAAI;AAC9B,MAAI,CAAC,UAAW;AAChB,MAAI,cAAc,oBAAoB;AAEpC,YAAQ;AAAA,MACN,uCAAuC,kBAAkB,SAAS,SAAS,uCACpC,kBAAkB;AAAA,IAC3D;AAAA,EACF;AACF;AAcO,SAAS,YACd,OAA0D,CAAC,GAC7C;AACd,sBAAoB;AAEpB,QAAM,YAAY,gBAAgB;AAClC,QAAM,WAAW,IAAI,gBAAgB,EAAE,eAAe,KAAK,cAAc,CAAC;AAC1E,WAAS,SAAS,OAAO,SAAS;AAIlC,QAAM,eAAe,mBAAmB;AACxC,WAAS,SAAS,OAAO,YAAY;AACrC,WAAS,SAAS,WAAW,YAAY;AAEzC,QAAM,YAA4D,CAAC;AACnE,MAAI,KAAK,iBAAiB,OAAW,WAAU,UAAU,KAAK;AAC9D,QAAM,QAAQ,IAAI,cAAc,SAAS;AAEzC,QAAM,MAAmB,EAAE,UAAU,MAAM;AAE3C,QAAM,MAAM,IAAI,UAAU;AAAA,IACxB,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,QAAM,QAAQ;AAAA;AAAA,IAEZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,aAAa,EAAE,IAAiC;AAC7D,QAAI;AAAA,MACF,EAAE;AAAA,MACF;AAAA,QACE,OAAO,MAAM;AAAA,QACb,aAAa,EAAE;AAAA,QACf,aAAa,EAAE;AAAA,QACf,aAAa,MAAM;AAAA,MACrB;AAAA,MACA,EAAE,MAAM,GAAG;AAAA,IACb;AAAA,EACF;AAEA,MAAI,KAAK,gCAAgC;AAAA,IACvC,SAAS;AAAA,IACT,UAAU;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAChC,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,WAAW;AACf,YAAM,SAAS,SAAS;AACxB,YAAM,IAAI,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,IACzC;AAAA,EACF;AACF;;;AnBzJA,IAAM,OAAO,mBAAmB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAW9C,eAAe,OAAsB;AACnC,QAAM,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,IAAI,QAAQ;AAEnC,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACH,aAAO,YAAY;AAAA,IACrB,KAAK;AACH,cAAQ,KAAK,MAAM,UAAU,CAAC;AAC9B;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,KAAK,iBAAiB,CAAC;AAC/B;AAAA,IACF,KAAK,UAAU;AACb,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,CAAC,QAAQ;AACX,gBAAQ,OAAO,MAAM,+CAA+C;AACpE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,cAAQ,KAAK,MAAM,UAAU,MAAM,CAAC;AACpC;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,OAAO,MAAM,GAAG,cAAc;AAAA,CAAI;AAC1C;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,OAAO,MAAM,IAAI;AACzB;AAAA,IACF;AACE,cAAQ,OAAO,MAAM,uBAAuB,GAAG;AAAA,EAAK,IAAI,EAAE;AAC1D,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,eAAe,cAA6B;AAC1C,QAAM,SAAS,YAAY;AAC3B,QAAM,YAAY,IAAI,qBAAqB;AAE3C,QAAM,WAAW,OAAO,WAA2B;AACjD,QAAI,KAAK,iBAAiB,EAAE,OAAO,CAAC;AACpC,UAAM,OAAO,SAAS,EAAE;AAAA,MAAM,CAAC,QAC7B,IAAI,MAAM,mBAAmB,EAAE,KAAK,OAAO,GAAG,EAAE,CAAC;AAAA,IACnD;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,MAAM,KAAK,SAAS,QAAQ,CAAC;AAClD,UAAQ,GAAG,WAAW,MAAM,KAAK,SAAS,SAAS,CAAC;AAEpD,QAAM,OAAO,IAAI,QAAQ,SAAS;AAClC,MAAI,KAAK,oCAAoC;AAC/C;AAEA,KAAK,EAAE,MAAM,CAAC,QAAiB;AAC7B,MAAI,MAAM,uBAAuB;AAAA,IAC/B,KAAK,eAAe,QAAQ,IAAI,QAAQ,OAAO,GAAG;AAAA,EACpD,CAAC;AACD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["osPlatform","resolve","resolve","resolve","randomUUID","XMLParser","parser","firstTagName","randomUUID","randomUUID","randomUUID","resolve","resolvePath","writeFile","resolve","resolve","writeFile","payload","resolvePath","resolve","readFile","resolve","readFile","resolve","existsSync","readFile","resolve","resolve","existsSync","manifestPath","readFile"]}
1
+ {"version":3,"sources":["../../bin/rolepod-uiproof.ts","../../src/cli/doctor.ts","../../src/cli/install_mobile.ts","../../src/cli/replay.ts","../../src/artifact/ArtifactStore.ts","../../src/util/log.ts","../../src/util/rolepodProtocol.ts","../../src/util/errors.ts","../../src/engine/AppiumEngine.ts","../../src/engine/a11y/uiautomator2.ts","../../src/engine/a11y/xcuitest.ts","../../src/engine/PlaywrightEngine.ts","../../src/engine/a11y/normalize.ts","../../src/engine/factory.ts","../../src/session/SessionRegistry.ts","../../src/tools/composite/verify_ui_flow.ts","../../src/schema/tools.ts","../../src/replay/minimize.ts","../../src/util/manifest.ts","../../src/tools/result.ts","../../src/server.ts","../../src/tools/atomic/browser_click.ts","../../src/tools/atomic/browser_close.ts","../../src/tools/atomic/browser_console.ts","../../src/tools/atomic/browser_drag.ts","../../src/tools/atomic/browser_evaluate.ts","../../src/tools/atomic/browser_fill_form.ts","../../src/tools/atomic/browser_handle_dialog.ts","../../src/tools/atomic/browser_hover.ts","../../src/tools/atomic/browser_key.ts","../../src/tools/atomic/browser_navigate.ts","../../src/tools/atomic/browser_network.ts","../../src/tools/atomic/browser_open.ts","../../src/tools/atomic/browser_pages.ts","../../src/tools/atomic/browser_screenshot.ts","../../src/tools/atomic/browser_scroll.ts","../../src/tools/atomic/browser_set_env.ts","../../src/tools/atomic/browser_snapshot.ts","../../src/tools/atomic/browser_switch_page.ts","../../src/tools/atomic/browser_type.ts","../../src/tools/atomic/browser_upload_file.ts","../../src/tools/atomic/browser_wait_for.ts","../../src/tools/composite/audit_a11y.ts","../../src/tools/composite/extract_ui_state.ts","../../src/tools/composite/scaffold_e2e.ts","../../src/tools/composite/visual_diff.ts","../../src/tools/metadata.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { runDoctor } from \"../src/cli/doctor.js\";\nimport { runInstallMobile } from \"../src/cli/install_mobile.js\";\nimport { runReplay } from \"../src/cli/replay.js\";\nimport { buildServer, SERVER_VERSION } from \"../src/server.js\";\nimport { log } from \"../src/util/log.js\";\n\nconst HELP = `rolepod-uiproof ${SERVER_VERSION}\n\nUsage:\n rolepod-uiproof Start the MCP server on stdio (default)\n rolepod-uiproof doctor Health check (Node, Playwright, Appium, SDKs)\n rolepod-uiproof install:mobile Print mobile setup checklist (iOS / Android)\n rolepod-uiproof replay <file> Re-run a verify_ui_flow replay bundle\n rolepod-uiproof --version Print version\n rolepod-uiproof --help This help\n`;\n\nasync function main(): Promise<void> {\n const [, , sub, ...rest] = process.argv;\n\n switch (sub) {\n case undefined:\n case \"serve\":\n return startServer();\n case \"doctor\":\n process.exit(await runDoctor());\n return;\n case \"install:mobile\":\n case \"install\":\n process.exit(runInstallMobile());\n return;\n case \"replay\": {\n const target = rest[0];\n if (!target) {\n process.stderr.write(\"Usage: rolepod-uiproof replay <bundle.json>\\n\");\n process.exit(2);\n }\n process.exit(await runReplay(target));\n return;\n }\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${SERVER_VERSION}\\n`);\n return;\n case \"--help\":\n case \"-h\":\n case \"help\":\n process.stdout.write(HELP);\n return;\n default:\n process.stderr.write(`Unknown subcommand: ${sub}\\n${HELP}`);\n process.exit(2);\n }\n}\n\nasync function startServer(): Promise<void> {\n const server = buildServer();\n const transport = new StdioServerTransport();\n\n const shutdown = async (signal: NodeJS.Signals) => {\n log.info(\"shutting down\", { signal });\n await server.shutdown().catch((err: unknown) =>\n log.error(\"shutdown failed\", { err: String(err) }),\n );\n process.exit(0);\n };\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n\n await server.mcp.connect(transport);\n log.info(\"rolepod-uiproof connected on stdio\");\n}\n\nmain().catch((err: unknown) => {\n log.error(\"fatal startup error\", {\n err: err instanceof Error ? err.stack : String(err),\n });\n process.exit(1);\n});\n","import { existsSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { homedir, platform as osPlatform } from \"node:os\";\n\ntype Check = {\n name: string;\n status: \"ok\" | \"warn\" | \"fail\";\n detail: string;\n};\n\n/**\n * `rolepod-uiproof doctor` — diagnose local environment readiness. Exits\n * with code 0 if every check is `ok` or `warn`, 1 if any `fail`.\n */\nexport async function runDoctor(): Promise<number> {\n const checks: Check[] = [];\n\n // Node version\n const major = Number(process.versions.node.split(\".\")[0]);\n checks.push({\n name: \"Node ≥20\",\n status: major >= 20 ? \"ok\" : \"fail\",\n detail: process.versions.node,\n });\n\n // Playwright Chromium install (looks under the default cache directory)\n checks.push(checkPlaywrightChromium());\n\n // webdriverio (optional)\n checks.push(await checkWebdriverIO());\n\n // Appium server reachable\n checks.push(await checkAppiumServer());\n\n // Xcode (macOS only, for iOS testing — roadmap v0.3)\n if (osPlatform() === \"darwin\") {\n checks.push(checkXcode());\n }\n\n // Android SDK (roadmap v0.3)\n checks.push(checkAndroidSdk());\n\n // SeleniumEngine status — explicitly roadmap v0.4\n checks.push({\n name: \"SeleniumEngine (roadmap v0.4)\",\n status: \"warn\",\n detail:\n \"Not implemented — deferred to v0.4 (legacy Selenium grid support, opt-in via ROLEPOD_MCP_WEB_ENGINE=selenium).\",\n });\n\n // Artifact dir writable\n checks.push(checkArtifactDir());\n\n print(checks);\n const failed = checks.some((c) => c.status === \"fail\");\n return failed ? 1 : 0;\n}\n\nfunction checkPlaywrightChromium(): Check {\n const candidates = [\n join(homedir(), \"Library\", \"Caches\", \"ms-playwright\"),\n join(homedir(), \".cache\", \"ms-playwright\"),\n process.env.PLAYWRIGHT_BROWSERS_PATH,\n ].filter((x): x is string => typeof x === \"string\");\n for (const base of candidates) {\n if (existsSync(base)) {\n return {\n name: \"Playwright Chromium installed\",\n status: \"ok\",\n detail: base,\n };\n }\n }\n return {\n name: \"Playwright Chromium installed\",\n status: \"fail\",\n detail: \"Run: npx playwright install chromium\",\n };\n}\n\nasync function checkWebdriverIO(): Promise<Check> {\n try {\n const url = await import.meta.resolve?.(\"webdriverio\");\n return {\n name: \"webdriverio (mobile client, v0.3)\",\n status: \"ok\",\n detail: url ?? \"resolved\",\n };\n } catch {\n return {\n name: \"webdriverio (mobile client, v0.3)\",\n status: \"warn\",\n detail:\n \"Not installed — web works fine without it. Mobile is roadmap v0.3. For mobile: npm i webdriverio\",\n };\n }\n}\n\nasync function checkAppiumServer(): Promise<Check> {\n const host = process.env.APPIUM_HOST ?? \"127.0.0.1\";\n const port = Number(process.env.APPIUM_PORT ?? 4723);\n const path = process.env.APPIUM_BASE_PATH ?? \"/\";\n const url = `http://${host}:${port}${path.endsWith(\"/\") ? path : path + \"/\"}status`;\n try {\n const ctrl = new AbortController();\n const timeout = setTimeout(() => ctrl.abort(), 1500);\n const res = await fetch(url, { signal: ctrl.signal });\n clearTimeout(timeout);\n return {\n name: \"Appium server (roadmap v0.3)\",\n status: res.ok ? \"ok\" : \"warn\",\n detail: `${url} → HTTP ${res.status}`,\n };\n } catch {\n return {\n name: \"Appium server (roadmap v0.3)\",\n status: \"warn\",\n detail: `Not reachable at ${url} — mobile sessions need a running Appium daemon. Web sessions are unaffected.`,\n };\n }\n}\n\nfunction checkXcode(): Check {\n const path = \"/Applications/Xcode.app\";\n if (existsSync(path)) {\n return { name: \"Xcode (iOS, roadmap v0.3)\", status: \"ok\", detail: path };\n }\n return {\n name: \"Xcode (iOS, roadmap v0.3)\",\n status: \"warn\",\n detail:\n \"Install Xcode via the App Store; required for iOS simulators. Not needed for web targets.\",\n };\n}\n\nfunction checkAndroidSdk(): Check {\n const candidates = [\n process.env.ANDROID_HOME,\n process.env.ANDROID_SDK_ROOT,\n join(homedir(), \"Library\", \"Android\", \"sdk\"),\n join(homedir(), \"Android\", \"Sdk\"),\n ].filter((x): x is string => typeof x === \"string\");\n for (const path of candidates) {\n if (existsSync(path)) {\n return { name: \"Android SDK (roadmap v0.3)\", status: \"ok\", detail: path };\n }\n }\n return {\n name: \"Android SDK (roadmap v0.3)\",\n status: \"warn\",\n detail:\n \"Set ANDROID_HOME — needed only for Android testing. Not needed for web or iOS targets.\",\n };\n}\n\nfunction checkArtifactDir(): Check {\n const dir = resolve(process.cwd(), \".rolepod-uiproof\");\n // Directory does not need to exist yet; only the parent does.\n return {\n name: \"Artifact root writable\",\n status: \"ok\",\n detail: `Will be created at: ${dir}/artifacts/{run_id}/`,\n };\n}\n\nfunction print(checks: Check[]): void {\n const icon = (s: Check[\"status\"]) => (s === \"ok\" ? \"✓\" : s === \"warn\" ? \"•\" : \"✗\");\n for (const c of checks) {\n // Doctor output is user-facing CLI; stdout is appropriate here\n // because this subcommand never speaks MCP on the same channel.\n process.stdout.write(` ${icon(c.status)} ${c.name.padEnd(30)} ${c.detail}\\n`);\n }\n}\n","import { platform as osPlatform } from \"node:os\";\n\nexport function runInstallMobile(): number {\n const os = osPlatform();\n const lines: string[] = [];\n\n lines.push(\"rolepod-uiproof install:mobile — setup checklist\\n\");\n lines.push(\"Mobile support is OPTIONAL. Skip if you only target the web.\\n\");\n\n lines.push(\"1. Install the Node client:\");\n lines.push(\" npm install webdriverio\\n\");\n\n lines.push(\"2. Install the Appium server (2.x):\");\n lines.push(\" npm install -g appium\");\n lines.push(\" appium driver install xcuitest # iOS\");\n lines.push(\" appium driver install uiautomator2 # Android\");\n lines.push(\" appium # leave running\\n\");\n\n if (os === \"darwin\") {\n lines.push(\"3. iOS — macOS host required:\");\n lines.push(\" • Install Xcode + Command Line Tools\");\n lines.push(\" • Open Xcode → Settings → Platforms → install an iOS Simulator\");\n lines.push(\" • `xcrun simctl list devices` confirms a device is available\\n\");\n } else {\n lines.push(\"3. iOS: not supported on this OS (macOS host required).\\n\");\n }\n\n lines.push(\"4. Android — any host:\");\n lines.push(\" • Install Android Studio OR command-line tools\");\n lines.push(\" • Set ANDROID_HOME to the SDK location\");\n lines.push(\" • `adb devices` confirms an emulator or device is reachable\\n\");\n\n lines.push(\"5. Verify:\");\n lines.push(\" npx rolepod-uiproof doctor\\n\");\n\n lines.push(\"Environment overrides (optional):\");\n lines.push(\" APPIUM_HOST default: 127.0.0.1\");\n lines.push(\" APPIUM_PORT default: 4723\");\n lines.push(\" APPIUM_BASE_PATH default: /\");\n\n for (const l of lines) process.stdout.write(l + \"\\n\");\n return 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { ArtifactStore } from \"../artifact/ArtifactStore.js\";\nimport { createMobileEngine, createWebEngine } from \"../engine/factory.js\";\nimport { SessionRegistry } from \"../session/SessionRegistry.js\";\nimport { verifyUiFlowTool } from \"../tools/composite/verify_ui_flow.js\";\nimport type { ToolContext } from \"../tools/types.js\";\n\n/**\n * `rolepod-uiproof replay <bundle.json>` — re-runs a verify_ui_flow\n * replay bundle deterministically, with no agent in the loop. Exit\n * code 0 = passed, 1 = failed or error.\n */\nexport async function runReplay(bundlePath: string): Promise<number> {\n const abs = resolve(bundlePath);\n const raw = await readFile(abs, \"utf8\");\n const bundle = JSON.parse(raw) as Record<string, unknown>;\n if (bundle.version !== 1) {\n process.stderr.write(`Unsupported replay bundle version: ${bundle.version}\\n`);\n return 1;\n }\n\n const webEngine = createWebEngine();\n const registry = new SessionRegistry({ idleTimeoutMs: 0 });\n registry.register(\"web\", webEngine);\n const mobileEngine = createMobileEngine();\n registry.register(\"ios\", mobileEngine);\n registry.register(\"android\", mobileEngine);\n const store = new ArtifactStore();\n const ctx: ToolContext = { registry, store };\n\n try {\n const handler = verifyUiFlowTool.build(ctx);\n const result = await handler({\n mode: \"assert\",\n open: (bundle.open as Record<string, unknown>) ?? {},\n steps:\n (bundle.steps as Array<{ kind: string }> | undefined) ?? [],\n expect:\n (bundle.expect as Array<{ kind: string }> | undefined) ?? [],\n capture: [\"screenshot\"],\n close_on_finish: true,\n minimize: false,\n } as Parameters<ReturnType<typeof verifyUiFlowTool.build>>[0]);\n const body = result.structuredContent as Record<string, unknown>;\n process.stdout.write(JSON.stringify(body, null, 2) + \"\\n\");\n return body.passed === true ? 0 : 1;\n } finally {\n await registry.shutdown().catch(() => undefined);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { log } from \"../util/log.js\";\nimport { detectRolepodParent } from \"../util/rolepodProtocol.js\";\n\n/**\n * Writes run artifacts. In **standalone** mode (default) — and in v0.4 and\n * earlier — runs live under `./.rolepod-uiproof/artifacts/{prefix}_{ts}_{uuid}/`.\n *\n * In **with-parent** mode — activated automatically when the marker file\n * `<git-root>/.rolepod/parent-active` exists (written by the parent\n * `rolepod` plugin's v2.7+ SessionStart hook) — runs live under\n * `<git-root>/.rolepod/evidence/{ts}-rolepod-uiproof-{skill}/`, per the\n * Extension Protocol v1 evidence-path convention. Parent's `check-work`\n * skill aggregates manifest.json files from this directory.\n *\n * Note: with-parent runs anchor at the git root (resolved via\n * `git rev-parse --show-toplevel`), so a uiproof skill invoked from a\n * subdirectory still lands under the worktree root where `check-work`\n * looks. Standalone runs stay anchored at `process.cwd()` — same as\n * pre-v0.6 behavior.\n *\n * Baselines for `visual_diff` always live in `./.rolepod-uiproof/baselines/`\n * regardless of mode — they are user-curated configuration, not per-run\n * evidence.\n */\nexport type ReplayStep = Record<string, unknown>;\n\nexport type ReplayBundle = {\n version: 1;\n run_id: string;\n recorded_at: string;\n open: Record<string, unknown>;\n steps: ReplayStep[];\n expect: ReplayStep[];\n};\n\nexport type ArtifactPaths = {\n screenshots: string[];\n replay_bundle?: string;\n};\n\nexport type ArtifactMode = \"standalone\" | \"with-parent\";\n\nexport type StartRunOptions = {\n /**\n * Skill name as it appears in marketplace (`verify-ui`, `audit-a11y`,\n * `visual-diff`, `scaffold-e2e`, `check-errors`). REQUIRED when emitting\n * a manifest.json (Extension Protocol v1) so parent's `check-work` can\n * route artifacts to the right phase.\n *\n * In `with-parent` mode the run dirname is derived from this field; if\n * omitted the `prefix` argument is used as a fallback (legacy).\n */\n skill?: string;\n};\n\nexport type StartRunResult = {\n runId: string;\n runDir: string;\n skill: string;\n mode: ArtifactMode;\n};\n\nexport class ArtifactStore {\n readonly rootDir: string;\n readonly mode: ArtifactMode;\n private readonly baselineRoot: string;\n\n constructor(\n opts: { rootDir?: string; mode?: ArtifactMode } = {},\n ) {\n const parent = detectRolepodParent();\n this.mode = opts.mode ?? (parent.active ? \"with-parent\" : \"standalone\");\n\n if (opts.rootDir !== undefined) {\n this.rootDir = opts.rootDir;\n } else if (this.mode === \"with-parent\") {\n // Anchor evidence at git root so `check-work` finds it regardless of\n // which subdirectory the skill was invoked from.\n this.rootDir = resolve(parent.gitRoot, \".rolepod\", \"evidence\");\n } else {\n this.rootDir = resolve(process.cwd(), \".rolepod-uiproof\", \"artifacts\");\n }\n\n // Baselines are config, not evidence — always live in the standalone\n // location so visual_diff sees the same set across modes.\n this.baselineRoot = resolve(process.cwd(), \".rolepod-uiproof\", \"baselines\");\n }\n\n /**\n * Allocate a fresh run dir and ensure it exists.\n *\n * - standalone: `./.rolepod-uiproof/artifacts/{prefix}_{ts}_{uuid}/`\n * - with-parent: `<git-root>/.rolepod/evidence/{ts}-rolepod-uiproof-{skill}/`\n *\n * `prefix` is preserved for back-compat with v0.5 callers; new callers\n * should also pass `opts.skill` so the with-parent path can be derived\n * unambiguously and the manifest can be emitted with the canonical\n * skill name.\n */\n async startRun(\n prefix = \"run\",\n opts: StartRunOptions = {},\n ): Promise<StartRunResult> {\n const ts = this.timestampSlug();\n const skill = opts.skill ?? prefix;\n\n let runId: string;\n if (this.mode === \"with-parent\") {\n // Parent expects a flat, sortable dirname. Append a short uuid only\n // when two runs of the same skill could collide within one second.\n runId = `${ts}-rolepod-uiproof-${skill}`;\n } else {\n runId = `${prefix}_${ts}_${randomUUID().slice(0, 8)}`;\n }\n\n const runDir = resolve(this.rootDir, runId);\n await mkdir(runDir, { recursive: true });\n log.debug(\"artifact run started\", {\n run_id: runId,\n dir: runDir,\n mode: this.mode,\n skill,\n });\n return { runId, runDir, skill, mode: this.mode };\n }\n\n async writeScreenshot(\n runDir: string,\n buf: Buffer,\n name: string,\n ): Promise<string> {\n const path = resolve(runDir, `${name}.png`);\n await writeFile(path, buf);\n return path;\n }\n\n async writeReplayBundle(\n runDir: string,\n bundle: ReplayBundle,\n name = \"replay.json\",\n ): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, JSON.stringify(bundle, null, 2), \"utf8\");\n return path;\n }\n\n async writeReport(runDir: string, name: string, body: string): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, body, \"utf8\");\n return path;\n }\n\n async writeBytes(runDir: string, name: string, buf: Buffer): Promise<string> {\n const path = resolve(runDir, name);\n await writeFile(path, buf);\n return path;\n }\n\n async ensureDir(absDir: string): Promise<string> {\n await mkdir(absDir, { recursive: true });\n return absDir;\n }\n\n /** Root for stored visual baselines: `./.rolepod-uiproof/baselines/`. */\n get baselineDir(): string {\n return this.baselineRoot;\n }\n\n private timestampSlug(): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return (\n `${d.getUTCFullYear()}` +\n pad(d.getUTCMonth() + 1) +\n pad(d.getUTCDate()) +\n \"T\" +\n pad(d.getUTCHours()) +\n pad(d.getUTCMinutes()) +\n pad(d.getUTCSeconds())\n );\n }\n}\n","/**\n * Stdio MCP servers MUST NOT write logs to stdout — stdout carries\n * JSON-RPC. All diagnostic output goes to stderr.\n *\n * Reference: MCP TypeScript SDK README, \"Logging on stdio servers\".\n */\n\nfunction emit(level: \"info\" | \"warn\" | \"error\" | \"debug\", msg: string, extra?: unknown): void {\n const line = JSON.stringify({\n ts: new Date().toISOString(),\n level,\n msg,\n ...(extra !== undefined ? { extra } : {}),\n });\n process.stderr.write(line + \"\\n\");\n}\n\nexport const log = {\n info: (msg: string, extra?: unknown) => emit(\"info\", msg, extra),\n warn: (msg: string, extra?: unknown) => emit(\"warn\", msg, extra),\n error: (msg: string, extra?: unknown) => emit(\"error\", msg, extra),\n debug: (msg: string, extra?: unknown) => {\n if (process.env.ROLEPOD_MCP_DEBUG) emit(\"debug\", msg, extra);\n },\n};\n","import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Extension Protocol — detection of the parent `rolepod` plugin.\n *\n * # Why a marker file (and not an env var)\n *\n * v0.6.0 attempted to detect the parent via `process.env.ROLEPOD_PARENT === \"1\"`.\n * That mechanism does not work in Claude Code: the SessionStart hook runs in\n * its own subprocess, and the env vars it sets do not propagate to the Bash\n * tool or to the MCP server subprocess Claude later spawns. So the env was\n * never visible to uiproof, and combined mode never activated.\n *\n * v0.6.1 switches to a filesystem marker that the parent `rolepod` plugin's\n * SessionStart hook writes:\n *\n * <git-root>/.rolepod/parent-active\n *\n * Content (UTF-8, single trimmed line): the protocol version string. v1 ships\n * `\"v1\"`. The marker is removed by the parent's Stop hook when no other\n * rolepod sessions hold locks on the same worktree.\n *\n * Detection is read-on-demand by callers — there is no caching. The marker\n * file existsSync check is sub-millisecond and runs at most twice per server\n * boot today (ArtifactStore constructor + checkProtocolCompat).\n */\nexport interface ParentState {\n /** True iff the marker file exists. */\n active: boolean;\n /** First trimmed line of the marker (the protocol version), or null. */\n protocol: string | null;\n /** Resolved git root (or `cwd` fallback when not in a git work tree). */\n gitRoot: string;\n}\n\nexport function detectRolepodParent(cwd: string = process.cwd()): ParentState {\n let gitRoot = cwd;\n try {\n gitRoot = execSync(\"git rev-parse --show-toplevel\", {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {\n // non-git project — keep cwd. The marker can't exist outside a repo\n // anyway, so this fallback is purely defensive.\n }\n\n const file = join(gitRoot, \".rolepod\", \"parent-active\");\n if (!existsSync(file)) {\n return { active: false, protocol: null, gitRoot };\n }\n\n const protocol = readFileSync(file, \"utf8\").trim().split(/\\r?\\n/)[0] ?? null;\n return { active: true, protocol, gitRoot };\n}\n\n/**\n * Manual-override hint for documentation only — implementation does not call\n * this. Users can force combined mode without a real parent session by\n * touching the marker file:\n *\n * mkdir -p .rolepod && echo v1 > .rolepod/parent-active\n *\n * And force back to standalone with:\n *\n * rm -f .rolepod/parent-active\n */\nexport const MARKER_RELPATH = \".rolepod/parent-active\" as const;\n","/**\n * Structured error types surfaced to MCP clients. Each carries enough\n * context for the Lead agent to recover (typically: re-snapshot, then retry).\n *\n * Snapshot freshness rule: any state-changing call invalidates the current\n * ref index; a stale ref returns `stale_ref` with the last valid snapshot\n * timestamp so the Lead can re-snapshot and retry.\n */\n\nexport type ErrorCode =\n | \"stale_ref\"\n | \"unknown_ref\"\n | \"unknown_session\"\n | \"unsupported_platform\"\n | \"unsupported_engine\"\n | \"not_implemented_in_v01\"\n | \"not_implemented_in_v02\"\n | \"invalid_input\"\n | \"engine_error\";\n\nexport class RolepodMcpError extends Error {\n override readonly name = \"RolepodMcpError\";\n constructor(\n readonly code: ErrorCode,\n message: string,\n readonly detail?: Record<string, unknown>,\n ) {\n super(message);\n }\n\n toJSON(): { code: ErrorCode; message: string; detail?: Record<string, unknown> } {\n return {\n code: this.code,\n message: this.message,\n ...(this.detail ? { detail: this.detail } : {}),\n };\n }\n}\n\nexport class StaleRefError extends RolepodMcpError {\n constructor(sessionId: string, ref: string, lastValidSnapshotAt: string | null) {\n super(\"stale_ref\", `Ref \"${ref}\" is stale — re-snapshot before retrying.`, {\n session_id: sessionId,\n ref,\n last_valid_snapshot_at: lastValidSnapshotAt,\n });\n }\n}\n\nexport class UnknownRefError extends RolepodMcpError {\n constructor(sessionId: string, ref: string) {\n super(\"unknown_ref\", `Ref \"${ref}\" was not found in the current snapshot.`, {\n session_id: sessionId,\n ref,\n });\n }\n}\n\nexport class UnknownSessionError extends RolepodMcpError {\n constructor(sessionId: string) {\n super(\"unknown_session\", `No open session with id \"${sessionId}\".`, {\n session_id: sessionId,\n });\n }\n}\n\nexport class UnsupportedPlatformError extends RolepodMcpError {\n constructor(platform: string) {\n super(\n \"unsupported_platform\",\n `Platform \"${platform}\" is not supported in v0.1 — only \"web\" is implemented. Mobile (ios/android) ships in v0.3.`,\n { platform },\n );\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n RolepodMcpError,\n UnknownRefError,\n UnknownSessionError,\n UnsupportedPlatformError,\n} from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport {\n parseUiAutomator2Tree,\n type AndroidRefMeta,\n} from \"./a11y/uiautomator2.js\";\nimport { parseXcuiTestTree, type IosRefMeta } from \"./a11y/xcuitest.js\";\nimport type {\n A11ySnapshot,\n Direction,\n Engine,\n OpenOptions,\n Platform,\n Session,\n WaitCondition,\n} from \"./Engine.js\";\n\ntype MobileRefMeta = IosRefMeta | AndroidRefMeta;\n\n/**\n * Minimal subset of the webdriverio `Browser` surface that AppiumEngine\n * relies on. We type only what we use so that consumers without\n * `webdriverio` installed still typecheck.\n */\ntype WdioElement = {\n click(): Promise<void>;\n clearValue(): Promise<void>;\n setValue(value: string): Promise<void>;\n isEnabled(): Promise<boolean>;\n};\n\ntype WdioBrowser = {\n sessionId: string;\n capabilities: Record<string, unknown>;\n getPageSource(): Promise<string>;\n saveScreenshot(filepath?: string): Promise<Buffer>;\n takeScreenshot(): Promise<string>; // base64\n pressKeyCode?: (code: number) => Promise<void>;\n $(selector: string): Promise<WdioElement> & WdioElement;\n execute<T = unknown>(script: string, ...args: unknown[]): Promise<T>;\n deleteSession(): Promise<void>;\n pause(ms: number): Promise<void>;\n};\n\ntype WdioRemote = (\n opts: Record<string, unknown>,\n) => Promise<WdioBrowser>;\n\ntype MobileSession = {\n readonly id: string;\n readonly platform: \"ios\" | \"android\";\n readonly driver: WdioBrowser;\n};\n\ntype SessionInternals = {\n session: MobileSession;\n refIndex: Map<string, MobileRefMeta>;\n snapshotGeneration: number;\n refGeneration: number;\n lastSnapshotAt: string | null;\n};\n\n/**\n * AppiumEngine — v0.3 mobile support via Appium 2.x + webdriverio.\n *\n * webdriverio is an `optionalDependency` (brief D-020). The engine\n * lazy-imports it; if missing, every public method throws a structured\n * `engine_error` with installation guidance.\n *\n * Smoke tests run against a real simulator only when one is reachable;\n * unit tests for AT normalization use fixture XML strings (see\n * `tests/unit/`).\n */\nexport class AppiumEngine implements Engine {\n readonly id = \"appium\" as const;\n\n private readonly sessions = new Map<string, SessionInternals>();\n private wdioCache: WdioRemote | null = null;\n\n async open(opts: OpenOptions): Promise<Session> {\n if (opts.platform !== \"ios\" && opts.platform !== \"android\") {\n throw new UnsupportedPlatformError(opts.platform);\n }\n const remote = await this.loadWdio();\n const caps = this.buildCapabilities(opts);\n const driver = await remote({\n hostname: process.env.APPIUM_HOST ?? \"127.0.0.1\",\n port: Number(process.env.APPIUM_PORT ?? 4723),\n path: process.env.APPIUM_BASE_PATH ?? \"/\",\n capabilities: caps,\n });\n\n const sessionId = randomUUID();\n const session: MobileSession = { id: sessionId, platform: opts.platform, driver };\n this.sessions.set(sessionId, {\n session,\n refIndex: new Map(),\n snapshotGeneration: 0,\n refGeneration: -1,\n lastSnapshotAt: null,\n });\n log.info(\"mobile session opened\", {\n session_id: sessionId,\n platform: opts.platform,\n remote_session: driver.sessionId,\n });\n return { id: sessionId, platform: opts.platform };\n }\n\n async close(session: Session): Promise<void> {\n const s = this.requireSession(session.id);\n await s.session.driver.deleteSession().catch((err: unknown) =>\n log.warn(\"appium deleteSession failed\", { session_id: session.id, err: String(err) }),\n );\n this.sessions.delete(session.id);\n log.info(\"mobile session closed\", { session_id: session.id });\n }\n\n async snapshot(session: Session, _mode?: \"visible\" | \"full\"): Promise<A11ySnapshot> {\n void _mode;\n const s = this.requireSession(session.id);\n const xml = await s.session.driver.getPageSource();\n const normalized =\n s.session.platform === \"ios\"\n ? parseXcuiTestTree(xml)\n : parseUiAutomator2Tree(xml);\n\n s.snapshotGeneration += 1;\n s.refGeneration = s.snapshotGeneration;\n s.refIndex = normalized.refIndex as Map<string, MobileRefMeta>;\n s.lastSnapshotAt = new Date().toISOString();\n\n return {\n session_id: session.id,\n platform: s.session.platform,\n url_or_screen: this.screenIdentifier(s),\n taken_at: s.lastSnapshotAt,\n tree: normalized.tree,\n };\n }\n\n async click(session: Session, ref: string): Promise<void> {\n const s = this.requireSession(session.id);\n const el = await this.resolveElement(s, ref);\n await el.click();\n this.invalidateRefs(s);\n }\n\n async type(\n session: Session,\n ref: string,\n text: string,\n opts?: { clearFirst?: boolean },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const el = await this.resolveElement(s, ref);\n if (opts?.clearFirst) await el.clearValue();\n await el.setValue(text);\n this.invalidateRefs(s);\n }\n\n async key(session: Session, key: string): Promise<void> {\n const s = this.requireSession(session.id);\n if (s.session.platform === \"android\" && s.session.driver.pressKeyCode) {\n const code = ANDROID_KEY_CODES[key];\n if (code !== undefined) {\n await s.session.driver.pressKeyCode(code);\n this.invalidateRefs(s);\n return;\n }\n }\n throw new RolepodMcpError(\n \"not_implemented_in_v02\",\n `Mobile key(\"${key}\") is partially supported in v0.3 — only well-known Android keycodes are mapped. iOS hardware keys land later.`,\n { platform: s.session.platform, key },\n );\n }\n\n async scroll(\n session: Session,\n dir: Direction,\n amount = 400,\n _ref?: string,\n ): Promise<void> {\n void _ref;\n const s = this.requireSession(session.id);\n // Mobile scroll is fiddly across drivers — fall back to a touch\n // gesture via execute(). Most consumers will prefer a `wait_for`\n // followed by a `click` on a ref that scrolls into view.\n const action =\n s.session.platform === \"ios\"\n ? \"mobile: swipe\"\n : \"mobile: scrollGesture\";\n const params =\n s.session.platform === \"ios\"\n ? { direction: dir }\n : { left: 100, top: 200, width: 400, height: 600, direction: dir, percent: amount / 1000 };\n await s.session.driver\n .execute(action, params)\n .catch((err: unknown) => log.warn(\"scroll gesture failed\", { err: String(err) }));\n this.invalidateRefs(s);\n }\n\n async waitFor(\n session: Session,\n cond: WaitCondition,\n timeoutMs = 10_000,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (cond.kind === \"idle\") {\n await s.session.driver.pause(cond.ms);\n this.invalidateRefs(s);\n return;\n }\n const snap = await this.snapshot(session);\n const matched =\n cond.kind === \"text_visible\"\n ? treeIncludesText(snap.tree, cond.text)\n : cond.kind === \"ref_exists\"\n ? treeIncludesText(snap.tree, cond.query)\n : false;\n if (matched) return;\n await s.session.driver.pause(250);\n }\n throw new RolepodMcpError(\n \"engine_error\",\n `wait_for ${cond.kind} timed out after ${timeoutMs}ms`,\n { condition: cond, timeout_ms: timeoutMs },\n );\n }\n\n async screenshot(session: Session, _fullPage?: boolean): Promise<Buffer> {\n void _fullPage;\n const s = this.requireSession(session.id);\n const b64 = await s.session.driver.takeScreenshot();\n return Buffer.from(b64, \"base64\");\n }\n\n async navigate(_session: Session, _url: string): Promise<void> {\n throw new UnsupportedPlatformError(_session.platform);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 cross-platform additions — mobile stubs.\n // These ship as `not_implemented_in_v05` until the mobile gesture work lands.\n // -------------------------------------------------------------------------\n\n async hover(_session: Session, _ref: string): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"hover is not yet implemented for mobile (Appium). Use long-press via custom gesture if needed.\",\n );\n }\n\n async drag(_session: Session, _fromRef: string, _toRef: string): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"drag is not yet implemented for mobile (Appium). Use the W3C Actions API directly if needed.\",\n );\n }\n\n async fillForm(\n session: Session,\n fields: { ref: string; value: string | boolean; kind?: string }[],\n ): Promise<void> {\n // Naive port: iterate type() per field. select/checkbox/radio not\n // applicable in native mobile in the same way; treat all as text input.\n for (const f of fields) {\n const v = typeof f.value === \"boolean\" ? String(f.value) : f.value;\n await this.type(session, f.ref, v);\n }\n }\n\n async uploadFile(\n _session: Session,\n _ref: string,\n _filePath: string,\n ): Promise<void> {\n throw new RolepodMcpError(\n \"engine_error\",\n \"upload_file is not supported on mobile (Appium).\",\n );\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n private async loadWdio(): Promise<WdioRemote> {\n if (this.wdioCache) return this.wdioCache;\n try {\n // Avoid TypeScript pulling the (optional) module into static types.\n const mod = (await import(/* @vite-ignore */ \"webdriverio\")) as unknown as {\n remote: WdioRemote;\n };\n this.wdioCache = mod.remote;\n return mod.remote;\n } catch {\n throw new RolepodMcpError(\n \"engine_error\",\n \"Mobile support needs webdriverio (and a running Appium server). Run `npx rolepod-uiproof install:mobile` for the setup checklist.\",\n );\n }\n }\n\n private buildCapabilities(opts: OpenOptions): Record<string, unknown> {\n const caps: Record<string, unknown> = {};\n if (opts.platform === \"ios\") {\n caps.platformName = \"iOS\";\n caps[\"appium:automationName\"] = \"XCUITest\";\n if (opts.device) caps[\"appium:deviceName\"] = opts.device;\n if (opts.bundle_id) caps[\"appium:bundleId\"] = opts.bundle_id;\n } else {\n caps.platformName = \"Android\";\n caps[\"appium:automationName\"] = \"UiAutomator2\";\n if (opts.emulator) caps[\"appium:avd\"] = opts.emulator;\n if (opts.app_package) caps[\"appium:appPackage\"] = opts.app_package;\n if (opts.app_activity) caps[\"appium:appActivity\"] = opts.app_activity;\n }\n if (opts.locale) caps[\"appium:language\"] = opts.locale;\n return caps;\n }\n\n private screenIdentifier(s: SessionInternals): string {\n const caps = s.session.driver.capabilities as Record<string, unknown>;\n return String(\n caps[\"appium:bundleId\"] ??\n caps[\"appium:appPackage\"] ??\n caps.platformName ??\n s.session.platform,\n );\n }\n\n private requireSession(sessionId: string): SessionInternals {\n const s = this.sessions.get(sessionId);\n if (!s) throw new UnknownSessionError(sessionId);\n return s;\n }\n\n private async resolveElement(s: SessionInternals, ref: string): Promise<WdioElement> {\n if (s.refGeneration !== s.snapshotGeneration) {\n throw new RolepodMcpError(\n \"stale_ref\",\n `Ref \"${ref}\" is stale — re-snapshot before retrying.`,\n {\n session_id: s.session.id,\n ref,\n last_valid_snapshot_at: s.lastSnapshotAt,\n },\n );\n }\n const meta = s.refIndex.get(ref);\n if (!meta) throw new UnknownRefError(s.session.id, ref);\n const selector = this.toSelector(meta);\n return s.session.driver.$(selector);\n }\n\n private toSelector(meta: MobileRefMeta): string {\n if (meta.kind === \"ios\") {\n if (meta.accessibilityId) return `~${meta.accessibilityId}`;\n const chain = `**/${meta.type}[${meta.classChainIndex}]`;\n return `-ios class chain:${chain}`;\n }\n if (meta.resourceId) {\n return `-android uiautomator:new UiSelector().resourceId(\"${escape(meta.resourceId)}\")`;\n }\n if (meta.contentDesc) return `~${meta.contentDesc}`;\n if (meta.text) {\n return `-android uiautomator:new UiSelector().text(\"${escape(meta.text)}\")`;\n }\n return `-android uiautomator:new UiSelector().className(\"${meta.androidClass}\").instance(${meta.classIndex - 1})`;\n }\n\n private invalidateRefs(s: SessionInternals): void {\n s.snapshotGeneration += 1;\n }\n}\n\nconst ANDROID_KEY_CODES: Record<string, number> = {\n Enter: 66,\n Tab: 61,\n Escape: 111,\n Back: 4,\n Home: 3,\n Menu: 82,\n Search: 84,\n Backspace: 67,\n ArrowUp: 19,\n ArrowDown: 20,\n ArrowLeft: 21,\n ArrowRight: 22,\n};\n\nfunction escape(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction treeIncludesText(node: { name?: string; value?: string; children?: unknown[] }, text: string): boolean {\n const target = text.toLowerCase();\n const visit = (n: { name?: string; value?: string; children?: unknown[] }): boolean => {\n if ((n.name && n.name.toLowerCase().includes(target)) ||\n (n.value && n.value.toLowerCase().includes(target))) return true;\n if (!n.children) return false;\n for (const c of n.children as Array<{ name?: string; value?: string; children?: unknown[] }>) {\n if (visit(c)) return true;\n }\n return false;\n };\n return visit(node);\n}\n\n// Helper so we don't accidentally export this typo'd internal name.\nfunction _platformGuard(p: Platform): void {\n void p;\n}\nvoid _platformGuard;\n","/**\n * UIAutomator2 (Android via Appium) accessibility-tree normalizer.\n *\n * Parses the Appium XML page source returned by\n * `driver.getPageSource()`. UIAutomator2 markup is rooted at\n * `<hierarchy>` and uses Android class names as tag names\n * (e.g. `android.widget.Button`), with attributes such as\n * `resource-id`, `content-desc`, `text`, `bounds`, `enabled`, etc.\n *\n * Inspired by alumnium-hq/alumnium's UIAutomator2AccessibilityTree\n * (MIT) — see UPSTREAM_TRACKING.md. Original implementation; no\n * verbatim copy.\n */\nimport { XMLParser } from \"fast-xml-parser\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\nexport type AndroidRefMeta = {\n kind: \"android\";\n resourceId?: string;\n contentDesc?: string;\n text?: string;\n androidClass: string;\n /** 1-based index among siblings of the same android class. */\n classIndex: number;\n};\n\nexport type AndroidNormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, AndroidRefMeta>;\n};\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n alwaysCreateTextNode: false,\n preserveOrder: true,\n});\n\ntype RawNode = Record<string, RawNode[] | undefined> & { \":@\"?: Record<string, string> };\n\nexport function parseUiAutomator2Tree(xmlString: string): AndroidNormalizedSnapshot {\n const refIndex = new Map<string, AndroidRefMeta>();\n let counter = 0;\n const nextRef = (): string => `e${++counter}`;\n\n let raw: RawNode[] = [];\n try {\n raw = parser.parse(xmlString) as RawNode[];\n } catch {\n raw = [];\n }\n\n const visit = (node: RawNode, siblingOcc: Map<string, number>): A11yNode | null => {\n const tagName = firstTagName(node);\n if (!tagName) return null;\n const attrs = node[\":@\"] ?? {};\n const childrenRaw = (node[tagName] as RawNode[]) ?? [];\n\n const idx = (siblingOcc.get(tagName) ?? 0) + 1;\n siblingOcc.set(tagName, idx);\n\n const ref = nextRef();\n refIndex.set(ref, {\n kind: \"android\",\n resourceId: attrs[\"@resource-id\"],\n contentDesc: attrs[\"@content-desc\"],\n text: attrs[\"@text\"],\n androidClass: tagName,\n classIndex: idx,\n });\n\n const role = simplifyAndroidClass(tagName);\n\n const a11y: A11yNode = { ref, role };\n const name = attrs[\"@content-desc\"] ?? attrs[\"@text\"];\n if (name) a11y.name = name;\n if (attrs[\"@text\"] && attrs[\"@text\"] !== name) a11y.value = attrs[\"@text\"];\n\n const state: A11yNode[\"state\"] = {};\n if (attrs[\"@enabled\"] === \"false\") state.disabled = true;\n if (attrs[\"@focused\"] === \"true\") state.focused = true;\n if (attrs[\"@selected\"] === \"true\") state.selected = true;\n if (Object.keys(state).length > 0) a11y.state = state;\n\n if (childrenRaw.length > 0) {\n const siblings = new Map<string, number>();\n const children: A11yNode[] = [];\n for (const child of childrenRaw) {\n const built = visit(child, siblings);\n if (built) children.push(built);\n }\n if (children.length > 0) a11y.children = children;\n }\n return a11y;\n };\n\n const hierarchy =\n raw.find((n) => Object.keys(n).some((k) => k === \"hierarchy\")) ?? raw[0];\n if (!hierarchy) {\n return {\n tree: { ref: \"e0\", role: \"RootWebArea\" },\n refIndex,\n };\n }\n const top = visit(hierarchy, new Map());\n if (top) return { tree: top, refIndex };\n return { tree: { ref: \"e0\", role: \"RootWebArea\" }, refIndex };\n}\n\nfunction firstTagName(node: RawNode): string | null {\n for (const key of Object.keys(node)) {\n if (key === \":@\") continue;\n // skip XML declarations (`<?xml ... ?>`) and processing instructions\n if (key.startsWith(\"?\")) continue;\n return key;\n }\n return null;\n}\n\n/** Map `android.widget.Button` → `Button`, fall back to the full class. */\nfunction simplifyAndroidClass(cls: string): string {\n const last = cls.split(\".\").pop();\n return last ?? cls;\n}\n","/**\n * XCUITest (iOS via Appium) accessibility-tree normalizer.\n *\n * Parses the Appium XML page source returned by\n * `driver.getPageSource()` and produces a unified `A11yNode` tree plus\n * a `refIndex` whose entries carry enough information for the engine to\n * resolve `ref → element` later (via accessibility id, name, or class\n * chain).\n *\n * Inspired by alumnium-hq/alumnium's XCUITestAccessibilityTree (MIT) —\n * see UPSTREAM_TRACKING.md. Original implementation; no verbatim copy.\n */\nimport { XMLParser } from \"fast-xml-parser\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\nexport type IosRefMeta = {\n kind: \"ios\";\n /** Accessibility id when present — primary locator. */\n accessibilityId?: string;\n name?: string;\n label?: string;\n type: string;\n /** 1-based class-chain index among siblings of the same `type`. */\n classChainIndex: number;\n};\n\nexport type IosNormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, IosRefMeta>;\n};\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n alwaysCreateTextNode: false,\n preserveOrder: true,\n});\n\ntype RawNode = Record<string, RawNode[] | undefined> & { \":@\"?: Record<string, string> };\n\nexport function parseXcuiTestTree(xmlString: string): IosNormalizedSnapshot {\n const refIndex = new Map<string, IosRefMeta>();\n let counter = 0;\n const nextRef = (): string => `e${++counter}`;\n\n let raw: RawNode[] = [];\n try {\n raw = parser.parse(xmlString) as RawNode[];\n } catch {\n raw = [];\n }\n\n const visit = (node: RawNode, classChainOcc: Map<string, number>): A11yNode | null => {\n const tagName = firstTagName(node);\n if (!tagName) return null;\n const attrs = node[\":@\"] ?? {};\n const childrenRaw = (node[tagName] as RawNode[]) ?? [];\n\n const idx = (classChainOcc.get(tagName) ?? 0) + 1;\n classChainOcc.set(tagName, idx);\n\n const ref = nextRef();\n refIndex.set(ref, {\n kind: \"ios\",\n accessibilityId: attrs[\"@name\"],\n name: attrs[\"@name\"],\n label: attrs[\"@label\"],\n type: tagName,\n classChainIndex: idx,\n });\n\n const role = tagName.startsWith(\"XCUIElementType\")\n ? tagName.slice(\"XCUIElementType\".length).toLowerCase()\n : tagName;\n\n const a11y: A11yNode = { ref, role };\n const name = attrs[\"@label\"] ?? attrs[\"@name\"];\n if (name) a11y.name = name;\n if (attrs[\"@value\"]) a11y.value = attrs[\"@value\"];\n\n const state: A11yNode[\"state\"] = {};\n if (attrs[\"@enabled\"] === \"false\") state.disabled = true;\n if (attrs[\"@selected\"] === \"true\") state.selected = true;\n if (Object.keys(state).length > 0) a11y.state = state;\n\n if (childrenRaw.length > 0) {\n const siblings = new Map<string, number>();\n const children: A11yNode[] = [];\n for (const child of childrenRaw) {\n const built = visit(child, siblings);\n if (built) children.push(built);\n }\n if (children.length > 0) a11y.children = children;\n }\n return a11y;\n };\n\n const topLevel: A11yNode[] = [];\n const rootOcc = new Map<string, number>();\n for (const node of raw) {\n const built = visit(node, rootOcc);\n if (built) topLevel.push(built);\n }\n\n if (topLevel.length === 1) {\n return { tree: topLevel[0]!, refIndex };\n }\n const rootRef = nextRef();\n refIndex.set(rootRef, {\n kind: \"ios\",\n type: \"XCUIElementTypeApplication\",\n classChainIndex: 1,\n });\n const root: A11yNode = { ref: rootRef, role: \"application\" };\n if (topLevel.length > 0) root.children = topLevel;\n return { tree: root, refIndex };\n}\n\nfunction firstTagName(node: RawNode): string | null {\n for (const key of Object.keys(node)) {\n if (key === \":@\") continue;\n // skip XML declarations (`<?xml ... ?>`) and processing instructions\n if (key.startsWith(\"?\")) continue;\n return key;\n }\n return null;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { resolve as resolvePath, isAbsolute } from \"node:path\";\nimport {\n chromium,\n firefox,\n webkit,\n type Browser,\n type BrowserContext,\n type Page,\n type Locator,\n type ConsoleMessage,\n type Request,\n type Response,\n type Dialog,\n} from \"playwright\";\nimport {\n RolepodMcpError,\n UnknownRefError,\n UnsupportedPlatformError,\n} from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport {\n parseAriaSnapshot,\n type RefMeta,\n} from \"./a11y/normalize.js\";\nimport type {\n A11ySnapshot,\n Direction,\n Engine,\n FillField,\n OpenOptions,\n Session,\n WaitCondition,\n} from \"./Engine.js\";\n\ntype WebSession = Session & {\n readonly platform: \"web\";\n readonly browser: Browser;\n readonly context: BrowserContext;\n /** Main (initial) page. Subsequent popups land in SessionInternals.pages. */\n readonly mainPage: Page;\n};\n\nexport type ConsoleEntry = {\n level: \"error\" | \"warning\" | \"info\" | \"log\" | \"debug\" | \"trace\";\n text: string;\n ts: string;\n /** Best-effort file:line if Playwright provides it. */\n location?: string;\n};\n\nexport type NetworkEntry = {\n id: number;\n url: string;\n method: string;\n status?: number;\n failure?: string;\n resource_type: string;\n ts: string;\n duration_ms?: number;\n};\n\ntype DialogArming = {\n action: \"accept\" | \"dismiss\" | \"accept_with_text\";\n text?: string;\n expiresAt: number;\n resolve: (handled: boolean) => void;\n};\n\ntype SessionInternals = {\n session: WebSession;\n refIndex: Map<string, RefMeta>;\n snapshotGeneration: number;\n refGeneration: number;\n lastSnapshotAt: string | null;\n\n // v0.5 additions\n pages: Page[];\n activePageIndex: number;\n consoleBuffer: ConsoleEntry[];\n networkBuffer: NetworkEntry[];\n networkInflight: Map<string, { id: number; startedAt: number; resourceType: string }>;\n networkNextId: number;\n dialogArming: DialogArming | null;\n captureOpts: NonNullable<OpenOptions[\"capture\"]> | undefined;\n traceStarted: boolean;\n};\n\nconst CONSOLE_BUFFER_CAP = 1000;\nconst NETWORK_BUFFER_CAP = 1000;\n\n// CDP network condition presets. Numbers match Chrome DevTools UI exactly.\nconst NETWORK_PRESETS = {\n offline: { offline: true, downloadThroughput: 0, uploadThroughput: 0, latency: 0 },\n \"slow-3g\": {\n offline: false,\n // 500 Kbps down / 500 Kbps up / 400ms RTT\n downloadThroughput: (500 * 1024) / 8,\n uploadThroughput: (500 * 1024) / 8,\n latency: 400,\n },\n \"fast-3g\": {\n offline: false,\n downloadThroughput: (1.5 * 1024 * 1024) / 8,\n uploadThroughput: (750 * 1024) / 8,\n latency: 150,\n },\n \"slow-4g\": {\n offline: false,\n downloadThroughput: (4 * 1024 * 1024) / 8,\n uploadThroughput: (3 * 1024 * 1024) / 8,\n latency: 100,\n },\n \"fast-4g\": {\n offline: false,\n downloadThroughput: (9 * 1024 * 1024) / 8,\n uploadThroughput: (4.5 * 1024 * 1024) / 8,\n latency: 60,\n },\n \"no-throttling\": {\n offline: false,\n downloadThroughput: -1,\n uploadThroughput: -1,\n latency: 0,\n },\n} as const;\n\nfunction pushRing<T>(buf: T[], entry: T, cap: number): void {\n buf.push(entry);\n if (buf.length > cap) buf.splice(0, buf.length - cap);\n}\n\nfunction mapConsoleLevel(t: string): ConsoleEntry[\"level\"] {\n switch (t) {\n case \"error\":\n return \"error\";\n case \"warning\":\n return \"warning\";\n case \"info\":\n return \"info\";\n case \"debug\":\n return \"debug\";\n case \"trace\":\n return \"trace\";\n default:\n return \"log\";\n }\n}\n\nfunction formatConsoleLocation(msg: ConsoleMessage): string | undefined {\n try {\n const loc = msg.location();\n if (!loc?.url) return undefined;\n return `${loc.url}:${loc.lineNumber}:${loc.columnNumber}`;\n } catch {\n return undefined;\n }\n}\n\nfunction findNetworkEntry(\n buf: NetworkEntry[],\n req: Request,\n): NetworkEntry | undefined {\n // Walk back-to-front — most recent match wins (handles redirects /\n // duplicate URLs with separate ids).\n const url = req.url();\n const method = req.method();\n for (let i = buf.length - 1; i >= 0; i--) {\n const e = buf[i];\n if (!e) continue;\n if (e.url === url && e.method === method && e.status === undefined && !e.failure) {\n return e;\n }\n }\n return undefined;\n}\n\n/**\n * PlaywrightEngine — v0.1 web-only implementation backed by Playwright's\n * Chromium / Firefox / WebKit drivers and the built-in\n * `page.accessibility.snapshot()` API.\n *\n * The interface contract (Engine.ts) is shared with AppiumEngine and the\n * optional SeleniumEngine.\n */\nexport class PlaywrightEngine implements Engine {\n readonly id = \"playwright\" as const;\n\n private readonly sessions = new Map<string, SessionInternals>();\n\n async open(opts: OpenOptions): Promise<Session> {\n if (opts.platform !== \"web\") {\n throw new UnsupportedPlatformError(opts.platform);\n }\n\n const browserName = opts.browser ?? \"chromium\";\n const launcher =\n browserName === \"firefox\"\n ? firefox\n : browserName === \"webkit\"\n ? webkit\n : chromium;\n\n const headless = opts.headless ?? (process.env.CI ? true : false);\n const browser = await launcher.launch({ headless });\n\n const contextOptions: Parameters<typeof browser.newContext>[0] = {};\n if (opts.viewport) contextOptions.viewport = opts.viewport;\n if (opts.user_agent) contextOptions.userAgent = opts.user_agent;\n if (opts.locale) contextOptions.locale = opts.locale;\n\n // Wire capture lifecycle. Playwright requires recordHar / recordVideo\n // to be set at context creation; trace is start/stop-based.\n if (opts.capture?.har) {\n contextOptions.recordHar = { path: opts.capture.har.path };\n }\n if (opts.capture?.video) {\n contextOptions.recordVideo = {\n dir: opts.capture.video.dir,\n size:\n opts.capture.video.sizeWidth && opts.capture.video.sizeHeight\n ? {\n width: opts.capture.video.sizeWidth,\n height: opts.capture.video.sizeHeight,\n }\n : undefined,\n };\n }\n\n const context = await browser.newContext(contextOptions);\n\n if (opts.capture?.trace) {\n await context.tracing.start({\n screenshots: true,\n snapshots: true,\n sources: false,\n });\n }\n\n const page = await context.newPage();\n const sessionId = randomUUID();\n\n const internals: SessionInternals = {\n session: {\n id: sessionId,\n platform: \"web\",\n browser,\n context,\n mainPage: page,\n },\n refIndex: new Map(),\n snapshotGeneration: 0,\n refGeneration: -1,\n lastSnapshotAt: null,\n pages: [page],\n activePageIndex: 0,\n consoleBuffer: [],\n networkBuffer: [],\n networkInflight: new Map(),\n networkNextId: 1,\n dialogArming: null,\n captureOpts: opts.capture,\n traceStarted: !!opts.capture?.trace,\n };\n\n this.attachPageListeners(internals, page);\n context.on(\"page\", (newPage) => {\n internals.pages.push(newPage);\n this.attachPageListeners(internals, newPage);\n });\n\n if (opts.url) {\n await page.goto(opts.url, { waitUntil: \"domcontentloaded\" });\n }\n\n this.sessions.set(sessionId, internals);\n log.info(\"session opened\", {\n session_id: sessionId,\n browser: browserName,\n url: opts.url ?? null,\n capture: opts.capture\n ? Object.keys(opts.capture).filter(\n (k) => opts.capture![k as keyof typeof opts.capture],\n )\n : [],\n });\n return { id: sessionId, platform: \"web\" };\n }\n\n async close(session: Session): Promise<void> {\n const s = this.requireSession(session.id);\n\n // Stop tracing before context closes — trace.zip is written here.\n if (s.traceStarted && s.captureOpts?.trace) {\n const tracePath = resolvePath(s.captureOpts.trace.artifactDir, \"trace.zip\");\n await s.session.context.tracing\n .stop({ path: tracePath })\n .catch((err: unknown) => {\n log.warn(\"trace stop failed\", {\n session_id: session.id,\n err: String(err),\n });\n });\n }\n\n await s.session.context.close().catch((err: unknown) => {\n log.warn(\"context close failed\", { session_id: session.id, err: String(err) });\n });\n await s.session.browser.close().catch((err: unknown) => {\n log.warn(\"browser close failed\", { session_id: session.id, err: String(err) });\n });\n this.sessions.delete(session.id);\n log.info(\"session closed\", { session_id: session.id });\n }\n\n async snapshot(\n session: Session,\n mode: \"visible\" | \"full\" = \"visible\",\n ): Promise<A11ySnapshot> {\n const s = this.requireSession(session.id);\n // Playwright 1.60 removed `page.accessibility`. The ai-mode aria\n // snapshot is the supported successor — it carries `[ref=eN]` markers\n // that the `aria-ref=` locator can resolve back to elements.\n const ariaYaml = await this.activePage(s).ariaSnapshot({ mode: \"ai\" });\n const { tree, refIndex } = parseAriaSnapshot(ariaYaml);\n void mode; // depth control will route here once we expose `depth` to callers.\n\n s.snapshotGeneration += 1;\n s.refGeneration = s.snapshotGeneration;\n s.refIndex = refIndex;\n s.lastSnapshotAt = new Date().toISOString();\n\n return {\n session_id: session.id,\n platform: \"web\",\n url_or_screen: this.activePage(s).url(),\n taken_at: s.lastSnapshotAt,\n tree,\n };\n }\n\n async click(\n session: Session,\n ref: string,\n opts?: { button?: \"left\" | \"right\" | \"middle\" },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n await locator.click(opts?.button ? { button: opts.button } : undefined);\n this.invalidateRefs(s);\n }\n\n async type(\n session: Session,\n ref: string,\n text: string,\n opts?: { clearFirst?: boolean },\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n if (opts?.clearFirst) await locator.fill(\"\");\n await locator.fill(text);\n this.invalidateRefs(s);\n }\n\n async key(session: Session, key: string): Promise<void> {\n const s = this.requireSession(session.id);\n await this.activePage(s).keyboard.press(key);\n this.invalidateRefs(s);\n }\n\n async scroll(\n session: Session,\n dir: Direction,\n amount = 400,\n ref?: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const dx = dir === \"left\" ? -amount : dir === \"right\" ? amount : 0;\n const dy = dir === \"up\" ? -amount : dir === \"down\" ? amount : 0;\n if (ref) {\n const locator = this.resolveLocator(s, ref);\n await locator.evaluate(\n (el, [x, y]) => el.scrollBy(x as number, y as number),\n [dx, dy],\n );\n } else {\n await this.activePage(s).mouse.wheel(dx, dy);\n }\n this.invalidateRefs(s);\n }\n\n async waitFor(\n session: Session,\n cond: WaitCondition,\n timeoutMs = 10_000,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const page = this.activePage(s);\n switch (cond.kind) {\n case \"text_visible\":\n await page\n .getByText(cond.text, { exact: false })\n .first()\n .waitFor({ state: \"visible\", timeout: timeoutMs });\n break;\n case \"ref_exists\":\n await page\n .getByRole(\"button\", { name: cond.query })\n .first()\n .waitFor({ state: \"attached\", timeout: timeoutMs });\n break;\n case \"url_matches\":\n await page.waitForURL(new RegExp(cond.pattern), { timeout: timeoutMs });\n break;\n case \"idle\":\n await page.waitForLoadState(\"networkidle\", { timeout: timeoutMs });\n await page.waitForTimeout(cond.ms);\n break;\n }\n this.invalidateRefs(s);\n }\n\n async screenshot(session: Session, fullPage = false): Promise<Buffer> {\n const s = this.requireSession(session.id);\n return this.activePage(s).screenshot({ fullPage });\n }\n\n async navigate(session: Session, url: string): Promise<void> {\n const s = this.requireSession(session.id);\n if (s.session.platform !== \"web\") {\n throw new UnsupportedPlatformError(s.session.platform);\n }\n await this.activePage(s).goto(url, { waitUntil: \"domcontentloaded\" });\n this.invalidateRefs(s);\n }\n\n /**\n * Composite-only escape hatch — exposes the raw Playwright Page so a\n * composite tool that genuinely needs page-level APIs (axe-core,\n * `getByText`, etc.) can use them without bloating the Engine interface\n * with web-specific verbs. Throws if the session is not web.\n */\n getPageForSession(sessionId: string): Page {\n const s = this.requireSession(sessionId);\n if (s.session.platform !== \"web\") {\n throw new UnsupportedPlatformError(s.session.platform);\n }\n return this.activePage(s);\n }\n\n /** Increment generation; the next ref-using call will see them as stale. */\n bumpGeneration(sessionId: string): void {\n const s = this.requireSession(sessionId);\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 — input additions\n // -------------------------------------------------------------------------\n\n async hover(session: Session, ref: string): Promise<void> {\n const s = this.requireSession(session.id);\n const locator = this.resolveLocator(s, ref);\n await locator.hover();\n // Hover does not modify DOM in the same way click does; keep refs valid.\n }\n\n async drag(\n session: Session,\n fromRef: string,\n toRef: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n const from = this.resolveLocator(s, fromRef);\n const to = this.resolveLocator(s, toRef);\n await from.dragTo(to);\n this.invalidateRefs(s);\n }\n\n async fillForm(session: Session, fields: FillField[]): Promise<void> {\n const s = this.requireSession(session.id);\n for (const field of fields) {\n const locator = this.resolveLocator(s, field.ref);\n const kind = field.kind;\n if (kind === \"checkbox\" || kind === \"radio\") {\n const checked = typeof field.value === \"boolean\"\n ? field.value\n : field.value === \"true\" || field.value === \"on\";\n await locator.setChecked(checked);\n } else if (kind === \"select\") {\n await locator.selectOption(String(field.value));\n } else {\n // input / textarea / contenteditable\n await locator.fill(String(field.value));\n }\n }\n this.invalidateRefs(s);\n }\n\n async uploadFile(\n session: Session,\n ref: string,\n filePath: string,\n ): Promise<void> {\n const s = this.requireSession(session.id);\n if (!isAbsolute(filePath)) {\n throw new RolepodMcpError(\n \"invalid_input\",\n `upload_file requires an absolute path; got \"${filePath}\".`,\n { file_path: filePath },\n );\n }\n const locator = this.resolveLocator(s, ref);\n await locator.setInputFiles(filePath);\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // v0.5 — web-only extensions (not on Engine interface; tools cast to\n // PlaywrightEngine before calling).\n // -------------------------------------------------------------------------\n\n /**\n * Pre-arm a one-shot dialog handler for the next dialog raised on the\n * active page. Returns when either the dialog fires (and is handled)\n * or the timeout elapses. The caller is expected to trigger the\n * dialog (via click etc.) AFTER arming.\n */\n async handleDialog(\n sessionId: string,\n opts: {\n action: \"accept\" | \"dismiss\" | \"accept_with_text\";\n text?: string;\n timeoutMs?: number;\n },\n ): Promise<{ handled: boolean }> {\n const s = this.requireSession(sessionId);\n const timeoutMs = opts.timeoutMs ?? 30_000;\n const expiresAt = Date.now() + timeoutMs;\n\n // If a previous arming is still pending, treat the new call as a\n // replacement.\n if (s.dialogArming) {\n s.dialogArming.resolve(false);\n }\n\n return new Promise<{ handled: boolean }>((resolve) => {\n const arming: DialogArming = {\n action: opts.action,\n text: opts.text,\n expiresAt,\n resolve: (handled) => {\n s.dialogArming = null;\n resolve({ handled });\n },\n };\n s.dialogArming = arming;\n\n // Timeout safety\n const timer = setTimeout(() => {\n if (s.dialogArming === arming) {\n s.dialogArming = null;\n resolve({ handled: false });\n }\n }, timeoutMs);\n timer.unref?.();\n });\n }\n\n getConsole(\n sessionId: string,\n opts?: {\n levels?: ConsoleEntry[\"level\"][];\n contains?: string;\n clear?: boolean;\n limit?: number;\n },\n ): ConsoleEntry[] {\n const s = this.requireSession(sessionId);\n const levels = opts?.levels;\n const contains = opts?.contains;\n const limit = opts?.limit ?? 50;\n let entries = s.consoleBuffer;\n if (levels && levels.length > 0) {\n entries = entries.filter((e) => levels.includes(e.level));\n }\n if (contains) {\n entries = entries.filter((e) => e.text.includes(contains));\n }\n const result = entries.slice(-limit);\n if (opts?.clear) s.consoleBuffer = [];\n return result;\n }\n\n getNetwork(\n sessionId: string,\n opts?: {\n urlPattern?: string;\n patternKind?: \"substring\" | \"regex\";\n method?: string;\n statusRange?: { min: number; max: number };\n onlyFailed?: boolean;\n clear?: boolean;\n limit?: number;\n },\n ): NetworkEntry[] {\n const s = this.requireSession(sessionId);\n let entries = s.networkBuffer;\n if (opts?.urlPattern) {\n if (opts.patternKind === \"regex\") {\n const re = new RegExp(opts.urlPattern);\n entries = entries.filter((e) => re.test(e.url));\n } else {\n entries = entries.filter((e) => e.url.includes(opts.urlPattern!));\n }\n }\n if (opts?.method) {\n const m = opts.method.toUpperCase();\n entries = entries.filter((e) => e.method.toUpperCase() === m);\n }\n if (opts?.statusRange) {\n const { min, max } = opts.statusRange;\n entries = entries.filter(\n (e) =>\n e.status !== undefined && e.status >= min && e.status <= max,\n );\n }\n if (opts?.onlyFailed) {\n entries = entries.filter(\n (e) => !!e.failure || (e.status !== undefined && e.status >= 400),\n );\n }\n const limit = opts?.limit ?? 50;\n const result = entries.slice(-limit);\n if (opts?.clear) s.networkBuffer = [];\n return result;\n }\n\n /**\n * Read the consoleBuffer/networkBuffer directly without filtering —\n * used by verify_ui_flow expect evaluators.\n */\n peekBuffers(sessionId: string): {\n console: ConsoleEntry[];\n network: NetworkEntry[];\n } {\n const s = this.requireSession(sessionId);\n return { console: s.consoleBuffer, network: s.networkBuffer };\n }\n\n /**\n * Runtime mutation of context-level emulation. CPU + network throttle\n * use CDP and only work on chromium; everything else is cross-browser.\n */\n async setEnv(\n sessionId: string,\n opts: {\n viewport?: { width: number; height: number };\n offline?: boolean;\n geolocation?: { latitude: number; longitude: number; accuracy?: number };\n colorScheme?: \"light\" | \"dark\" | \"no-preference\";\n reducedMotion?: \"reduce\" | \"no-preference\";\n extraHeaders?: Record<string, string>;\n networkThrottle?:\n | \"offline\"\n | \"slow-3g\"\n | \"fast-3g\"\n | \"slow-4g\"\n | \"fast-4g\"\n | \"no-throttling\";\n cpuThrottle?: number;\n },\n ): Promise<void> {\n const s = this.requireSession(sessionId);\n const page = this.activePage(s);\n const ctx = s.session.context;\n\n if (opts.viewport) {\n await page.setViewportSize(opts.viewport);\n }\n if (opts.offline !== undefined) {\n await ctx.setOffline(opts.offline);\n }\n if (opts.geolocation) {\n await ctx.setGeolocation(opts.geolocation);\n }\n if (opts.extraHeaders) {\n await ctx.setExtraHTTPHeaders(opts.extraHeaders);\n }\n if (opts.colorScheme || opts.reducedMotion) {\n await page.emulateMedia({\n ...(opts.colorScheme ? { colorScheme: opts.colorScheme } : {}),\n ...(opts.reducedMotion ? { reducedMotion: opts.reducedMotion } : {}),\n });\n }\n if (opts.networkThrottle || opts.cpuThrottle !== undefined) {\n const browserName = ctx.browser()?.browserType().name();\n if (browserName !== \"chromium\") {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `networkThrottle / cpuThrottle require chromium (CDP-backed); current browser is \"${browserName}\".`,\n );\n }\n const cdp = await ctx.newCDPSession(page);\n try {\n if (opts.networkThrottle) {\n const preset = NETWORK_PRESETS[opts.networkThrottle];\n await cdp.send(\"Network.enable\");\n await cdp.send(\"Network.emulateNetworkConditions\", preset);\n }\n if (opts.cpuThrottle !== undefined) {\n await cdp.send(\"Emulation.setCPUThrottlingRate\", {\n rate: opts.cpuThrottle,\n });\n }\n } finally {\n await cdp.detach().catch(() => undefined);\n }\n }\n this.invalidateRefs(s);\n }\n\n /**\n * Execute a JavaScript function in the page context. ALWAYS gated by\n * the tool layer (`ROLEPOD_ALLOW_EVAL=1`); this method does not enforce\n * the env check.\n */\n async evaluate(\n sessionId: string,\n script: string,\n args?: unknown[],\n ): Promise<unknown> {\n const s = this.requireSession(sessionId);\n const page = this.activePage(s);\n // Script body runs inside `(async () => { ... })()` in the page context.\n // Caller can `return await fetch(...)` etc. `args` is exposed as a global\n // `args` array.\n return page.evaluate(\n ({ src, a }) =>\n // eslint-disable-next-line no-new-func\n new Function(\"args\", `return (async () => { ${src} })();`)(a),\n { src: script, a: args ?? [] },\n );\n }\n\n listPages(sessionId: string): {\n index: number;\n url: string;\n title_promise: Promise<string>;\n active: boolean;\n }[] {\n const s = this.requireSession(sessionId);\n return s.pages.map((p, i) => ({\n index: i,\n url: p.url(),\n title_promise: p.title(),\n active: i === s.activePageIndex,\n }));\n }\n\n async switchPage(sessionId: string, index: number): Promise<void> {\n const s = this.requireSession(sessionId);\n if (index < 0 || index >= s.pages.length) {\n throw new RolepodMcpError(\n \"invalid_input\",\n `Page index ${index} out of range (have ${s.pages.length} page(s)).`,\n { index, available: s.pages.length },\n );\n }\n s.activePageIndex = index;\n this.invalidateRefs(s);\n }\n\n // -------------------------------------------------------------------------\n // Internal helpers\n // -------------------------------------------------------------------------\n\n private activePage(s: SessionInternals): Page {\n return s.pages[s.activePageIndex] ?? s.session.mainPage;\n }\n\n private attachPageListeners(s: SessionInternals, page: Page): void {\n page.on(\"console\", (msg: ConsoleMessage) => {\n const level = mapConsoleLevel(msg.type());\n pushRing(\n s.consoleBuffer,\n {\n level,\n text: msg.text(),\n ts: new Date().toISOString(),\n location: formatConsoleLocation(msg),\n },\n CONSOLE_BUFFER_CAP,\n );\n });\n\n page.on(\"request\", (req: Request) => {\n const id = s.networkNextId++;\n s.networkInflight.set(req.url() + \"::\" + req.method() + \"::\" + id, {\n id,\n startedAt: Date.now(),\n resourceType: req.resourceType(),\n });\n // Optimistic entry — will be updated on response/failed.\n pushRing(\n s.networkBuffer,\n {\n id,\n url: req.url(),\n method: req.method(),\n resource_type: req.resourceType(),\n ts: new Date().toISOString(),\n },\n NETWORK_BUFFER_CAP,\n );\n });\n\n page.on(\"response\", (res: Response) => {\n const req = res.request();\n const entry = findNetworkEntry(s.networkBuffer, req);\n if (entry) {\n entry.status = res.status();\n entry.duration_ms = Date.now() - new Date(entry.ts).getTime();\n }\n });\n\n page.on(\"requestfailed\", (req: Request) => {\n const entry = findNetworkEntry(s.networkBuffer, req);\n if (entry) {\n entry.failure = req.failure()?.errorText ?? \"request failed\";\n }\n });\n\n page.on(\"dialog\", (dialog: Dialog) => {\n void this.handlePageDialog(s, dialog);\n });\n }\n\n private async handlePageDialog(\n s: SessionInternals,\n dialog: Dialog,\n ): Promise<void> {\n const arm = s.dialogArming;\n if (!arm || Date.now() > arm.expiresAt) {\n // Nothing armed → auto-dismiss so the page does not hang.\n await dialog.dismiss().catch(() => undefined);\n if (arm) arm.resolve(false);\n return;\n }\n try {\n if (arm.action === \"accept\") {\n await dialog.accept();\n } else if (arm.action === \"accept_with_text\") {\n await dialog.accept(arm.text ?? \"\");\n } else {\n await dialog.dismiss();\n }\n arm.resolve(true);\n } catch (err) {\n log.warn(\"dialog handle failed\", {\n session_id: s.session.id,\n err: String(err),\n });\n arm.resolve(false);\n }\n }\n\n private requireSession(sessionId: string): SessionInternals {\n const s = this.sessions.get(sessionId);\n if (!s) {\n throw new RolepodMcpError(\n \"unknown_session\",\n `No open session with id \"${sessionId}\".`,\n { session_id: sessionId },\n );\n }\n return s;\n }\n\n private resolveLocator(s: SessionInternals, ref: string): Locator {\n if (s.refGeneration !== s.snapshotGeneration) {\n throw new RolepodMcpError(\n \"stale_ref\",\n `Ref \"${ref}\" is stale — re-snapshot before retrying.`,\n {\n session_id: s.session.id,\n ref,\n last_valid_snapshot_at: s.lastSnapshotAt,\n },\n );\n }\n const meta = s.refIndex.get(ref);\n if (!meta) throw new UnknownRefError(s.session.id, ref);\n // The synthetic refs (`s1`, `s2`, ...) we issue for the wrapper root\n // are not real elements; the Lead should never click them.\n if (meta.ref.startsWith(\"s\")) {\n throw new UnknownRefError(s.session.id, ref);\n }\n return this.activePage(s).locator(`aria-ref=${meta.ref}`);\n }\n\n private invalidateRefs(s: SessionInternals): void {\n s.snapshotGeneration += 1;\n }\n\n /**\n * Test / shutdown helper. Closes every open session.\n */\n async shutdown(): Promise<void> {\n const ids = [...this.sessions.keys()];\n await Promise.all(\n ids.map((id) => this.close({ id, platform: \"web\" }).catch(() => undefined)),\n );\n }\n}\n","import yaml from \"js-yaml\";\nimport type { A11yNode } from \"../../schema/tools.js\";\n\n/**\n * Unified accessibility-tree normalization.\n *\n * Implements the Chromium path by parsing Playwright 1.60's\n * `page.ariaSnapshot({ mode: \"ai\" })` YAML output. Each leaf carries a\n * stable `[ref=eN]` marker that Playwright resolves back to a real\n * locator via `page.locator(\"aria-ref=eN\")`.\n *\n * Mobile A11y normalizers (XCUITest / UIAutomator2) are alumnium-inspired\n * — see THIRD_PARTY.md + UPSTREAM_TRACKING.md.\n */\n\n/** Locator metadata for ref → driver resolution. Never sent to the Lead. */\nexport type WebRefMeta = {\n kind: \"web\";\n /** The `eN` ref string. Used as `page.locator(\"aria-ref=\" + ref)`. */\n ref: string;\n};\n\nexport type RefMeta = WebRefMeta;\n\nexport type NormalizedSnapshot = {\n tree: A11yNode;\n refIndex: Map<string, RefMeta>;\n};\n\ntype YamlValue = string | YamlArray | YamlObject;\ntype YamlArray = YamlValue[];\ntype YamlObject = { [key: string]: YamlValue | null };\n\nconst KEY_RE = /^(?<role>\\S+?)(?:\\s+\"(?<name>(?:[^\"\\\\]|\\\\.)*)\")?(?<rest>(?:\\s+\\[[^\\]]+\\])*)\\s*$/;\nconst ATTR_RE = /\\[([^=\\]]+)(?:=([^\\]]+))?\\]/g;\n\ntype ParsedKey = {\n role: string;\n name?: string;\n attrs: Record<string, string>;\n};\n\nfunction parseKey(key: string): ParsedKey {\n const trimmed = key.trim();\n const m = KEY_RE.exec(trimmed);\n if (!m) {\n return { role: trimmed, attrs: {} };\n }\n const groups = m.groups!;\n const out: ParsedKey = { role: groups.role!, attrs: {} };\n if (groups.name !== undefined) out.name = unescapeQuoted(groups.name);\n const rest = groups.rest ?? \"\";\n for (const attrMatch of rest.matchAll(ATTR_RE)) {\n const [, k, v] = attrMatch;\n if (k) out.attrs[k] = v ?? \"true\";\n }\n return out;\n}\n\nfunction unescapeQuoted(s: string): string {\n return s.replace(/\\\\(.)/g, \"$1\");\n}\n\n/**\n * Parse a Playwright ai-mode aria snapshot string and produce the unified\n * A11yNode tree plus a refIndex for locator resolution.\n */\nexport function parseAriaSnapshot(snapshotYaml: string): NormalizedSnapshot {\n const refIndex = new Map<string, RefMeta>();\n let synthCounter = 0;\n const nextSynthRef = (): string => `s${++synthCounter}`;\n\n const consumeNode = (value: YamlValue): A11yNode | null => {\n // Object with one key like { 'link \"Home\" [ref=e3]': [...] | \"text\" }\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const keys = Object.keys(value);\n if (keys.length !== 1) return null;\n const key = keys[0]!;\n // Pseudo-keys like `/url` carry hyperlink metadata, not real nodes.\n if (key.startsWith(\"/\")) return null;\n const inner = value[key];\n if (typeof inner === \"string\") return buildNode(key, null, inner);\n if (Array.isArray(inner)) return buildNode(key, inner, undefined);\n return buildNode(key, null, undefined);\n }\n // Bare string like `link \"Home\" [ref=e3]` or `text \"hello\"`\n if (typeof value === \"string\") {\n return buildNode(value, null, undefined);\n }\n return null;\n };\n\n const buildNode = (\n key: string,\n rawChildren: YamlValue | null | undefined,\n inlineText: string | undefined,\n ): A11yNode => {\n const parsed = parseKey(key);\n const ref = parsed.attrs.ref ?? nextSynthRef();\n refIndex.set(ref, { kind: \"web\", ref });\n\n const node: A11yNode = {\n ref,\n role: parsed.role,\n };\n if (parsed.name !== undefined) node.name = parsed.name;\n if (inlineText !== undefined) {\n node.value = inlineText;\n } else if (parsed.attrs.level) {\n node.value = parsed.attrs.level;\n }\n\n const state: A11yNode[\"state\"] = {};\n if (\"disabled\" in parsed.attrs) state.disabled = parsed.attrs.disabled !== \"false\";\n if (\"focused\" in parsed.attrs) state.focused = parsed.attrs.focused !== \"false\";\n if (\"selected\" in parsed.attrs) state.selected = parsed.attrs.selected !== \"false\";\n if (\"expanded\" in parsed.attrs) state.expanded = parsed.attrs.expanded !== \"false\";\n if (Object.keys(state).length > 0) node.state = state;\n\n if (Array.isArray(rawChildren)) {\n const children: A11yNode[] = [];\n for (const child of rawChildren) {\n const built = consumeNode(child);\n if (built) children.push(built);\n }\n if (children.length > 0) node.children = children;\n }\n return node;\n };\n\n let loaded: YamlValue;\n try {\n loaded = (yaml.load(snapshotYaml) as YamlValue) ?? [];\n } catch {\n loaded = [];\n }\n\n const topLevel: A11yNode[] = [];\n if (Array.isArray(loaded)) {\n for (const entry of loaded) {\n const node = consumeNode(entry);\n if (node) topLevel.push(node);\n }\n } else if (loaded && typeof loaded === \"object\") {\n const node = consumeNode(loaded);\n if (node) topLevel.push(node);\n } else if (typeof loaded === \"string\" && loaded.length > 0) {\n const node = consumeNode(loaded);\n if (node) topLevel.push(node);\n }\n\n // The composite needs a single root. Wrap when there are 0 or >1 entries.\n if (topLevel.length === 1) {\n return { tree: topLevel[0]!, refIndex };\n }\n const rootRef = nextSynthRef();\n refIndex.set(rootRef, { kind: \"web\", ref: rootRef });\n const root: A11yNode = { ref: rootRef, role: \"RootWebArea\" };\n if (topLevel.length > 0) root.children = topLevel;\n return { tree: root, refIndex };\n}\n","import { RolepodMcpError } from \"../util/errors.js\";\nimport { AppiumEngine } from \"./AppiumEngine.js\";\nimport { PlaywrightEngine } from \"./PlaywrightEngine.js\";\nimport type { Engine } from \"./Engine.js\";\n\n/**\n * Engine selection happens once at server startup. v0.3 wires\n * Playwright for `web` and Appium for `ios`/`android`. The\n * `ROLEPOD_MCP_WEB_ENGINE` env var (D-012) only governs the *web*\n * engine; mobile always routes to Appium.\n */\nexport function createWebEngine(): Engine {\n const choice = (process.env.ROLEPOD_MCP_WEB_ENGINE ?? \"playwright\").toLowerCase();\n switch (choice) {\n case \"playwright\":\n return new PlaywrightEngine();\n case \"selenium\":\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"SeleniumEngine ships in v0.4 — set ROLEPOD_MCP_WEB_ENGINE=playwright until then.\",\n { requested: choice },\n );\n default:\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `Unknown web engine \"${choice}\" — supported: playwright.`,\n { requested: choice },\n );\n }\n}\n\nexport function createMobileEngine(): Engine {\n return new AppiumEngine();\n}\n\n/** Back-compat alias for v0.1 callers. */\nexport function createEngine(): Engine {\n return createWebEngine();\n}\n","import { UnknownSessionError, UnsupportedPlatformError } from \"../util/errors.js\";\nimport { log } from \"../util/log.js\";\nimport type { Engine, OpenOptions, Platform, Session } from \"../engine/Engine.js\";\n\n/**\n * Routes sessions to the correct engine and enforces idle-timeout cleanup.\n *\n * v0.1: only PlaywrightEngine is wired up, so every `platform: 'web'`\n * request goes there. AppiumEngine (v0.3) will register against the\n * `ios`/`android` platform keys without touching tool code.\n */\nexport class SessionRegistry {\n private readonly enginesByPlatform = new Map<Platform, Engine>();\n private readonly engineBySession = new Map<string, Engine>();\n private readonly platformBySession = new Map<string, Platform>();\n private readonly lastActivity = new Map<string, number>();\n private readonly idleTimeoutMs: number;\n private idleTimer: NodeJS.Timeout | null = null;\n\n constructor(opts: { idleTimeoutMs?: number } = {}) {\n this.idleTimeoutMs = opts.idleTimeoutMs ?? 5 * 60 * 1000;\n }\n\n /** Register an engine as the handler for a given platform. */\n register(platform: Platform, engine: Engine): void {\n this.enginesByPlatform.set(platform, engine);\n }\n\n async open(opts: OpenOptions): Promise<Session> {\n const engine = this.enginesByPlatform.get(opts.platform);\n if (!engine) throw new UnsupportedPlatformError(opts.platform);\n const session = await engine.open(opts);\n this.engineBySession.set(session.id, engine);\n this.platformBySession.set(session.id, session.platform);\n this.touch(session.id);\n this.ensureIdleSweep();\n return session;\n }\n\n engineFor(sessionId: string): Engine {\n const engine = this.engineBySession.get(sessionId);\n if (!engine) throw new UnknownSessionError(sessionId);\n this.touch(sessionId);\n return engine;\n }\n\n async close(session: Session): Promise<void> {\n const engine = this.engineBySession.get(session.id);\n if (!engine) throw new UnknownSessionError(session.id);\n await engine.close(session);\n this.engineBySession.delete(session.id);\n this.platformBySession.delete(session.id);\n this.lastActivity.delete(session.id);\n }\n\n /** Look up the platform recorded for an open session. */\n platformOf(sessionId: string): Platform {\n const platform = this.platformBySession.get(sessionId);\n if (!platform) throw new UnknownSessionError(sessionId);\n return platform;\n }\n\n async shutdown(): Promise<void> {\n if (this.idleTimer) {\n clearInterval(this.idleTimer);\n this.idleTimer = null;\n }\n const closes: Array<Promise<void>> = [];\n for (const [sessionId, engine] of this.engineBySession) {\n const platform = this.platformFor(sessionId);\n closes.push(\n engine\n .close({ id: sessionId, platform })\n .catch((err: unknown) =>\n log.warn(\"shutdown close failed\", { sessionId, err: String(err) }),\n ),\n );\n }\n await Promise.all(closes);\n this.engineBySession.clear();\n this.platformBySession.clear();\n this.lastActivity.clear();\n }\n\n private touch(sessionId: string): void {\n this.lastActivity.set(sessionId, Date.now());\n }\n\n private platformFor(sessionId: string): Platform {\n return this.platformBySession.get(sessionId) ?? \"web\";\n }\n\n private ensureIdleSweep(): void {\n if (this.idleTimer || this.idleTimeoutMs <= 0) return;\n const interval = Math.max(30_000, Math.floor(this.idleTimeoutMs / 4));\n this.idleTimer = setInterval(() => {\n const cutoff = Date.now() - this.idleTimeoutMs;\n for (const [sessionId, lastSeen] of this.lastActivity) {\n if (lastSeen < cutoff) {\n const engine = this.engineBySession.get(sessionId);\n if (!engine) {\n this.lastActivity.delete(sessionId);\n continue;\n }\n log.info(\"idle session sweep — closing\", { sessionId });\n engine\n .close({ id: sessionId, platform: this.platformFor(sessionId) })\n .catch((err: unknown) =>\n log.warn(\"idle close failed\", { sessionId, err: String(err) }),\n )\n .finally(() => {\n this.engineBySession.delete(sessionId);\n this.lastActivity.delete(sessionId);\n });\n }\n }\n }, interval);\n this.idleTimer.unref();\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n ToolNames,\n verifyUiFlowShape,\n type A11yNode,\n type VerifyUiFlowInput,\n} from \"../../schema/tools.js\";\nimport type {\n A11ySnapshot,\n Engine,\n OpenOptions,\n Session,\n} from \"../../engine/Engine.js\";\nimport { ddmin } from \"../../replay/minimize.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest, type ManifestArtifact } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolContext, ToolModule } from \"../types.js\";\n\n/**\n * Composite `verify_ui_flow` — drive a session through steps and evaluate\n * expectations against the resulting state.\n *\n * - `mode: 'assert'` (default): pass = \"expected feature works\".\n * - `mode: 'reproduce'`: pass = \"expected bug surfaced\". When `minimize`\n * is true (default) and the initial run reproduces, the composite\n * performs a linear delta-removal pass over `steps` to find a smaller\n * sequence that still reproduces. See D-025.\n */\nexport const verifyUiFlowTool: ToolModule<typeof verifyUiFlowShape> = {\n name: ToolNames.verifyUiFlow,\n description:\n \"Open a session, run UI steps, evaluate assertions, and save evidence. Set mode='reproduce' for bug reproduction with optional step minimization.\",\n inputShape: verifyUiFlowShape,\n build(ctx) {\n return safeHandler(async (args: VerifyUiFlowInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"verify\",\n { skill: \"verify-ui\" },\n );\n\n const initial = await runFlow(ctx, args, args.steps, runDir, {\n captureEvidence: true,\n bundleName: \"replay.json\",\n });\n\n const result: Record<string, unknown> = {\n run_id: runId,\n mode: args.mode,\n passed: initial.passed,\n evidence_paths: initial.evidence,\n };\n if (initial.failedAtStep !== undefined) result.failed_at_step = initial.failedAtStep;\n if (initial.failureReason !== undefined) result.failure_reason = initial.failureReason;\n if (initial.finalUrl !== undefined) result.final_url_or_screen = initial.finalUrl;\n\n if (args.mode === \"reproduce\" && initial.passed && args.minimize) {\n const min = await minimize(ctx, args, args.steps, runDir);\n result.minimized = {\n original_step_count: args.steps.length,\n minimized_step_count: min.steps.length,\n minimal_steps: min.steps,\n steps_removed: min.removed,\n replay_bundle: min.replayPath,\n attempts: min.attempts,\n };\n }\n\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: initial.passed ? \"pass\" : \"fail\",\n summary: buildVerifySummary(args, initial),\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: flattenVerifyEvidence(initial.evidence),\n metadata: {\n mode: args.mode,\n step_count: args.steps.length,\n expect_count: args.expect.length,\n ...(initial.finalUrl !== undefined ? { final_url: initial.finalUrl } : {}),\n },\n });\n if (manifestPath) result.manifest = manifestPath;\n\n return ok(result);\n });\n },\n};\n\nfunction buildVerifySummary(\n args: VerifyUiFlowInput,\n outcome: RunOutcome,\n): string {\n const stepCount = args.steps.length;\n const expectCount = args.expect.length;\n if (outcome.passed) {\n return `${stepCount} step(s), ${expectCount} expect(s) passed`;\n }\n if (outcome.failedAtStep !== undefined) {\n return `failed at step ${outcome.failedAtStep}: ${outcome.failureReason ?? \"unknown\"}`;\n }\n return `failed: ${outcome.failureReason ?? \"unknown\"}`;\n}\n\nfunction flattenVerifyEvidence(ev: Evidence): ManifestArtifact[] {\n const out: ManifestArtifact[] = [];\n for (const s of ev.screenshots) out.push({ type: \"screenshot\", path: s });\n if (ev.replay_bundle) out.push({ type: \"replay_bundle\", path: ev.replay_bundle });\n if (ev.console) out.push({ type: \"console\", path: ev.console });\n if (ev.a11y_tree) out.push({ type: \"a11y_tree\", path: ev.a11y_tree });\n if (ev.har) out.push({ type: \"har\", path: ev.har });\n if (ev.trace) out.push({ type: \"trace\", path: ev.trace });\n if (ev.video) for (const v of ev.video) out.push({ type: \"video\", path: v });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Core single-run logic — shared by the initial run and every minimization\n// attempt.\n// ---------------------------------------------------------------------------\n\ntype Evidence = {\n screenshots: string[];\n replay_bundle?: string;\n console?: string;\n a11y_tree?: string;\n har?: string;\n trace?: string;\n video?: string[];\n};\n\ntype RunOutcome = {\n passed: boolean;\n failedAtStep?: number;\n failureReason?: string;\n finalUrl?: string;\n evidence: Evidence;\n};\n\nfunction buildCaptureOptions(\n captures: Set<string>,\n runDir: string,\n): OpenOptions[\"capture\"] | undefined {\n const cap: NonNullable<OpenOptions[\"capture\"]> = {};\n if (captures.has(\"har\")) {\n cap.har = { path: resolvePath(runDir, \"network.har\") };\n }\n if (captures.has(\"video\")) {\n cap.video = { dir: resolvePath(runDir, \"videos\") };\n }\n if (captures.has(\"trace\")) {\n cap.trace = { artifactDir: runDir };\n }\n return Object.keys(cap).length > 0 ? cap : undefined;\n}\n\nasync function runFlow(\n ctx: ToolContext,\n args: VerifyUiFlowInput,\n steps: VerifyUiFlowInput[\"steps\"],\n runDir: string,\n opts: { captureEvidence: boolean; bundleName: string },\n): Promise<RunOutcome> {\n const evidence: Evidence = { screenshots: [] };\n const captures = new Set<string>(args.capture ?? [\"screenshot\"]);\n let passed = false;\n let failedAtStep: number | undefined;\n let failureReason: string | undefined;\n let finalSnapshot: A11ySnapshot | undefined;\n\n // Build OpenOptions enriched with capture lifecycle requests. The\n // engine wires recordHar / recordVideo / tracing at context creation.\n const openOpts: OpenOptions = { ...args.open };\n const captureCfg = buildCaptureOptions(captures, runDir);\n if (captureCfg) {\n openOpts.capture = captureCfg;\n }\n\n const session = await ctx.registry.open(openOpts);\n const engine = ctx.registry.engineFor(session.id);\n const sessionHandle: Session = { id: session.id, platform: session.platform };\n\n try {\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const beforeSnap = await engine.snapshot(sessionHandle);\n try {\n await runStep(engine, sessionHandle, step, beforeSnap);\n } catch (err) {\n failedAtStep = i;\n failureReason = `Step ${i} (${step.kind}) failed: ${describeError(err)}`;\n throw err;\n }\n }\n\n finalSnapshot = await engine.snapshot(sessionHandle);\n const failures: string[] = [];\n for (let i = 0; i < args.expect.length; i++) {\n const expectation = args.expect[i]!;\n if (!evaluateExpect(expectation, finalSnapshot, engine, session.id)) {\n failures.push(`expect[${i}] ${describeExpect(expectation)}`);\n }\n }\n if (failures.length === 0) {\n passed = true;\n } else {\n failureReason = `Expectations failed: ${failures.join(\"; \")}`;\n }\n } catch (err) {\n if (!failureReason) failureReason = describeError(err);\n passed = false;\n } finally {\n if (opts.captureEvidence) {\n if (captures.has(\"screenshot\")) {\n try {\n const buf = await engine.screenshot(sessionHandle, true);\n const p = await ctx.store.writeScreenshot(runDir, buf, \"final\");\n evidence.screenshots.push(p);\n } catch (err) {\n failureReason ??= `screenshot capture failed: ${describeError(err)}`;\n }\n }\n\n if (captures.has(\"console\") && engine instanceof PlaywrightEngine) {\n try {\n const messages = engine.peekBuffers(session.id).console;\n evidence.console = await ctx.store.writeReport(\n runDir,\n \"console.json\",\n JSON.stringify(\n {\n count: messages.length,\n by_level: countByLevel(messages),\n messages,\n },\n null,\n 2,\n ),\n );\n } catch (err) {\n failureReason ??= `console capture failed: ${describeError(err)}`;\n }\n }\n\n if (captures.has(\"a11y_tree\") && finalSnapshot) {\n try {\n evidence.a11y_tree = await ctx.store.writeReport(\n runDir,\n \"a11y_tree.json\",\n JSON.stringify(finalSnapshot, null, 2),\n );\n } catch (err) {\n failureReason ??= `a11y_tree capture failed: ${describeError(err)}`;\n }\n }\n\n try {\n evidence.replay_bundle = await ctx.store.writeReplayBundle(\n runDir,\n {\n version: 1,\n run_id: runDir.split(\"/\").pop() ?? \"run\",\n recorded_at: new Date().toISOString(),\n open: args.open as unknown as Record<string, unknown>,\n steps: steps as unknown as Record<string, unknown>[],\n expect: args.expect as unknown as Record<string, unknown>[],\n },\n opts.bundleName,\n );\n } catch {\n /* swallow — replay bundle is best-effort */\n }\n }\n if (args.close_on_finish) {\n await ctx.registry.close(sessionHandle).catch(() => undefined);\n }\n }\n\n // HAR / video / trace artifacts are flushed by the engine on context close.\n // Surface their paths now that the close has completed (if captureEvidence\n // was requested).\n if (opts.captureEvidence) {\n if (captureCfg?.har) evidence.har = captureCfg.har.path;\n if (captureCfg?.trace) {\n evidence.trace = resolvePath(captureCfg.trace.artifactDir, \"trace.zip\");\n }\n if (captureCfg?.video) {\n try {\n const files = await readdir(captureCfg.video.dir).catch(() => [] as string[]);\n evidence.video = files\n .filter((f) => f.endsWith(\".webm\"))\n .map((f) => resolvePath(captureCfg.video!.dir, f));\n } catch {\n /* swallow — video is best-effort */\n }\n }\n }\n\n const out: RunOutcome = { passed, evidence };\n if (failedAtStep !== undefined) out.failedAtStep = failedAtStep;\n if (failureReason !== undefined) out.failureReason = failureReason;\n if (finalSnapshot) out.finalUrl = finalSnapshot.url_or_screen;\n return out;\n}\n\nfunction countByLevel(\n messages: { level: string }[],\n): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const m of messages) {\n counts[m.level] = (counts[m.level] ?? 0) + 1;\n }\n return counts;\n}\n\n// ---------------------------------------------------------------------------\n// Linear delta-removal — naive but bounded by the step count.\n// ---------------------------------------------------------------------------\n\ntype MinimizeResult = {\n steps: VerifyUiFlowInput[\"steps\"];\n removed: number[];\n attempts: number;\n replayPath: string | undefined;\n};\n\nasync function minimize(\n ctx: ToolContext,\n args: VerifyUiFlowInput,\n initialSteps: VerifyUiFlowInput[\"steps\"],\n runDir: string,\n): Promise<MinimizeResult> {\n // Tag each step with its original index so we can report what was removed.\n type Tagged = { step: VerifyUiFlowInput[\"steps\"][number]; origIndex: number };\n const tagged: Tagged[] = initialSteps.map((step, origIndex) => ({ step, origIndex }));\n let attempts = 0;\n\n const predicate = async (subset: Tagged[]): Promise<boolean> => {\n attempts += 1;\n const outcome = await runFlow(\n ctx,\n args,\n subset.map((t) => t.step),\n runDir,\n { captureEvidence: false, bundleName: \"minimize-tmp.json\" },\n );\n return outcome.passed;\n };\n\n const minimal = await ddmin(tagged, predicate);\n const remainingIdx = new Set(minimal.map((t) => t.origIndex));\n const removed = tagged\n .map((t) => t.origIndex)\n .filter((i) => !remainingIdx.has(i));\n\n // One final capture run with the minimized sequence to anchor evidence.\n let replayPath: string | undefined;\n if (minimal.length !== initialSteps.length) {\n const finalRun = await runFlow(\n ctx,\n args,\n minimal.map((t) => t.step),\n runDir,\n { captureEvidence: true, bundleName: \"replay-minimized.json\" },\n );\n replayPath = finalRun.evidence.replay_bundle;\n }\n return {\n steps: minimal.map((t) => t.step),\n removed: removed.sort((a, b) => a - b),\n attempts,\n replayPath,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Step + expect evaluation helpers (shared with mode='assert').\n// ---------------------------------------------------------------------------\n\nasync function runStep(\n engine: Engine,\n session: Session,\n step: VerifyUiFlowInput[\"steps\"][number],\n snap: A11ySnapshot,\n): Promise<void> {\n switch (step.kind) {\n case \"click\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.click(session, ref);\n return;\n }\n case \"type\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.type(\n session,\n ref,\n step.text,\n step.clear_first ? { clearFirst: true } : undefined,\n );\n return;\n }\n case \"key\":\n await engine.key(session, step.key);\n return;\n case \"wait_for\":\n await engine.waitFor(session, step.condition);\n return;\n case \"navigate\":\n await engine.navigate(session, step.url);\n return;\n case \"hover\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.hover(session, ref);\n return;\n }\n case \"drag\": {\n const fromRef = findRefByQuery(snap.tree, step.from_query);\n if (!fromRef) throw missingQuery(step.from_query);\n const toRef = findRefByQuery(snap.tree, step.to_query);\n if (!toRef) throw missingQuery(step.to_query);\n await engine.drag(session, fromRef, toRef);\n return;\n }\n case \"fill_form\": {\n const resolved = step.fields.map((f) => {\n const ref = findRefByQuery(snap.tree, f.query);\n if (!ref) throw missingQuery(f.query);\n return f.kind !== undefined\n ? { ref, value: f.value, kind: f.kind }\n : { ref, value: f.value };\n });\n await engine.fillForm(session, resolved);\n return;\n }\n case \"upload\": {\n const ref = findRefByQuery(snap.tree, step.query);\n if (!ref) throw missingQuery(step.query);\n await engine.uploadFile(session, ref, step.file_path);\n return;\n }\n case \"dialog\": {\n requirePlaywright(engine, \"dialog\");\n // Fire and forget — the next step (the dialog trigger) will resolve\n // the handler. We register synchronously inside handleDialog.\n void engine\n .handleDialog(session.id, {\n action: step.action,\n ...(step.text !== undefined ? { text: step.text } : {}),\n })\n .catch(() => undefined);\n return;\n }\n case \"set_env\": {\n requirePlaywright(engine, \"set_env\");\n await engine.setEnv(session.id, {\n ...(step.viewport !== undefined ? { viewport: step.viewport } : {}),\n ...(step.offline !== undefined ? { offline: step.offline } : {}),\n ...(step.geolocation !== undefined\n ? { geolocation: step.geolocation }\n : {}),\n ...(step.color_scheme !== undefined\n ? { colorScheme: step.color_scheme }\n : {}),\n ...(step.reduced_motion !== undefined\n ? { reducedMotion: step.reduced_motion }\n : {}),\n ...(step.extra_headers !== undefined\n ? { extraHeaders: step.extra_headers }\n : {}),\n ...(step.network_throttle !== undefined\n ? { networkThrottle: step.network_throttle }\n : {}),\n ...(step.cpu_throttle !== undefined\n ? { cpuThrottle: step.cpu_throttle }\n : {}),\n });\n return;\n }\n case \"switch_page\": {\n requirePlaywright(engine, \"switch_page\");\n await engine.switchPage(session.id, step.index);\n return;\n }\n case \"evaluate\": {\n requirePlaywright(engine, \"evaluate\");\n if (process.env.ROLEPOD_ALLOW_EVAL !== \"1\") {\n throw new RolepodMcpError(\n \"engine_error\",\n \"verify_ui_flow step kind 'evaluate' is disabled. Restart the rolepod-uiproof MCP server with ROLEPOD_ALLOW_EVAL=1 to enable.\",\n );\n }\n await engine.evaluate(session.id, step.script);\n return;\n }\n }\n}\n\nfunction requirePlaywright(\n engine: Engine,\n stepKind: string,\n): asserts engine is PlaywrightEngine {\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n `verify_ui_flow step kind \"${stepKind}\" is web-only and requires PlaywrightEngine.`,\n );\n }\n}\n\nfunction evaluateExpect(\n exp: VerifyUiFlowInput[\"expect\"][number],\n snap: A11ySnapshot,\n engine: Engine,\n sessionId: string,\n): boolean {\n switch (exp.kind) {\n case \"text_visible\":\n return treeHasText(snap.tree, exp.text);\n case \"text_absent\":\n return !treeHasText(snap.tree, exp.text);\n case \"url_matches\":\n return new RegExp(exp.pattern).test(snap.url_or_screen);\n case \"ref_in_state\": {\n const node = findNodeByQuery(snap.tree, exp.query);\n if (!node) return false;\n switch (exp.state) {\n case \"visible\":\n return true;\n case \"enabled\":\n return node.state?.disabled !== true;\n case \"focused\":\n return node.state?.focused === true;\n }\n }\n case \"no_console_errors\": {\n if (!(engine instanceof PlaywrightEngine)) return true; // mobile = no console\n const msgs = engine.peekBuffers(sessionId).console.filter(\n (m) => m.level === \"error\",\n );\n const excludes = exp.exclude_patterns ?? [];\n const remaining = msgs.filter(\n (m) => !excludes.some((p) => m.text.includes(p)),\n );\n return remaining.length === 0;\n }\n case \"no_failed_requests\": {\n if (!(engine instanceof PlaywrightEngine)) return true;\n const reqs = engine.peekBuffers(sessionId).network.filter((r) => {\n if (r.failure) return true;\n if (r.status === undefined) return false;\n if (exp.allow_4xx) return r.status >= 500;\n return r.status >= 400;\n });\n const excludes = exp.exclude_patterns ?? [];\n const remaining = reqs.filter(\n (r) => !excludes.some((p) => r.url.includes(p)),\n );\n return remaining.length === 0;\n }\n case \"request_made\": {\n if (!(engine instanceof PlaywrightEngine)) return false;\n const re = new RegExp(exp.url_pattern);\n const wantMethod = exp.method?.toUpperCase();\n const matches = engine.peekBuffers(sessionId).network.filter((r) => {\n if (!re.test(r.url)) return false;\n if (wantMethod && r.method.toUpperCase() !== wantMethod) return false;\n return true;\n });\n const min = exp.min_count ?? 1;\n return matches.length >= min;\n }\n case \"response_status\": {\n if (!(engine instanceof PlaywrightEngine)) return false;\n const re = new RegExp(exp.url_pattern);\n const match = engine\n .peekBuffers(sessionId)\n .network.find((r) => re.test(r.url) && r.status === exp.status);\n return match !== undefined;\n }\n }\n}\n\nfunction describeExpect(exp: VerifyUiFlowInput[\"expect\"][number]): string {\n switch (exp.kind) {\n case \"text_visible\":\n return `text_visible \"${exp.text}\"`;\n case \"text_absent\":\n return `text_absent \"${exp.text}\"`;\n case \"url_matches\":\n return `url_matches /${exp.pattern}/`;\n case \"ref_in_state\":\n return `ref_in_state \"${exp.query}\" → ${exp.state}`;\n case \"no_console_errors\":\n return \"no_console_errors\";\n case \"no_failed_requests\":\n return \"no_failed_requests\";\n case \"request_made\":\n return `request_made ${exp.method ?? \"\"} ${exp.url_pattern}`.trim();\n case \"response_status\":\n return `response_status ${exp.url_pattern} = ${exp.status}`;\n }\n}\n\nfunction missingQuery(query: string): RolepodMcpError {\n return new RolepodMcpError(\n \"invalid_input\",\n `No element matched query \"${query}\" in the current snapshot.`,\n { query },\n );\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nfunction findRefByQuery(tree: A11yNode, query: string): string | null {\n const node = findNodeByQuery(tree, query);\n return node ? node.ref : null;\n}\n\nfunction findNodeByQuery(tree: A11yNode, query: string): A11yNode | null {\n const target = query.toLowerCase();\n const visit = (node: A11yNode): A11yNode | null => {\n if (\n (node.name && node.name.toLowerCase().includes(target)) ||\n (node.value && node.value.toLowerCase().includes(target))\n ) {\n return node;\n }\n if (node.children) {\n for (const c of node.children) {\n const hit = visit(c);\n if (hit) return hit;\n }\n }\n return null;\n };\n return visit(tree);\n}\n\nfunction treeHasText(tree: A11yNode, text: string): boolean {\n const target = text.toLowerCase();\n const visit = (node: A11yNode): boolean => {\n if (\n (node.name && node.name.toLowerCase().includes(target)) ||\n (node.value && node.value.toLowerCase().includes(target))\n ) {\n return true;\n }\n return node.children?.some(visit) ?? false;\n };\n return visit(tree);\n}\n","import { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Shared building blocks\n// ---------------------------------------------------------------------------\n\nexport const platformSchema = z.enum([\"web\", \"ios\", \"android\"]);\nexport const browserSchema = z.enum([\"chromium\", \"firefox\", \"webkit\"]);\n\nexport const viewportSchema = z.object({\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n});\n\nexport const bboxSchema = z.object({\n x: z.number(),\n y: z.number(),\n w: z.number(),\n h: z.number(),\n});\n\nexport const a11yStateSchema = z.object({\n focused: z.boolean().optional(),\n selected: z.boolean().optional(),\n expanded: z.boolean().optional(),\n disabled: z.boolean().optional(),\n});\n\nexport type A11yNode = {\n ref: string;\n role: string;\n name?: string;\n value?: string;\n state?: z.infer<typeof a11yStateSchema>;\n bbox?: z.infer<typeof bboxSchema>;\n children?: A11yNode[];\n};\n\nexport const a11yNodeSchema: z.ZodType<A11yNode> = z.lazy(() =>\n z.object({\n ref: z.string(),\n role: z.string(),\n name: z.string().optional(),\n value: z.string().optional(),\n state: a11yStateSchema.optional(),\n bbox: bboxSchema.optional(),\n children: z.array(a11yNodeSchema).optional(),\n }),\n);\n\nexport const waitConditionSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"text_visible\"), text: z.string() }),\n z.object({ kind: z.literal(\"ref_exists\"), query: z.string() }),\n z.object({ kind: z.literal(\"url_matches\"), pattern: z.string() }),\n z.object({ kind: z.literal(\"idle\"), ms: z.number().int().positive() }),\n]);\n\n// ---------------------------------------------------------------------------\n// Atomic tools — input shapes\n//\n// NOTE: MCP SDK's `registerTool({ inputSchema })` expects a Zod *raw shape*\n// (a plain object whose values are Zod schemas), NOT a `z.object(...)`. We\n// export both the raw shape (for the SDK) and a derived `z.object` (for\n// internal parsing / type inference).\n// ---------------------------------------------------------------------------\n\nexport const browserOpenShape = {\n platform: platformSchema.default(\"web\"),\n url: z.string().url().optional(),\n browser: browserSchema.optional(),\n viewport: viewportSchema.optional(),\n // mobile fields kept for forward compat; v0.1 only handles platform='web'\n bundle_id: z.string().optional(),\n device: z.string().optional(),\n app_package: z.string().optional(),\n app_activity: z.string().optional(),\n emulator: z.string().optional(),\n headless: z.boolean().optional(),\n user_agent: z.string().optional(),\n locale: z.string().optional(),\n} as const;\nexport const browserOpenSchema = z.object(browserOpenShape);\nexport type BrowserOpenInput = z.infer<typeof browserOpenSchema>;\n\nexport const browserCloseShape = {\n session_id: z.string().min(1),\n} as const;\nexport const browserCloseSchema = z.object(browserCloseShape);\nexport type BrowserCloseInput = z.infer<typeof browserCloseSchema>;\n\nexport const browserSnapshotShape = {\n session_id: z.string().min(1),\n mode: z.enum([\"visible\", \"full\"]).optional(),\n} as const;\nexport const browserSnapshotSchema = z.object(browserSnapshotShape);\nexport type BrowserSnapshotInput = z.infer<typeof browserSnapshotSchema>;\n\nexport const browserClickShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n button: z.enum([\"left\", \"right\", \"middle\"]).optional(),\n} as const;\nexport const browserClickSchema = z.object(browserClickShape);\nexport type BrowserClickInput = z.infer<typeof browserClickSchema>;\n\nexport const browserTypeShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n text: z.string(),\n clear_first: z.boolean().optional(),\n} as const;\nexport const browserTypeSchema = z.object(browserTypeShape);\nexport type BrowserTypeInput = z.infer<typeof browserTypeSchema>;\n\nexport const browserKeyShape = {\n session_id: z.string().min(1),\n key: z.string().min(1),\n} as const;\nexport const browserKeySchema = z.object(browserKeyShape);\nexport type BrowserKeyInput = z.infer<typeof browserKeySchema>;\n\nexport const browserScrollShape = {\n session_id: z.string().min(1),\n direction: z.enum([\"up\", \"down\", \"left\", \"right\"]),\n amount: z.number().int().positive().optional(),\n ref: z.string().min(1).optional(),\n} as const;\nexport const browserScrollSchema = z.object(browserScrollShape);\nexport type BrowserScrollInput = z.infer<typeof browserScrollSchema>;\n\nexport const browserWaitForShape = {\n session_id: z.string().min(1),\n condition: waitConditionSchema,\n timeout_ms: z.number().int().positive().optional(),\n} as const;\nexport const browserWaitForSchema = z.object(browserWaitForShape);\nexport type BrowserWaitForInput = z.infer<typeof browserWaitForSchema>;\n\nexport const browserScreenshotShape = {\n session_id: z.string().min(1),\n full_page: z.boolean().optional(),\n} as const;\nexport const browserScreenshotSchema = z.object(browserScreenshotShape);\nexport type BrowserScreenshotInput = z.infer<typeof browserScreenshotSchema>;\n\nexport const browserNavigateShape = {\n session_id: z.string().min(1),\n url: z.string().url(),\n} as const;\nexport const browserNavigateSchema = z.object(browserNavigateShape);\nexport type BrowserNavigateInput = z.infer<typeof browserNavigateSchema>;\n\n// ---------------------------------------------------------------------------\n// v0.5 atomic additions\n// ---------------------------------------------------------------------------\n\nexport const browserHoverShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n} as const;\nexport const browserHoverSchema = z.object(browserHoverShape);\nexport type BrowserHoverInput = z.infer<typeof browserHoverSchema>;\n\nexport const browserDragShape = {\n session_id: z.string().min(1),\n from_ref: z.string().min(1),\n to_ref: z.string().min(1),\n} as const;\nexport const browserDragSchema = z.object(browserDragShape);\nexport type BrowserDragInput = z.infer<typeof browserDragSchema>;\n\nexport const fillFieldKindSchema = z.enum([\n \"input\",\n \"select\",\n \"checkbox\",\n \"radio\",\n]);\n\nexport const fillFormFieldSchema = z.object({\n ref: z.string().min(1),\n value: z.union([z.string(), z.boolean()]),\n kind: fillFieldKindSchema.optional(),\n});\n\nexport const browserFillFormShape = {\n session_id: z.string().min(1),\n fields: z.array(fillFormFieldSchema).min(1),\n} as const;\nexport const browserFillFormSchema = z.object(browserFillFormShape);\nexport type BrowserFillFormInput = z.infer<typeof browserFillFormSchema>;\n\nexport const browserUploadFileShape = {\n session_id: z.string().min(1),\n ref: z.string().min(1),\n file_path: z.string().min(1),\n} as const;\nexport const browserUploadFileSchema = z.object(browserUploadFileShape);\nexport type BrowserUploadFileInput = z.infer<typeof browserUploadFileSchema>;\n\nexport const dialogActionSchema = z.enum([\n \"accept\",\n \"dismiss\",\n \"accept_with_text\",\n]);\n\nexport const browserHandleDialogShape = {\n session_id: z.string().min(1),\n action: dialogActionSchema,\n /** Only used when action='accept_with_text'. */\n text: z.string().optional(),\n /**\n * Arming behavior: registers a one-shot handler for the NEXT dialog\n * raised on the page. Call this BEFORE the action that triggers the\n * dialog (e.g. before clicking the button that calls `confirm()`).\n * Default 30s if no dialog appears, handler is auto-removed.\n */\n timeout_ms: z.number().int().positive().optional(),\n} as const;\nexport const browserHandleDialogSchema = z.object(browserHandleDialogShape);\nexport type BrowserHandleDialogInput = z.infer<typeof browserHandleDialogSchema>;\n\nexport const consoleLevelSchema = z.enum([\n \"error\",\n \"warning\",\n \"info\",\n \"log\",\n \"debug\",\n \"trace\",\n]);\n\nexport const browserConsoleShape = {\n session_id: z.string().min(1),\n /** Filter to only these levels. Default: errors+warnings. */\n levels: z.array(consoleLevelSchema).optional(),\n /** Substring match on message text. */\n contains: z.string().optional(),\n /** Drop all buffered messages after returning. */\n clear: z.boolean().default(false),\n /** Cap on returned messages (artifact still holds full ring buffer). */\n limit: z.number().int().positive().max(1000).default(50),\n} as const;\nexport const browserConsoleSchema = z.object(browserConsoleShape);\nexport type BrowserConsoleInput = z.infer<typeof browserConsoleSchema>;\n\nexport const browserNetworkShape = {\n session_id: z.string().min(1),\n /** Substring or regex (per `pattern_kind`) match on URL. */\n url_pattern: z.string().optional(),\n pattern_kind: z.enum([\"substring\", \"regex\"]).default(\"substring\"),\n method: z.string().optional(),\n /** Inclusive range — e.g. `{min: 400, max: 599}` for any error response. */\n status_range: z\n .object({\n min: z.number().int().min(100).max(599),\n max: z.number().int().min(100).max(599),\n })\n .optional(),\n only_failed: z.boolean().default(false),\n /** Write the full HAR file for this session to artifacts/{runId}/network.har. */\n export_har: z.boolean().default(false),\n /** Drop buffered entries after returning. */\n clear: z.boolean().default(false),\n limit: z.number().int().positive().max(1000).default(50),\n} as const;\nexport const browserNetworkSchema = z.object(browserNetworkShape);\nexport type BrowserNetworkInput = z.infer<typeof browserNetworkSchema>;\n\nexport const networkPresetSchema = z.enum([\n \"offline\",\n \"slow-3g\",\n \"fast-3g\",\n \"slow-4g\",\n \"fast-4g\",\n \"no-throttling\",\n]);\n\nexport const geolocationSchema = z.object({\n latitude: z.number().min(-90).max(90),\n longitude: z.number().min(-180).max(180),\n accuracy: z.number().nonnegative().optional(),\n});\n\n/**\n * Runtime environment mutation. Merges resize+emulate. Fields here are\n * the ones Playwright supports changing AFTER context creation. Things\n * that must be set at context-creation time (user_agent, locale,\n * timezone) live on `browser_open` and cannot be changed mid-session.\n *\n * `network_throttle` and `cpu_throttle` are chromium-only (CDP-backed).\n */\nexport const browserSetEnvShape = {\n session_id: z.string().min(1),\n viewport: viewportSchema.optional(),\n offline: z.boolean().optional(),\n geolocation: geolocationSchema.optional(),\n color_scheme: z.enum([\"light\", \"dark\", \"no-preference\"]).optional(),\n reduced_motion: z.enum([\"reduce\", \"no-preference\"]).optional(),\n extra_headers: z.record(z.string(), z.string()).optional(),\n network_throttle: networkPresetSchema.optional(),\n /** CPU slowdown multiplier (1 = no throttle, 4 = 4x slower). Chromium only. */\n cpu_throttle: z.number().min(1).max(20).optional(),\n} as const;\nexport const browserSetEnvSchema = z.object(browserSetEnvShape);\nexport type BrowserSetEnvInput = z.infer<typeof browserSetEnvSchema>;\n\n/**\n * Execute JavaScript in the page context. GATED: server must be started\n * with env `ROLEPOD_ALLOW_EVAL=1`, otherwise the tool returns an\n * `eval_disabled` error. Equivalent to arbitrary code execution — only\n * enable for trusted automation scenarios.\n *\n * `script` is the body of an async function whose return value is sent\n * back as `result`. Use `args` to pass JSON-serialisable values.\n */\nexport const browserEvaluateShape = {\n session_id: z.string().min(1),\n script: z.string().min(1),\n args: z.array(z.unknown()).optional(),\n} as const;\nexport const browserEvaluateSchema = z.object(browserEvaluateShape);\nexport type BrowserEvaluateInput = z.infer<typeof browserEvaluateSchema>;\n\n/**\n * Multi-page support. A session owns one browser context, which may\n * have multiple pages (e.g. when an OAuth popup or `target=\"_blank\"`\n * link opens). The active page index is sticky — all subsequent\n * tool calls operate on it until `switch_page` changes it.\n */\nexport const browserPagesShape = {\n session_id: z.string().min(1),\n} as const;\nexport const browserPagesSchema = z.object(browserPagesShape);\nexport type BrowserPagesInput = z.infer<typeof browserPagesSchema>;\n\nexport const browserSwitchPageShape = {\n session_id: z.string().min(1),\n index: z.number().int().nonnegative(),\n} as const;\nexport const browserSwitchPageSchema = z.object(browserSwitchPageShape);\nexport type BrowserSwitchPageInput = z.infer<typeof browserSwitchPageSchema>;\n\n// ---------------------------------------------------------------------------\n// Composite verify_ui_flow\n//\n// Both `mode: 'assert'` and `mode: 'reproduce'` are implemented (D-025).\n// When mode='reproduce' && passed && minimize, the composite runs a\n// classic ddmin pass over `steps` and adds a `minimized` block to the\n// output carrying the surviving step list and a `replay-minimized.json`\n// artifact path.\n// ---------------------------------------------------------------------------\n\nexport const verifyFillFieldSchema = z.object({\n query: z.string(),\n value: z.union([z.string(), z.boolean()]),\n kind: fillFieldKindSchema.optional(),\n});\n\nexport const verifyStepSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"click\"), query: z.string() }),\n z.object({\n kind: z.literal(\"type\"),\n query: z.string(),\n text: z.string(),\n clear_first: z.boolean().optional(),\n }),\n z.object({ kind: z.literal(\"key\"), key: z.string() }),\n z.object({ kind: z.literal(\"wait_for\"), condition: waitConditionSchema }),\n z.object({ kind: z.literal(\"navigate\"), url: z.string().url() }),\n // v0.5 additions\n z.object({ kind: z.literal(\"hover\"), query: z.string() }),\n z.object({\n kind: z.literal(\"drag\"),\n from_query: z.string(),\n to_query: z.string(),\n }),\n z.object({\n kind: z.literal(\"fill_form\"),\n fields: z.array(verifyFillFieldSchema).min(1),\n }),\n z.object({\n kind: z.literal(\"upload\"),\n query: z.string(),\n file_path: z.string().min(1),\n }),\n z.object({\n kind: z.literal(\"dialog\"),\n action: dialogActionSchema,\n text: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"set_env\"),\n viewport: viewportSchema.optional(),\n offline: z.boolean().optional(),\n geolocation: geolocationSchema.optional(),\n color_scheme: z.enum([\"light\", \"dark\", \"no-preference\"]).optional(),\n reduced_motion: z.enum([\"reduce\", \"no-preference\"]).optional(),\n extra_headers: z.record(z.string(), z.string()).optional(),\n network_throttle: networkPresetSchema.optional(),\n cpu_throttle: z.number().min(1).max(20).optional(),\n }),\n z.object({\n kind: z.literal(\"switch_page\"),\n index: z.number().int().nonnegative(),\n }),\n z.object({ kind: z.literal(\"evaluate\"), script: z.string().min(1) }),\n]);\n\nexport const verifyExpectSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"text_visible\"), text: z.string() }),\n z.object({ kind: z.literal(\"text_absent\"), text: z.string() }),\n z.object({ kind: z.literal(\"url_matches\"), pattern: z.string() }),\n z.object({\n kind: z.literal(\"ref_in_state\"),\n query: z.string(),\n state: z.enum([\"visible\", \"enabled\", \"focused\"]),\n }),\n // v0.5 additions\n z.object({\n kind: z.literal(\"no_console_errors\"),\n exclude_patterns: z.array(z.string()).optional(),\n }),\n z.object({\n kind: z.literal(\"no_failed_requests\"),\n exclude_patterns: z.array(z.string()).optional(),\n /** When true, only 5xx counts as a failure. Default false (4xx + 5xx). */\n allow_4xx: z.boolean().optional(),\n }),\n z.object({\n kind: z.literal(\"request_made\"),\n url_pattern: z.string(),\n method: z.string().optional(),\n min_count: z.number().int().positive().optional(),\n }),\n z.object({\n kind: z.literal(\"response_status\"),\n url_pattern: z.string(),\n status: z.number().int().min(100).max(599),\n }),\n]);\n\nexport const captureKindSchema = z.enum([\n \"screenshot\",\n \"har\",\n \"console\",\n \"a11y_tree\",\n \"video\",\n \"trace\",\n]);\n\nexport const verifyUiFlowShape = {\n mode: z.enum([\"assert\", \"reproduce\"]).default(\"assert\"),\n open: browserOpenSchema,\n steps: z.array(verifyStepSchema).default([]),\n expect: z.array(verifyExpectSchema).default([]),\n capture: z.array(captureKindSchema).optional(),\n close_on_finish: z.boolean().default(true),\n /**\n * Only consulted when `mode='reproduce'`. When true (default) and the\n * initial run reproduces the bug, the composite tries to remove each\n * step in turn and re-runs to find a smaller reproducer.\n */\n minimize: z.boolean().default(true),\n} as const;\nexport const verifyUiFlowSchema = z.object(verifyUiFlowShape);\nexport type VerifyUiFlowInput = z.infer<typeof verifyUiFlowSchema>;\n\n// ---------------------------------------------------------------------------\n// audit_a11y\n// ---------------------------------------------------------------------------\n\nexport const wcagLevelSchema = z.enum([\"wcag-a\", \"wcag-aa\", \"wcag-aaa\"]);\nexport const a11ySeveritySchema = z.enum([\n \"critical\",\n \"serious\",\n \"moderate\",\n \"minor\",\n]);\nexport const auditScopeSchema = z.union([\n z.literal(\"page\"),\n z.object({ ref: z.string().min(1) }),\n]);\n\nexport const auditA11yShape = {\n open: browserOpenSchema,\n level: wcagLevelSchema.default(\"wcag-aa\"),\n scope: auditScopeSchema.default(\"page\"),\n report_format: z.enum([\"json\", \"markdown\"]).default(\"json\"),\n close_on_finish: z.boolean().default(true),\n} as const;\nexport const auditA11ySchema = z.object(auditA11yShape);\nexport type AuditA11yInput = z.infer<typeof auditA11ySchema>;\n\n// ---------------------------------------------------------------------------\n// visual_diff\n// ---------------------------------------------------------------------------\n\nexport const visualDiffShape = {\n open: browserOpenSchema,\n baseline_id: z.string().min(1),\n viewport: viewportSchema.optional(),\n threshold_pct: z.number().min(0).max(1).default(0.1),\n close_on_finish: z.boolean().default(true),\n /** Pixel sensitivity for pixelmatch (0 = strict, 1 = lax). Default 0.1. */\n pixel_threshold: z.number().min(0).max(1).default(0.1),\n} as const;\nexport const visualDiffSchema = z.object(visualDiffShape);\nexport type VisualDiffInput = z.infer<typeof visualDiffSchema>;\n\n// ---------------------------------------------------------------------------\n// scaffold_e2e\n// ---------------------------------------------------------------------------\n\nexport const e2eFrameworkSchema = z.enum([\n \"playwright-test\",\n \"vitest+playwright\",\n \"pytest+selenium\",\n]);\n\nexport const scaffoldE2eShape = {\n framework: e2eFrameworkSchema,\n scenario_nl: z.string().min(1),\n url: z.string().url(),\n recorded_bundle: z.string().min(1).optional(),\n /** Override the generated test file name. */\n filename: z.string().min(1).optional(),\n} as const;\nexport const scaffoldE2eSchema = z.object(scaffoldE2eShape);\nexport type ScaffoldE2eInput = z.infer<typeof scaffoldE2eSchema>;\n\n// ---------------------------------------------------------------------------\n// extract_ui_state — used internally by other shipped skills (not user-facing).\n// ---------------------------------------------------------------------------\n\nexport const extractUiStateShape = {\n session_id: z.string().min(1).optional(),\n open: browserOpenSchema.optional(),\n question_nl: z.string().min(1),\n close_on_finish: z.boolean().default(false),\n} as const;\nexport const extractUiStateSchema = z.object(extractUiStateShape);\nexport type ExtractUiStateInput = z.infer<typeof extractUiStateSchema>;\n\n// ---------------------------------------------------------------------------\n// Tool name registry — single source of truth for tool naming.\n// All names are prefixed `rolepod_*` per brief 03-tool-surface.md.\n// ---------------------------------------------------------------------------\n\nexport const ToolNames = {\n browserOpen: \"rolepod_browser_open\",\n browserClose: \"rolepod_browser_close\",\n browserSnapshot: \"rolepod_browser_snapshot\",\n browserClick: \"rolepod_browser_click\",\n browserType: \"rolepod_browser_type\",\n browserKey: \"rolepod_browser_key\",\n browserScroll: \"rolepod_browser_scroll\",\n browserWaitFor: \"rolepod_browser_wait_for\",\n browserScreenshot: \"rolepod_browser_screenshot\",\n browserNavigate: \"rolepod_browser_navigate\",\n // v0.5 atomics\n browserHover: \"rolepod_browser_hover\",\n browserDrag: \"rolepod_browser_drag\",\n browserFillForm: \"rolepod_browser_fill_form\",\n browserUploadFile: \"rolepod_browser_upload_file\",\n browserHandleDialog: \"rolepod_browser_handle_dialog\",\n browserConsole: \"rolepod_browser_console\",\n browserNetwork: \"rolepod_browser_network\",\n browserSetEnv: \"rolepod_browser_set_env\",\n browserEvaluate: \"rolepod_browser_evaluate\",\n browserPages: \"rolepod_browser_pages\",\n browserSwitchPage: \"rolepod_browser_switch_page\",\n // composite\n verifyUiFlow: \"rolepod_verify_ui_flow\",\n auditA11y: \"rolepod_audit_a11y\",\n visualDiff: \"rolepod_visual_diff\",\n scaffoldE2e: \"rolepod_scaffold_e2e\",\n extractUiState: \"rolepod_extract_ui_state\",\n} as const;\n\nexport type ToolName = (typeof ToolNames)[keyof typeof ToolNames];\n","/**\n * Classic delta-debugging minimization (`ddmin`) — Zeller & Hildebrandt,\n * 2002. Given a sequence `input` and a predicate `reproduces(subset)`\n * that returns true when the subset still triggers the target outcome,\n * returns a 1-minimal subset.\n *\n * The algorithm is bounded by `O(N log N)` predicate calls in the\n * common case and `O(N²)` in the worst case — but each call is an\n * expensive browser run, so the caller is encouraged to cap the run\n * count separately if needed.\n */\nexport type DdminPredicate<T> = (subset: T[]) => Promise<boolean>;\n\nexport async function ddmin<T>(input: T[], reproduces: DdminPredicate<T>): Promise<T[]> {\n let current = [...input];\n let n = 2;\n while (current.length >= 2) {\n const chunkSize = Math.max(1, Math.floor(current.length / n));\n let reduced = false;\n\n // Try removing each chunk (delta) one at a time.\n for (let i = 0; i < current.length; i += chunkSize) {\n const complement = [\n ...current.slice(0, i),\n ...current.slice(i + chunkSize),\n ];\n if (complement.length === 0) continue;\n if (await reproduces(complement)) {\n current = complement;\n n = Math.max(n - 1, 2);\n reduced = true;\n break;\n }\n }\n if (reduced) continue;\n\n // No single delta worked — increase granularity.\n if (n >= current.length) break;\n n = Math.min(n * 2, current.length);\n }\n return current;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Extension Protocol v1 — manifest.json schema.\n *\n * Parent `rolepod` plugin's `check-work` skill scans `.rolepod/evidence/`\n * for `manifest.json` files and aggregates them into the verify report.\n * uiproof writes one of these in BOTH standalone and with-parent modes —\n * uniform tooling surface, and a user who later installs the parent gets\n * historic artifacts already in the right shape.\n */\nexport const ROLEPOD_PROTOCOL_VERSION = \"rolepod/v1\" as const;\n\nexport type ManifestPhase = \"verify\" | \"debug\" | \"build\" | \"review\";\nexport type ManifestStatus = \"pass\" | \"fail\" | \"warn\";\n\nexport type ManifestArtifact = {\n type: string;\n path: string;\n};\n\nexport type ManifestInput = {\n runDir: string;\n skill: string;\n phase: ManifestPhase;\n status: ManifestStatus;\n summary: string;\n startedAt: string;\n finishedAt: string;\n artifacts: ManifestArtifact[];\n metadata?: Record<string, unknown>;\n};\n\nexport type Manifest = {\n protocol: typeof ROLEPOD_PROTOCOL_VERSION;\n plugin: \"rolepod-uiproof\";\n skill: string;\n phase: ManifestPhase;\n status: ManifestStatus;\n summary: string;\n started_at: string;\n finished_at: string;\n artifacts: ManifestArtifact[];\n metadata: Record<string, unknown>;\n};\n\n/**\n * Write the manifest.json next to the run's other artifacts. Best-effort:\n * any IO failure is logged but never thrown — a missing manifest must not\n * fail an otherwise-successful composite tool call.\n */\nexport async function writeManifest(input: ManifestInput): Promise<string | undefined> {\n const manifest: Manifest = {\n protocol: ROLEPOD_PROTOCOL_VERSION,\n plugin: \"rolepod-uiproof\",\n skill: input.skill,\n phase: input.phase,\n status: input.status,\n summary: input.summary,\n started_at: input.startedAt,\n finished_at: input.finishedAt,\n artifacts: input.artifacts,\n metadata: input.metadata ?? {},\n };\n const path = resolve(input.runDir, \"manifest.json\");\n try {\n await writeFile(path, JSON.stringify(manifest, null, 2), \"utf8\");\n return path;\n } catch (err) {\n log.warn(\"manifest write failed\", {\n run_dir: input.runDir,\n skill: input.skill,\n err: String(err),\n });\n return undefined;\n }\n}\n","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { RolepodMcpError } from \"../util/errors.js\";\n\n/**\n * Pack a successful tool result into the MCP wire format. The same value\n * is emitted both as a text content block (for the Lead to read) and as\n * `structuredContent` (for any client that prefers typed JSON).\n */\nexport function ok(value: unknown): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify(value, null, 2) }],\n structuredContent: value as Record<string, unknown>,\n };\n}\n\n/**\n * Pack a structured error. RolepodMcpError surfaces a stable error code +\n * detail bag; anything else degrades to \"engine_error\" with the message.\n */\nexport function failure(err: unknown): CallToolResult {\n if (err instanceof RolepodMcpError) {\n const payload = err.toJSON();\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n structuredContent: payload as unknown as Record<string, unknown>,\n };\n }\n const message = err instanceof Error ? err.message : String(err);\n const payload = { code: \"engine_error\" as const, message };\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n structuredContent: payload as unknown as Record<string, unknown>,\n };\n}\n\n/** Wrap a handler so any thrown error is converted to a structured failure. */\nexport function safeHandler<Args>(\n fn: (args: Args) => Promise<CallToolResult>,\n): (args: Args) => Promise<CallToolResult> {\n return async (args: Args) => {\n try {\n return await fn(args);\n } catch (err) {\n return failure(err);\n }\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ArtifactStore } from \"./artifact/ArtifactStore.js\";\nimport { createMobileEngine, createWebEngine } from \"./engine/factory.js\";\nimport { SessionRegistry } from \"./session/SessionRegistry.js\";\nimport { browserClickTool } from \"./tools/atomic/browser_click.js\";\nimport { browserCloseTool } from \"./tools/atomic/browser_close.js\";\nimport { browserConsoleTool } from \"./tools/atomic/browser_console.js\";\nimport { browserDragTool } from \"./tools/atomic/browser_drag.js\";\nimport { browserEvaluateTool } from \"./tools/atomic/browser_evaluate.js\";\nimport { browserFillFormTool } from \"./tools/atomic/browser_fill_form.js\";\nimport { browserHandleDialogTool } from \"./tools/atomic/browser_handle_dialog.js\";\nimport { browserHoverTool } from \"./tools/atomic/browser_hover.js\";\nimport { browserKeyTool } from \"./tools/atomic/browser_key.js\";\nimport { browserNavigateTool } from \"./tools/atomic/browser_navigate.js\";\nimport { browserNetworkTool } from \"./tools/atomic/browser_network.js\";\nimport { browserOpenTool } from \"./tools/atomic/browser_open.js\";\nimport { browserPagesTool } from \"./tools/atomic/browser_pages.js\";\nimport { browserScreenshotTool } from \"./tools/atomic/browser_screenshot.js\";\nimport { browserScrollTool } from \"./tools/atomic/browser_scroll.js\";\nimport { browserSetEnvTool } from \"./tools/atomic/browser_set_env.js\";\nimport { browserSnapshotTool } from \"./tools/atomic/browser_snapshot.js\";\nimport { browserSwitchPageTool } from \"./tools/atomic/browser_switch_page.js\";\nimport { browserTypeTool } from \"./tools/atomic/browser_type.js\";\nimport { browserUploadFileTool } from \"./tools/atomic/browser_upload_file.js\";\nimport { browserWaitForTool } from \"./tools/atomic/browser_wait_for.js\";\nimport { auditA11yTool } from \"./tools/composite/audit_a11y.js\";\nimport { extractUiStateTool } from \"./tools/composite/extract_ui_state.js\";\nimport { scaffoldE2eTool } from \"./tools/composite/scaffold_e2e.js\";\nimport { verifyUiFlowTool } from \"./tools/composite/verify_ui_flow.js\";\nimport { visualDiffTool } from \"./tools/composite/visual_diff.js\";\nimport { toolMetadata } from \"./tools/metadata.js\";\nimport type { ToolContext } from \"./tools/types.js\";\nimport { log } from \"./util/log.js\";\nimport { detectRolepodParent } from \"./util/rolepodProtocol.js\";\n\nexport const SERVER_NAME = \"rolepod-uiproof\";\nexport const SERVER_VERSION = \"0.6.2\";\n\n/**\n * Extension Protocol version this build implements. Compared at server\n * start against the protocol string in the marker file content, read by\n * `detectRolepodParent()` (see `src/util/rolepodProtocol.ts`).\n */\nexport const SUPPORTED_PROTOCOL = \"v1\" as const;\n\n/**\n * Warn (don't fail) when the parent `rolepod` plugin signals a protocol\n * version we don't implement. Skipping the check would let a parent on a\n * future v2 silently get mis-shaped evidence; throwing would break older\n * parents that haven't dropped the marker at all.\n */\nfunction checkProtocolCompat(): void {\n const parent = detectRolepodParent();\n if (!parent.active || !parent.protocol) return;\n if (parent.protocol !== SUPPORTED_PROTOCOL) {\n // eslint-disable-next-line no-console\n console.warn(\n `rolepod protocol mismatch: expected ${SUPPORTED_PROTOCOL}, got ${parent.protocol}. ` +\n `Manifest will still be written in ${SUPPORTED_PROTOCOL} shape — parent may not parse it correctly.`,\n );\n }\n}\n\nexport type ServerHandle = {\n mcp: McpServer;\n registry: SessionRegistry;\n store: ArtifactStore;\n shutdown(): Promise<void>;\n};\n\n/**\n * Build the MCP server with every v0.1 tool registered. Caller is\n * responsible for choosing a transport (stdio for production, in-memory\n * for tests) and invoking `mcp.connect(transport)`.\n */\nexport function buildServer(\n opts: { artifactRoot?: string; idleTimeoutMs?: number } = {},\n): ServerHandle {\n checkProtocolCompat();\n\n const webEngine = createWebEngine();\n const registry = new SessionRegistry({ idleTimeoutMs: opts.idleTimeoutMs });\n registry.register(\"web\", webEngine);\n // Mobile engines are lazy — the webdriverio import only fires when an\n // `ios`/`android` session is actually opened. So registering Appium\n // unconditionally is safe for web-only installs.\n const mobileEngine = createMobileEngine();\n registry.register(\"ios\", mobileEngine);\n registry.register(\"android\", mobileEngine);\n\n const storeOpts: ConstructorParameters<typeof ArtifactStore>[0] = {};\n if (opts.artifactRoot !== undefined) storeOpts.rootDir = opts.artifactRoot;\n const store = new ArtifactStore(storeOpts);\n\n const ctx: ToolContext = { registry, store };\n\n const mcp = new McpServer({\n name: SERVER_NAME,\n version: SERVER_VERSION,\n });\n\n const tools = [\n // atomic (v0.1-v0.4)\n browserOpenTool,\n browserCloseTool,\n browserSnapshotTool,\n browserClickTool,\n browserTypeTool,\n browserKeyTool,\n browserScrollTool,\n browserWaitForTool,\n browserScreenshotTool,\n browserNavigateTool,\n // atomic (v0.5)\n browserHoverTool,\n browserDragTool,\n browserFillFormTool,\n browserUploadFileTool,\n browserHandleDialogTool,\n browserConsoleTool,\n browserNetworkTool,\n browserSetEnvTool,\n browserEvaluateTool,\n browserPagesTool,\n browserSwitchPageTool,\n // composite\n verifyUiFlowTool,\n auditA11yTool,\n visualDiffTool,\n scaffoldE2eTool,\n extractUiStateTool,\n ] as const;\n\n for (const t of tools) {\n const meta = toolMetadata[t.name as keyof typeof toolMetadata];\n mcp.registerTool(\n t.name,\n {\n title: meta?.title,\n description: t.description,\n inputSchema: t.inputShape,\n annotations: meta?.annotations,\n },\n t.build(ctx) as Parameters<typeof mcp.registerTool>[2],\n );\n }\n\n log.info(\"rolepod-uiproof server built\", {\n version: SERVER_VERSION,\n protocol: SUPPORTED_PROTOCOL,\n mode: store.mode,\n tools: tools.map((t) => t.name),\n });\n\n return {\n mcp,\n registry,\n store,\n async shutdown() {\n await registry.shutdown();\n await mcp.close().catch(() => undefined);\n },\n };\n}\n","import { browserClickShape, ToolNames, type BrowserClickInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserClickTool: ToolModule<typeof browserClickShape> = {\n name: ToolNames.browserClick,\n description:\n \"Click the element identified by `ref` from the most recent snapshot. Invalidates all refs on success.\",\n inputShape: browserClickShape,\n build(ctx) {\n return safeHandler(async (args: BrowserClickInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.click(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.ref,\n args.button ? { button: args.button } : undefined,\n );\n return ok({ clicked: true });\n });\n },\n};\n","import { browserCloseShape, ToolNames, type BrowserCloseInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserCloseTool: ToolModule<typeof browserCloseShape> = {\n name: ToolNames.browserClose,\n description: \"Close an open session and free its browser / driver resources.\",\n inputShape: browserCloseShape,\n build(ctx) {\n return safeHandler(async (args: BrowserCloseInput) => {\n const platform = ctx.registry.platformOf(args.session_id);\n await ctx.registry.close({ id: args.session_id, platform });\n return ok({ closed: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserConsoleShape,\n ToolNames,\n type BrowserConsoleInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserConsoleTool: ToolModule<typeof browserConsoleShape> = {\n name: ToolNames.browserConsole,\n description:\n \"List console messages emitted by the active page since the session opened (or since the last `clear`). Filters: `levels` (default: errors+warnings), substring `contains`, and `limit` (default 50, max 1000). Set `clear: true` to drain the buffer after returning. Read-only.\",\n inputShape: browserConsoleShape,\n build(ctx) {\n return safeHandler(async (args: BrowserConsoleInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"console is web-only and requires PlaywrightEngine.\",\n );\n }\n // Default: errors + warnings only (token-conscious).\n const levels: BrowserConsoleInput[\"levels\"] =\n args.levels && args.levels.length > 0\n ? args.levels\n : [\"error\", \"warning\"];\n const messages = engine.getConsole(args.session_id, {\n levels,\n ...(args.contains !== undefined ? { contains: args.contains } : {}),\n clear: args.clear,\n limit: args.limit,\n });\n return ok({\n count: messages.length,\n messages,\n });\n });\n },\n};\n","import {\n browserDragShape,\n ToolNames,\n type BrowserDragInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserDragTool: ToolModule<typeof browserDragShape> = {\n name: ToolNames.browserDrag,\n description:\n \"Drag the element identified by `from_ref` onto the element identified by `to_ref`. Both refs come from the most recent snapshot. Invalidates all refs on success.\",\n inputShape: browserDragShape,\n build(ctx) {\n return safeHandler(async (args: BrowserDragInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.drag(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.from_ref,\n args.to_ref,\n );\n return ok({ dragged: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserEvaluateShape,\n ToolNames,\n type BrowserEvaluateInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\n/**\n * Gating: this tool executes ARBITRARY JavaScript in the page context,\n * which can read DOM state, mutate it, or exfiltrate data. It is disabled\n * by default and only registers a working handler when the server was\n * started with the env var `ROLEPOD_ALLOW_EVAL=1`. Otherwise the tool is\n * still listed (so callers can discover the capability) but every call\n * returns an `eval_disabled` error.\n */\nexport const browserEvaluateTool: ToolModule<typeof browserEvaluateShape> = {\n name: ToolNames.browserEvaluate,\n description:\n \"Execute JavaScript in the active page's context. The `script` is the body of an async function — use `return` for the result and reference inputs via the implicit `args` array. DISABLED unless the MCP server was launched with `ROLEPOD_ALLOW_EVAL=1`; intended for trusted automation setups only (state seeding, computed-style reads, synthetic event dispatch).\",\n inputShape: browserEvaluateShape,\n build(ctx) {\n const allowed = process.env.ROLEPOD_ALLOW_EVAL === \"1\";\n return safeHandler(async (args: BrowserEvaluateInput) => {\n if (!allowed) {\n throw new RolepodMcpError(\n \"engine_error\",\n \"browser_evaluate is disabled. Restart the rolepod-uiproof MCP server with the env var ROLEPOD_ALLOW_EVAL=1 to enable arbitrary JavaScript execution in the page context.\",\n );\n }\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"evaluate is web-only and requires PlaywrightEngine.\",\n );\n }\n const result = await engine.evaluate(\n args.session_id,\n args.script,\n args.args,\n );\n return ok({ result });\n });\n },\n};\n","import {\n browserFillFormShape,\n ToolNames,\n type BrowserFillFormInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserFillFormTool: ToolModule<typeof browserFillFormShape> = {\n name: ToolNames.browserFillForm,\n description:\n \"Batch-fill multiple form fields (inputs, selects, checkboxes, radios) in one call. Each field needs a `ref` from the latest snapshot and a `value`; pass `kind` to disambiguate non-input controls. Token-efficient alternative to a sequence of `type` calls. Invalidates all refs on success.\",\n inputShape: browserFillFormShape,\n build(ctx) {\n return safeHandler(async (args: BrowserFillFormInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.fillForm(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.fields,\n );\n return ok({ filled: args.fields.length });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserHandleDialogShape,\n ToolNames,\n type BrowserHandleDialogInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserHandleDialogTool: ToolModule<\n typeof browserHandleDialogShape\n> = {\n name: ToolNames.browserHandleDialog,\n description:\n \"Pre-arm a one-shot handler for the NEXT JavaScript dialog (`alert`/`confirm`/`prompt`/`beforeunload`) on the active page. Call this BEFORE the action that triggers the dialog (e.g. before clicking the button that calls `confirm()`). Returns when the dialog fires or the timeout (default 30s) elapses. Un-armed dialogs are auto-dismissed so the page does not hang.\",\n inputShape: browserHandleDialogShape,\n build(ctx) {\n return safeHandler(async (args: BrowserHandleDialogInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"handle_dialog is web-only and requires PlaywrightEngine.\",\n );\n }\n const { handled } = await engine.handleDialog(args.session_id, {\n action: args.action,\n ...(args.text !== undefined ? { text: args.text } : {}),\n ...(args.timeout_ms !== undefined ? { timeoutMs: args.timeout_ms } : {}),\n });\n return ok({ handled, action: args.action });\n });\n },\n};\n","import {\n browserHoverShape,\n ToolNames,\n type BrowserHoverInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserHoverTool: ToolModule<typeof browserHoverShape> = {\n name: ToolNames.browserHover,\n description:\n \"Hover the pointer over the element identified by `ref`. Refs remain valid afterwards (read-mostly).\",\n inputShape: browserHoverShape,\n build(ctx) {\n return safeHandler(async (args: BrowserHoverInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.hover(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.ref,\n );\n return ok({ hovered: true });\n });\n },\n};\n","import { browserKeyShape, ToolNames, type BrowserKeyInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserKeyTool: ToolModule<typeof browserKeyShape> = {\n name: ToolNames.browserKey,\n description:\n \"Press a single key (e.g. 'Enter', 'Tab', 'Escape'). Invalidates all refs on success.\",\n inputShape: browserKeyShape,\n build(ctx) {\n return safeHandler(async (args: BrowserKeyInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.key({ id: args.session_id, platform: ctx.registry.platformOf(args.session_id) }, args.key);\n return ok({ pressed: true });\n });\n },\n};\n","import {\n browserNavigateShape,\n ToolNames,\n type BrowserNavigateInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserNavigateTool: ToolModule<typeof browserNavigateShape> = {\n name: ToolNames.browserNavigate,\n description:\n \"Navigate the session to a new URL (web only). Invalidates all refs on success.\",\n inputShape: browserNavigateShape,\n build(ctx) {\n return safeHandler(async (args: BrowserNavigateInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.navigate({ id: args.session_id, platform: ctx.registry.platformOf(args.session_id) }, args.url);\n return ok({ navigated: true, url: args.url });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserNetworkShape,\n ToolNames,\n type BrowserNetworkInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserNetworkTool: ToolModule<typeof browserNetworkShape> = {\n name: ToolNames.browserNetwork,\n description:\n \"List network requests captured on the active page. Filters: `url_pattern` (substring or regex via `pattern_kind`), `method`, `status_range`, `only_failed`. Set `export_har: true` to require the session to have been opened with HAR recording — see `verify_ui_flow` capture=[\\\"har\\\"] or call `browser_open` with capture.har=true. Read-only unless `clear: true`.\",\n inputShape: browserNetworkShape,\n build(ctx) {\n return safeHandler(async (args: BrowserNetworkInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"network is web-only and requires PlaywrightEngine.\",\n );\n }\n const requests = engine.getNetwork(args.session_id, {\n ...(args.url_pattern !== undefined ? { urlPattern: args.url_pattern } : {}),\n patternKind: args.pattern_kind,\n ...(args.method !== undefined ? { method: args.method } : {}),\n ...(args.status_range !== undefined\n ? { statusRange: args.status_range }\n : {}),\n onlyFailed: args.only_failed,\n clear: args.clear,\n limit: args.limit,\n });\n const failed = requests.filter(\n (r) => !!r.failure || (r.status !== undefined && r.status >= 400),\n ).length;\n return ok({\n count: requests.length,\n failed_count: failed,\n requests,\n // HAR file lives wherever the session was opened with\n // `capture.har.path`. We don't echo it here to avoid leaking\n // filesystem paths into untrusted logs; the verify_ui_flow run\n // result surfaces it in `evidence_paths.har`.\n har_recording: args.export_har\n ? \"HAR is written at session close to the path passed via capture.har at open time.\"\n : undefined,\n });\n });\n },\n};\n","import { browserOpenShape, ToolNames, type BrowserOpenInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserOpenTool: ToolModule<typeof browserOpenShape> = {\n name: ToolNames.browserOpen,\n description:\n \"Open a new browser or mobile session against a target. v0.1 supports platform='web' only; mobile lands in v0.3.\",\n inputShape: browserOpenShape,\n build(ctx) {\n return safeHandler(async (args: BrowserOpenInput) => {\n const session = await ctx.registry.open(args);\n return ok({ session_id: session.id, platform: session.platform });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserPagesShape,\n ToolNames,\n type BrowserPagesInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserPagesTool: ToolModule<typeof browserPagesShape> = {\n name: ToolNames.browserPages,\n description:\n \"List all pages currently open in the session's browser context — typically just the main page, plus any popups, OAuth windows, or `target=_blank` tabs that the page itself opened. Each entry carries `{ index, url, title, active }`. Read-only.\",\n inputShape: browserPagesShape,\n build(ctx) {\n return safeHandler(async (args: BrowserPagesInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"pages is web-only and requires PlaywrightEngine.\",\n );\n }\n const raw = engine.listPages(args.session_id);\n // Resolve titles (best-effort — closed pages reject).\n const pages = await Promise.all(\n raw.map(async (p) => ({\n index: p.index,\n url: p.url,\n title: await p.title_promise.catch(() => \"\"),\n active: p.active,\n })),\n );\n return ok({ count: pages.length, pages });\n });\n },\n};\n","import {\n browserScreenshotShape,\n ToolNames,\n type BrowserScreenshotInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserScreenshotTool: ToolModule<typeof browserScreenshotShape> = {\n name: ToolNames.browserScreenshot,\n description:\n \"Capture a screenshot and save under ./.rolepod-uiproof/artifacts/{run_id}/. Set `full_page: true` for full-page capture; default is viewport only. Read-only (does NOT invalidate refs).\",\n inputShape: browserScreenshotShape,\n build(ctx) {\n return safeHandler(async (args: BrowserScreenshotInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const { runId, runDir } = await ctx.store.startRun(\"snap\");\n const buf = await engine.screenshot(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.full_page ?? false,\n );\n const path = await ctx.store.writeScreenshot(runDir, buf, \"shot\");\n return ok({\n run_id: runId,\n path,\n width: undefined,\n height: undefined,\n bytes: buf.byteLength,\n });\n });\n },\n};\n","import { browserScrollShape, ToolNames, type BrowserScrollInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserScrollTool: ToolModule<typeof browserScrollShape> = {\n name: ToolNames.browserScroll,\n description:\n \"Scroll the page (or a specific scrollable element when `ref` is set) by `amount` pixels in `direction`. Invalidates all refs on success.\",\n inputShape: browserScrollShape,\n build(ctx) {\n return safeHandler(async (args: BrowserScrollInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.scroll(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.direction,\n args.amount,\n args.ref,\n );\n return ok({ scrolled: true });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserSetEnvShape,\n ToolNames,\n type BrowserSetEnvInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSetEnvTool: ToolModule<typeof browserSetEnvShape> = {\n name: ToolNames.browserSetEnv,\n description:\n \"Mutate session environment at runtime: viewport, offline state, geolocation, color_scheme (`light`/`dark`), reduced_motion, extra HTTP headers, network throttle preset (`slow-3g`/`fast-3g`/`slow-4g`/`fast-4g`/`offline`/`no-throttling`), and CPU throttle multiplier. `network_throttle` and `cpu_throttle` are chromium-only (CDP). `user_agent`, `locale`, and `timezone` cannot be changed mid-session — set them at `browser_open` time. Invalidates all refs.\",\n inputShape: browserSetEnvShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSetEnvInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"set_env is web-only and requires PlaywrightEngine.\",\n );\n }\n await engine.setEnv(args.session_id, {\n ...(args.viewport !== undefined ? { viewport: args.viewport } : {}),\n ...(args.offline !== undefined ? { offline: args.offline } : {}),\n ...(args.geolocation !== undefined\n ? { geolocation: args.geolocation }\n : {}),\n ...(args.color_scheme !== undefined\n ? { colorScheme: args.color_scheme }\n : {}),\n ...(args.reduced_motion !== undefined\n ? { reducedMotion: args.reduced_motion }\n : {}),\n ...(args.extra_headers !== undefined\n ? { extraHeaders: args.extra_headers }\n : {}),\n ...(args.network_throttle !== undefined\n ? { networkThrottle: args.network_throttle }\n : {}),\n ...(args.cpu_throttle !== undefined\n ? { cpuThrottle: args.cpu_throttle }\n : {}),\n });\n return ok({ applied: true });\n });\n },\n};\n","import {\n browserSnapshotShape,\n ToolNames,\n type BrowserSnapshotInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSnapshotTool: ToolModule<typeof browserSnapshotShape> = {\n name: ToolNames.browserSnapshot,\n description:\n \"Return the current accessibility tree with stable refs (e1, e2, …). Refs are valid only until the next state-changing call (D-010).\",\n inputShape: browserSnapshotShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSnapshotInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const snap = await engine.snapshot(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.mode,\n );\n return ok({\n session_id: snap.session_id,\n url_or_screen: snap.url_or_screen,\n tree: snap.tree,\n taken_at: snap.taken_at,\n });\n });\n },\n};\n","import { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n browserSwitchPageShape,\n ToolNames,\n type BrowserSwitchPageInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserSwitchPageTool: ToolModule<typeof browserSwitchPageShape> = {\n name: ToolNames.browserSwitchPage,\n description:\n \"Set the active page for subsequent tool calls. Use `browser_pages` to discover indexes. Switching invalidates all refs because each page has its own DOM. Page 0 is the main page; popups land at higher indexes in the order they opened.\",\n inputShape: browserSwitchPageShape,\n build(ctx) {\n return safeHandler(async (args: BrowserSwitchPageInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"switch_page is web-only and requires PlaywrightEngine.\",\n );\n }\n await engine.switchPage(args.session_id, args.index);\n return ok({ active_index: args.index });\n });\n },\n};\n","import { browserTypeShape, ToolNames, type BrowserTypeInput } from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserTypeTool: ToolModule<typeof browserTypeShape> = {\n name: ToolNames.browserType,\n description:\n \"Type `text` into the element identified by `ref`. Set `clear_first: true` to replace the existing value. Invalidates all refs on success.\",\n inputShape: browserTypeShape,\n build(ctx) {\n return safeHandler(async (args: BrowserTypeInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.type(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.ref,\n args.text,\n args.clear_first ? { clearFirst: true } : undefined,\n );\n return ok({ typed: true });\n });\n },\n};\n","import {\n browserUploadFileShape,\n ToolNames,\n type BrowserUploadFileInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserUploadFileTool: ToolModule<typeof browserUploadFileShape> = {\n name: ToolNames.browserUploadFile,\n description:\n \"Attach a local file to the `<input type=file>` element identified by `ref`. `file_path` MUST be an absolute path on the host filesystem. Invalidates all refs on success.\",\n inputShape: browserUploadFileShape,\n build(ctx) {\n return safeHandler(async (args: BrowserUploadFileInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n await engine.uploadFile(\n {\n id: args.session_id,\n platform: ctx.registry.platformOf(args.session_id),\n },\n args.ref,\n args.file_path,\n );\n return ok({ uploaded: true, file_path: args.file_path });\n });\n },\n};\n","import {\n browserWaitForShape,\n ToolNames,\n type BrowserWaitForInput,\n} from \"../../schema/tools.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const browserWaitForTool: ToolModule<typeof browserWaitForShape> = {\n name: ToolNames.browserWaitFor,\n description:\n \"Wait until a condition holds: text_visible, ref_exists, url_matches, or idle. Defaults to a 10s timeout. Invalidates all refs on success.\",\n inputShape: browserWaitForShape,\n build(ctx) {\n return safeHandler(async (args: BrowserWaitForInput) => {\n const engine = ctx.registry.engineFor(args.session_id);\n const start = Date.now();\n await engine.waitFor(\n { id: args.session_id, platform: ctx.registry.platformOf(args.session_id) },\n args.condition,\n args.timeout_ms,\n );\n return ok({ matched: true, waited_ms: Date.now() - start });\n });\n },\n};\n","import AxeBuilder from \"@axe-core/playwright\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n auditA11yShape,\n ToolNames,\n type AuditA11yInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport {\n writeManifest,\n type ManifestArtifact,\n type ManifestStatus,\n} from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nconst TAGS_BY_LEVEL: Record<AuditA11yInput[\"level\"], string[]> = {\n \"wcag-a\": [\"wcag2a\", \"wcag21a\"],\n \"wcag-aa\": [\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\"],\n \"wcag-aaa\": [\n \"wcag2a\",\n \"wcag2aa\",\n \"wcag2aaa\",\n \"wcag21a\",\n \"wcag21aa\",\n \"wcag21aaa\",\n ],\n};\n\nconst AXE_TO_SEVERITY: Record<string, \"critical\" | \"serious\" | \"moderate\" | \"minor\"> = {\n critical: \"critical\",\n serious: \"serious\",\n moderate: \"moderate\",\n minor: \"minor\",\n};\n\nexport const auditA11yTool: ToolModule<typeof auditA11yShape> = {\n name: ToolNames.auditA11y,\n description:\n \"Run an accessibility audit on the page using axe-core. Returns issues grouped by severity with WCAG references and fix suggestions. v0.2: scope='page' only.\",\n inputShape: auditA11yShape,\n build(ctx) {\n return safeHandler(async (args: AuditA11yInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"audit\",\n { skill: \"audit-a11y\" },\n );\n const session = await ctx.registry.open(args.open);\n const engine = ctx.registry.engineFor(session.id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"audit_a11y currently requires PlaywrightEngine (mobile a11y audit lands later).\",\n );\n }\n const page = engine.getPageForSession(session.id);\n\n let reportPath: string | undefined;\n let issues: Array<Record<string, unknown>> = [];\n let scopeTagged = false;\n try {\n // Tag the scope element so axe-core can include it via CSS.\n if (args.scope !== \"page\") {\n // refresh refIndex so the supplied ref is meaningful\n await engine.snapshot({ id: session.id, platform: \"web\" });\n const ref = args.scope.ref;\n const locator = page.locator(`aria-ref=${ref}`);\n if ((await locator.count()) === 0) {\n throw new RolepodMcpError(\n \"unknown_ref\",\n `Ref \"${ref}\" not found in the current snapshot.`,\n { session_id: session.id, ref },\n );\n }\n await locator\n .first()\n .evaluate((el) => el.setAttribute(\"data-rolepod-axe-scope\", \"true\"));\n scopeTagged = true;\n }\n\n const builder = new AxeBuilder({ page }).withTags(TAGS_BY_LEVEL[args.level]);\n if (scopeTagged) builder.include(\"[data-rolepod-axe-scope]\");\n const results = await builder.analyze();\n issues = results.violations.flatMap((v) =>\n v.nodes.map((n, idx) => ({\n wcag_ref: pickWcagRef(v.tags) ?? v.id,\n severity: AXE_TO_SEVERITY[v.impact ?? \"minor\"] ?? \"minor\",\n ref: `${v.id}#${idx}`,\n description: v.help,\n fix_suggestion: v.helpUrl,\n target: n.target.join(\" \"),\n })),\n );\n\n const payload = {\n run_id: runId,\n level: args.level,\n counts: countBySeverity(issues),\n issues,\n };\n if (args.report_format === \"markdown\") {\n reportPath = await ctx.store.writeReport(\n runDir,\n \"report.md\",\n renderMarkdown(payload),\n );\n } else {\n reportPath = await ctx.store.writeReport(\n runDir,\n \"report.json\",\n JSON.stringify(payload, null, 2),\n );\n }\n } finally {\n if (scopeTagged) {\n await page\n .locator(\"[data-rolepod-axe-scope]\")\n .first()\n .evaluate((el) => el.removeAttribute(\"data-rolepod-axe-scope\"))\n .catch(() => undefined);\n }\n if (args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n\n const counts = countBySeverity(issues);\n const status = a11yStatus(counts);\n const artifacts: ManifestArtifact[] = reportPath\n ? [{ type: \"report\", path: reportPath }]\n : [];\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status,\n summary: buildAuditSummary(args.level, counts, status),\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts,\n metadata: {\n level: args.level,\n scope: args.scope,\n counts,\n report_format: args.report_format,\n },\n });\n\n return ok({\n run_id: runId,\n counts,\n issues,\n report_path: reportPath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n });\n },\n};\n\n/**\n * Graduated status mapping for a11y audits — keeps `warn` signal that a\n * strict pass/fail would discard.\n *\n * critical + serious > 0 → fail (blocking issues)\n * moderate + minor > 0 → warn (worth surfacing, not blocking)\n * no issues → pass\n */\nfunction a11yStatus(counts: Record<string, number>): ManifestStatus {\n if ((counts.critical ?? 0) + (counts.serious ?? 0) > 0) return \"fail\";\n if ((counts.moderate ?? 0) + (counts.minor ?? 0) > 0) return \"warn\";\n return \"pass\";\n}\n\nfunction buildAuditSummary(\n level: string,\n counts: Record<string, number>,\n status: ManifestStatus,\n): string {\n const total =\n (counts.critical ?? 0) +\n (counts.serious ?? 0) +\n (counts.moderate ?? 0) +\n (counts.minor ?? 0);\n if (status === \"pass\") return `${level}: 0 issues`;\n return `${level}: ${total} issue(s) — critical=${counts.critical ?? 0}, serious=${counts.serious ?? 0}, moderate=${counts.moderate ?? 0}, minor=${counts.minor ?? 0}`;\n}\n\nfunction pickWcagRef(tags: string[]): string | undefined {\n return tags.find((t) => /^wcag\\d/.test(t));\n}\n\nfunction countBySeverity(\n issues: Array<Record<string, unknown>>,\n): Record<string, number> {\n const out: Record<string, number> = {\n critical: 0,\n serious: 0,\n moderate: 0,\n minor: 0,\n };\n for (const i of issues) {\n const s = String(i.severity);\n out[s] = (out[s] ?? 0) + 1;\n }\n return out;\n}\n\nfunction renderMarkdown(p: {\n run_id: string;\n level: string;\n counts: Record<string, number>;\n issues: Array<Record<string, unknown>>;\n}): string {\n const header = `# A11y audit — ${p.run_id}\\n\\nLevel: \\`${p.level}\\`\\n\\n## Counts\\n\\n- critical: ${p.counts.critical}\\n- serious: ${p.counts.serious}\\n- moderate: ${p.counts.moderate}\\n- minor: ${p.counts.minor}\\n\\n## Issues\\n\\n`;\n const body = p.issues\n .map(\n (i) =>\n `### ${i.severity} — ${i.description}\\n\\n- WCAG: ${i.wcag_ref}\\n- Target: \\`${i.target}\\`\\n- Fix: ${i.fix_suggestion}\\n`,\n )\n .join(\"\\n\");\n return header + body;\n}\n","import {\n extractUiStateShape,\n ToolNames,\n type A11yNode,\n type ExtractUiStateInput,\n} from \"../../schema/tools.js\";\nimport type { Session } from \"../../engine/Engine.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\n/**\n * Returns the most-relevant accessibility-tree subtree plus the refs\n * matched by the question. **No LLM is invoked** — the Lead interprets\n * the returned subtree.\n */\nexport const extractUiStateTool: ToolModule<typeof extractUiStateShape> = {\n name: ToolNames.extractUiState,\n description:\n \"Return the AT-tree subtree most likely to answer a natural-language question, plus matched refs. No LLM is called — the Lead does the interpretation.\",\n inputShape: extractUiStateShape,\n build(ctx) {\n return safeHandler(async (args: ExtractUiStateInput) => {\n let session: Session;\n let openedHere = false;\n if (args.session_id) {\n const platform = ctx.registry.platformOf(args.session_id);\n session = { id: args.session_id, platform };\n } else if (args.open) {\n session = await ctx.registry.open(args.open);\n openedHere = true;\n } else {\n throw new RolepodMcpError(\n \"invalid_input\",\n \"Provide either `session_id` (existing session) or `open` (to start one).\",\n );\n }\n\n try {\n const engine = ctx.registry.engineFor(session.id);\n const snap = await engine.snapshot(session);\n const tokens = tokenize(args.question_nl);\n const matches = scoreTree(snap.tree, tokens);\n const top = matches[0];\n const subtree = top\n ? (top.subtree as A11yNode)\n : snap.tree;\n const matchedRefs = matches.slice(0, 8).map((m) => m.ref);\n\n let confidence: \"high\" | \"medium\" | \"low\" = \"low\";\n if (top) {\n if (top.score >= tokens.length && tokens.length > 0) confidence = \"high\";\n else if (top.score >= Math.max(1, Math.ceil(tokens.length / 2)))\n confidence = \"medium\";\n }\n\n return ok({\n snapshot_ref: snap.taken_at,\n confidence,\n matched_refs: matchedRefs,\n value: subtree,\n url_or_screen: snap.url_or_screen,\n });\n } finally {\n if (openedHere && args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n });\n },\n};\n\nfunction tokenize(q: string): string[] {\n return q\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .split(/\\s+/)\n .filter((t) => t.length >= 2);\n}\n\ntype ScoredMatch = {\n ref: string;\n score: number;\n subtree: A11yNode;\n};\n\nfunction scoreTree(root: A11yNode, tokens: string[]): ScoredMatch[] {\n const matches: ScoredMatch[] = [];\n const visit = (node: A11yNode, ancestors: A11yNode[]): void => {\n const hay = `${node.name ?? \"\"} ${node.value ?? \"\"}`.toLowerCase();\n let score = 0;\n for (const t of tokens) if (hay.includes(t)) score += 1;\n if (score > 0) {\n // surface the matching node plus one ancestor for context\n const subtree = ancestors.length > 0 ? ancestors[ancestors.length - 1]! : node;\n matches.push({ ref: node.ref, score, subtree });\n }\n if (node.children) {\n for (const c of node.children) visit(c, [...ancestors, node]);\n }\n };\n visit(root, []);\n matches.sort((a, b) => b.score - a.score);\n return matches;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport {\n scaffoldE2eShape,\n ToolNames,\n type ScaffoldE2eInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\ntype Step = { kind: string; [k: string]: unknown };\ntype Expect = { kind: string; [k: string]: unknown };\ntype ReplayShape = {\n version: number;\n open?: { url?: string };\n steps?: Step[];\n expect?: Expect[];\n};\n\nexport const scaffoldE2eTool: ToolModule<typeof scaffoldE2eShape> = {\n name: ToolNames.scaffoldE2e,\n description:\n \"Generate a runnable e2e test file (playwright-test, vitest+playwright, or pytest+selenium) from a scenario description and optional replay bundle from a prior verify_ui_flow run.\",\n inputShape: scaffoldE2eShape,\n build(ctx) {\n return safeHandler(async (args: ScaffoldE2eInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"scaffold\",\n { skill: \"scaffold-e2e\" },\n );\n const slug = slugify(args.scenario_nl);\n const bundle = args.recorded_bundle\n ? await loadReplay(args.recorded_bundle)\n : null;\n const ctxObj = { args, slug, bundle };\n\n let body: string;\n let language: \"typescript\" | \"python\";\n let filename: string;\n let dependencies: string[];\n let setupNotes: string;\n\n switch (args.framework) {\n case \"playwright-test\":\n body = renderPlaywrightTest(ctxObj);\n language = \"typescript\";\n filename = args.filename ?? `${slug}.spec.ts`;\n dependencies = [\"@playwright/test\"];\n setupNotes =\n \"Install: `npm i -D @playwright/test && npx playwright install`. Run: `npx playwright test`.\";\n break;\n case \"vitest+playwright\":\n body = renderVitestPlaywright(ctxObj);\n language = \"typescript\";\n filename = args.filename ?? `${slug}.test.ts`;\n dependencies = [\"vitest\", \"playwright\"];\n setupNotes =\n \"Install: `npm i -D vitest playwright && npx playwright install chromium`. Run: `npx vitest`.\";\n break;\n case \"pytest+selenium\":\n body = renderPytestSelenium(ctxObj);\n language = \"python\";\n filename = args.filename ?? `test_${slug}.py`;\n dependencies = [\"pytest\", \"selenium\"];\n setupNotes =\n \"Install: `pip install pytest selenium`. Ensure a Chrome driver is on PATH. Run: `pytest`.\";\n break;\n default:\n throw new RolepodMcpError(\n \"invalid_input\",\n `Unknown framework \"${args.framework}\".`,\n );\n }\n\n const path = await ctx.store.writeReport(runDir, filename, body);\n\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"build\",\n status: \"pass\",\n summary: `generated ${args.framework} test \"${filename}\" from ${bundle ? \"replay bundle\" : \"scenario\"}`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: [{ type: \"test_file\", path }],\n metadata: {\n framework: args.framework,\n language,\n from_replay_bundle: Boolean(bundle),\n },\n });\n\n return ok({\n run_id: runId,\n test_file_path: path,\n language,\n dependencies,\n setup_notes: setupNotes,\n from_replay_bundle: Boolean(bundle),\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n });\n },\n};\n\nasync function loadReplay(bundlePath: string): Promise<ReplayShape> {\n const raw = await readFile(resolve(bundlePath), \"utf8\");\n return JSON.parse(raw) as ReplayShape;\n}\n\nfunction slugify(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 40) || \"scenario\"\n );\n}\n\ntype RenderCtx = {\n args: ScaffoldE2eInput;\n slug: string;\n bundle: ReplayShape | null;\n};\n\nfunction renderPlaywrightTest(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(playwrightStepLine).join(\"\\n\")\n : ` // TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(playwrightExpectLine).join(\"\\n\")\n : ` // TODO: add expectations`;\n return [\n `import { test, expect } from \"@playwright/test\";`,\n ``,\n `test(${JSON.stringify(c.args.scenario_nl)}, async ({ page }) => {`,\n ` await page.goto(${JSON.stringify(url)});`,\n stepLines,\n expectLines,\n `});`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction renderVitestPlaywright(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(playwrightStepLine).join(\"\\n\")\n : ` // TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(playwrightExpectLine).join(\"\\n\")\n : ` // TODO: add expectations`;\n return [\n `import { test } from \"vitest\";`,\n `import { chromium, expect } from \"playwright/test\";`,\n ``,\n `test(${JSON.stringify(c.args.scenario_nl)}, async () => {`,\n ` const browser = await chromium.launch();`,\n ` const page = await browser.newPage();`,\n ` try {`,\n ` await page.goto(${JSON.stringify(url)});`,\n indent(stepLines, 2),\n indent(expectLines, 2),\n ` } finally {`,\n ` await browser.close();`,\n ` }`,\n `});`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction renderPytestSelenium(c: RenderCtx): string {\n const url = c.bundle?.open?.url ?? c.args.url;\n const stepLines = c.bundle?.steps?.length\n ? c.bundle.steps.map(seleniumStepLine).join(\"\\n\")\n : ` # TODO: implement steps for: ${c.args.scenario_nl}`;\n const expectLines = c.bundle?.expect?.length\n ? c.bundle.expect.map(seleniumExpectLine).join(\"\\n\")\n : ` # TODO: add expectations`;\n return [\n `import pytest`,\n `from selenium import webdriver`,\n `from selenium.webdriver.common.by import By`,\n `from selenium.webdriver.common.keys import Keys`,\n ``,\n `def test_${slugifyPy(c.args.scenario_nl)}():`,\n ` \"\"\"${c.args.scenario_nl}\"\"\"`,\n ` driver = webdriver.Chrome()`,\n ` try:`,\n ` driver.get(${JSON.stringify(url)})`,\n indent(stepLines, 2),\n indent(expectLines, 2),\n ` finally:`,\n ` driver.quit()`,\n ``,\n ].join(\"\\n\");\n}\n\nfunction playwrightStepLine(step: Step): string {\n switch (step.kind) {\n case \"click\":\n return ` await page.getByText(${JSON.stringify(step.query)}, { exact: false }).first().click();`;\n case \"type\":\n return ` await page.getByRole(\"textbox\", { name: ${JSON.stringify(step.query)} }).fill(${JSON.stringify(step.text)});`;\n case \"key\":\n return ` await page.keyboard.press(${JSON.stringify(step.key)});`;\n case \"navigate\":\n return ` await page.goto(${JSON.stringify(step.url)});`;\n case \"wait_for\":\n return ` // wait_for: ${JSON.stringify(step.condition)} — translate to page.waitForXxx()`;\n case \"hover\":\n return ` await page.getByText(${JSON.stringify(step.query)}, { exact: false }).first().hover();`;\n case \"drag\":\n return [\n ` await page`,\n ` .getByText(${JSON.stringify(step.from_query)}, { exact: false })`,\n ` .first()`,\n ` .dragTo(page.getByText(${JSON.stringify(step.to_query)}, { exact: false }).first());`,\n ].join(\"\\n\");\n case \"fill_form\": {\n const fields = Array.isArray(step.fields) ? (step.fields as Array<{ query: string; value: unknown; kind?: string }>) : [];\n return fields\n .map((f) => {\n const q = JSON.stringify(f.query);\n if (f.kind === \"select\") {\n return ` await page.getByLabel(${q}).selectOption(${JSON.stringify(String(f.value))});`;\n }\n if (f.kind === \"checkbox\" || f.kind === \"radio\") {\n const checked = typeof f.value === \"boolean\"\n ? f.value\n : String(f.value) === \"true\" || String(f.value) === \"on\";\n return ` await page.getByLabel(${q}).setChecked(${checked});`;\n }\n return ` await page.getByLabel(${q}).fill(${JSON.stringify(String(f.value))});`;\n })\n .join(\"\\n\");\n }\n case \"upload\":\n return ` await page.getByLabel(${JSON.stringify(step.query)}).setInputFiles(${JSON.stringify(step.file_path)});`;\n case \"dialog\":\n return [\n ` page.once(\"dialog\", async (dialog) => {`,\n step.action === \"accept\"\n ? ` await dialog.accept();`\n : step.action === \"accept_with_text\"\n ? ` await dialog.accept(${JSON.stringify(step.text ?? \"\")});`\n : ` await dialog.dismiss();`,\n ` });`,\n ].join(\"\\n\");\n case \"set_env\": {\n const lines: string[] = [];\n if (step.viewport && typeof step.viewport === \"object\") {\n const v = step.viewport as { width: number; height: number };\n lines.push(` await page.setViewportSize({ width: ${v.width}, height: ${v.height} });`);\n }\n if (step.offline !== undefined) {\n lines.push(` await page.context().setOffline(${Boolean(step.offline)});`);\n }\n if (step.geolocation) {\n lines.push(` await page.context().setGeolocation(${JSON.stringify(step.geolocation)});`);\n }\n if (step.color_scheme || step.reduced_motion) {\n const opts: Record<string, unknown> = {};\n if (step.color_scheme) opts.colorScheme = step.color_scheme;\n if (step.reduced_motion) opts.reducedMotion = step.reduced_motion;\n lines.push(` await page.emulateMedia(${JSON.stringify(opts)});`);\n }\n if (step.extra_headers) {\n lines.push(` await page.context().setExtraHTTPHeaders(${JSON.stringify(step.extra_headers)});`);\n }\n if (step.network_throttle || step.cpu_throttle !== undefined) {\n lines.push(` // network/cpu throttle requires CDP — see Playwright docs (chromium only)`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : ` // set_env: nothing to apply`;\n }\n case \"switch_page\":\n return ` const allPages = page.context().pages(); /* switch to index ${step.index} */ if (allPages[${step.index}]) await allPages[${step.index}].bringToFront();`;\n case \"evaluate\":\n return ` await page.evaluate(${JSON.stringify(step.script)});`;\n default:\n return ` // unsupported step kind: ${step.kind}`;\n }\n}\n\nfunction playwrightExpectLine(exp: Expect): string {\n switch (exp.kind) {\n case \"text_visible\":\n return ` await expect(page.getByText(${JSON.stringify(exp.text)}, { exact: false }).first()).toBeVisible();`;\n case \"text_absent\":\n return ` await expect(page.getByText(${JSON.stringify(exp.text)}, { exact: false }).first()).toHaveCount(0);`;\n case \"url_matches\":\n return ` await expect(page).toHaveURL(new RegExp(${JSON.stringify(exp.pattern)}));`;\n case \"ref_in_state\":\n return ` // ref_in_state ${JSON.stringify(exp.query)} → ${String(exp.state)} — translate as needed`;\n case \"no_console_errors\":\n return [\n ` // no_console_errors — collect via page.on('console') before the steps, then:`,\n ` // expect(consoleErrors).toEqual([]);`,\n ].join(\"\\n\");\n case \"no_failed_requests\":\n return [\n ` // no_failed_requests — collect via page.on('requestfailed'/'response') before the steps, then:`,\n ` // expect(failedRequests).toEqual([]);`,\n ].join(\"\\n\");\n case \"request_made\":\n return ` await page.waitForRequest(new RegExp(${JSON.stringify(exp.url_pattern)}));`;\n case \"response_status\":\n return ` await page.waitForResponse((r) => new RegExp(${JSON.stringify(exp.url_pattern)}).test(r.url()) && r.status() === ${Number(exp.status)});`;\n default:\n return ` // unsupported expect kind: ${exp.kind}`;\n }\n}\n\nfunction seleniumStepLine(step: Step): string {\n switch (step.kind) {\n case \"click\":\n return ` driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.query))}\\\\\")]\").click()`;\n case \"type\":\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${escapePy(String(step.query))}\\\\\" or @placeholder=\\\\\"${escapePy(String(step.query))}\\\\\"]\").send_keys(${JSON.stringify(step.text)})`;\n case \"key\":\n return ` driver.switch_to.active_element.send_keys(Keys.${pyKeyName(String(step.key))})`;\n case \"navigate\":\n return ` driver.get(${JSON.stringify(step.url)})`;\n case \"wait_for\":\n return ` # wait_for: ${JSON.stringify(step.condition)} — translate to WebDriverWait`;\n case \"hover\":\n return [\n ` from selenium.webdriver.common.action_chains import ActionChains`,\n ` target = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.query))}\\\\\")]\")`,\n ` ActionChains(driver).move_to_element(target).perform()`,\n ].join(\"\\n\");\n case \"drag\":\n return [\n ` from selenium.webdriver.common.action_chains import ActionChains`,\n ` src = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.from_query))}\\\\\")]\")`,\n ` dst = driver.find_element(By.XPATH, f\"//*[contains(text(), \\\\\"${escapePy(String(step.to_query))}\\\\\")]\")`,\n ` ActionChains(driver).drag_and_drop(src, dst).perform()`,\n ].join(\"\\n\");\n case \"fill_form\": {\n const fields = Array.isArray(step.fields)\n ? (step.fields as Array<{ query: string; value: unknown; kind?: string }>)\n : [];\n return fields\n .map((f) => {\n const q = escapePy(f.query);\n if (f.kind === \"select\") {\n return [\n ` from selenium.webdriver.support.ui import Select`,\n ` Select(driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\")).select_by_visible_text(${JSON.stringify(String(f.value))})`,\n ].join(\"\\n\");\n }\n if (f.kind === \"checkbox\" || f.kind === \"radio\") {\n const checked =\n typeof f.value === \"boolean\"\n ? f.value\n : String(f.value) === \"true\";\n return ` el = driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\"); el.click() if el.is_selected() != ${checked ? \"True\" : \"False\"} else None`;\n }\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${q}\\\\\"]\").send_keys(${JSON.stringify(String(f.value))})`;\n })\n .join(\"\\n\");\n }\n case \"upload\":\n return ` driver.find_element(By.XPATH, f\"//*[@aria-label=\\\\\"${escapePy(String(step.query))}\\\\\"]\").send_keys(${JSON.stringify(step.file_path)})`;\n case \"dialog\":\n return [\n ` alert = driver.switch_to.alert`,\n step.action === \"accept\"\n ? ` alert.accept()`\n : step.action === \"accept_with_text\"\n ? ` alert.send_keys(${JSON.stringify(step.text ?? \"\")}); alert.accept()`\n : ` alert.dismiss()`,\n ].join(\"\\n\");\n case \"set_env\": {\n const lines: string[] = [];\n if (step.viewport && typeof step.viewport === \"object\") {\n const v = step.viewport as { width: number; height: number };\n lines.push(` driver.set_window_size(${v.width}, ${v.height})`);\n }\n lines.push(` # set_env partially supported in Selenium — see selenium docs for offline/geolocation/colorScheme via CDP`);\n return lines.join(\"\\n\");\n }\n case \"switch_page\":\n return ` driver.switch_to.window(driver.window_handles[${step.index}])`;\n case \"evaluate\":\n return ` driver.execute_script(${JSON.stringify(step.script)})`;\n default:\n return ` # unsupported step kind: ${step.kind}`;\n }\n}\n\nfunction seleniumExpectLine(exp: Expect): string {\n switch (exp.kind) {\n case \"text_visible\":\n return ` assert ${JSON.stringify(exp.text)} in driver.page_source`;\n case \"text_absent\":\n return ` assert ${JSON.stringify(exp.text)} not in driver.page_source`;\n case \"url_matches\":\n return ` import re; assert re.search(${JSON.stringify(exp.pattern)}, driver.current_url)`;\n case \"ref_in_state\":\n return ` # ref_in_state ${JSON.stringify(exp.query)} → ${String(exp.state)}`;\n case \"no_console_errors\":\n return [\n ` # no_console_errors — read browser logs via driver.get_log(\"browser\")`,\n ` errors = [l for l in driver.get_log(\"browser\") if l.get(\"level\") == \"SEVERE\"]`,\n ` assert errors == [], f\"console errors: {errors}\"`,\n ].join(\"\\n\");\n case \"no_failed_requests\":\n return ` # no_failed_requests — selenium has no built-in network capture. Enable selenium-wire or BiDi for this.`;\n case \"request_made\":\n return ` # request_made ${JSON.stringify(exp.url_pattern)} — use selenium-wire (driver.requests) or BiDi`;\n case \"response_status\":\n return ` # response_status ${JSON.stringify(exp.url_pattern)} == ${Number(exp.status)} — use selenium-wire (driver.requests) or BiDi`;\n default:\n return ` # unsupported expect kind: ${exp.kind}`;\n }\n}\n\nfunction slugifyPy(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 40) || \"scenario\"\n );\n}\n\nfunction escapePy(s: string): string {\n return s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction pyKeyName(k: string): string {\n const map: Record<string, string> = {\n Enter: \"ENTER\",\n Tab: \"TAB\",\n Escape: \"ESCAPE\",\n Backspace: \"BACK_SPACE\",\n ArrowUp: \"ARROW_UP\",\n ArrowDown: \"ARROW_DOWN\",\n ArrowLeft: \"ARROW_LEFT\",\n ArrowRight: \"ARROW_RIGHT\",\n };\n return map[k] ?? `RETURN # unknown key: ${k}`;\n}\n\nfunction indent(block: string, n: number): string {\n const pad = \" \".repeat(n);\n return block\n .split(\"\\n\")\n .map((l) => (l.length > 0 ? pad + l : l))\n .join(\"\\n\");\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport pixelmatch from \"pixelmatch\";\nimport { PNG } from \"pngjs\";\nimport { PlaywrightEngine } from \"../../engine/PlaywrightEngine.js\";\nimport {\n ToolNames,\n visualDiffShape,\n type VisualDiffInput,\n} from \"../../schema/tools.js\";\nimport { RolepodMcpError } from \"../../util/errors.js\";\nimport { writeManifest, type ManifestArtifact } from \"../../util/manifest.js\";\nimport { ok, safeHandler } from \"../result.js\";\nimport type { ToolModule } from \"../types.js\";\n\nexport const visualDiffTool: ToolModule<typeof visualDiffShape> = {\n name: ToolNames.visualDiff,\n description:\n \"Capture a screenshot and compare against a named baseline under ./.rolepod-uiproof/baselines/. First call for a baseline_id seeds the baseline (passed=true, diff_pct=0). Subsequent calls return the diff percentage and an annotated diff image.\",\n inputShape: visualDiffShape,\n build(ctx) {\n return safeHandler(async (args: VisualDiffInput) => {\n const startedAt = new Date().toISOString();\n const { runId, runDir, skill } = await ctx.store.startRun(\n \"vdiff\",\n { skill: \"visual-diff\" },\n );\n const session = await ctx.registry.open({\n ...args.open,\n ...(args.viewport ? { viewport: args.viewport } : {}),\n });\n const engine = ctx.registry.engineFor(session.id);\n if (!(engine instanceof PlaywrightEngine)) {\n throw new RolepodMcpError(\n \"unsupported_engine\",\n \"visual_diff currently requires PlaywrightEngine.\",\n );\n }\n\n try {\n const buf = await engine.screenshot(\n { id: session.id, platform: session.platform },\n true,\n );\n const currentPath = await ctx.store.writeScreenshot(runDir, buf, \"current\");\n\n await ctx.store.ensureDir(ctx.store.baselineDir);\n const baselinePath = resolve(\n ctx.store.baselineDir,\n `${args.baseline_id}.png`,\n );\n\n if (!existsSync(baselinePath)) {\n await ctx.store.writeBytes(\n ctx.store.baselineDir,\n `${args.baseline_id}.png`,\n buf,\n );\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: \"pass\",\n summary: `baseline \"${args.baseline_id}\" seeded from current capture`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts: [\n { type: \"baseline\", path: baselinePath },\n { type: \"screenshot\", path: currentPath },\n ],\n metadata: { baseline_id: args.baseline_id, seeded: true },\n });\n return ok({\n run_id: runId,\n baseline_id: args.baseline_id,\n diff_pct: 0,\n passed: true,\n baseline_path: baselinePath,\n current_path: currentPath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n note: \"Baseline did not exist — current capture saved as the new baseline.\",\n });\n }\n\n const [baselineRaw, currentRaw] = await Promise.all([\n readFile(baselinePath),\n readFile(currentPath),\n ]);\n const baseline = PNG.sync.read(baselineRaw);\n const current = PNG.sync.read(currentRaw);\n\n if (baseline.width !== current.width || baseline.height !== current.height) {\n throw new RolepodMcpError(\n \"engine_error\",\n `Dimension mismatch for baseline \"${args.baseline_id}\" — baseline ${baseline.width}x${baseline.height}, current ${current.width}x${current.height}. Delete the baseline or pass a matching viewport.`,\n {\n baseline: { w: baseline.width, h: baseline.height },\n current: { w: current.width, h: current.height },\n },\n );\n }\n\n const diff = new PNG({ width: baseline.width, height: baseline.height });\n const diffPixels = pixelmatch(\n baseline.data,\n current.data,\n diff.data,\n baseline.width,\n baseline.height,\n { threshold: args.pixel_threshold, includeAA: true },\n );\n const total = baseline.width * baseline.height;\n const diffPct = diffPixels / total;\n const passed = diffPct <= args.threshold_pct;\n\n const diffImagePath = await ctx.store.writeBytes(\n runDir,\n \"diff.png\",\n PNG.sync.write(diff),\n );\n\n const artifacts: ManifestArtifact[] = [\n { type: \"baseline\", path: baselinePath },\n { type: \"screenshot\", path: currentPath },\n { type: \"diff\", path: diffImagePath },\n ];\n const manifestPath = await writeManifest({\n runDir,\n skill,\n phase: \"verify\",\n status: passed ? \"pass\" : \"fail\",\n summary: `diff ${(diffPct * 100).toFixed(3)}% vs baseline \"${args.baseline_id}\" (threshold ${(args.threshold_pct * 100).toFixed(3)}%)`,\n startedAt,\n finishedAt: new Date().toISOString(),\n artifacts,\n metadata: {\n baseline_id: args.baseline_id,\n diff_pct: Number(diffPct.toFixed(6)),\n diff_pixels: diffPixels,\n total_pixels: total,\n threshold_pct: args.threshold_pct,\n },\n });\n\n return ok({\n run_id: runId,\n baseline_id: args.baseline_id,\n diff_pct: Number(diffPct.toFixed(6)),\n diff_pixels: diffPixels,\n total_pixels: total,\n passed,\n baseline_path: baselinePath,\n current_path: currentPath,\n diff_image_path: diffImagePath,\n ...(manifestPath ? { manifest: manifestPath } : {}),\n });\n } finally {\n if (args.close_on_finish) {\n await ctx.registry.close(session).catch(() => undefined);\n }\n }\n });\n },\n};\n","import type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ToolNames, type ToolName } from \"../schema/tools.js\";\n\n/**\n * Per-tool display metadata exposed via MCP `registerTool`.\n *\n * - `title`: human-readable label shown in client UIs (Claude Code, Cursor, etc.)\n * - `annotations`: trust-and-safety hints. Per spec these are advisory only —\n * clients still gate on user consent — but they let well-behaved clients\n * auto-approve read-only calls and prompt harder on destructive ones.\n *\n * `destructiveHint`/`idempotentHint` are only meaningful when `readOnlyHint`\n * is false, so we omit them for read-only tools.\n */\nexport type ToolMetadata = {\n title: string;\n annotations: ToolAnnotations;\n};\n\nexport const toolMetadata: Record<ToolName, ToolMetadata> = {\n // ---------- atomic ----------\n [ToolNames.browserOpen]: {\n title: \"Open Browser/Mobile Session\",\n annotations: {\n title: \"Open Browser/Mobile Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserClose]: {\n title: \"Close Session\",\n annotations: {\n title: \"Close Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSnapshot]: {\n title: \"Capture Accessibility Snapshot\",\n annotations: {\n title: \"Capture Accessibility Snapshot\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserClick]: {\n title: \"Click Element\",\n annotations: {\n title: \"Click Element\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserType]: {\n title: \"Type Text\",\n annotations: {\n title: \"Type Text\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserKey]: {\n title: \"Press Key\",\n annotations: {\n title: \"Press Key\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserScroll]: {\n title: \"Scroll Viewport\",\n annotations: {\n title: \"Scroll Viewport\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserWaitFor]: {\n title: \"Wait For Condition\",\n annotations: {\n title: \"Wait For Condition\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserScreenshot]: {\n title: \"Take Screenshot\",\n annotations: {\n title: \"Take Screenshot\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserNavigate]: {\n title: \"Navigate URL\",\n annotations: {\n title: \"Navigate URL\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n\n // ---------- composite ----------\n [ToolNames.verifyUiFlow]: {\n title: \"Verify UI Flow\",\n annotations: {\n title: \"Verify UI Flow\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.auditA11y]: {\n title: \"Audit Accessibility (axe-core)\",\n annotations: {\n title: \"Audit Accessibility (axe-core)\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.visualDiff]: {\n title: \"Visual Diff vs Baseline\",\n annotations: {\n title: \"Visual Diff vs Baseline\",\n // Writes to ./.rolepod-uiproof/{baselines,artifacts}/ but only adds files —\n // never destroys an existing baseline silently.\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.scaffoldE2e]: {\n title: \"Scaffold E2E Test File\",\n annotations: {\n title: \"Scaffold E2E Test File\",\n // Writes a test file to the local repo.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n [ToolNames.extractUiState]: {\n title: \"Extract UI State (NL Query)\",\n annotations: {\n title: \"Extract UI State (NL Query)\",\n readOnlyHint: true,\n openWorldHint: true,\n },\n },\n\n // ---------- v0.5 atomic additions ----------\n [ToolNames.browserHover]: {\n title: \"Hover Element\",\n annotations: {\n title: \"Hover Element\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n [ToolNames.browserDrag]: {\n title: \"Drag Element\",\n annotations: {\n title: \"Drag Element\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserFillForm]: {\n title: \"Fill Form (Batch)\",\n annotations: {\n title: \"Fill Form (Batch)\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserUploadFile]: {\n title: \"Upload File\",\n annotations: {\n title: \"Upload File\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserHandleDialog]: {\n title: \"Pre-arm Dialog Handler\",\n annotations: {\n title: \"Pre-arm Dialog Handler\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n [ToolNames.browserConsole]: {\n title: \"Inspect Console Logs\",\n annotations: {\n title: \"Inspect Console Logs\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserNetwork]: {\n title: \"Inspect Network Requests\",\n annotations: {\n title: \"Inspect Network Requests\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSetEnv]: {\n title: \"Set Browser Environment\",\n annotations: {\n title: \"Set Browser Environment\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserEvaluate]: {\n title: \"Evaluate JavaScript (gated; arbitrary code execution)\",\n annotations: {\n title: \"Evaluate JavaScript\",\n // Arbitrary code execution in the page context. Gated by\n // ROLEPOD_ALLOW_EVAL=1 server-side. Always treat as destructive.\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n [ToolNames.browserPages]: {\n title: \"List Open Pages\",\n annotations: {\n title: \"List Open Pages\",\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n [ToolNames.browserSwitchPage]: {\n title: \"Switch Active Page\",\n annotations: {\n title: \"Switch Active Page\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n};\n"],"mappings":"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","names":["osPlatform","resolve","resolve","existsSync","join","resolve","randomUUID","XMLParser","parser","firstTagName","randomUUID","randomUUID","randomUUID","resolve","resolvePath","writeFile","resolve","resolve","writeFile","payload","resolvePath","resolve","readFile","resolve","readFile","resolve","existsSync","readFile","resolve","resolve","existsSync","manifestPath","readFile"]}