@rallycry/conveyor-agent 8.3.4 → 8.4.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup/bootstrap.ts","../src/connection/agent-connection.ts","../src/runner/mode-controller.ts","../src/runner/lifecycle.ts","../src/runner/git-utils.ts","../src/runner/plan-sync.ts","../src/execution/query-executor.ts","../../shared/dist/index.js","../src/execution/pack-runner-prompt.ts","../src/execution/prompt-formatters.ts","../src/execution/tag-context-resolver.ts","../src/execution/prompt-truncation.ts","../src/execution/mode-prompt.ts","../src/execution/system-prompt.ts","../src/execution/prompt-builder.ts","../src/tools/task-context-tools.ts","../src/tools/dependency-suggestion-tools.ts","../src/tools/mutation-tools.ts","../src/tools/attachment-tools.ts","../src/tools/checklist-tools.ts","../src/tools/common-tools.ts","../src/tools/pm-tools.ts","../src/tools/discovery-tools.ts","../src/tools/code-review-tools.ts","../src/tools/debug-tools.ts","../src/tools/telemetry-tools.ts","../src/debug/telemetry-injector.ts","../src/tools/client-debug-tools.ts","../src/tools/index.ts","../src/execution/event-handlers.ts","../src/execution/event-processor.ts","../src/execution/task-property-utils.ts","../src/execution/tool-access.ts","../src/execution/redactor.ts","../src/execution/cost-tracker.ts","../src/execution/exploration-tracker.ts","../src/runner/query-bridge.ts","../src/runner/session-runner-helpers.ts","../src/runner/parent-pull-handler.ts","../src/runner/session-runner.ts","../src/connection/project-connection.ts","../src/runner/commit-watcher.ts","../src/runner/worktree.ts","../src/setup/commands.ts","../src/tools/project-tools.ts","../src/tools/project-action-tools.ts","../src/tools/project-suggestion-dependency-tools.ts","../src/runner/project-chat-handler.ts","../src/runner/project-runner-helpers.ts","../src/runner/project-runner-children.ts","../src/runner/project-runner-git.ts","../src/runner/project-runner-sync.ts","../src/runner/project-runner.ts","../src/setup/config.ts","../src/setup/codespace.ts"],"sourcesContent":["/**\n * Codespace bootstrap fetch — wraps the `/api/codespace/bootstrap/:name` call\n * with an AbortController timeout, exponential-backoff retries, and structured\n * stderr events the agent-runner-handler can ingest.\n *\n * Used at agent startup (`cli.ts`) and for runtime taskToken refresh when the\n * server signals an auth rejection (`agent-connection.ts`).\n */\n\nexport interface BootstrapConfig {\n mode?: \"task\" | \"project\";\n taskId?: string;\n sessionId?: string;\n taskToken?: string;\n runnerMode?: string;\n agentMode?: string;\n isAuto?: string;\n taskBranch?: string;\n projectId?: string;\n projectToken?: string;\n apiUrl?: string;\n workspaceBranch?: string;\n envVars?: Record<string, string>;\n}\n\nexport interface BootstrapAttemptResult {\n ok: boolean;\n status?: number;\n body?: BootstrapConfig;\n errorText?: string;\n reason?: string;\n}\n\nexport interface BootstrapFailureEvent {\n event: \"bootstrap_failed\";\n reason: string;\n apiUrl: string;\n instanceName: string;\n hasBootstrapToken: boolean;\n hasTaskToken: boolean;\n attempt: number;\n status?: number;\n detail?: string;\n}\n\nconst BOOTSTRAP_TIMEOUT_MS = 30_000;\nconst RETRY_DELAYS_MS = [5_000, 10_000, 20_000];\n\nfunction emitFailureEvent(payload: BootstrapFailureEvent): void {\n process.stderr.write(JSON.stringify(payload) + \"\\n\");\n}\n\nasync function singleBootstrapAttempt(\n apiUrl: string,\n instanceName: string,\n bootstrapToken: string | undefined,\n timeoutMs: number,\n): Promise<BootstrapAttemptResult> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const headers: Record<string, string> = {};\n if (bootstrapToken) headers[\"x-codespace-token\"] = bootstrapToken;\n const response = await fetch(`${apiUrl}/api/codespace/bootstrap/${instanceName}`, {\n headers,\n signal: controller.signal,\n });\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n return {\n ok: false,\n status: response.status,\n errorText: errorText.slice(0, 500),\n reason: response.status === 401 || response.status === 403 ? \"auth_rejected\" : \"http_error\",\n };\n }\n const body = (await response.json()) as BootstrapConfig;\n return { ok: true, body };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const reason = controller.signal.aborted ? \"timeout\" : \"network_error\";\n return { ok: false, errorText: message.slice(0, 500), reason };\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nexport interface FetchBootstrapOptions {\n apiUrl: string;\n instanceName: string;\n bootstrapToken: string | undefined;\n timeoutMs?: number;\n retryDelaysMs?: number[];\n /** Whether to consider any HTTP error retryable. Network/timeout always retry. */\n retryOnHttpError?: boolean;\n}\n\nexport interface FetchBootstrapSuccess {\n ok: true;\n config: BootstrapConfig;\n attempts: number;\n}\n\nexport interface FetchBootstrapFailure {\n ok: false;\n reason: string;\n status?: number;\n detail?: string;\n attempts: number;\n}\n\nfunction buildFailure(\n reason: string,\n attempts: number,\n status: number | undefined,\n detail: string | undefined,\n): FetchBootstrapFailure {\n const out: FetchBootstrapFailure = { ok: false, reason, attempts };\n if (status === undefined) {\n // no status field\n } else {\n out.status = status;\n }\n if (detail) out.detail = detail;\n return out;\n}\n\nfunction isRetryable(reason: string, retryOnHttpError: boolean | undefined): boolean {\n if (reason === \"timeout\" || reason === \"network_error\") return true;\n return retryOnHttpError === true && reason === \"http_error\";\n}\n\n/**\n * Fetch the bootstrap payload with retries. Network errors and timeouts always\n * trigger a retry; HTTP errors are retried only when `retryOnHttpError` is set\n * (off by default — a 401/403/404 won't recover from retries).\n */\nexport async function fetchBootstrap(\n opts: FetchBootstrapOptions,\n): Promise<FetchBootstrapSuccess | FetchBootstrapFailure> {\n const timeoutMs = opts.timeoutMs ?? BOOTSTRAP_TIMEOUT_MS;\n const delays = opts.retryDelaysMs ?? RETRY_DELAYS_MS;\n const maxAttempts = delays.length + 1;\n const hasBootstrapToken = Boolean(opts.bootstrapToken);\n const hasTaskToken = Boolean(process.env.CONVEYOR_TASK_TOKEN);\n\n let lastReason = \"unknown\";\n let lastStatus: number | undefined;\n let lastDetail: string | undefined;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const result = await singleBootstrapAttempt(\n opts.apiUrl,\n opts.instanceName,\n opts.bootstrapToken,\n timeoutMs,\n );\n if (result.ok && result.body) {\n return { ok: true, config: result.body, attempts: attempt };\n }\n lastReason = result.reason ?? \"unknown\";\n lastStatus = result.status;\n lastDetail = result.errorText;\n\n const failurePayload: BootstrapFailureEvent = {\n event: \"bootstrap_failed\",\n reason: lastReason,\n apiUrl: opts.apiUrl,\n instanceName: opts.instanceName,\n hasBootstrapToken,\n hasTaskToken,\n attempt,\n };\n if (lastStatus === undefined) {\n // no status field\n } else {\n failurePayload.status = lastStatus;\n }\n if (lastDetail) failurePayload.detail = lastDetail;\n emitFailureEvent(failurePayload);\n\n if (!isRetryable(lastReason, opts.retryOnHttpError) || attempt >= maxAttempts) {\n return buildFailure(lastReason, attempt, lastStatus, lastDetail);\n }\n await sleep(delays[attempt - 1]);\n }\n\n return buildFailure(lastReason, maxAttempts, lastStatus, lastDetail);\n}\n\n/** Apply a successful bootstrap config to process.env (mutates env vars). */\nexport function applyBootstrapToEnv(config: BootstrapConfig): void {\n for (const [key, value] of Object.entries(config.envVars ?? {})) {\n process.env[key] = value;\n }\n if (config.mode === \"project\") {\n if (config.projectToken) process.env.CONVEYOR_PROJECT_TOKEN = config.projectToken;\n if (config.projectId) process.env.CONVEYOR_PROJECT_ID = config.projectId;\n if (config.workspaceBranch) process.env.CONVEYOR_WORKSPACE_BRANCH = config.workspaceBranch;\n return;\n }\n if (config.taskId) process.env.CONVEYOR_TASK_ID = config.taskId;\n if (config.sessionId) process.env.CONVEYOR_SESSION_ID = config.sessionId;\n if (config.taskToken) process.env.CONVEYOR_TASK_TOKEN = config.taskToken;\n if (config.agentMode !== undefined) process.env.CONVEYOR_AGENT_MODE = config.agentMode;\n if (config.isAuto !== undefined) process.env.CONVEYOR_IS_AUTO = config.isAuto;\n if (config.runnerMode) process.env.CONVEYOR_MODE = config.runnerMode;\n if (config.taskBranch) process.env.CONVEYOR_TASK_BRANCH = config.taskBranch;\n}\n","/* oxlint-disable max-lines -- service method bindings are flat and cohesive; splitting would scatter closely-coupled call wrappers */\nimport { io, type Socket } from \"socket.io-client\";\nimport type {\n AgentSessionServiceMethods,\n AgentMode,\n AgentQuestion,\n SocketResponse,\n} from \"@project/shared\";\nimport type { ModelUsageEntry } from \"../execution/cost-tracker.js\";\nimport { fetchBootstrap, applyBootstrapToEnv } from \"../setup/bootstrap.js\";\n\n// ── Configuration ──────────────────────────────────────────────────────────\n\nexport interface AgentConnectionConfig {\n apiUrl: string;\n taskToken: string;\n sessionId: string;\n runnerMode?: \"task\" | \"pm\" | \"code-review\";\n}\n\n// ── Incoming server-push event types ───────────────────────────────────────\n\nexport interface IncomingMessage {\n content: string;\n userId: string;\n source?: string;\n files?: Array<{ name: string; content: string; mimeType?: string }>;\n}\n\nexport interface SetModeData {\n agentMode: AgentMode;\n}\n\nexport interface ApiKeyUpdateData {\n apiKey: string;\n isSubscription?: boolean;\n}\n\n// ── Connection class ───────────────────────────────────────────────────────\n\nconst EVENT_BATCH_MS = 500;\nconst MAX_EVENT_BUFFER = 5000;\n\nexport class AgentConnection {\n private socket: Socket | null = null;\n private readonly config: AgentConnectionConfig;\n private eventBuffer: Array<{ event: { type: string; [key: string]: unknown } }> = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private lastEmittedStatus: string | null = null;\n private lastReportedStatus: string | null = null;\n private droppedEventCount = 0;\n\n // Pending answer resolvers for askUserQuestion room-event fallback\n private pendingAnswerResolvers = new Map<string, (answers: Record<string, string>) => void>();\n\n // Dedup: suppress near-identical messages within a short window\n private recentMessages: Array<{ words: Set<string>; timestamp: number; preview: string }> = [];\n private static readonly DEDUP_WINDOW_MS = 30_000;\n private static readonly DEDUP_SIMILARITY_THRESHOLD = 0.7;\n private static readonly DEDUP_PREVIEW_LIMIT = 120;\n\n // Early-buffering: events that arrive before callbacks are registered\n private earlyMessages: IncomingMessage[] = [];\n private earlyStop = false;\n private earlySoftStop = false;\n private earlyModeChanges: SetModeData[] = [];\n\n // Registered callbacks\n private messageCallback: ((msg: IncomingMessage) => void) | null = null;\n private stopCallback: (() => void) | null = null;\n private softStopCallback: (() => void) | null = null;\n private modeChangeCallback: ((data: SetModeData) => void) | null = null;\n private apiKeyUpdateCallback: ((data: ApiKeyUpdateData) => void) | null = null;\n private pullBranchCallback: ((data: { branch: string }) => void) | null = null;\n private earlyPullBranches: Array<{ branch: string }> = [];\n\n // PTY relay (S5 terminal). Single-slot callbacks, set per PtySession run.\n private ptyInputCallback: ((data: string) => void) | null = null;\n private ptyResizeCallback: ((cols: number, rows: number) => void) | null = null;\n\n constructor(config: AgentConnectionConfig) {\n this.config = config;\n }\n\n get sessionId(): string {\n return this.config.sessionId;\n }\n\n get connected(): boolean {\n return this.socket?.connected ?? false;\n }\n\n // ── Typed service method call ──────────────────────────────────────────\n\n call<M extends keyof AgentSessionServiceMethods>(\n method: M,\n payload: AgentSessionServiceMethods[M][\"payload\"],\n ): Promise<AgentSessionServiceMethods[M][\"response\"]> {\n if (!this.socket) {\n return Promise.reject(\n new Error(`Not connected (method: ${String(method)}, session: ${this.config.sessionId})`),\n );\n }\n const socket = this.socket;\n return new Promise((resolve, reject) => {\n socket.emit(\n `agentSessionService:${String(method)}`,\n payload,\n (response: SocketResponse<AgentSessionServiceMethods[M][\"response\"]>) => {\n if (response.success && response.data !== undefined) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? `Service call failed: ${String(method)}`));\n }\n },\n );\n });\n }\n\n // ── Connection lifecycle ───────────────────────────────────────────────\n\n // oxlint-disable-next-line max-lines-per-function -- socket setup requires registering many co-located event handlers\n connect(): Promise<void> {\n if (!this.config.apiUrl) {\n return Promise.reject(new Error(\"Cannot connect: apiUrl is empty\"));\n }\n // oxlint-disable-next-line max-lines-per-function -- socket event registration requires co-located handlers\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n process.stderr.write(\n `[conveyor-agent] Connecting to ${this.config.apiUrl} (mode: ${this.config.runnerMode ?? \"task\"}, session: ${this.config.sessionId})\\n`,\n );\n\n this.socket = io(this.config.apiUrl, {\n auth: {\n taskToken: this.config.taskToken,\n runnerMode: this.config.runnerMode ?? \"task\",\n },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: { \"ngrok-skip-browser-warning\": \"true\" },\n });\n\n // ── Server-push event handlers (v7 room-based events) ─────────\n // These events are emitted to the agentSessionService:<sessionId>\n // room. The agent joins this room via the connectAgent() call after\n // the socket connects.\n\n this.socket.on(\"session:message\", (msg: IncomingMessage) => {\n // Preserve source field from server for critical message filtering\n const incoming: IncomingMessage = {\n content: msg.content,\n userId: msg.userId,\n ...(msg.source && { source: msg.source }),\n ...(msg.files && { files: msg.files }),\n };\n if (this.messageCallback) this.messageCallback(incoming);\n else this.earlyMessages.push(incoming);\n });\n\n this.socket.on(\"session:stop\", () => {\n if (this.stopCallback) this.stopCallback();\n else this.earlyStop = true;\n });\n\n this.socket.on(\"session:softStop\", () => {\n if (this.softStopCallback) this.softStopCallback();\n else this.earlySoftStop = true;\n });\n\n this.socket.on(\"session:modeChange\", (data: SetModeData) => {\n if (this.modeChangeCallback) this.modeChangeCallback(data);\n else this.earlyModeChanges.push(data);\n });\n\n this.socket.on(\n \"session:answerQuestion\",\n (data: { requestId: string; answers: Record<string, string> }) => {\n const resolver = this.pendingAnswerResolvers.get(data.requestId);\n if (resolver) resolver(data.answers);\n },\n );\n\n this.socket.on(\"agentRunner:updateApiKey\", (data: ApiKeyUpdateData) => {\n if (this.apiKeyUpdateCallback) this.apiKeyUpdateCallback(data);\n });\n\n this.socket.on(\"session:pullBranch\", (data: { branch: string }) => {\n if (this.pullBranchCallback) this.pullBranchCallback(data);\n else this.earlyPullBranches.push(data);\n });\n\n // PTY relay (S2 → agent): keystrokes and reconciled resizes from the S5\n // terminal. Events are room-scoped so each targets this session; the\n // sessionId guard is defensive. No early-buffer — input/resize are\n // meaningless until a PtySession is live and has registered a callback.\n this.socket.on(\"pty:input\", (data: { sessionId?: string; data: string }) => {\n if (data.sessionId && data.sessionId !== this.config.sessionId) return;\n this.ptyInputCallback?.(data.data);\n });\n\n this.socket.on(\"pty:resize\", (data: { sessionId?: string; cols: number; rows: number }) => {\n if (data.sessionId && data.sessionId !== this.config.sessionId) return;\n this.ptyResizeCallback?.(data.cols, data.rows);\n });\n\n // ── Socket lifecycle events ────────────────────────────────────\n this.socket.on(\"connect\", () => {\n process.stderr.write(\"[conveyor-agent] Socket connected\\n\");\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.on(\"connect_error\", (err: Error) => {\n attempts++;\n process.stderr.write(\n `[conveyor-agent] Connection error (attempt ${attempts}/${maxInitialAttempts}): ${err.message}\\n`,\n );\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(\n new Error(\n `Failed to connect to ${this.config.apiUrl} after ${maxInitialAttempts} attempts: ${err.message}`,\n ),\n );\n }\n });\n\n this.socket.on(\"disconnect\", (reason: string) => {\n process.stderr.write(`[conveyor-agent] Disconnected: ${reason}\\n`);\n // Server-initiated disconnect (auth rejected, session terminated)\n // arrives with reason \"server namespace disconnect\" or\n // \"io server disconnect\". The token may be stale — try refreshing\n // before Socket.IO's transport-level reconnect kicks in.\n if (reason === \"io server disconnect\" || reason === \"server namespace disconnect\") {\n void this.refreshTaskTokenFromBootstrap()\n .then((refreshed) => {\n if (refreshed && this.socket) {\n // socket.io's `io server disconnect` does NOT auto-reconnect\n // — we have to nudge it manually after refreshing the token.\n this.socket.connect();\n }\n })\n .catch(() => {});\n }\n });\n\n this.socket.on(\"auth:rejected\", () => {\n process.stderr.write(\"[conveyor-agent] Auth rejected by server, refreshing taskToken\\n\");\n void this.refreshTaskTokenFromBootstrap().catch(() => {});\n });\n\n this.socket.io.on(\"reconnect\", () => {\n process.stderr.write(\"[conveyor-agent] Reconnected\\n\");\n // Re-join the session room and process any pending messages from the disconnect window\n void this.reconnectToSession();\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n // Attempt counting is handled in connect_error handler above\n });\n });\n }\n\n disconnect(): void {\n // Best-effort flush on disconnect — don't await\n void this.flushEvents();\n if (this.socket) {\n this.socket.io.reconnection(false);\n this.socket.removeAllListeners();\n this.socket.disconnect();\n this.socket = null;\n }\n }\n\n // ── Reconnect with retry ────────────────────────────────────────────\n //\n // Socket.IO already retries the transport forever. This higher-level helper\n // re-issues the `connectAgent` RPC after a successful reconnect to re-join\n // the session room and drain pending messages. We retry indefinitely with a\n // capped exponential backoff — a stranded codespace with a missing agent is\n // worse than a long-running reconnect loop, and a transient API outage\n // shouldn't kill the agent process.\n\n private static readonly RECONNECT_BASE_DELAY_MS = 2_000;\n private static readonly RECONNECT_MAX_DELAY_MS = 60_000;\n private static readonly RECONNECT_STATUS_EVERY_N = 3;\n\n private isReconnecting = false;\n\n private async reconnectToSession(): Promise<void> {\n if (this.isReconnecting) return;\n this.isReconnecting = true;\n try {\n let attempt = 0;\n while (this.socket) {\n attempt++;\n try {\n const { pendingMessages } = await this.call(\"connectAgent\", {\n sessionId: this.config.sessionId,\n });\n this.drainPendingMessages(pendingMessages);\n process.stderr.write(\n `[conveyor-agent] Reconnected to session successfully (attempts: ${attempt})\\n`,\n );\n // Only re-report status if it actually changed since the last\n // successful report — avoids spamming duplicate status transitions\n // through the system on every reconnect.\n if (this.lastEmittedStatus && this.lastEmittedStatus !== this.lastReportedStatus) {\n const status = this.lastEmittedStatus;\n void this.call(\"reportAgentStatus\", {\n sessionId: this.config.sessionId,\n status,\n })\n .then(() => {\n this.lastReportedStatus = status;\n })\n .catch(() => {});\n }\n // Notify UI subscribers that reconnect succeeded.\n this.sendEvent({\n type: \"agent_runner_status\",\n reason: \"reconnected\",\n attempts: attempt,\n });\n return;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n // Capped exponential backoff: 2s, 4s, 8s, 16s, 32s, then 60s steady.\n const delayMs = Math.min(\n AgentConnection.RECONNECT_BASE_DELAY_MS * 2 ** Math.min(attempt - 1, 5),\n AgentConnection.RECONNECT_MAX_DELAY_MS,\n );\n process.stderr.write(\n `[conveyor-agent] connectAgent failed (attempt ${attempt}): ${errMsg} — retrying in ${delayMs / 1000}s\\n`,\n );\n\n // Auth-rejected on the connectAgent RPC — the taskToken may be\n // stale (e.g. after a 24h JWT TTL or a server-side rotation). Try\n // refreshing from the bootstrap endpoint before the next attempt.\n if (this.looksLikeAuthError(errMsg)) {\n void this.refreshTaskTokenFromBootstrap().catch(() => {});\n }\n\n // Every Nth failure, emit a status event so the UI shows we're\n // still trying — piggybacks on the existing `task:agentStatus`\n // pathway via sendEvent (no new socket event needed).\n if (attempt % AgentConnection.RECONNECT_STATUS_EVERY_N === 0) {\n this.sendEvent({\n type: \"agent_runner_status\",\n reason: \"reconnecting\",\n attempt,\n });\n }\n\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n }\n }\n } finally {\n this.isReconnecting = false;\n }\n }\n\n private looksLikeAuthError(message: string): boolean {\n return /unauthor|forbid|auth|token/i.test(message);\n }\n\n private drainPendingMessages(messages: Array<{ content: string; userId: string }>): void {\n for (const msg of messages) {\n if (!msg.content) continue;\n if (this.messageCallback) {\n this.messageCallback({ content: msg.content, userId: msg.userId });\n } else {\n this.earlyMessages.push({ content: msg.content, userId: msg.userId });\n }\n }\n }\n\n // ── Callback registration with early-buffer draining ───────────────\n\n onMessage(callback: (msg: IncomingMessage) => void): void {\n this.messageCallback = callback;\n for (const msg of this.earlyMessages) callback(msg);\n this.earlyMessages = [];\n }\n\n onStop(callback: () => void): void {\n this.stopCallback = callback;\n if (this.earlyStop) {\n callback();\n this.earlyStop = false;\n }\n }\n\n onSoftStop(callback: () => void): void {\n this.softStopCallback = callback;\n if (this.earlySoftStop) {\n callback();\n this.earlySoftStop = false;\n }\n }\n\n onModeChange(callback: (data: SetModeData) => void): void {\n this.modeChangeCallback = callback;\n for (const data of this.earlyModeChanges) callback(data);\n this.earlyModeChanges = [];\n }\n\n onApiKeyUpdate(callback: (data: ApiKeyUpdateData) => void): void {\n this.apiKeyUpdateCallback = callback;\n }\n\n onPullBranch(callback: (data: { branch: string }) => void): void {\n this.pullBranchCallback = callback;\n for (const data of this.earlyPullBranches) callback(data);\n this.earlyPullBranches = [];\n }\n\n // ── PTY relay (S5 Connected-TUI terminal) ──────────────────────────\n\n /**\n * Forward a raw chunk of terminal output to the S2 relay (fire-and-forget).\n * The first chunk creates the server-side scrollback ring, which is what\n * surfaces the terminal in the UI. `dims` seed/refresh the ring geometry.\n */\n sendPtyOutput(data: string, dims?: { cols: number; rows: number }): void {\n if (!this.socket) return;\n void this.call(\"ptyOutput\", {\n sessionId: this.config.sessionId,\n data,\n ...(dims ? { cols: dims.cols, rows: dims.rows } : {}),\n }).catch(() => {});\n }\n\n /** Subscribe to relayed keystrokes. Returns an unsubscribe fn. */\n onPtyInput(handler: (data: string) => void): () => void {\n this.ptyInputCallback = handler;\n return () => {\n if (this.ptyInputCallback === handler) this.ptyInputCallback = null;\n };\n }\n\n /** Subscribe to relayed (reconciled) terminal resizes. Returns an unsubscribe fn. */\n onPtyResize(handler: (cols: number, rows: number) => void): () => void {\n this.ptyResizeCallback = handler;\n return () => {\n if (this.ptyResizeCallback === handler) this.ptyResizeCallback = null;\n };\n }\n\n // ── Convenience methods (thin wrappers around call / emit) ─────────\n\n async emitStatus(status: string): Promise<void> {\n this.lastEmittedStatus = status;\n // Await event flush (e.g. \"completed\") before reporting status change\n // so the API processes \"completed\" before \"idle\" — eliminates the\n // ordering race that caused duplicate completion message spam.\n await this.flushEvents();\n const AWAIT_STATUSES = [\"idle\", \"waiting_for_input\", \"connected\"];\n if (AWAIT_STATUSES.includes(status)) {\n // Critical transition — server must process before agent blocks on waitForMessage()\n try {\n await this.call(\"reportAgentStatus\", {\n sessionId: this.config.sessionId,\n status,\n });\n this.lastReportedStatus = status;\n } catch {\n // Best-effort — proceed even if status report fails.\n // Server-side forwardOrQueue has a DB cross-check fallback.\n }\n } else {\n void this.call(\"reportAgentStatus\", {\n sessionId: this.config.sessionId,\n status,\n })\n .then(() => {\n this.lastReportedStatus = status;\n })\n .catch(() => {});\n }\n }\n\n postChatMessage(content: string): void {\n if (!this.socket) return;\n if (this.suppressIfDuplicate(content)) return;\n void this.call(\"postAgentMessage\", {\n sessionId: this.config.sessionId,\n content,\n }).catch(() => {});\n }\n\n // Awaitable variant of postChatMessage for callers that need to guarantee\n // the message is acknowledged by the server before proceeding (e.g. before\n // aborting the session). Dedup still applies; a suppressed message resolves\n // immediately without hitting the wire.\n async postChatMessageAwait(content: string): Promise<void> {\n if (!this.socket) return;\n if (this.suppressIfDuplicate(content)) return;\n try {\n await this.call(\"postAgentMessage\", {\n sessionId: this.config.sessionId,\n content,\n });\n } catch (err) {\n process.stderr.write(\n `[conveyor-agent] postChatMessageAwait failed: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n }\n\n private suppressIfDuplicate(content: string): boolean {\n const d = this.checkAndTrackDuplicate(content);\n if (!d.duplicate) return false;\n process.stderr.write(\n `[dedup] Suppressed near-duplicate (matched: \"${d.matchedMessagePreview}\")\\n`,\n );\n return true;\n }\n\n // Exposed so `post_to_chat` can surface suppression back to the agent.\n checkAndTrackDuplicate(\n content: string,\n ): { duplicate: false } | { duplicate: true; matchedMessagePreview: string } {\n const now = Date.now();\n this.recentMessages = this.recentMessages.filter(\n (m) => now - m.timestamp < AgentConnection.DEDUP_WINDOW_MS,\n );\n const words = new Set(\n content\n .toLowerCase()\n .replace(/[^\\w\\s]/g, \"\")\n .split(/\\s+/)\n .filter((w) => w.length >= 3),\n );\n if (words.size === 0) return { duplicate: false };\n for (const recent of this.recentMessages) {\n let intersection = 0;\n for (const w of words) if (recent.words.has(w)) intersection++;\n const union = new Set([...words, ...recent.words]).size;\n if (union > 0 && intersection / union > AgentConnection.DEDUP_SIMILARITY_THRESHOLD) {\n return { duplicate: true, matchedMessagePreview: recent.preview };\n }\n }\n const max = AgentConnection.DEDUP_PREVIEW_LIMIT;\n const preview = content.length > max ? content.slice(0, max) + \"…\" : content;\n this.recentMessages.push({ words, timestamp: now, preview });\n if (this.recentMessages.length > 3) this.recentMessages.shift();\n return { duplicate: false };\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n const statusMap: Record<string, \"active\" | \"idle\" | \"building\"> = {\n running: \"active\",\n fetching_context: \"active\",\n connected: \"active\",\n connecting: \"active\",\n idle: \"idle\",\n };\n const heartbeatStatus = statusMap[this.lastEmittedStatus ?? \"idle\"] ?? \"active\";\n void this.call(\"heartbeat\", {\n sessionId: this.config.sessionId,\n timestamp: new Date().toISOString(),\n status: heartbeatStatus,\n }).catch(() => {});\n }\n\n emitModeChanged(agentMode?: AgentMode | null): void {\n this.sendEvent({ type: \"mode_changed\", agentMode });\n }\n\n async updateTaskFields(fields: {\n plan?: string;\n description?: string;\n }): Promise<{ ok: boolean; error?: string }> {\n if (!this.socket) return { ok: false, error: \"socket not connected\" };\n try {\n await this.call(\"updateTaskFields\", { sessionId: this.config.sessionId, ...fields });\n return { ok: true };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n storeSessionId(sdkSessionId: string): void {\n void this.call(\"storeSessionId\", { sessionId: this.config.sessionId, sdkSessionId }).catch(\n () => {},\n );\n }\n\n // ── Typing indicators ───────────────────────────────────────────────\n\n sendTypingStart(): void {\n this.sendEvent({ type: \"agent_typing_start\" });\n }\n\n sendTypingStop(): void {\n this.sendEvent({ type: \"agent_typing_stop\" });\n }\n\n // ── RPC convenience wrappers (v6 compat, will migrate to call()) ───\n\n trackSpending(params: {\n agentId: string;\n sessionId: string;\n totalCostUsd: number;\n onSubscription: boolean;\n modelUsage?: ModelUsageEntry[];\n }): void {\n if (!this.socket) return;\n // Use v7 service method for tracking spending\n void this.call(\"trackSpending\", {\n sessionId: this.config.sessionId,\n inputTokens: params.modelUsage?.reduce((s, m) => s + (m.inputTokens ?? 0), 0) ?? 0,\n outputTokens: params.modelUsage?.reduce((s, m) => s + (m.outputTokens ?? 0), 0) ?? 0,\n costUsd: params.totalCostUsd,\n model: params.modelUsage?.[0]?.model ?? \"unknown\",\n }).catch(() => {});\n }\n\n emitRateLimitPause(resetsAt: string): void {\n this.sendEvent({ type: \"rate_limit_update\", resetsAt });\n }\n\n updateStatus(status: string): void {\n this.emitStatus(status);\n }\n\n emitCodeReviewResult(content: string, approved: boolean): void {\n if (!this.socket) return;\n void this.call(\"submitCodeReviewResult\", {\n sessionId: this.config.sessionId,\n content,\n approved,\n }).catch(() => {});\n }\n\n // ── Question handling ──────────────────────────────────────────────\n\n async askUserQuestion(questions: AgentQuestion[]): Promise<Record<string, string>> {\n const questionText = questions\n .map(\n (q) =>\n `**${q.header}**\\n${q.question}${q.options.length ? \"\\n\" + q.options.map((o) => `- ${o.label}: ${o.description}`).join(\"\\n\") : \"\"}`,\n )\n .join(\"\\n\\n\");\n\n const requestId = crypto.randomUUID();\n\n // Race the RPC callback against the room-event fallback.\n // If the socket disconnects/reconnects while waiting, the RPC callback is\n // lost but the room event (emitted after reconnect to the session room)\n // will still deliver the answer.\n const roomEventPromise = new Promise<Record<string, string>>((resolve) => {\n this.pendingAnswerResolvers.set(requestId, resolve);\n });\n\n const rpcPromise = this.call(\"askUserQuestion\", {\n sessionId: this.config.sessionId,\n question: questionText,\n requestId,\n questions,\n }).then((res) => res.answers);\n\n try {\n return await Promise.race([rpcPromise, roomEventPromise]);\n } finally {\n this.pendingAnswerResolvers.delete(requestId);\n }\n }\n\n // ── Typed service method wrappers ───────────────────────────────────\n\n getTaskProperties(): Promise<{\n plan?: string;\n storyPointId?: string;\n title?: string;\n }> {\n return this.call(\"getTaskProperties\", { sessionId: this.config.sessionId });\n }\n\n triggerIdentification(): Promise<{ identified: boolean }> {\n return this.call(\"triggerIdentification\", { sessionId: this.config.sessionId });\n }\n\n getCumulativeSpending(): Promise<{\n totalCostUsd: number;\n modelUsage: ModelUsageEntry[];\n }> {\n return this.call(\"getCumulativeSpending\", { sessionId: this.config.sessionId });\n }\n\n async refreshAuthToken(): Promise<boolean> {\n const result = await this.refreshFromBootstrap();\n return result.refreshedClaude;\n }\n\n /**\n * Refresh the in-process `CONVEYOR_TASK_TOKEN` from the bootstrap endpoint.\n * Returns true if a new token was applied. Rate-limited locally to once per\n * 60s so a tight auth-rejected loop can't hammer the bootstrap endpoint —\n * the server enforces the same window via `lastBootstrapAt`.\n */\n private lastTaskTokenRefreshAt = 0;\n async refreshTaskTokenFromBootstrap(): Promise<boolean> {\n const result = await this.refreshFromBootstrap();\n return result.refreshedTaskToken;\n }\n\n private async refreshFromBootstrap(): Promise<{\n refreshedClaude: boolean;\n refreshedTaskToken: boolean;\n }> {\n const codespaceName = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;\n const apiUrl = this.config.apiUrl;\n if (!codespaceName || !apiUrl) return { refreshedClaude: false, refreshedTaskToken: false };\n const now = Date.now();\n if (now - this.lastTaskTokenRefreshAt < 60_000) {\n return { refreshedClaude: false, refreshedTaskToken: false };\n }\n this.lastTaskTokenRefreshAt = now;\n const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;\n const result = await fetchBootstrap({\n apiUrl,\n instanceName: codespaceName,\n bootstrapToken,\n // Do not retry on http errors during a runtime refresh — a 401/403\n // means the token is consumed / session terminal and retrying won't\n // help. Network/timeout still retry inside fetchBootstrap.\n });\n if (!result.ok) return { refreshedClaude: false, refreshedTaskToken: false };\n const previousTaskToken = process.env.CONVEYOR_TASK_TOKEN;\n applyBootstrapToEnv(result.config);\n const refreshedTaskToken =\n result.config.mode !== \"project\" &&\n Boolean(result.config.taskToken) &&\n result.config.taskToken !== previousTaskToken;\n if (refreshedTaskToken && result.config.taskToken) {\n this.config.taskToken = result.config.taskToken;\n // Update socket auth so the next reconnect cycle uses the fresh token.\n if (this.socket) {\n const auth = this.socket.auth as Record<string, unknown> | undefined;\n if (auth && typeof auth === \"object\") {\n auth.taskToken = result.config.taskToken;\n }\n }\n }\n const refreshedClaude = Boolean(result.config.envVars?.CLAUDE_CODE_OAUTH_TOKEN);\n return { refreshedClaude, refreshedTaskToken };\n }\n\n // ── Event buffering ────────────────────────────────────────────────\n\n sendEvent(event: { type: string; [key: string]: unknown }): void {\n if (!this.socket) return;\n // Cap the buffer so a long disconnect can't accumulate an unbounded\n // replay storm. Drop oldest on overflow (keeps the most recent state).\n if (this.eventBuffer.length >= MAX_EVENT_BUFFER) {\n this.eventBuffer.shift();\n this.droppedEventCount++;\n if (this.droppedEventCount === 1 || this.droppedEventCount % 500 === 0) {\n process.stderr.write(\n `[conveyor-agent] eventBuffer overflow — dropped ${this.droppedEventCount} event(s) (cap: ${MAX_EVENT_BUFFER})\\n`,\n );\n }\n }\n this.eventBuffer.push({ event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => void this.flushEvents(), EVENT_BATCH_MS);\n }\n }\n\n async flushEvents(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (!this.socket || this.eventBuffer.length === 0) return;\n const events = this.eventBuffer.map((entry) => entry.event);\n this.eventBuffer = [];\n // Await so callers (emitStatus) can guarantee ordering\n await this.call(\"emitAgentEvent\", { sessionId: this.config.sessionId, events }).catch(() => {});\n }\n}\n","import type { AgentMode } from \"@project/shared\";\n\n// ── Mode action types ──────────────────────────────────────────────────────\n\nexport type ModeAction =\n | { type: \"noop\" }\n | { type: \"restart_query\"; newMode: AgentMode }\n | { type: \"soft_stop\" }\n | { type: \"start_auto\" };\n\n// ── Task context subset needed by ModeController ───────────────────────────\n\nexport interface ModeTaskContext {\n status: string;\n plan: string | null;\n storyPointId: string | null;\n isParentTask?: boolean;\n model: string;\n builderModel?: string | null;\n githubPRUrl?: string | null;\n}\n\n// ── ModeController: pure state machine with no I/O ─────────────────────────\n\nexport class ModeController {\n private _mode: AgentMode;\n private _hasExitedPlanMode = false;\n private _pendingModeRestart = false;\n private _runnerMode: \"task\" | \"pm\" | \"code-review\";\n private _isAuto: boolean;\n\n constructor(\n initialMode: AgentMode,\n runnerMode: \"task\" | \"pm\" | \"code-review\" = \"task\",\n isAuto = false,\n ) {\n this._mode = initialMode;\n this._runnerMode = runnerMode;\n this._isAuto = isAuto;\n }\n\n // ── Getters ────────────────────────────────────────────────────────\n\n get mode(): AgentMode {\n return this._mode;\n }\n\n get isAuto(): boolean {\n return this._isAuto;\n }\n\n get hasExitedPlanMode(): boolean {\n return this._hasExitedPlanMode;\n }\n\n set hasExitedPlanMode(val: boolean) {\n this._hasExitedPlanMode = val;\n }\n\n get pendingModeRestart(): boolean {\n return this._pendingModeRestart;\n }\n\n set pendingModeRestart(val: boolean) {\n this._pendingModeRestart = val;\n }\n\n /** Effective mode accounting for PM/task defaults */\n get effectiveMode(): AgentMode {\n if (this._mode) return this._mode;\n if (this._runnerMode === \"pm\") {\n return this._isAuto ? \"auto\" : \"discovery\";\n }\n return \"building\";\n }\n\n get isReadOnly(): boolean {\n const m = this.effectiveMode;\n if ([\"discovery\", \"help\"].includes(m)) return true;\n return m === \"auto\" && !this._hasExitedPlanMode;\n }\n\n get isAutoPlanning(): boolean {\n return this.effectiveMode === \"auto\" && !this._hasExitedPlanMode;\n }\n\n get isBuildCapable(): boolean {\n const m = this.effectiveMode;\n return m === \"building\" || m === \"review\" || (m === \"auto\" && this._hasExitedPlanMode);\n }\n\n /**\n * Apply authoritative mode from the server's task context.\n * Called after getTaskContext to override env-var defaults with the\n * actual task state — ensures pods that launch without CONVEYOR_AGENT_MODE\n * still get the correct mode.\n */\n applyServerMode(agentMode: AgentMode | null | undefined, isAuto: boolean | undefined): void {\n if (agentMode) {\n this._mode = agentMode;\n this._isAuto = agentMode === \"auto\" || !!isAuto;\n } else if (isAuto !== undefined) {\n this._isAuto = isAuto;\n if (isAuto && this._runnerMode === \"pm\" && !this._mode) {\n this._mode = \"auto\";\n }\n }\n\n // Safety net: discovery + isAuto means the server didn't set agentMode correctly\n if (this._isAuto && this._mode === \"discovery\") {\n this._mode = \"auto\";\n }\n }\n\n // ── Mode resolution ────────────────────────────────────────────────\n\n /** Resolve the initial mode based on task context */\n resolveInitialMode(context: ModeTaskContext): AgentMode {\n // Code-review runner maps to unified review mode\n if (this._runnerMode === \"code-review\") {\n this._mode = \"review\";\n return this._mode;\n }\n\n // Auto mode: check if we can bypass planning (already identified or past planning)\n if (this._mode === \"auto\" && this.canBypassPlanning(context)) {\n this.transitionToBuilding(context);\n return this._mode;\n }\n\n return this._mode;\n }\n\n /** Check if auto-mode can bypass planning (task already has plan + properties) */\n canBypassPlanning(context: ModeTaskContext): boolean {\n if (this._mode !== \"auto\") return false;\n if (context.status !== \"Planning\") return true;\n if (context.plan?.trim() && context.storyPointId) return true;\n return false;\n }\n\n // ── Mode transitions ───────────────────────────────────────────────\n\n /** Handle mode change from server */\n handleModeChange(newMode: AgentMode): ModeAction {\n if (newMode === this._mode) return { type: \"noop\" };\n\n // Task runners can transition to review mode (same-box code review)\n if (this._runnerMode === \"task\" && newMode === \"review\") {\n this._mode = newMode;\n return { type: \"restart_query\", newMode: \"review\" };\n }\n\n // Task runners can transition to building mode (server-side auto-advancement)\n if (this._runnerMode === \"task\" && newMode === \"building\") {\n this._mode = newMode;\n this._isAuto = true;\n this._hasExitedPlanMode = true;\n return { type: \"restart_query\", newMode: \"building\" };\n }\n\n // Task runners can transition to auto mode (e.g., Build button after discovery)\n if (this._runnerMode === \"task\" && newMode === \"auto\") {\n this._mode = newMode;\n this._isAuto = true;\n this._hasExitedPlanMode = true;\n return { type: \"restart_query\", newMode: \"auto\" };\n }\n\n // Already building in auto mode — server confirmed via wakeAgentForBuilding.\n // Update mode label but don't restart the running query.\n if (this._mode === \"auto\" && this._hasExitedPlanMode && newMode === \"building\") {\n this._mode = newMode;\n return { type: \"noop\" };\n }\n\n if (this._runnerMode !== \"pm\") return { type: \"noop\" };\n\n this._mode = newMode;\n this.updateExitedPlanModeFlag(newMode);\n\n if (this.isBuildCapable) {\n return { type: \"start_auto\" };\n }\n return { type: \"noop\" };\n }\n\n /** Handle ExitPlanMode call from the agent */\n handleExitPlanMode(context: ModeTaskContext): ModeAction {\n if (this._hasExitedPlanMode) return { type: \"noop\" };\n this.transitionToBuilding(context);\n this._pendingModeRestart = true;\n return { type: \"restart_query\", newMode: this._mode };\n }\n\n /** Check if pack runner behavior should be used */\n isPackRunner(context: ModeTaskContext): boolean {\n return !!context.isParentTask;\n }\n\n // ── Internal helpers ───────────────────────────────────────────────\n\n private transitionToBuilding(context: ModeTaskContext): void {\n this._hasExitedPlanMode = true;\n this._mode = context.isParentTask ? \"review\" : \"building\";\n }\n\n private updateExitedPlanModeFlag(newMode: AgentMode): void {\n if (newMode === \"building\") {\n this._hasExitedPlanMode = true;\n }\n // For auto mode, we can't set the flag without context — it gets\n // set during context fetch or when ExitPlanMode is called\n }\n}\n","// ── Configuration ──────────────────────────────────────────────────────────\n\nexport interface LifecycleConfig {\n /** Idle timeout before the agent stops (default: 30 min) */\n idleTimeoutMs: number;\n /** Dormant timeout — bound on dormant-after-completed wait (default: 60 min).\n * Defense-in-depth: the server-side polling is supposed to shut us down,\n * but if it regresses, the agent shuts itself down here. */\n dormantTimeoutMs: number;\n /** Heartbeat interval (default: 30s) */\n heartbeatIntervalMs: number;\n /** Token refresh interval (default: 45 min — before 1h GitHub token expiry) */\n tokenRefreshIntervalMs: number;\n /** Periodic WIP git flush interval (default: 2 min). Covers ungraceful\n * pod termination (OOMKilled, node eviction) where preStop doesn't run.\n * Set to `0` to disable the timer entirely — used for environments with\n * persistent state (local, workspace, GitHub Codespaces) that don't lose\n * in-flight work on a crash. */\n gitFlushIntervalMs: number;\n}\n\nexport interface LifecycleCallbacks {\n onHeartbeat: () => void;\n onIdleTimeout: () => void;\n onDormantTimeout: () => void;\n onTokenRefresh: () => void;\n onGitFlush: () => void;\n}\n\n// ── Default configuration ──────────────────────────────────────────────────\n\n/** 30 min idle, 60 min dormant, 30s heartbeat, 45 min token refresh, 2 min git flush */\nexport const DEFAULT_LIFECYCLE_CONFIG: LifecycleConfig = {\n idleTimeoutMs: 30 * 60 * 1000,\n dormantTimeoutMs: 60 * 60 * 1000,\n heartbeatIntervalMs: 30_000,\n tokenRefreshIntervalMs: 45 * 60 * 1000,\n gitFlushIntervalMs: 2 * 60 * 1000,\n};\n\n// ── Lifecycle: timer management for idle/heartbeat ───────────────────────\n\nexport class Lifecycle {\n readonly config: LifecycleConfig;\n private readonly callbacks: LifecycleCallbacks;\n\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private tokenRefreshTimer: ReturnType<typeof setInterval> | null = null;\n private idleTimer: ReturnType<typeof setTimeout> | null = null;\n private idleCheckInterval: ReturnType<typeof setInterval> | null = null;\n private dormantTimer: ReturnType<typeof setTimeout> | null = null;\n private gitFlushTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(config: LifecycleConfig, callbacks: LifecycleCallbacks) {\n this.config = config;\n this.callbacks = callbacks;\n }\n\n // ── Heartbeat ──────────────────────────────────────────────────────\n\n startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n this.callbacks.onHeartbeat();\n }, this.config.heartbeatIntervalMs);\n }\n\n stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // ── Token refresh ─────────────────────────────────────────────────\n\n startTokenRefresh(): void {\n this.stopTokenRefresh();\n // Immediately refresh to ensure we have a fresh token at startup\n this.callbacks.onTokenRefresh();\n this.tokenRefreshTimer = setInterval(() => {\n this.callbacks.onTokenRefresh();\n }, this.config.tokenRefreshIntervalMs);\n }\n\n stopTokenRefresh(): void {\n if (this.tokenRefreshTimer) {\n clearInterval(this.tokenRefreshTimer);\n this.tokenRefreshTimer = null;\n }\n }\n\n // ── Periodic git flush ────────────────────────────────────────────\n\n startGitFlush(): void {\n this.stopGitFlush();\n if (this.config.gitFlushIntervalMs <= 0) return;\n this.gitFlushTimer = setInterval(() => {\n this.callbacks.onGitFlush();\n }, this.config.gitFlushIntervalMs);\n }\n\n stopGitFlush(): void {\n if (this.gitFlushTimer) {\n clearInterval(this.gitFlushTimer);\n this.gitFlushTimer = null;\n }\n }\n\n // ── Idle timer ─────────────────────────────────────────────────────\n\n startIdleTimer(): void {\n this.clearIdleTimers();\n this.idleTimer = setTimeout(() => {\n this.callbacks.onIdleTimeout();\n }, this.config.idleTimeoutMs);\n }\n\n cancelIdleTimer(): void {\n this.clearIdleTimers();\n }\n\n // ── Dormant timer ──────────────────────────────────────────────────\n\n /** Start (or restart) the dormant timer.\n * @param overrideMs Optional custom delay in ms. When provided, the timer\n * fires after exactly that delay instead of `dormantTimeoutMs`. SessionRunner\n * uses this to enforce an *absolute* deadline across cycles: even if the\n * dormant wait is interrupted by an inbound message, the next iteration\n * passes the remaining time, so the agent shuts down at the original\n * deadline regardless of message volume. */\n startDormantTimer(overrideMs?: number): void {\n this.cancelDormantTimer();\n const delay = Math.max(0, overrideMs ?? this.config.dormantTimeoutMs);\n this.dormantTimer = setTimeout(() => {\n this.callbacks.onDormantTimeout();\n }, delay);\n }\n\n cancelDormantTimer(): void {\n if (this.dormantTimer) {\n clearTimeout(this.dormantTimer);\n this.dormantTimer = null;\n }\n }\n\n // ── Cleanup ────────────────────────────────────────────────────────\n\n destroy(): void {\n this.stopHeartbeat();\n this.stopTokenRefresh();\n this.stopGitFlush();\n this.clearIdleTimers();\n this.cancelDormantTimer();\n }\n\n // ── Private ────────────────────────────────────────────────────────\n\n private clearIdleTimers(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer);\n this.idleTimer = null;\n }\n if (this.idleCheckInterval) {\n clearInterval(this.idleCheckInterval);\n this.idleCheckInterval = null;\n }\n }\n}\n","import { execSync } from \"node:child_process\";\n\n/** Fetch and merge the latest base branch to prevent stale-base merge conflicts.\n * Returns true on success or no-op (empty baseBranch), false on failure. */\nexport function syncWithBaseBranch(cwd: string, baseBranch: string): boolean {\n if (!baseBranch) return true;\n\n try {\n execSync(`git fetch origin ${baseBranch}`, { cwd, stdio: \"ignore\", timeout: 60_000 });\n } catch {\n process.stderr.write(\n `[conveyor-agent] Warning: git fetch origin ${baseBranch} failed, continuing with current base\\n`,\n );\n return false;\n }\n\n try {\n execSync(`git merge origin/${baseBranch} --no-edit`, { cwd, stdio: \"ignore\", timeout: 30_000 });\n } catch {\n process.stderr.write(\n `[conveyor-agent] Warning: merge origin/${baseBranch} failed, aborting merge and continuing\\n`,\n );\n try {\n execSync(\"git merge --abort\", { cwd, stdio: \"ignore\" });\n } catch {\n // merge --abort can fail if there's nothing to abort\n }\n return false;\n }\n\n process.stderr.write(`[conveyor-agent] Synced with latest origin/${baseBranch}\\n`);\n return true;\n}\n\n/** Ensure the repo is on the expected task branch. No-op if already correct.\n * Returns true on success, false on failure. */\nexport function ensureOnTaskBranch(cwd: string, taskBranch: string): boolean {\n if (!taskBranch) return true;\n\n const current = getCurrentBranch(cwd);\n if (current === taskBranch) return true;\n\n try {\n execSync(`git fetch origin ${taskBranch}`, { cwd, stdio: \"ignore\", timeout: 60_000 });\n } catch {\n process.stderr.write(`[conveyor-agent] Warning: git fetch origin ${taskBranch} failed\\n`);\n return false;\n }\n\n // Use `checkout -B` which creates or resets the local branch to track origin.\n // This handles the detached-HEAD case (entrypoint.sh leaves the repo detached\n // after `git reset --hard origin/<branch>`) and the case where a stale local\n // branch exists pointing at a different SHA.\n try {\n execSync(`git checkout -B ${taskBranch} origin/${taskBranch}`, {\n cwd,\n stdio: \"ignore\",\n timeout: 30_000,\n });\n } catch {\n process.stderr.write(`[conveyor-agent] Warning: git checkout ${taskBranch} failed\\n`);\n return false;\n }\n\n process.stderr.write(`[conveyor-agent] Checked out task branch ${taskBranch}\\n`);\n return true;\n}\n\n/** Returns true if the working tree has uncommitted changes (staged or unstaged). */\nexport function hasUncommittedChanges(cwd: string): boolean {\n const status = execSync(\"git status --porcelain\", {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n return status.length > 0;\n}\n\n/** Returns the current branch name, or null if on detached HEAD. */\nexport function getCurrentBranch(cwd: string): string | null {\n try {\n const branch = execSync(\"git branch --show-current\", {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n return branch || null;\n } catch {\n return null;\n }\n}\n\n/** Returns true if there are committed changes that haven't been pushed to origin. */\nexport function hasUnpushedCommits(cwd: string): boolean {\n try {\n const currentBranch = getCurrentBranch(cwd);\n if (!currentBranch) return false;\n\n try {\n execSync(`git rev-parse origin/${currentBranch}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n } catch {\n try {\n execSync(\"git rev-parse HEAD\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n return true;\n } catch {\n return false;\n }\n }\n\n const ahead = execSync(`git rev-list --count HEAD --not origin/${currentBranch}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n return parseInt(ahead, 10) > 0;\n } catch {\n return false;\n }\n}\n\n/** Stage all changes and create a commit. Returns the commit hash if successful. */\nexport function stageAndCommit(cwd: string, message: string): string | null {\n try {\n execSync(\"git add -A\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n\n if (!hasUncommittedChanges(cwd)) return null;\n\n execSync(`git commit -m ${JSON.stringify(message)}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n\n return execSync(\"git rev-parse HEAD\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] })\n .toString()\n .trim();\n } catch {\n return null;\n }\n}\n\nfunction tryPush(cwd: string, branch: string): boolean {\n try {\n execSync(`git push origin ${branch}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 30_000,\n });\n return true;\n } catch {\n try {\n execSync(`git push --force-with-lease origin ${branch}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 30_000,\n });\n return true;\n } catch {\n return false;\n }\n }\n}\n\nfunction isAuthError(cwd: string): boolean {\n try {\n execSync(\"git push --dry-run\", { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"], timeout: 30_000 });\n return false;\n } catch (err: unknown) {\n if ((err as { killed?: boolean }).killed) return true;\n const stderr = (err as { stderr?: Buffer }).stderr?.toString() ?? \"\";\n const stdout = (err as { stdout?: Buffer }).stdout?.toString() ?? \"\";\n const msg = stderr || stdout || (err instanceof Error ? err.message : \"\");\n return /authentication|authorization|403|401|token/i.test(msg);\n }\n}\n\n/** Update the git remote URL with a fresh token. */\nexport function updateRemoteToken(cwd: string, token: string): void {\n try {\n const url = execSync(\"git remote get-url origin\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] })\n .toString()\n .trim();\n const match = url.match(/github\\.com[/:]([^/]+\\/[^/.]+)/);\n if (match) {\n const repo = match[1].replace(/\\.git$/, \"\");\n execSync(\n `git remote set-url origin \"https://x-access-token:${token}@github.com/${repo}.git\"`,\n { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] },\n );\n }\n } catch {\n // silently fail — push retry will surface the real error\n }\n}\n\n// ── WIP snapshot ref ────────────────────────────────────────────────────\n//\n// Crash protection without polluting the task branch: uncommitted work is\n// captured as a stash-shaped commit (`git stash create` — does not touch\n// HEAD, the index, or the working tree) and force-pushed to a dedicated\n// `conveyor-wip/<branch>` ref. Real (intentional) commits are still pushed\n// to the task branch itself. On a fresh pod, `restoreWipSnapshot` re-applies\n// the snapshot when the branch head matches; once the tree is clean the\n// stale remote ref is deleted.\n\n/** The remote ref that holds the WIP snapshot for a task branch. */\nexport function wipRefForBranch(branch: string): string {\n return `conveyor-wip/${branch}`;\n}\n\n/** cwd values that have (or may have) a live remote WIP ref to clean up. */\nconst wipRefPushed = new Set<string>();\n\n/**\n * Capture the working tree + index (including untracked files) as a\n * stash-shaped commit WITHOUT moving HEAD or dirtying history. The index is\n * staged so untracked files are included, then restored so the agent's\n * `git status` view is unchanged.\n */\nfunction createWipSnapshot(cwd: string, message: string): string | null {\n try {\n execSync(\"git add -A\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n const sha = execSync(`git stash create ${JSON.stringify(message)}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n return sha || null;\n } catch {\n return null;\n } finally {\n try {\n execSync(\"git reset -q\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n } catch {\n /* nothing staged */\n }\n }\n}\n\nfunction tryPushRefspec(cwd: string, refspec: string, force = false): boolean {\n try {\n execSync(`git push ${force ? \"--force \" : \"\"}origin ${JSON.stringify(refspec)}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 30_000,\n });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function refreshRemoteToken(\n cwd: string,\n refreshToken?: () => Promise<string | undefined>,\n): Promise<void> {\n if (!refreshToken) return;\n try {\n const token = await refreshToken();\n if (token) {\n updateRemoteToken(cwd, token);\n process.env.GITHUB_TOKEN = token;\n process.env.GH_TOKEN = token;\n }\n } catch {\n // best effort — proceed with existing token\n }\n}\n\n/**\n * Re-apply a WIP snapshot pushed by a previous pod of this task. Applies only\n * when the snapshot was taken on the current HEAD (the branch hasn't moved),\n * so a stale snapshot can never conflict its way into the tree.\n */\nexport function restoreWipSnapshot(\n cwd: string,\n branch: string,\n): \"applied\" | \"stale\" | \"none\" | \"failed\" {\n if (!branch) return \"none\";\n const ref = wipRefForBranch(branch);\n try {\n execSync(`git fetch origin +refs/heads/${ref}:refs/remotes/origin/${ref}`, {\n cwd,\n stdio: \"ignore\",\n timeout: 60_000,\n });\n } catch {\n // Ref doesn't exist remotely (or fetch failed) — nothing to restore.\n return \"none\";\n }\n // A remote ref exists — remember to clean it up once the tree is clean.\n wipRefPushed.add(cwd);\n try {\n const sha = execSync(`git rev-parse refs/remotes/origin/${ref}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n // First parent of a stash-shaped commit is the HEAD it was created on.\n const parent = execSync(`git rev-parse \"${sha}^\"`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n const head = execSync(\"git rev-parse HEAD\", { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] })\n .toString()\n .trim();\n if (parent !== head) return \"stale\";\n execSync(`git stash apply ${sha}`, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n return \"applied\";\n } catch {\n return \"failed\";\n }\n}\n\n/** Best-effort flush of pending work: pushes any real (intentional) commits to\n * the task branch, and captures uncommitted changes as a WIP snapshot on the\n * `conveyor-wip/<branch>` ref — never as commits on the branch itself. When\n * the tree is clean, a previously pushed WIP ref is deleted. Never throws. */\nexport async function flushPendingChanges(\n cwd: string,\n opts?: { wipMessage?: string; refreshToken?: () => Promise<string | undefined> },\n): Promise<{ committed: boolean; pushed: boolean; hadWork: boolean }> {\n let committed = false;\n let pushed = false;\n let hadWork = false;\n\n try {\n const branch = getCurrentBranch(cwd);\n if (!branch) return { committed, pushed, hadWork };\n\n const dirty = hasUncommittedChanges(cwd);\n const unpushed = hasUnpushedCommits(cwd);\n\n if (!dirty && !unpushed) {\n await dropStaleWipRef(cwd, branch, opts?.refreshToken);\n return { committed, pushed, hadWork };\n }\n\n hadWork = true;\n await refreshRemoteToken(cwd, opts?.refreshToken);\n\n // Real commits first so a WIP snapshot taken below sits on the pushed head.\n if (unpushed) {\n pushed = await pushToOrigin(cwd, opts?.refreshToken);\n }\n\n if (dirty) {\n const message = opts?.wipMessage ?? \"WIP: conveyor-agent snapshot\";\n const sha = createWipSnapshot(cwd, message);\n if (sha) {\n committed = tryPushRefspec(cwd, `${sha}:refs/heads/${wipRefForBranch(branch)}`, true);\n if (committed) wipRefPushed.add(cwd);\n }\n }\n } catch {\n // best effort\n }\n\n return { committed, pushed, hadWork };\n}\n\n/** Clean tree: the last WIP snapshot is stale — drop the remote ref so\n * recovery never resurrects superseded work. */\nasync function dropStaleWipRef(\n cwd: string,\n branch: string,\n refreshToken?: () => Promise<string | undefined>,\n): Promise<void> {\n if (!wipRefPushed.has(cwd)) return;\n await refreshRemoteToken(cwd, refreshToken);\n if (tryPushRefspec(cwd, `:refs/heads/${wipRefForBranch(branch)}`)) {\n wipRefPushed.delete(cwd);\n }\n}\n\n/** Push current branch to origin. Proactively refreshes the GitHub token before\n * attempting the push. On auth failure, refreshes again and retries. */\nexport async function pushToOrigin(\n cwd: string,\n refreshToken?: () => Promise<string | undefined>,\n): Promise<boolean> {\n try {\n const currentBranch = getCurrentBranch(cwd);\n if (!currentBranch) return false;\n\n // Proactively refresh token before pushing to avoid wasting time with a stale token\n if (refreshToken) {\n try {\n const token = await refreshToken();\n if (token) {\n updateRemoteToken(cwd, token);\n process.env.GITHUB_TOKEN = token;\n process.env.GH_TOKEN = token;\n }\n } catch {\n // best effort — proceed with existing token\n }\n }\n\n if (tryPush(cwd, currentBranch)) return true;\n\n if (refreshToken && isAuthError(cwd)) {\n const token = await refreshToken();\n if (token) {\n updateRemoteToken(cwd, token);\n process.env.GITHUB_TOKEN = token;\n process.env.GH_TOKEN = token;\n return tryPush(cwd, currentBranch);\n }\n }\n\n return false;\n } catch {\n return false;\n }\n}\n","import { readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\n\nexport class PlanSync {\n private planFileSnapshot = new Map<string, number>();\n private lockedPlanFile: string | null = null;\n private workspaceDir: string;\n private connection: AgentConnection;\n\n constructor(workspaceDir: string, connection: AgentConnection) {\n this.workspaceDir = workspaceDir;\n this.connection = connection;\n }\n\n updateWorkspaceDir(workspaceDir: string): void {\n this.workspaceDir = workspaceDir;\n }\n\n private getPlanDirs(): string[] {\n return [join(this.workspaceDir, \".claude\", \"plans\")];\n }\n\n snapshotPlanFiles(): void {\n this.planFileSnapshot.clear();\n this.lockedPlanFile = null;\n for (const plansDir of this.getPlanDirs()) {\n try {\n for (const file of readdirSync(plansDir).filter((f) => f.endsWith(\".md\"))) {\n try {\n const fullPath = join(plansDir, file);\n const stat = statSync(fullPath);\n this.planFileSnapshot.set(fullPath, stat.mtimeMs);\n } catch {\n continue;\n }\n }\n } catch {\n /* plans dir doesn't exist yet */\n }\n }\n }\n\n private findNewestPlanFile(): { path: string; mtime: number } | null {\n let newest: { path: string; mtime: number } | null = null;\n for (const plansDir of this.getPlanDirs()) {\n let files: string[];\n try {\n files = readdirSync(plansDir).filter((f) => f.endsWith(\".md\"));\n } catch {\n continue;\n }\n\n for (const file of files) {\n const fullPath = join(plansDir, file);\n try {\n const stat = statSync(fullPath);\n const prevMtime = this.planFileSnapshot.get(fullPath);\n const isNew = prevMtime === undefined || stat.mtimeMs > prevMtime;\n if (isNew && (!newest || stat.mtimeMs > newest.mtime)) {\n newest = { path: fullPath, mtime: stat.mtimeMs };\n }\n } catch {\n continue;\n }\n }\n }\n return newest;\n }\n\n async syncPlanFile(): Promise<void> {\n const isInitialDetection = this.lockedPlanFile === null;\n const target = this.lockedPlanFile ?? this.findNewestPlanFile()?.path ?? null;\n if (!target) return;\n\n // Lock on initial detection before reading — matches prior behavior and\n // prevents a broken file from re-triggering detection on every tick.\n if (isInitialDetection) {\n this.lockedPlanFile = target;\n }\n\n const fileName = target.split(\"/\").pop() ?? \"plan\";\n\n let content: string;\n try {\n content = readFileSync(target, \"utf-8\").trim();\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n this.connection.postChatMessage(\n `Plan sync warning: could not read local plan file (${fileName}): ${reason}. The task plan was not updated.`,\n );\n return;\n }\n\n if (!content) return;\n\n const result = await this.connection.updateTaskFields({ plan: content });\n if (!result.ok) {\n this.connection.postChatMessage(\n `Plan sync failed: the local plan file (${fileName}) was not persisted to the task (${result.error ?? \"unknown error\"}). Retry update_task_plan or re-run ExitPlanMode.`,\n );\n return;\n }\n\n const verb = isInitialDetection ? \"Detected local plan file\" : \"Synced local plan file\";\n const suffix = isInitialDetection ? \" and synced it to the task plan.\" : \" to the task plan.\";\n this.connection.postChatMessage(`${verb} (${fileName})${suffix}`);\n }\n}\n","/* oxlint-disable max-lines, max-dependencies -- query orchestration + retry logic is cohesive; splitting would scatter tightly-coupled control flow */\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, truncateSync } from \"node:fs\";\nimport { sessionTranscriptPath } from \"../harness/pty/settings.js\";\nimport type {\n AgentHarness,\n HarnessEvent,\n HarnessUserMessage,\n HarnessQueryOptions,\n HarnessHookInput,\n HarnessHookOutput,\n HarnessKind,\n} from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\nimport type { TaskContext, MultimodalBlock, AgentMode } from \"@project/shared\";\nimport type { AgentRunnerConfig, AgentRunnerCallbacks } from \"../types.js\";\nimport { buildInitialPrompt } from \"./prompt-builder.js\";\nimport { buildSystemPrompt } from \"./system-prompt.js\";\nimport { createConveyorMcpServer } from \"../tools/index.js\";\nimport { processEvents } from \"./event-processor.js\";\nimport { API_ERROR_PATTERN, isAuthError } from \"./event-handlers.js\";\nimport type { CostTracker } from \"./cost-tracker.js\";\nimport type { ExplorationTracker } from \"./exploration-tracker.js\";\nimport { buildCanUseTool } from \"./tool-access.js\";\nimport { collectMissingProps } from \"./task-property-utils.js\";\nimport { redact } from \"./redactor.js\";\n\nconst logger = createServiceLogger(\"QueryExecutor\");\nconst IMAGE_ERROR_PATTERN = /Could not process image/i;\nconst RETRY_DELAYS_MS = [60_000, 120_000, 180_000, 300_000];\n\nexport interface QueryHost {\n config: AgentRunnerConfig;\n connection: AgentConnection;\n callbacks: AgentRunnerCallbacks;\n harness: AgentHarness;\n harnessKind: HarnessKind;\n setupLog: string[];\n costTracker: CostTracker;\n explorationTracker: ExplorationTracker | null;\n agentMode: AgentMode;\n isAuto: boolean;\n isParentTask: boolean;\n hasExitedPlanMode: boolean;\n pendingModeRestart: boolean;\n discoveryCompleted: boolean;\n wasRateLimited: boolean;\n sessionIds: Map<string, string>;\n activeQuery: AsyncGenerator<HarnessEvent, void> | null;\n pendingToolOutputs: { tool: string; output: string }[];\n abortController: AbortController | null;\n isStopped(): boolean;\n requestStop(): void;\n requestSoftStop(): void;\n createInputStream(\n prompt: string | MultimodalBlock[],\n ): AsyncGenerator<HarnessUserMessage, void, unknown>;\n snapshotPlanFiles(): void;\n syncPlanFile(): Promise<void>;\n onModeTransition?: (newMode: AgentMode) => void;\n}\n\n// ── Query options builder ───────────────────────────────────────────────────\n\nfunction buildHooks(host: QueryHost): HarnessQueryOptions[\"hooks\"] {\n return {\n PostToolUse: [\n {\n hooks: [\n async (input: HarnessHookInput): Promise<HarnessHookOutput> => {\n if (host.isStopped()) return await Promise.resolve({ continue: false });\n if (input.hook_event_name === \"PostToolUse\") {\n const raw =\n typeof input.tool_response === \"string\"\n ? input.tool_response\n : JSON.stringify(input.tool_response);\n const { output: redacted, redacted: redactedCount } = redact(raw);\n const output = redacted.slice(0, 500);\n host.connection.sendEvent({\n type: \"tool_result\",\n tool: input.tool_name,\n output,\n isError: false,\n ...(redactedCount > 0 ? { redactedCount } : {}),\n });\n host.pendingToolOutputs.push({ tool: input.tool_name, output });\n\n // After PR creation, nudge agent to backfill missing task properties\n if (input.tool_name === \"mcp__conveyor__create_pull_request\") {\n try {\n const props = await host.connection.getTaskProperties();\n const missing = collectMissingProps(props);\n if (missing.length > 0) {\n host.connection.postChatMessage(\n `PR created! Please backfill missing task properties: ${missing.join(\", \")}`,\n );\n }\n } catch {\n /* best-effort */\n }\n }\n }\n return await Promise.resolve({ continue: true });\n },\n ],\n timeout: 5,\n },\n ],\n };\n}\n\n/**\n * Derive a deterministic UUID v8-style from a session lineage key.\n * The Claude SDK requires UUID format for sessionId; task IDs are cuids.\n * Using sha256(key) ensures the same lineage always maps to the same session.\n */\nfunction taskIdToSessionUuid(lineageKey: string): string {\n const hash = createHash(\"sha256\").update(lineageKey).digest(\"hex\");\n // Format as UUID: xxxxxxxx-xxxx-8xxx-axxx-xxxxxxxxxxxx (v8 + RFC 4122 variant)\n return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-8${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;\n}\n\n/**\n * Conversation lineage for a task. Review runs (code review, pack-runner\n * orchestration) get their OWN session lineage so:\n * - a review never resumes the building conversation (it may use a\n * different model — this was previously \"prevented\" by the server\n * clearing `sdkSessionId`, which never actually worked because resume is\n * filesystem-driven), and\n * - flipping back to building resumes the ORIGINAL building conversation\n * untouched.\n */\nexport function sessionLineageKey(\n taskId: string,\n agentMode: AgentMode,\n runnerMode: AgentRunnerConfig[\"mode\"],\n): string {\n return agentMode === \"review\" || runnerMode === \"code-review\" ? `${taskId}:review` : taskId;\n}\n\n/**\n * Check if a Claude session file exists for the given session UUID + cwd.\n * Session files live at <config-home>/projects/<cwd-slug>/<sessionId>.jsonl\n * (the same CLAUDE_CONFIG_DIR-aware path the PTY transcript tailer uses).\n */\nfunction sessionFileExists(sessionUuid: string, cwd: string): boolean {\n try {\n return existsSync(sessionTranscriptPath(cwd, sessionUuid));\n } catch {\n return false;\n }\n}\n\n/** Does a resumable Claude session already exist for this lineage + workspace? */\nexport function hasExistingSessionFile(\n taskId: string,\n cwd: string,\n lineage: { agentMode: AgentMode; runnerMode: AgentRunnerConfig[\"mode\"] },\n): boolean {\n const key = sessionLineageKey(taskId, lineage.agentMode, lineage.runnerMode);\n return sessionFileExists(taskIdToSessionUuid(key), cwd);\n}\n\n/**\n * Repair a transcript whose final record was torn by an ungraceful pod death\n * (SIGKILL mid-append, gcsfuse upload cut short): truncate to the end of the\n * last complete, parseable line so `--resume` gets a well-formed JSONL.\n * Returns true when a truncation was performed.\n */\nexport function repairTornSessionFile(path: string): boolean {\n try {\n if (!existsSync(path)) return false;\n const content = readFileSync(path, \"utf8\");\n if (content.length === 0) return false;\n\n // Phase 1: drop a trailing partial line (no terminating newline).\n let keepEnd = content.length;\n if (!content.endsWith(\"\\n\")) {\n // 0 when no newline exists at all.\n keepEnd = content.lastIndexOf(\"\\n\") + 1;\n }\n // Phase 2: drop trailing terminated lines that don't parse as JSON\n // (a write torn mid-line that still got its newline flushed).\n while (keepEnd > 0) {\n const prevNewline = content.lastIndexOf(\"\\n\", keepEnd - 2);\n const line = content.slice(prevNewline + 1, keepEnd - 1).trim();\n if (line.length > 0) {\n try {\n JSON.parse(line);\n // Trailing line is whole — done.\n break;\n } catch {\n /* unparseable — trim it */\n }\n }\n keepEnd = prevNewline + 1;\n }\n\n if (keepEnd === content.length) return false;\n truncateSync(path, Buffer.byteLength(content.slice(0, keepEnd), \"utf8\"));\n logger.warn(\"Repaired torn transcript before resume\", {\n path,\n trimmedBytes: content.length - keepEnd,\n });\n return true;\n } catch {\n // Best-effort — a failed repair falls through to the CLI.\n return false;\n }\n}\n\nexport interface PromptDeliveryInputs {\n harnessKind: HarnessKind;\n runnerMode: AgentRunnerConfig[\"mode\"];\n isAuto: boolean;\n agentMode: AgentMode;\n isFollowUp: boolean;\n hasExistingSession: boolean;\n}\n\n/**\n * Decide how a query's prompt reaches the agent.\n *\n * \"prefill\" (paste into the TUI input, let the human review/edit/Enter) applies\n * only to the INITIAL instructions of a manual-mode task chat under the PTY\n * harness. Everything else submits immediately:\n * - SDK harness: no interactive input box exists.\n * - non-task runner modes (pm, code-review): autonomous, no human at the TUI.\n * - auto tasks (isAuto or agentMode \"auto\"): full-auto is the whole point.\n * - follow-ups: the human already directed the agent via chat.\n * - resumes: the conversation exists; re-prefilling the initial\n * instructions into it would be confusing.\n */\nexport function resolvePromptDelivery(inputs: PromptDeliveryInputs): \"submit\" | \"prefill\" {\n if (inputs.harnessKind !== \"pty\") return \"submit\";\n if ((inputs.runnerMode ?? \"task\") !== \"task\") return \"submit\";\n if (inputs.isFollowUp || inputs.hasExistingSession) return \"submit\";\n if (inputs.isAuto || inputs.agentMode === \"auto\") return \"submit\";\n return \"prefill\";\n}\n\nfunction isReadOnlyMode(mode: AgentMode, hasExitedPlanMode: boolean): boolean {\n return mode === \"discovery\" || mode === \"help\" || (mode === \"auto\" && !hasExitedPlanMode);\n}\n\nfunction buildDisallowedTools(\n settings: { disallowedTools?: string[] },\n mode: AgentMode,\n hasExitedPlanMode: boolean,\n): string[] | undefined {\n const modeDisallowed = isReadOnlyMode(mode, hasExitedPlanMode)\n ? [\"TodoWrite\", \"TodoRead\", \"NotebookEdit\"]\n : [];\n const configured = settings.disallowedTools ?? [];\n const combined = [...configured, ...modeDisallowed];\n return combined.length > 0 ? combined : undefined;\n}\n\nfunction buildQueryOptions(host: QueryHost, context: TaskContext): HarnessQueryOptions {\n const settings = context.agentSettings ?? host.config.agentSettings ?? {};\n const mode = host.agentMode;\n\n // Read-only modes (auto pre-exit, discovery, help) use the SDK's native \"plan\"\n // permission mode which enforces no-execution (blocks file edits and destructive commands).\n // canUseTool is still registered to intercept ExitPlanMode for custom validation\n // (plan/SP/title checks, triggerIdentification, mode restart).\n const isReadOnly = isReadOnlyMode(mode, host.hasExitedPlanMode);\n const needsCanUseTool = isReadOnly;\n\n const systemPromptText = buildSystemPrompt(\n host.config.mode,\n context,\n { ...host.config, isAuto: host.isAuto },\n host.setupLog,\n mode,\n );\n const settingSources = (settings.settingSources ?? [\"user\", \"project\"]) as (\n | \"user\"\n | \"project\"\n | \"local\"\n )[];\n\n return {\n model: context.model || host.config.model,\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: systemPromptText || undefined,\n },\n settingSources,\n cwd: host.config.workspaceDir,\n permissionMode: needsCanUseTool ? \"plan\" : \"bypassPermissions\",\n allowDangerouslySkipPermissions: !needsCanUseTool,\n canUseTool: buildCanUseTool(host),\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: {\n conveyor: createConveyorMcpServer(host.harness, host.connection, host.config, context, mode),\n },\n sandbox: context.useSandbox ? { enabled: true } : { enabled: false },\n hooks: buildHooks(host),\n maxTurns: settings.maxTurns,\n effort: settings.effort,\n thinking: settings.thinking,\n betas: settings.betas,\n maxBudgetUsd: settings.maxBudgetUsd ?? 50,\n abortController: host.abortController ?? undefined,\n disallowedTools: buildDisallowedTools(settings, mode, host.hasExitedPlanMode),\n enableFileCheckpointing: settings.enableFileCheckpointing,\n stderr: (data: string) => {\n logger.warn(\"Claude Code stderr\", { data: data.trimEnd() });\n },\n };\n}\n\n// ── Multimodal prompt builder ────────────────────────────────────────────\n\ntype ImageMediaType = \"image/gif\" | \"image/jpeg\" | \"image/png\" | \"image/webp\";\n\nfunction buildMultimodalPrompt(\n textPrompt: string,\n context: TaskContext,\n skipImages = false,\n): string | MultimodalBlock[] {\n if (skipImages) return textPrompt;\n\n const taskImages = (context.files ?? []).filter(\n (f) => f.content && f.contentEncoding === \"base64\",\n );\n const chatImages: { fileName: string; mimeType: string; content: string }[] = [];\n for (const msg of context.chatHistory) {\n for (const f of msg.files ?? []) {\n if (f.content && f.contentEncoding === \"base64\") {\n chatImages.push({ fileName: f.fileName, mimeType: f.mimeType, content: f.content });\n }\n }\n }\n\n if (taskImages.length === 0 && chatImages.length === 0) return textPrompt;\n\n const blocks: MultimodalBlock[] = [{ type: \"text\", text: textPrompt }];\n for (const file of taskImages) {\n blocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: file.mimeType as ImageMediaType,\n data: file.content ?? \"\",\n },\n });\n blocks.push({ type: \"text\", text: `[Attached image: ${file.fileName} (${file.mimeType})]` });\n }\n for (const file of chatImages) {\n blocks.push({\n type: \"image\",\n source: { type: \"base64\", media_type: file.mimeType as ImageMediaType, data: file.content },\n });\n blocks.push({ type: \"text\", text: `[Chat image: ${file.fileName} (${file.mimeType})]` });\n }\n return blocks;\n}\n\n// ── Follow-up prompt builder ─────────────────────────────────────────────\n\nasync function buildFollowUpPrompt(\n host: QueryHost,\n context: TaskContext,\n followUpContent: string | MultimodalBlock[],\n): Promise<string | MultimodalBlock[]> {\n const isPmMode = host.config.mode === \"pm\";\n const followUpText =\n typeof followUpContent === \"string\"\n ? followUpContent\n : followUpContent\n .filter((b): b is Extract<MultimodalBlock, { type: \"text\" }> => b.type === \"text\")\n .map((b) => b.text)\n .join(\"\\n\");\n\n const followUpImages =\n typeof followUpContent === \"string\"\n ? []\n : followUpContent.filter(\n (b): b is Extract<MultimodalBlock, { type: \"image\" }> => b.type === \"image\",\n );\n\n const textPrompt = isPmMode\n ? `${await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode)}\\n\\n---\\n\\nThe team says:\\n${followUpText}`\n : followUpText;\n\n if (isPmMode) {\n const prompt = buildMultimodalPrompt(textPrompt, context);\n if (followUpImages.length > 0 && Array.isArray(prompt)) {\n prompt.push(...followUpImages);\n }\n return prompt;\n }\n if (followUpImages.length > 0) {\n return [{ type: \"text\", text: textPrompt }, ...followUpImages];\n }\n return textPrompt;\n}\n\n// ── SDK query execution ──────────────────────────────────────────────────\n\n/** Pass events through, firing `onFirst` before the first non-system event. */\nasync function* notifyOnFirstEvent(\n inner: AsyncGenerator<HarnessEvent, void>,\n onFirst: () => Promise<void>,\n): AsyncGenerator<HarnessEvent, void> {\n let fired = false;\n for await (const event of inner) {\n if (!fired && event.type !== \"system\") {\n fired = true;\n await onFirst();\n }\n yield event;\n }\n}\n\n// How long a submitted PTY query may stay silent (zero transcript events)\n// before the agent reports waiting_for_input instead of running. A healthy\n// turn writes its first transcript record well inside this window; a TUI\n// parked on an unexpected dialog (trust prompt, onboarding wizard, login\n// screen) never produces one, which previously left the card stuck on\n// \"working\" indefinitely.\nconst PARKED_TUI_GRACE_MS = 45_000;\n\n/**\n * Status-accuracy watchdog for submitted PTY queries. Display-only: the\n * query keeps draining either way, `_state` in SessionRunner is untouched\n * (so chat-message supersede and idle-timer behavior are unchanged), and the\n * first event flips the reported status back to running.\n */\nexport async function* watchForParkedTui(\n inner: AsyncGenerator<HarnessEvent, void>,\n host: Pick<QueryHost, \"connection\" | \"callbacks\">,\n): AsyncGenerator<HarnessEvent, void> {\n let parked = false;\n // The generator body runs lazily, so the timer starts when the consumer\n // begins draining — i.e. when the spawned CLI is live and the prompt has\n // been submitted.\n const timer = setTimeout(() => {\n parked = true;\n host.connection.emitStatus(\"waiting_for_input\");\n void host.callbacks.onStatusChange(\"waiting_for_input\");\n }, PARKED_TUI_GRACE_MS);\n try {\n for await (const event of inner) {\n clearTimeout(timer);\n if (parked) {\n parked = false;\n host.connection.emitStatus(\"running\");\n await host.callbacks.onStatusChange(\"running\");\n }\n yield event;\n }\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function runSdkQuery(\n host: QueryHost,\n context: TaskContext,\n followUpContent?: string | MultimodalBlock[],\n promptDeliveryOverride?: \"submit\" | \"prefill\",\n): Promise<void> {\n if (host.isStopped()) return;\n\n const mode = host.agentMode;\n const isDiscoveryLike = mode === \"discovery\" || mode === \"help\";\n const needsPlanSync = isDiscoveryLike || (mode === \"auto\" && !host.hasExitedPlanMode);\n if (needsPlanSync) {\n host.snapshotPlanFiles();\n }\n\n // Use a deterministic UUID derived from the session lineage (taskId, with a\n // \":review\" variant for review runs) as the session ID. Sessions persist via\n // GCS-FUSE, so resuming by the derived UUID works across pod restarts\n // without tracking SDK-generated session IDs.\n //\n // The SDK's `sessionId` and `resume` options are mutually exclusive:\n // - `sessionId` creates a new session with a specific UUID\n // - `resume` loads an existing session\n // Pass `resume` only if the session file already exists on disk;\n // otherwise pass `sessionId` to create fresh with our deterministic ID.\n const sessionUuid = taskIdToSessionUuid(\n sessionLineageKey(context.taskId, mode, host.config.mode),\n );\n const hasExistingSession = sessionFileExists(sessionUuid, host.config.workspaceDir);\n if (hasExistingSession) {\n // An ungraceful pod death can tear the final transcript record mid-append;\n // trim it so --resume gets well-formed JSONL instead of failing outright.\n repairTornSessionFile(sessionTranscriptPath(host.config.workspaceDir, sessionUuid));\n }\n const promptDelivery =\n promptDeliveryOverride ??\n resolvePromptDelivery({\n harnessKind: host.harnessKind,\n runnerMode: host.config.mode,\n isAuto: host.isAuto,\n agentMode: mode,\n isFollowUp: !!followUpContent,\n hasExistingSession,\n });\n const options = {\n ...buildQueryOptions(host, context),\n promptDelivery,\n ...(hasExistingSession ? {} : { sessionId: sessionUuid }),\n };\n const resume = hasExistingSession ? sessionUuid : undefined;\n\n if (followUpContent) {\n const prompt = await buildFollowUpPrompt(host, context, followUpContent);\n const agentQuery = host.harness.executeQuery({\n prompt: typeof prompt === \"string\" ? prompt : host.createInputStream(prompt),\n options: { ...options },\n resume,\n });\n await trackAndRun(host, context, options, agentQuery);\n } else if (isDiscoveryLike && promptDelivery !== \"prefill\") {\n // SDK harness (or a resumed session): there is no TUI input box to\n // pre-fill, and discovery must not auto-run — wait for a chat message.\n return;\n } else {\n await runInitialQuery(host, context, options, resume, promptDelivery);\n }\n\n if (needsPlanSync) {\n await host.syncPlanFile();\n }\n}\n\n/** Track the active query while runWithRetry drains it. */\nasync function trackAndRun(\n host: QueryHost,\n context: TaskContext,\n options: HarnessQueryOptions,\n agentQuery: AsyncGenerator<HarnessEvent, void>,\n): Promise<void> {\n // Prefill queries are parked by design (already reported as\n // waiting_for_input); SDK queries emit an init event immediately. Only a\n // submitted PTY turn can silently park on an unexpected CLI dialog.\n if (host.harnessKind === \"pty\" && options.promptDelivery !== \"prefill\") {\n agentQuery = watchForParkedTui(agentQuery, host);\n }\n host.activeQuery = agentQuery;\n try {\n await runWithRetry(agentQuery, context, host, options);\n } finally {\n host.activeQuery = null;\n }\n}\n\n/** Build and run the initial (non-follow-up) query for the current mode. */\nasync function runInitialQuery(\n host: QueryHost,\n context: TaskContext,\n options: HarnessQueryOptions,\n resume: string | undefined,\n promptDelivery: \"submit\" | \"prefill\",\n): Promise<void> {\n const initialPrompt = await buildInitialPrompt(\n host.config.mode,\n context,\n host.isAuto,\n host.agentMode,\n );\n const prompt = buildMultimodalPrompt(initialPrompt, context);\n let agentQuery = host.harness.executeQuery({\n prompt: host.createInputStream(prompt),\n options: { ...options },\n resume,\n });\n if (promptDelivery === \"prefill\") {\n // The prompt sits unsubmitted in the TUI; the transcript stays empty\n // until the human presses Enter, so the first non-system event is the\n // \"human engaged\" signal — report running so the runner can leave\n // waiting_for_input and stop the prefill-wait idle timer.\n agentQuery = notifyOnFirstEvent(agentQuery, async () => {\n host.connection.emitStatus(\"running\");\n await host.callbacks.onStatusChange(\"running\");\n });\n }\n await trackAndRun(host, context, options, agentQuery);\n}\n\n// ── Retry logic ──────────────────────────────────────────────────────────\n\nasync function buildRetryQuery(\n host: QueryHost,\n context: TaskContext,\n options: HarnessQueryOptions,\n lastErrorWasImage: boolean,\n): Promise<AsyncGenerator<HarnessEvent, void>> {\n if (lastErrorWasImage) {\n host.connection.postChatMessage(\n \"An attached image could not be processed. Retrying without images...\",\n );\n }\n const retryPrompt = buildMultimodalPrompt(\n await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),\n context,\n lastErrorWasImage,\n );\n return host.harness.executeQuery({\n prompt: host.createInputStream(retryPrompt),\n // Strip sessionId on retry — if the failing query partially created a\n // session with that ID, passing it again would error. Let the SDK\n // auto-generate on retry attempts.\n options: { ...options, sessionId: undefined },\n resume: undefined,\n });\n}\n\nasync function handleAuthError(\n context: TaskContext,\n host: QueryHost,\n options: HarnessQueryOptions,\n): Promise<void> {\n host.connection.postChatMessage(\"Authentication expired. Re-bootstrapping credentials...\");\n\n const refreshed = await host.connection.refreshAuthToken();\n if (!refreshed) {\n host.connection.postChatMessage(\"Failed to refresh authentication. Agent will restart.\");\n host.connection.sendEvent({\n type: \"error\",\n message: \"Auth re-bootstrap failed, exiting for restart\",\n });\n process.exit(1);\n }\n\n // Clear session since it's tied to the old token\n context.claudeSessionId = null;\n host.connection.storeSessionId(\"\");\n\n const freshPrompt = buildMultimodalPrompt(\n await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),\n context,\n );\n const freshQuery = host.harness.executeQuery({\n prompt: host.createInputStream(freshPrompt),\n options: { ...options, sessionId: undefined },\n resume: undefined,\n });\n return runWithRetry(freshQuery, context, host, options);\n}\n\nasync function handleStaleSession(\n context: TaskContext,\n host: QueryHost,\n options: HarnessQueryOptions,\n): Promise<void> {\n context.claudeSessionId = null;\n host.connection.storeSessionId(\"\");\n const freshPrompt = buildMultimodalPrompt(\n await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),\n context,\n );\n const freshQuery = host.harness.executeQuery({\n prompt: host.createInputStream(freshPrompt),\n options: { ...options, sessionId: undefined },\n resume: undefined,\n });\n return runWithRetry(freshQuery, context, host, options);\n}\n\nasync function waitForRetryDelay(host: QueryHost, delayMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, delayMs);\n const checkStopped = setInterval(() => {\n if (host.isStopped()) {\n clearTimeout(timer);\n clearInterval(checkStopped);\n resolve();\n }\n }, 1000);\n setTimeout(() => clearInterval(checkStopped), delayMs + 100);\n });\n}\n\nfunction isStaleOrExitedSession(error: unknown, context: TaskContext): boolean {\n if (!(error instanceof Error)) return false;\n if (error.message.includes(\"No conversation found with session ID\")) return true;\n return !!context.claudeSessionId && error.message.includes(\"process exited\");\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === \"string\") return error;\n return String(error);\n}\n\nfunction isRetriableError(error: unknown): boolean {\n const message = getErrorMessage(error);\n return API_ERROR_PATTERN.test(message) || IMAGE_ERROR_PATTERN.test(message);\n}\n\nfunction classifyImageError(error: unknown): boolean {\n return IMAGE_ERROR_PATTERN.test(getErrorMessage(error));\n}\n\nasync function emitRetryStatus(host: QueryHost, attempt: number, delayMs: number): Promise<void> {\n const delayMin = Math.round(delayMs / 60_000);\n host.connection.postChatMessage(\n `API error encountered. Retrying in ${delayMin} minute${delayMin > 1 ? \"s\" : \"\"}... (attempt ${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n );\n host.connection.sendEvent({\n type: \"error\",\n message: `API error, retrying in ${delayMin}m (${attempt + 1}/${RETRY_DELAYS_MS.length})`,\n });\n host.connection.emitStatus(\"waiting_for_input\");\n await host.callbacks.onStatusChange(\"waiting_for_input\");\n\n await waitForRetryDelay(host, delayMs);\n\n host.connection.emitStatus(\"running\");\n await host.callbacks.onStatusChange(\"running\");\n}\n\nfunction handleRateLimitPause(host: QueryHost, rateLimitResetsAt: string): void {\n host.wasRateLimited = true;\n host.connection.emitRateLimitPause(rateLimitResetsAt);\n host.connection.postChatMessage(\n `Rate limited. The task will be automatically re-queued and resume after ${new Date(rateLimitResetsAt).toLocaleString()}.`,\n );\n}\n\ntype RetryOutcome = { action: \"return\" } | { action: \"continue\"; lastErrorWasImage: boolean };\n\nfunction handleRetryError(\n error: unknown,\n context: TaskContext,\n host: QueryHost,\n options: HarnessQueryOptions,\n prevImageError: boolean,\n): RetryOutcome | Promise<void> {\n if (isStaleOrExitedSession(error, context) && context.claudeSessionId) {\n return handleStaleSession(context, host, options);\n }\n if (isAuthError(getErrorMessage(error))) {\n return handleAuthError(context, host, options);\n }\n if (!isRetriableError(error)) throw error;\n return { action: \"continue\", lastErrorWasImage: classifyImageError(error) || prevImageError };\n}\n\ntype ProcessResult =\n | { action: \"return\" }\n | { action: \"return_promise\"; promise: Promise<void> }\n | { action: \"continue\"; lastErrorWasImage: boolean };\n\nfunction handleProcessResult(\n result: Awaited<ReturnType<typeof processEvents>>,\n context: TaskContext,\n host: QueryHost,\n options: HarnessQueryOptions,\n): ProcessResult {\n if (result.modeRestart || host.isStopped()) return { action: \"return\" };\n\n if (result.rateLimitResetsAt) {\n handleRateLimitPause(host, result.rateLimitResetsAt);\n return { action: \"return\" };\n }\n\n // Handle stale session result errors (same recovery as thrown exceptions)\n if (result.staleSession && context.claudeSessionId) {\n return { action: \"return_promise\", promise: handleStaleSession(context, host, options) };\n }\n\n // Handle auth errors — re-bootstrap token and retry\n if (result.authError) {\n return { action: \"return_promise\", promise: handleAuthError(context, host, options) };\n }\n\n if (!result.retriable) return { action: \"return\" };\n return {\n action: \"continue\",\n lastErrorWasImage: IMAGE_ERROR_PATTERN.test(result.resultSummary ?? \"\"),\n };\n}\n\nasync function runWithRetry(\n initialQuery: AsyncGenerator<HarnessEvent, void>,\n context: TaskContext,\n host: QueryHost,\n options: HarnessQueryOptions,\n): Promise<void> {\n let lastErrorWasImage = false;\n\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n if (host.isStopped()) return;\n\n const agentQuery =\n attempt === 0\n ? initialQuery\n : await buildRetryQuery(host, context, options, lastErrorWasImage);\n\n try {\n const result = await processEvents(agentQuery, context, host);\n const outcome = handleProcessResult(result, context, host, options);\n if (outcome.action === \"return\") return;\n if (outcome.action === \"return_promise\") return outcome.promise;\n lastErrorWasImage = outcome.lastErrorWasImage;\n } catch (error) {\n const outcome = handleRetryError(error, context, host, options, lastErrorWasImage);\n if (outcome instanceof Promise) return outcome;\n if (outcome.action === \"return\") return;\n lastErrorWasImage = outcome.lastErrorWasImage;\n }\n\n if (attempt >= RETRY_DELAYS_MS.length) {\n host.connection.postChatMessage(\n `Agent shutting down after ${RETRY_DELAYS_MS.length} failed retry attempts due to API errors. ` +\n `The task will resume automatically when the codespace restarts.`,\n );\n return;\n }\n\n await emitRetryStatus(host, attempt, RETRY_DELAYS_MS[attempt]);\n }\n}\n","// src/types/common.ts\nfunction isCuid(str) {\n return /^c[a-z0-9]{24}$/.test(str);\n}\n\n// src/types/project-settings-types.ts\nvar PREVIEW_PORT_DENY_LIST = [5432, 6379, 9200];\nfunction isAllowablePreviewPort(port) {\n if (typeof port !== \"number\" || !Number.isInteger(port)) return false;\n if (port < 1 || port > 65535) return false;\n return !PREVIEW_PORT_DENY_LIST.includes(port);\n}\nfunction sanitizeSessionPreviewPorts(ports) {\n if (!Array.isArray(ports)) return [];\n const seen = /* @__PURE__ */ new Set();\n const out = [];\n for (const raw of ports) {\n if (!raw || typeof raw !== \"object\") continue;\n const portValue = raw.port;\n if (!isAllowablePreviewPort(portValue)) continue;\n if (seen.has(portValue)) continue;\n seen.add(portValue);\n const labelValue = raw.label;\n const visValue = raw.visibility;\n out.push({\n port: portValue,\n ...typeof labelValue === \"string\" ? { label: labelValue } : {},\n ...visValue === \"public\" || visValue === \"private\" ? { visibility: visValue } : {}\n });\n }\n return out;\n}\nfunction resolveAllowedPreviewPorts(sources) {\n const set = /* @__PURE__ */ new Set();\n const add = (p) => {\n if (isAllowablePreviewPort(p)) set.add(p);\n };\n add(sources.taskPreviewPort);\n add(sources.projectPreviewPort);\n if (Array.isArray(sources.sessionPreviewPorts)) {\n for (const entry of sources.sessionPreviewPorts) add(entry?.port);\n }\n return [...set].sort((a, b) => a - b);\n}\nfunction pickPreferredPreviewPort(sources) {\n const fallback = sources.defaultPort ?? 3050;\n if (isAllowablePreviewPort(sources.taskPreviewPort)) return sources.taskPreviewPort;\n const sessionPorts = sanitizeSessionPreviewPorts(sources.sessionPreviewPorts);\n const firstSession = sessionPorts[0]?.port;\n if (isAllowablePreviewPort(firstSession)) return firstSession;\n if (isAllowablePreviewPort(sources.projectPreviewPort)) return sources.projectPreviewPort;\n return fallback;\n}\nvar PROJECT_FUNCTION_DEFAULTS = {\n identification: {\n model: \"claude-sonnet-4-20250514\",\n effort: \"low\",\n thinking: { type: \"adaptive\" }\n },\n tagAudit: {\n model: \"claude-opus-4-8\",\n effort: \"medium\",\n thinking: { type: \"adaptive\" }\n },\n taskAudit: {\n model: \"claude-sonnet-4-20250514\",\n effort: \"high\",\n thinking: { type: \"adaptive\" }\n },\n suggestionHandler: {\n model: \"claude-sonnet-4-20250514\",\n effort: \"high\",\n thinking: { type: \"adaptive\" }\n },\n prReview: {\n model: \"claude-sonnet-4-20250514\",\n effort: \"low\",\n thinking: { type: \"adaptive\" }\n }\n};\nfunction resolveProjectFunctionConfig(settings, functionId) {\n const defaults = PROJECT_FUNCTION_DEFAULTS[functionId];\n const override = settings?.functionSettings?.[functionId];\n return {\n model: override?.model ?? defaults.model,\n effort: override?.effort ?? defaults.effort,\n thinking: override?.thinking ?? defaults.thinking,\n instructions: override?.instructions\n };\n}\nfunction resolveCodeReviewMode(settings) {\n const s = settings ?? {};\n if (s.codeReviewMode) return s.codeReviewMode;\n if (s.codeReviewEnabled === true) return \"blocking\";\n return \"off\";\n}\n\n// src/types/agent-project-types.ts\nvar TASK_STATUS_ORDER = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\"\n];\n\n// src/types/task-types.ts\nvar CARD_TYPE_VALUES = [\"task\", \"incident\", \"suggestion\"];\nvar UNIFIED_STATUSES = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\"\n];\nvar CARD_TYPE_STATUSES = {\n task: UNIFIED_STATUSES,\n incident: UNIFIED_STATUSES,\n suggestion: UNIFIED_STATUSES\n};\nfunction validateStatusForType(type, status) {\n return CARD_TYPE_STATUSES[type].includes(status);\n}\n\n// src/types/service-map.ts\nvar ALLOWED_FILE_MIME_TYPES = [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"application/json\",\n \"text/csv\",\n \"text/plain\",\n \"text/markdown\",\n \"application/pdf\"\n];\nvar MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;\nvar EMBED_THRESHOLD_IMAGES = 5 * 1024 * 1024;\nvar EMBED_THRESHOLD_TEXT = 2 * 1024 * 1024;\nvar EMBEDDABLE_IMAGE_TYPES = [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\"\n];\nvar EMBEDDABLE_TEXT_TYPES = [\n \"text/plain\",\n \"text/csv\",\n \"text/markdown\",\n \"application/json\"\n];\nfunction isEmbeddableFile(mimeType, fileSize) {\n if (EMBEDDABLE_IMAGE_TYPES.some((t) => mimeType === t)) {\n return fileSize <= EMBED_THRESHOLD_IMAGES;\n }\n if (EMBEDDABLE_TEXT_TYPES.some((t) => mimeType === t)) {\n return fileSize <= EMBED_THRESHOLD_TEXT;\n }\n return false;\n}\n\n// src/types/connection-state.ts\nvar IDLE_HEARTBEAT_MS = 90 * 1e3;\nvar STRANDED_RUNNER_STATUSES = /* @__PURE__ */ new Set([\"stalled_heartbeat\", \"stranded\", \"crashed\"]);\nfunction deriveConnectionState(inputs, now = Date.now()) {\n const heartbeatAgeMs = inputs.lastHeartbeatAt ? Math.max(0, now - new Date(inputs.lastHeartbeatAt).getTime()) : null;\n if (inputs.deletionRequestedAt) {\n return { state: \"pendingDeletion\", heartbeatAgeMs };\n }\n const status = inputs.codespaceStatus;\n if (status === \"Deleted\") {\n return { state: \"deleted\", heartbeatAgeMs };\n }\n if (status === \"Creating\" || inputs.podStatus === \"Creating\") {\n return { state: \"creating\", heartbeatAgeMs };\n }\n if (inputs.agentRunnerStatus && STRANDED_RUNNER_STATUSES.has(inputs.agentRunnerStatus)) {\n return { state: \"stranded\", heartbeatAgeMs };\n }\n if (status === \"Stopped\" || inputs.podStatus === \"Stopped\" || inputs.podStatus === \"Sleeping\") {\n return { state: \"stopped\", heartbeatAgeMs };\n }\n if (status !== \"Running\" && !inputs.codespaceId && !inputs.podName) {\n return { state: \"none\", heartbeatAgeMs };\n }\n if (heartbeatAgeMs !== null && heartbeatAgeMs >= IDLE_HEARTBEAT_MS) {\n return { state: \"idle\", heartbeatAgeMs };\n }\n if (status === \"Running\") {\n return { state: \"active\", heartbeatAgeMs };\n }\n return { state: \"none\", heartbeatAgeMs };\n}\nfunction formatHeartbeatAge(ms) {\n if (ms === null) return \"never\";\n const sec = Math.floor(ms / 1e3);\n if (sec < 60) return `${sec}s ago`;\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const days = Math.floor(hr / 24);\n return `${days}d ago`;\n}\n\n// src/types/agent-session-requests.ts\nimport { z } from \"zod\";\nvar AgentHeartbeatSchema = z.object({\n sessionId: z.string().optional(),\n timestamp: z.string(),\n status: z.enum([\"active\", \"idle\", \"building\"]),\n currentAction: z.string().optional()\n});\nvar CreatePRInputSchema = z.object({\n title: z.string().min(1),\n body: z.string(),\n head: z.string().optional(),\n base: z.string().optional()\n});\nvar PostToChatInputSchema = z.object({\n message: z.string().min(1),\n type: z.enum([\"message\", \"question\", \"update\"]).optional().default(\"message\")\n});\nvar GetTaskContextRequestSchema = z.object({\n sessionId: z.string(),\n includeHistory: z.boolean().optional().default(false)\n});\nvar GetChatMessagesRequestSchema = z.object({\n sessionId: z.string(),\n limit: z.number().int().positive().optional().default(50),\n offset: z.number().int().nonnegative().optional().default(0)\n});\nvar GetTaskFilesRequestSchema = z.object({\n sessionId: z.string()\n});\nvar GetTaskFileRequestSchema = z.object({\n sessionId: z.string(),\n fileId: z.string()\n});\nvar GetTaskRequestSchema = z.object({\n sessionId: z.string(),\n taskSlugOrId: z.string()\n});\nvar GetCliHistoryRequestSchema = z.object({\n sessionId: z.string(),\n limit: z.number().int().positive().optional().default(100),\n source: z.enum([\"agent\", \"application\"]).optional()\n});\nvar ListSubtasksRequestSchema = z.object({\n sessionId: z.string()\n});\nvar GetDependenciesRequestSchema = z.object({\n sessionId: z.string()\n});\nvar GetSuggestionsRequestSchema = z.object({\n sessionId: z.string(),\n status: z.string().optional(),\n limit: z.number().int().min(1).max(100).optional()\n});\nvar ListManualTestsRequestSchema = z.object({\n sessionId: z.string()\n});\nvar PostToChatRequestSchema = PostToChatInputSchema;\nvar CreatePullRequestRequestSchema = CreatePRInputSchema.extend({ sessionId: z.string() });\nvar RequestFileUploadRequestSchema = z.object({\n sessionId: z.string(),\n fileName: z.string().min(1).max(255),\n mimeType: z.string().min(1).max(128),\n fileSize: z.number().int().positive().max(MAX_FILE_SIZE_BYTES)\n});\nvar ConfirmFileUploadRequestSchema = z.object({\n sessionId: z.string(),\n fileId: z.string(),\n title: z.string().max(500).optional()\n});\nvar UpdateTaskStatusRequestSchema = z.object({\n sessionId: z.string(),\n status: z.string(),\n force: z.boolean().optional().default(false)\n});\nvar StoreSessionIdRequestSchema = z.object({\n sessionId: z.string(),\n sdkSessionId: z.string()\n});\nvar SetManualTestsRequestSchema = z.object({\n sessionId: z.string(),\n items: z.array(z.object({ title: z.string().min(1) })).min(1)\n});\nvar TrackSpendingRequestSchema = z.object({\n sessionId: z.string(),\n inputTokens: z.number().int().nonnegative(),\n outputTokens: z.number().int().nonnegative(),\n costUsd: z.number().nonnegative(),\n model: z.string()\n});\nvar HeartbeatRequestSchema = AgentHeartbeatSchema;\nvar SessionStartRequestSchema = z.object({\n sessionId: z.string(),\n agentVersion: z.string(),\n capabilities: z.array(z.string())\n});\nvar SessionStopRequestSchema = z.object({\n sessionId: z.string(),\n reason: z.string().optional()\n});\nvar ConnectAgentRequestSchema = z.object({\n sessionId: z.string()\n});\nvar ReportAgentStatusRequestSchema = z.object({\n sessionId: z.string(),\n status: z.string()\n});\nvar NotifyAgentVersionRequestSchema = z.object({\n sessionId: z.string(),\n agentVersion: z.string()\n});\nvar CreateSubtaskRequestSchema = z.object({\n sessionId: z.string(),\n title: z.string().min(1),\n description: z.string().optional(),\n plan: z.string().optional(),\n storyPointValue: z.number().int().positive().optional(),\n ordinal: z.number().int().nonnegative().optional()\n});\nvar UpdateSubtaskRequestSchema = z.object({\n sessionId: z.string(),\n subtaskId: z.string(),\n title: z.string().min(1).optional(),\n description: z.string().optional(),\n plan: z.string().optional(),\n status: z.string().optional(),\n storyPointValue: z.number().int().positive().optional()\n});\nvar DeleteSubtaskRequestSchema = z.object({\n sessionId: z.string(),\n subtaskId: z.string()\n});\nvar GetTaskPropertiesRequestSchema = z.object({\n sessionId: z.string()\n});\nvar GetCumulativeSpendingRequestSchema = z.object({\n sessionId: z.string()\n});\nvar ModelUsageEntrySchema = z.object({\n model: z.string(),\n inputTokens: z.number().nonnegative(),\n outputTokens: z.number().nonnegative(),\n cacheReadInputTokens: z.number().nonnegative(),\n cacheCreationInputTokens: z.number().nonnegative(),\n costUSD: z.number().nonnegative()\n});\nvar GetCumulativeSpendingResponseSchema = z.object({\n totalCostUsd: z.number().nonnegative(),\n modelUsage: z.array(ModelUsageEntrySchema)\n});\nvar UpdateTaskFieldsRequestSchema = z.object({\n sessionId: z.string(),\n plan: z.string().optional(),\n description: z.string().optional()\n});\nvar UpdateTaskPropertiesRequestSchema = z.object({\n sessionId: z.string(),\n title: z.string().optional(),\n storyPointValue: z.number().int().positive().optional(),\n tagIds: z.array(z.string()).optional(),\n tagNames: z.array(z.string()).optional(),\n githubPRUrl: z.string().url().optional(),\n githubBranch: z.string().optional()\n});\nvar ListIconsRequestSchema = z.object({\n sessionId: z.string()\n});\nvar GenerateTaskIconRequestSchema = z.object({\n sessionId: z.string(),\n prompt: z.string().min(1),\n aspectRatio: z.string().optional()\n});\nvar SearchFaIconsRequestSchema = z.object({\n sessionId: z.string(),\n query: z.string().min(1),\n first: z.number().int().positive().optional()\n});\nvar PickFaIconRequestSchema = z.object({\n sessionId: z.string(),\n fontAwesomeId: z.string().min(1),\n fontAwesomeStyle: z.string().optional()\n});\nvar CreateFollowUpTaskRequestSchema = z.object({\n sessionId: z.string(),\n title: z.string().min(1),\n description: z.string().optional(),\n plan: z.string().optional(),\n storyPointValue: z.number().int().positive().optional()\n});\nvar AddDependencyRequestSchema = z.object({\n sessionId: z.string(),\n dependsOnSlugOrId: z.string()\n});\nvar RemoveDependencyRequestSchema = z.object({\n sessionId: z.string(),\n dependsOnSlugOrId: z.string()\n});\nvar CreateSuggestionRequestSchema = z.object({\n sessionId: z.string(),\n title: z.string().min(1),\n description: z.string().optional(),\n tagNames: z.array(z.string()).optional()\n});\nvar VoteSuggestionRequestSchema = z.object({\n sessionId: z.string(),\n suggestionId: z.string(),\n value: z.union([z.literal(1), z.literal(-1)])\n});\nvar TriggerIdentificationRequestSchema = z.object({\n sessionId: z.string()\n});\nvar SubmitCodeReviewResultRequestSchema = z.object({\n sessionId: z.string(),\n approved: z.boolean(),\n content: z.string()\n});\nvar StartChildCloudBuildRequestSchema = z.object({\n sessionId: z.string(),\n childTaskId: z.string()\n});\nvar StopChildBuildRequestSchema = z.object({\n sessionId: z.string(),\n childTaskId: z.string()\n});\nvar ApproveAndMergePRRequestSchema = z.object({\n sessionId: z.string(),\n childTaskId: z.string()\n});\nvar PostChildChatMessageRequestSchema = z.object({\n sessionId: z.string(),\n childTaskId: z.string(),\n message: z.string().min(1)\n});\nvar UpdateChildStatusRequestSchema = z.object({\n sessionId: z.string(),\n childTaskId: z.string(),\n status: z.string()\n});\nvar GetAgentStatusRequestSchema = z.object({\n taskId: z.string()\n});\nvar GetUiCliHistoryRequestSchema = z.object({\n taskId: z.string()\n});\nvar GetActivePtySessionRequestSchema = z.object({\n taskId: z.string()\n});\nvar SendSoftStopRequestSchema = z.object({\n taskId: z.string().optional(),\n projectId: z.string().optional()\n});\nvar FlushTaskQueueRequestSchema = z.object({\n taskId: z.string(),\n softStop: z.boolean().optional()\n});\nvar FlushProjectQueueRequestSchema = z.object({\n projectId: z.string()\n});\nvar CancelTaskQueuedMessageRequestSchema = z.object({\n taskId: z.string(),\n messageId: z.string()\n});\nvar FlushSingleQueuedMessageRequestSchema = z.object({\n taskId: z.string(),\n messageId: z.string(),\n softStop: z.boolean().optional()\n});\nvar FlushSingleProjectQueuedMessageRequestSchema = z.object({\n projectId: z.string(),\n index: z.number().int().nonnegative()\n});\nvar AnswerAgentQuestionRequestSchema = z.object({\n taskId: z.string(),\n requestId: z.string(),\n answers: z.record(z.string(), z.string())\n});\nvar ClearAgentTodosRequestSchema = z.object({\n taskId: z.string()\n});\nvar AgentQuestionOptionSchema = z.object({\n label: z.string(),\n description: z.string(),\n preview: z.string().optional()\n});\nvar AgentQuestionSchema = z.object({\n question: z.string(),\n header: z.string(),\n options: z.array(AgentQuestionOptionSchema),\n multiSelect: z.boolean().optional()\n});\nvar AskUserQuestionRequestSchema = z.object({\n sessionId: z.string(),\n question: z.string().min(1),\n requestId: z.string().min(1),\n questions: z.array(AgentQuestionSchema).min(1)\n});\nvar AgentEventSchema = z.object({\n type: z.string().min(1)\n}).catchall(z.unknown());\nvar EmitAgentEventRequestSchema = z.object({\n sessionId: z.string(),\n events: z.array(AgentEventSchema).max(500)\n});\nvar RefreshGithubTokenRequestSchema = z.object({\n sessionId: z.string()\n});\nvar RefreshGithubTokenResponseSchema = z.object({\n token: z.string()\n});\nvar PTY_FRAME_MAX_CHARS = 256 * 1024;\nvar PTY_MAX_DIMENSION = 1e3;\nvar PtyOutputRequestSchema = z.object({\n sessionId: z.string(),\n data: z.string().max(PTY_FRAME_MAX_CHARS),\n cols: z.number().int().positive().max(PTY_MAX_DIMENSION).optional(),\n rows: z.number().int().positive().max(PTY_MAX_DIMENSION).optional()\n});\nvar PtyInputRequestSchema = z.object({\n sessionId: z.string(),\n data: z.string().max(PTY_FRAME_MAX_CHARS)\n});\nvar PtyResizeRequestSchema = z.object({\n sessionId: z.string(),\n cols: z.number().int().positive().max(PTY_MAX_DIMENSION),\n rows: z.number().int().positive().max(PTY_MAX_DIMENSION)\n});\nvar PtyAttachRequestSchema = z.object({\n sessionId: z.string()\n});\nvar CreatePRResponseSchema = z.object({\n prNumber: z.number().int().positive(),\n prUrl: z.string().url()\n});\nvar PostToChatResponseSchema = z.object({\n messageId: z.string()\n});\nvar UpdateTaskStatusResponseSchema = z.object({\n taskId: z.string(),\n status: z.string()\n});\nvar StoreSessionIdResponseSchema = z.object({\n success: z.boolean()\n});\nvar HeartbeatResponseSchema = z.object({\n acknowledged: z.boolean()\n});\nvar SessionStartResponseSchema = z.object({\n sessionId: z.string(),\n startedAt: z.string()\n});\nvar SessionStopResponseSchema = z.object({\n sessionId: z.string(),\n stoppedAt: z.string()\n});\nvar DeleteSubtaskResponseSchema = z.object({\n deleted: z.boolean()\n});\nvar RegisterProjectAgentResponseSchema = z.object({\n registered: z.boolean(),\n /** ProjectCodespaceSession id — used by the runner to filter targeted chat messages. */\n sessionId: z.string(),\n agentName: z.string(),\n agentInstructions: z.string(),\n model: z.string(),\n agentSettings: z.record(z.string(), z.unknown()).nullable(),\n branchSwitchCommand: z.string().nullable()\n});\n\n// src/types/agent-session-project-requests.ts\nimport { z as z2 } from \"zod\";\nvar RegisterProjectAgentRequestSchema = z2.object({\n projectId: z2.string(),\n capabilities: z2.array(z2.string())\n});\nvar ProjectRunnerHeartbeatRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar ReportProjectAgentStatusRequestSchema = z2.object({\n projectId: z2.string(),\n status: z2.enum([\"busy\", \"idle\"]),\n activeChatId: z2.string().nullish(),\n activeTaskId: z2.string().nullish(),\n activeBranch: z2.string().nullish()\n});\nvar DisconnectProjectRunnerRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar GetProjectAgentContextRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar GetProjectAgentContextByRoleRequestSchema = z2.object({\n projectId: z2.string(),\n role: z2.string()\n});\nvar GetProjectFunctionConfigRequestSchema = z2.object({\n projectId: z2.string(),\n functionId: z2.string()\n});\nvar GetProjectChatHistoryRequestSchema = z2.object({\n projectId: z2.string(),\n limit: z2.number().int().positive().optional().default(50),\n chatId: z2.string().optional()\n});\nvar PostProjectAgentMessageRequestSchema = z2.object({\n projectId: z2.string(),\n content: z2.string().min(1),\n chatId: z2.string().optional()\n});\nvar ListProjectTasksRequestSchema = z2.object({\n projectId: z2.string(),\n status: z2.string().optional(),\n assigneeId: z2.string().optional(),\n unassigned: z2.boolean().optional(),\n limit: z2.number().int().positive().optional().default(50)\n}).refine((p) => !(p.unassigned && p.assigneeId), {\n message: \"Pass either assigneeId or unassigned, not both\"\n});\nvar GetProjectTaskRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string()\n});\nvar SearchProjectTasksRequestSchema = z2.object({\n projectId: z2.string(),\n tagNames: z2.array(z2.string()).optional(),\n searchQuery: z2.string().optional(),\n statusFilters: z2.array(z2.string()).optional(),\n assigneeId: z2.string().optional(),\n unassigned: z2.boolean().optional(),\n limit: z2.number().int().positive().optional().default(20)\n}).refine((p) => !(p.unassigned && p.assigneeId), {\n message: \"Pass either assigneeId or unassigned, not both\"\n});\nvar ListProjectTagsRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar GetProjectSummaryRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar CreateProjectTaskRequestSchema = z2.object({\n projectId: z2.string(),\n title: z2.string().min(1),\n description: z2.string().optional(),\n plan: z2.string().optional(),\n status: z2.string().optional(),\n requestingUserId: z2.string().optional()\n});\nvar UpdateProjectTaskRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n title: z2.string().optional(),\n description: z2.string().optional(),\n plan: z2.string().optional(),\n status: z2.string().optional(),\n assignedUserId: z2.string().nullish(),\n requestingUserId: z2.string().optional()\n});\nvar ReportProjectAgentEventRequestSchema = z2.object({\n projectId: z2.string(),\n event: z2.record(z2.string(), z2.unknown())\n});\nvar ReportTagAuditProgressRequestSchema = z2.object({\n projectId: z2.string(),\n requestId: z2.string(),\n activity: z2.object({\n tool: z2.string(),\n input: z2.string().optional(),\n timestamp: z2.string()\n })\n});\nvar ReportTagAuditResultRequestSchema = z2.object({\n projectId: z2.string(),\n requestId: z2.string(),\n recommendations: z2.array(z2.record(z2.string(), z2.unknown())),\n summary: z2.string(),\n complete: z2.boolean()\n});\nvar ReportNewCommitsDetectedRequestSchema = z2.object({\n projectId: z2.string(),\n commits: z2.array(\n z2.object({\n sha: z2.string(),\n message: z2.string(),\n author: z2.string()\n })\n ),\n branch: z2.string()\n});\nvar ReportEnvironmentReadyRequestSchema = z2.object({\n projectId: z2.string(),\n branch: z2.string(),\n setupComplete: z2.boolean(),\n startCommandRunning: z2.boolean()\n});\nvar ReportEnvSwitchProgressRequestSchema = z2.object({\n projectId: z2.string(),\n step: z2.string(),\n progress: z2.number(),\n message: z2.string().optional()\n});\nvar ForwardProjectChatMessageRequestSchema = z2.object({\n projectId: z2.string(),\n chatId: z2.string(),\n content: z2.string().min(1),\n targetUserId: z2.string().optional()\n});\nvar CancelQueuedProjectMessageRequestSchema = z2.object({\n projectId: z2.string(),\n index: z2.number().int().nonnegative()\n});\nvar GetProjectCliHistoryRequestSchema = z2.object({\n projectId: z2.string(),\n limit: z2.number().int().positive().optional().default(50),\n source: z2.string().optional()\n});\nvar PostToProjectTaskChatRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n content: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar GetProjectTaskCliRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n limit: z2.number().int().positive().optional().default(50),\n source: z2.string().optional()\n});\nvar StartProjectBuildRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar StopProjectBuildRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar ApproveProjectMergePRRequestSchema = z2.object({\n projectId: z2.string(),\n childTaskId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar ListProjectSubtasksRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string()\n});\nvar CreateProjectSubtaskRequestSchema = z2.object({\n projectId: z2.string(),\n parentTaskId: z2.string(),\n title: z2.string().min(1),\n description: z2.string().optional(),\n plan: z2.string().optional(),\n ordinal: z2.number().int().nonnegative().optional(),\n storyPointValue: z2.number().int().positive().optional(),\n requestingUserId: z2.string().optional()\n});\nvar UpdateProjectSubtaskRequestSchema = z2.object({\n projectId: z2.string(),\n subtaskId: z2.string(),\n title: z2.string().optional(),\n description: z2.string().optional(),\n plan: z2.string().optional(),\n status: z2.string().optional(),\n ordinal: z2.number().int().nonnegative().optional(),\n storyPointValue: z2.number().int().positive().optional(),\n requestingUserId: z2.string().optional()\n});\nvar DeleteProjectSubtaskRequestSchema = z2.object({\n projectId: z2.string(),\n subtaskId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar GetProjectTaskChatRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n limit: z2.number().int().positive().optional().default(20)\n});\nvar AddProjectTaskDependencyRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n dependsOnSlugOrId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar RemoveProjectTaskDependencyRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n dependsOnSlugOrId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar VoteProjectSuggestionRequestSchema = z2.object({\n projectId: z2.string(),\n suggestionId: z2.string(),\n value: z2.union([z2.literal(1), z2.literal(-1)]),\n requestingUserId: z2.string().optional()\n});\nvar GetProjectTaskDependenciesRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string()\n});\nvar ListProjectTaskFilesRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string()\n});\nvar GetProjectAttachmentRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n fileId: z2.string(),\n /** Byte offset into text content (paging large logs/JSON). Default 0. */\n offset: z2.number().int().nonnegative().optional(),\n /** Max bytes of text content to return from `offset`. Server default applies. */\n maxBytes: z2.number().int().positive().optional()\n});\nvar CreateProjectPullRequestRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n title: z2.string().min(1),\n body: z2.string(),\n head: z2.string().optional(),\n base: z2.string().optional(),\n requestingUserId: z2.string().optional()\n});\nvar ListProjectMembersRequestSchema = z2.object({\n projectId: z2.string()\n});\nvar AddProjectTaskReviewerRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n userId: z2.string(),\n requestingUserId: z2.string().optional()\n});\nvar RemoveProjectTaskReviewerRequestSchema = z2.object({\n projectId: z2.string(),\n taskId: z2.string(),\n userId: z2.string(),\n requestingUserId: z2.string().optional()\n});\n\n// src/types/agent-session-events.ts\nvar CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set([\n \"ci_failure\",\n \"review_trigger\",\n \"merge_conflict\",\n \"merge_failed\",\n \"pull_branch\"\n]);\nvar createAgentSessionRoom = (sessionId) => `agentSession:${sessionId}`;\nvar createProjectRoom = (projectId) => `project:${projectId}`;\n\n// src/types/deployment-service-types.ts\nvar DEPLOYMENT_TARGET_PROVIDERS = [\n \"pm2-local\",\n \"github-actions\",\n \"vercel\",\n \"cloud-run\",\n \"gke\"\n];\nvar DEPLOYMENT_TARGET_ENVIRONMENTS = [\"dev\", \"prod\", \"staging\", \"custom\"];\n\n// src/generated/mcp-tool-registry.generated.ts\nvar MCP_TOOL_REGISTRY = [\n {\n name: \"upload_attachment\",\n description: \"Upload an image file (e.g. a Playwright screenshot) as a task attachment AND post it to the task chat in one step \\u2014 no follow-up post_to_chat call needed. Supports png/jpg/gif/webp.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/attachment-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"list_manual_tests\",\n description: \"List the manual test checklist items for the current task. Use to see what manual verification steps have already been recorded.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/checklist-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"set_manual_tests\",\n description: \"Add manual test steps to the task checklist. Existing items with the same title are automatically skipped (deduplication). Use to record specific manual verification steps that reviewers should follow when testing this PR.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/checklist-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"debug_click_client\",\n description: \"Click an element in the headless browser by CSS selector. Playwright auto-waits for visibility/stability/enabled up to 10s \\u2014 a miss throws with a failure message.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_client_screenshot\",\n description: \"Take a screenshot of the current page state in the headless browser. Returns the image as base64-encoded PNG.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_continue_client\",\n description: \"Resume client-side execution after the browser debugger has paused at a breakpoint.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_evaluate_client\",\n description: \"Evaluate a JavaScript expression in the browser context. When paused, runs in the paused frame's scope; otherwise the page's global scope. Side effects execute \\u2014 prefer read-only.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_get_client_console\",\n description: \"Get console messages captured from the headless browser. Includes console.log, warn, error, etc.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_get_client_errors\",\n description: \"Get uncaught errors captured from the headless browser. Includes error messages and source-mapped stack traces.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_get_client_network\",\n description: \"Get network requests captured from the headless browser. Shows URLs, methods, status codes, and timing.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_inspect_client_paused\",\n description: \"When the client (browser) debugger is paused, returns call stack and local variables. For server pauses use debug_inspect_paused. Queued hits returned if already resumed.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_list_client_breakpoints\",\n description: \"List all active client-side breakpoints with their file, line, and condition.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_navigate_client\",\n description: \"Navigate the headless browser to a URL. Waits for domcontentloaded (Playwright's default ~30s timeout applies).\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_remove_client_breakpoint\",\n description: \"Remove a previously set client-side breakpoint by its ID.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_set_client_breakpoint\",\n description: \"Set a breakpoint in client-side code running in headless Chromium. V8 resolves source maps automatically \\u2014 use original .tsx/.ts file paths.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/client-debug-tools.ts\",\n category: \"clientDebug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"approve_code_review\",\n description: \"Approve the code review and exit. Use when the diff passes all review criteria. Takes only a summary \\u2014 for changes, use request_code_changes with a structured issues[] list.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/code-review-tools.ts\",\n category: \"codeReview\",\n modes: \"review\"\n },\n {\n name: \"request_code_changes\",\n description: \"Request changes during code review and exit. Use when substantive issues must be fixed before merge. Each issue: { file, line?, severity: critical|major|minor, description }.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/code-review-tools.ts\",\n category: \"codeReview\",\n modes: \"review\"\n },\n {\n name: \"debug_add_probe\",\n description: \"Add a debug probe at a code location. Captures expression values each time the line executes, without pausing or modifying source. Auto-cleaned on debug exit.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_continue\",\n description: \"Resume execution after the debugger has paused at a breakpoint.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_enter_mode\",\n description: \"Activate debug mode. Default: server-only (Node --inspect via CDP). Set clientSide=true (previewUrl required) or both flags for full-stack (adds headless Chromium via Playwright).\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_evaluate\",\n description: \"Evaluate a JavaScript expression server-side in the Node process. When paused, runs in the frame's scope (frameIndex selects frame). Side effects execute \\u2014 prefer read-only.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_exit_mode\",\n description: \"Exit debug mode: removes all breakpoints, disconnects the debugger, and restarts the dev server normally.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_get_probe_results\",\n description: \"Fetch captured probe hit data. Filter by label (wins) or probeId. Returns grouped text with per-probe hit count, timestamps, and captured expression values.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_inspect_paused\",\n description: \"When the debugger is paused at a breakpoint, returns the call stack and local variables. Check this after a breakpoint is hit to understand the current execution state.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_list_breakpoints\",\n description: \"List all currently active breakpoints with their file, line, and condition.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_list_probes\",\n description: \"List all active debug probes with their file, line, expressions, and labels.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_remove_breakpoint\",\n description: \"Remove a previously set breakpoint by its ID.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_remove_probe\",\n description: \"Remove a previously set debug probe by its ID.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_set_breakpoint\",\n description: \"Set a breakpoint at the specified file and line number. Optionally provide a condition expression that must evaluate to true for the breakpoint to pause execution.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_step_into\",\n description: \"Step into the function call on the current line while paused at a breakpoint. Pauses at the first line inside the called function.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_step_over\",\n description: \"Step over the current line while paused at a breakpoint. Executes the current line and pauses at the next line in the same function.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/debug-tools.ts\",\n category: \"debug\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"get_dependencies\",\n description: \"Get this task's dependencies and their met/unmet status (met = merged to dev). Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/dependency-suggestion-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"get_suggestions\",\n description: \"List project suggestions sorted by vote score. Filter by status or cap with limit (default 20). Suggestions are project-level ideas, not tasks \\u2014 use get_task for tasks.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/dependency-suggestion-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"update_task_properties\",\n description: \"Set one or more task properties in a single call. All fields are optional \\u2014 only include the fields you want to update.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/discovery-tools.ts\",\n category: \"discovery\",\n modes: \"discovery, auto\"\n },\n {\n name: \"add_dependency\",\n description: \"Add a blocking dependency \\u2014 this task cannot start until the named task is merged to dev. For post-task follow-ups use create_follow_up_task instead.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"create_follow_up_task\",\n description: \"Create a follow-up task that depends on the current task. Use for out-of-scope work or cleanup that should land after this task merges. For blockers use add_dependency.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"create_pull_request\",\n description: \"Create a GitHub PR for this task. Auto-stages, commits (commitMessage or title default), pushes to origin, then opens the PR. Always use this instead of gh CLI or raw git.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"create_suggestion\",\n description: \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded. For actionable work on this task open a follow-up task.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"force_update_task_status\",\n description: \"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all modes (emergency override; always exposed)\"\n },\n {\n name: \"post_to_chat\",\n description: \"Post an out-of-band chat message to a task. Use only when explicitly asked, or to message a child's chat (pass its ID). Normal replies already appear in chat automatically.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"remove_dependency\",\n description: \"Remove a previously added dependency from this task. When to use: the dependency was added in error or is no longer relevant. Returns: confirmation string.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"vote_suggestion\",\n description: \"Vote +1 or -1 on a project suggestion. Use to express support or disagreement with a specific suggestion returned by get_suggestions.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/mutation-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (common tools)\"\n },\n {\n name: \"approve_and_merge_pr\",\n description: \"Approve and merge a child task's PR. Preconditions: child in ReviewPR. Returns { merged }: true = merged (status\\u2192ReviewDev); false = automerge queued, wait for ReviewDev.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"packRunner\",\n modes: \"parent task only (review, auto, discovery, help, building)\"\n },\n {\n name: \"create_subtask\",\n description: \"Create a subtask under the current parent task. Use when breaking a complex parent into smaller pieces during planning. For post-task follow-ups use create_follow_up_task.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"pm\",\n modes: \"review, auto, discovery, help; building (parent task only). Pack tools (start_child_cloud_build, stop_child_build, approve_and_merge_pr) require parent task.\"\n },\n {\n name: \"delete_subtask\",\n description: \"Delete a subtask by id. When to use: a subtask was created in error or is no longer needed. Returns: confirmation string.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"pm\",\n modes: \"review, auto, discovery, help; building (parent task only). Pack tools (start_child_cloud_build, stop_child_build, approve_and_merge_pr) require parent task.\"\n },\n {\n name: \"list_subtasks\",\n description: \"List all subtasks under the current parent task. Use to coordinate child work \\u2014 check who is running, ready for review, or blocked. For non-child tasks use get_task.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"pm\",\n modes: \"review, auto, discovery, help; building (parent task only). Pack tools (start_child_cloud_build, stop_child_build, approve_and_merge_pr) require parent task.\"\n },\n {\n name: \"start_child_cloud_build\",\n description: \"Start a cloud build (codespace) for a child task. Preconditions: child is in Open status, has a story point value, and has an agent assigned.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"packRunner\",\n modes: \"parent task only (review, auto, discovery, help, building)\"\n },\n {\n name: \"stop_child_build\",\n description: \"Send a graceful stop signal to a running child build's agent. Not a force-kill \\u2014 the agent may take a moment to wind down.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"packRunner\",\n modes: \"parent task only (review, auto, discovery, help, building)\"\n },\n {\n name: \"update_subtask\",\n description: \"Update an existing subtask's fields (title, description, plan, ordinal, storyPointValue). Use when refining a child's plan or reordering. For the current task use update_task_plan.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"pm\",\n modes: \"review, auto, discovery, help; building (parent task only). Pack tools (start_child_cloud_build, stop_child_build, approve_and_merge_pr) require parent task.\"\n },\n {\n name: \"update_task_plan\",\n description: \"Save the finalized plan and/or description to the current task. Use in Plan mode after alignment. For children use update_subtask; for title/tags/PR use update_task_properties.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/pm-tools.ts\",\n category: \"pm\",\n modes: \"task mode: discovery, auto only. PM/agent modes: review, auto, discovery, help; building (parent task only).\"\n },\n {\n name: \"add_reviewer\",\n description: \"Add a project member as a reviewer on a task. Idempotent \\u2014 adding an existing reviewer is a no-op.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"approve_and_merge_pr\",\n description: \"Approve and merge a task's PR. Preconditions: task in ReviewPR with an open PR. Returns { merged }: false means automerge queued \\u2014 wait for status to flip to ReviewDev.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"create_subtask\",\n description: \"Create a subtask under a parent task in this project. Use for breaking parent tasks into smaller pieces during planning.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"create_task\",\n description: \"Create a new task in the project.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"delete_subtask\",\n description: \"Delete a subtask by id. Use when a subtask was created in error or is no longer needed.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"force_update_task_status\",\n description: \"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"remove_reviewer\",\n description: \"Remove a reviewer from a task. Idempotent \\u2014 removing a non-reviewer is a no-op.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"start_task\",\n description: \"Start a cloud build (codespace) for a task. Preconditions: task has a story point value and an agent assigned.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"stop_task\",\n description: \"Send a stop signal to a running task's cloud build. Not a force-kill \\u2014 the agent may take a moment to wind down.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"update_project_task\",\n description: \"Update an existing task's title, description, plan, status, or assignee. Project-runner scope.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"update_subtask\",\n description: \"Update an existing subtask's fields (title, description, plan, status, ordinal, storyPointValue).\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"update_task_plan\",\n description: \"Save a plan or description to a task. Convenience wrapper around update_project_task for the common Plan-mode case.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-action-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"add_dependency\",\n description: \"Add a blocking dependency \\u2014 a task cannot start until the named task is merged to dev.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-suggestion-dependency-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"create_suggestion\",\n description: \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-suggestion-dependency-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"remove_dependency\",\n description: \"Remove a previously added dependency from a task.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-suggestion-dependency-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"vote_suggestion\",\n description: \"Vote +1 or -1 on a project suggestion.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-suggestion-dependency-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"get_project_summary\",\n description: \"Get a summary of the project including task counts by status and active builds.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"get_project_task\",\n description: \"Get detailed information about a task in this project (chat messages, child tasks, session). Project-runner scope.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"get_task_logs\",\n description: \"Read CLI execution logs for a task \\u2014 agent reasoning, tool calls, and setup/dev-server output. For human chat use read_task_chat.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"list_project_members\",\n description: \"List project members with user ID, name, email, and access level. Use to resolve a person's name or email to a user ID for task assignment or review.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"list_subtasks\",\n description: \"List the immediate child tasks under a parent task. Use to coordinate subtask work \\u2014 see status, ordering, and PR state.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"list_tags\",\n description: \"List all tags available in the project.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"list_tasks\",\n description: \"List tasks in the project. Optionally filter by status or assignment (a specific assignee, or unassigned tasks). Returns summaries \\u2014 plan omitted, description truncated; use get_project_task for full details.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"post_to_chat\",\n description: \"Post an out-of-band message into a chat. Omit task_id to post into the project chat; pass task_id to post into a specific task's chat. Normal replies already appear in chat automatically.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"read_chat_history\",\n description: \"Read recent messages from a chat. Omit chat_id to read the project chat; pass a chat_id to read a specific chat.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"read_task_chat\",\n description: \"Read recent human/user chat messages for a specific task in this project. For agent execution logs use get_task_logs.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"search_tasks\",\n description: \"Search tasks by tags, text query, status filters, or assignment. Returns summaries \\u2014 plan omitted, description truncated; use get_project_task for full details.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/project-tools.ts\",\n category: \"projectRunner\",\n modes: \"project-runner (not mode-gated \\u2014 separate harness)\"\n },\n {\n name: \"get_attachment\",\n description: \"Fetch one task file's content plus metadata by file ID. Call list_task_files first to discover IDs and check sizes \\u2014 large binaries may be truncated by the service's size limit.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"get_current_plan\",\n description: \"Re-read the current task's plan. Use when the user updated the plan or asked you to re-read it \\u2014 otherwise the plan is already in initial context. For task metadata use get_task.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"get_execution_logs\",\n description: \"Read CLI execution logs \\u2014 agent reasoning, tool calls, and setup/dev-server output. Filter via source='agent' or 'application'. For human chat use read_task_chat.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"get_task\",\n description: \"Look up any task by slug or ID. Returns JSON with id, slug, title, description, plan, status, branch, githubPRNumber, githubPRUrl, storyPoints. For children use list_subtasks.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"list_task_files\",\n description: \"List all files attached to this task with metadata. Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"read_task_chat\",\n description: \"Read recent human/user chat messages for a task. Omit task_id for the current task; pass a child ID for a child's chat. For agent logs use get_execution_logs.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/task-context-tools.ts\",\n category: \"global\",\n modes: \"all PM/agent modes (read-only common tools)\"\n },\n {\n name: \"debug_clear_telemetry\",\n description: \"Clear all captured telemetry events from the buffer. Useful to reset before reproducing a specific issue.\",\n readOnly: false,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/telemetry-tools.ts\",\n category: \"telemetry\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_get_telemetry\",\n description: \"Query structured telemetry events (HTTP, DB, Socket.IO, errors) captured from the dev server. Returns filtered structured data instead of raw logs.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/telemetry-tools.ts\",\n category: \"telemetry\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"debug_telemetry_status\",\n description: \"Check if telemetry is active, how many events have been captured, and which framework patches (Express, Prisma, Socket.IO) were successfully applied.\",\n readOnly: true,\n package: \"conveyor-agent\",\n sourceFile: \"packages/conveyor-agent/src/tools/telemetry-tools.ts\",\n category: \"telemetry\",\n modes: \"building (requires debug manager)\"\n },\n {\n name: \"get_attachment\",\n description: \"Fetch one task file's content plus metadata by file ID (accepts task id or slug). Images are returned as viewable image blocks. Large text files (logs, JSON) are returned in pages \\u2014 use `offset`/`maxBytes` to read more, or fetch `downloadUrl` for the whole file. Call list_task_files first to discover IDs and sizes.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/attachments.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"list_task_files\",\n description: \"List all files attached to a task with metadata (no contents \\u2014 fast and small). Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/attachments.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"get_build_status\",\n description: \"Check codespace and agent status for a task\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/builds.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"start_task\",\n description: \"Start a cloud build (codespace) for a task\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/builds.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"stop_task\",\n description: \"Stop a running cloud build for a task\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/builds.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"add_dependency\",\n description: \"Add a blocking dependency \\u2014 this task cannot start until the named task is merged to dev.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/dependencies.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"get_dependencies\",\n description: \"Get a task's dependencies and their met/unmet status (met = merged to dev). Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/dependencies.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"remove_dependency\",\n description: \"Remove a previously added dependency from a task. The task is no longer blocked by the named task. Returns: confirmation string.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/dependencies.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"get_project_summary\",\n description: \"Get overall project status: task counts by status, active builds, repo info\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/project.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"list_project_members\",\n description: \"List project members with user ID, name, email, and access level \\u2014 use to resolve a person's name or email to a user ID for task assignment or review\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/project.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"create_pull_request\",\n description: \"Open a GitHub pull request for a task's existing branch (the branch must already be pushed to origin). Moves the task to ReviewPR. Returns the PR number and URL.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/pull-request.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"create_subtask\",\n description: \"Create a subtask under a parent task. Subtasks break a larger task into independently buildable pieces.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/subtasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"delete_subtask\",\n description: \"Delete a subtask by ID. This is permanent \\u2014 use update_subtask to set status to Cancelled if you only want to close it.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/subtasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"list_subtasks\",\n description: \"List all subtasks of a parent task with their status and ordering.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/subtasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"update_subtask\",\n description: \"Update a subtask's fields: title, description, plan, status, ordering, or story points.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/subtasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"create_suggestion\",\n description: \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/suggestions.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"add_reviewer\",\n description: \"Add a project member as a reviewer on a task. Idempotent \\u2014 adding an existing reviewer is a no-op.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"approve_and_merge_pr\",\n description: \"Approve and merge a child task's pull request. Only succeeds if all CI/CD checks are passing. The child task must be in ReviewPR status with a PR.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"approve_task\",\n description: \"Move a task forward in the review flow (ReviewPR -> ReviewDev, or -> Complete)\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"create_task\",\n description: \"Create a new task with title, description, and optional plan\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"get_task\",\n description: \"Get full task details including plan, chat history, PR info, subtasks, and build status\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"get_task_logs\",\n description: \"Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events. For human chat use read_task_chat.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"list_tags\",\n description: \"List all project tags with their names, IDs, and colors\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"list_tasks\",\n description: \"List project tasks, optionally filtered by status or assignment (a specific assignee, or unassigned tasks). Returns summaries \\u2014 plan omitted, description truncated; use get_task for full details.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"post_to_chat\",\n description: \"Post a message to a task's chat\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"read_task_chat\",\n description: \"Read messages from a task's chat. For agent execution logs use get_task_logs.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"remove_reviewer\",\n description: \"Remove a reviewer from a task. Idempotent \\u2014 removing a non-reviewer is a no-op.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"request_changes\",\n description: \"Post feedback and send task back to InProgress for more work\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"search_tasks\",\n description: \"Search tasks by tag name, text query, status, and/or assignment. Use tag names like 'agent-runner', not IDs. Returns summaries \\u2014 plan omitted, description truncated; use get_task for full details.\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n },\n {\n name: \"update_task\",\n description: \"Update task fields: title, description, plan, status, or assignment\",\n readOnly: false,\n package: \"conveyor-mcp\",\n sourceFile: \"packages/conveyor-mcp/src/tools/tasks.ts\",\n category: \"mcp\",\n modes: \"conveyor-mcp (MCP server)\"\n }\n];\n\n// src/types/agent-tool-registry.ts\nfunction getToolsByCategory(category) {\n return MCP_TOOL_REGISTRY.filter((tool) => tool.category === category);\n}\n\n// src/types/task-audit-requests.ts\nimport { z as z3 } from \"zod\";\nvar StartTaskAuditRequestSchema = z3.object({\n projectId: z3.string(),\n taskIds: z3.array(z3.string()).min(1)\n});\nvar ReportTaskAuditProgressRequestSchema = z3.object({\n projectId: z3.string(),\n requestId: z3.string(),\n taskId: z3.string(),\n activity: z3.object({\n tool: z3.string(),\n input: z3.string().optional(),\n timestamp: z3.string()\n })\n});\nvar CreateProjectSuggestionRequestSchema = z3.object({\n projectId: z3.string(),\n title: z3.string().min(1),\n description: z3.string().optional(),\n tagNames: z3.array(z3.string()).optional(),\n requestingUserId: z3.string().optional()\n});\nvar ReportTaskAuditBatchCompleteRequestSchema = z3.object({\n projectId: z3.string(),\n requestId: z3.string()\n});\nvar ReportTaskAuditResultRequestSchema = z3.object({\n projectId: z3.string(),\n requestId: z3.string(),\n taskId: z3.string(),\n summary: z3.string(),\n turnGrades: z3.array(\n z3.object({\n turnIndex: z3.number(),\n phase: z3.enum([\"planning\", \"building\", \"human\"]),\n grade: z3.enum([\"correct\", \"neutral\", \"blunder\"]),\n reasoning: z3.string(),\n eventType: z3.string(),\n eventSummary: z3.string()\n })\n ),\n planningAccuracy: z3.number().nullable(),\n buildingAccuracy: z3.number().nullable(),\n humanAccuracy: z3.number().nullable(),\n planningCorrect: z3.number(),\n planningNeutral: z3.number(),\n planningBlunder: z3.number(),\n buildingCorrect: z3.number(),\n buildingNeutral: z3.number(),\n buildingBlunder: z3.number(),\n humanCorrect: z3.number(),\n humanNeutral: z3.number(),\n humanBlunder: z3.number(),\n humanEvaluations: z3.array(\n z3.object({\n messageIndex: z3.number(),\n rating: z3.number().int().min(-1).max(1),\n reasoning: z3.string()\n })\n ).optional().default([]),\n suggestionIds: z3.array(z3.string()),\n auditCostUsd: z3.number().nullable(),\n model: z3.string().nullable(),\n error: z3.string().optional()\n});\n\n// src/constants/timezone.ts\nvar PROJECT_TIMEZONE = \"America/Los_Angeles\";\n\n// src/constants/agent-session-runner.ts\nvar CODESPACE_SESSION_ACTIVE_RUNNER_STATUSES = [\n \"connected\",\n \"idle\",\n \"busy\",\n \"running\",\n \"fetching_context\",\n \"waiting_for_input\",\n \"setup\",\n \"connecting\"\n];\nvar TERMINAL_TASK_STATUSES = [\"Complete\", \"Cancelled\"];\n\n// src/constants/agent-chat-history.ts\nvar TASK_CHAT_HISTORY_LIMIT = 20;\nvar PM_CHAT_HISTORY_LIMIT = 40;\nvar AGENT_CHAT_HISTORY_FETCH_LIMIT = Math.max(TASK_CHAT_HISTORY_LIMIT, PM_CHAT_HISTORY_LIMIT) + 10;\n\n// src/room-helpers.ts\nfunction serviceRoom(service, entityId) {\n return `${service}:${entityId}`;\n}\nfunction userRoom(userId) {\n return `user:${userId}`;\n}\nfunction notificationUserRoom(userId) {\n return `notificationService:user:${userId}`;\n}\nfunction cliRoom(taskId) {\n return `task:${taskId}:cli`;\n}\nfunction projectCliRoom(projectId, userId) {\n return `project:${projectId}:cli:${userId}`;\n}\nfunction projectEventsRoom(projectId) {\n return `project:${projectId}:events`;\n}\n\n// src/utils/stat-date.ts\nfunction todayInProjectTZ() {\n return (/* @__PURE__ */ new Date()).toLocaleDateString(\"en-CA\", { timeZone: PROJECT_TIMEZONE });\n}\nfunction formatDateInProjectTZ(date) {\n return date.toLocaleDateString(\"en-CA\", { timeZone: PROJECT_TIMEZONE });\n}\nfunction resolveStatDateRange(statDate, fallbackDays) {\n const today = todayInProjectTZ();\n if (statDate) {\n if (statDate.mode === \"month\" && typeof statDate.month === \"number\") {\n const sinceDate3 = `${statDate.year}-${String(statDate.month).padStart(2, \"0\")}-01`;\n const lastDay = new Date(statDate.year, statDate.month, 0).getDate();\n const endStr2 = `${statDate.year}-${String(statDate.month).padStart(2, \"0\")}-${String(lastDay).padStart(2, \"0\")}`;\n return { sinceDate: sinceDate3, untilDate: endStr2 < today ? endStr2 : today };\n }\n const sinceDate2 = `${statDate.year}-01-01`;\n const endStr = `${statDate.year}-12-31`;\n return { sinceDate: sinceDate2, untilDate: endStr < today ? endStr : today };\n }\n const days = fallbackDays ?? 30;\n const d = /* @__PURE__ */ new Date();\n d.setDate(d.getDate() - days);\n const sinceDate = formatDateInProjectTZ(d);\n return { sinceDate, untilDate: today };\n}\nfunction generateDateRange(sinceStr, untilStr) {\n const dates = [];\n const [sy, sm, sd] = sinceStr.split(\"-\").map(Number);\n const [uy, um, ud] = untilStr.split(\"-\").map(Number);\n let current = Date.UTC(sy, sm - 1, sd);\n const end = Date.UTC(uy, um - 1, ud);\n while (current <= end) {\n const d = new Date(current);\n const yyyy = d.getUTCFullYear();\n const mm = String(d.getUTCMonth() + 1).padStart(2, \"0\");\n const dd = String(d.getUTCDate()).padStart(2, \"0\");\n dates.push(`${yyyy}-${mm}-${dd}`);\n current += 24 * 60 * 60 * 1e3;\n }\n return dates;\n}\n\n// src/utils/message-filter.ts\nfunction messageMatchesFilters(msg, channelFilters) {\n if (!channelFilters || channelFilters.length === 0) return true;\n if (msg.role === \"user\") return true;\n const filterSet = new Set(channelFilters);\n const isToolCall = msg.metadata?.type === \"activity_block\";\n if (isToolCall) return filterSet.has(\"tools\");\n return filterSet.has(msg.channel ?? \"agent\");\n}\n\n// src/utils/mentions.ts\nvar MENTION_TOKEN_REGEX = /@\\[(\\w+):([^\\]]+)\\]/g;\nfunction serializeMention(type, id) {\n return `@[${type}:${id}]`;\n}\nfunction buildMentionKey(type, id) {\n return `${type}:${id}`;\n}\nfunction parseMentions(content) {\n const tokens = [];\n for (const match of content.matchAll(MENTION_TOKEN_REGEX)) {\n tokens.push({ type: match[1], id: match[2] });\n }\n return tokens;\n}\nfunction resolveMentions(content, metadata) {\n if (!metadata || typeof metadata !== \"object\") return content;\n const meta = metadata;\n if (meta.type !== \"mentions\" || !meta.mentions) return content;\n const mentions = meta.mentions;\n return content.replace(MENTION_TOKEN_REGEX, (_match, type, id) => {\n const key = `${type}:${id}`;\n const mention = mentions[key];\n if (!mention) return _match;\n const prefix = mention.slug ? `#${mention.slug}` : `@${mention.label}`;\n return `${prefix} (${type}:${id})`;\n });\n}\n\n// src/utils/autopilot-ratio.ts\nvar AUTOPILOT_RATIO_MIN = 1;\nvar AUTOPILOT_RATIO_MAX = 6.5;\nfunction computeMemoryBounds(agentCpu, sidecarCpu, sidecarMemoryGi) {\n const totalCpu = agentCpu + sidecarCpu;\n const minPodMemory = totalCpu * AUTOPILOT_RATIO_MIN;\n const maxPodMemory = totalCpu * AUTOPILOT_RATIO_MAX;\n const minAgentMemory = minPodMemory - sidecarMemoryGi;\n const maxAgentMemory = maxPodMemory - sidecarMemoryGi;\n const minMemoryGi = Math.max(1, Math.ceil(minAgentMemory));\n const maxMemoryGi = Math.floor(maxAgentMemory);\n return { minMemoryGi, maxMemoryGi };\n}\nfunction computePodRatio(agentCpu, agentMemoryGi, sidecarCpu, sidecarMemoryGi) {\n const totalCpu = agentCpu + sidecarCpu;\n const totalMemory = agentMemoryGi + sidecarMemoryGi;\n if (totalCpu === 0) return 0;\n return totalMemory / totalCpu;\n}\nfunction isValidAutopilotConfig(agentCpu, agentMemoryGi, sidecarCpu, sidecarMemoryGi) {\n const ratio = computePodRatio(agentCpu, agentMemoryGi, sidecarCpu, sidecarMemoryGi);\n return ratio >= AUTOPILOT_RATIO_MIN && ratio <= AUTOPILOT_RATIO_MAX;\n}\n\n// src/utils/sidecar-overhead.ts\nvar SIDECAR_OVERHEAD = {\n postgresql: {\n // 50m\n cpu: 0.05,\n // 128Mi\n memoryGi: 0.125\n },\n redis: {\n // 25m\n cpu: 0.025,\n // 32Mi\n memoryGi: 0.03125\n },\n elasticsearch: {\n // 100m\n cpu: 0.1,\n // 256Mi\n memoryGi: 0.25\n },\n lgtm: {\n // 250m — bundles Grafana + Loki + Tempo + Mimir + OTEL Collector\n cpu: 0.25,\n // 1Gi\n memoryGi: 1\n },\n \"firebase-auth-emulator\": {\n // 100m\n cpu: 0.1,\n // 256Mi\n memoryGi: 0.25\n }\n};\nfunction sidecarRequestTotals(deps) {\n let totalCpu = 0;\n let totalMemoryGi = 0;\n for (const dep of deps) {\n const overhead = SIDECAR_OVERHEAD[dep];\n if (overhead) {\n totalCpu += overhead.cpu;\n totalMemoryGi += overhead.memoryGi;\n }\n }\n return { cpu: totalCpu, memoryGi: totalMemoryGi };\n}\nexport {\n AGENT_CHAT_HISTORY_FETCH_LIMIT,\n ALLOWED_FILE_MIME_TYPES,\n AUTOPILOT_RATIO_MAX,\n AUTOPILOT_RATIO_MIN,\n AddDependencyRequestSchema,\n AddProjectTaskDependencyRequestSchema,\n AddProjectTaskReviewerRequestSchema,\n AgentEventSchema,\n AgentHeartbeatSchema,\n AgentQuestionOptionSchema,\n AgentQuestionSchema,\n AnswerAgentQuestionRequestSchema,\n ApproveAndMergePRRequestSchema,\n ApproveProjectMergePRRequestSchema,\n AskUserQuestionRequestSchema,\n CARD_TYPE_STATUSES,\n CARD_TYPE_VALUES,\n CODESPACE_SESSION_ACTIVE_RUNNER_STATUSES,\n CRITICAL_AUTOMATED_SOURCES,\n CancelQueuedProjectMessageRequestSchema,\n CancelTaskQueuedMessageRequestSchema,\n ClearAgentTodosRequestSchema,\n ConfirmFileUploadRequestSchema,\n ConnectAgentRequestSchema,\n CreateFollowUpTaskRequestSchema,\n CreatePRInputSchema,\n CreatePRResponseSchema,\n CreateProjectPullRequestRequestSchema,\n CreateProjectSubtaskRequestSchema,\n CreateProjectSuggestionRequestSchema,\n CreateProjectTaskRequestSchema,\n CreatePullRequestRequestSchema,\n CreateSubtaskRequestSchema,\n CreateSuggestionRequestSchema,\n DEPLOYMENT_TARGET_ENVIRONMENTS,\n DEPLOYMENT_TARGET_PROVIDERS,\n DeleteProjectSubtaskRequestSchema,\n DeleteSubtaskRequestSchema,\n DeleteSubtaskResponseSchema,\n DisconnectProjectRunnerRequestSchema,\n EMBEDDABLE_IMAGE_TYPES,\n EmitAgentEventRequestSchema,\n FlushProjectQueueRequestSchema,\n FlushSingleProjectQueuedMessageRequestSchema,\n FlushSingleQueuedMessageRequestSchema,\n FlushTaskQueueRequestSchema,\n ForwardProjectChatMessageRequestSchema,\n GenerateTaskIconRequestSchema,\n GetActivePtySessionRequestSchema,\n GetAgentStatusRequestSchema,\n GetChatMessagesRequestSchema,\n GetCliHistoryRequestSchema,\n GetCumulativeSpendingRequestSchema,\n GetCumulativeSpendingResponseSchema,\n GetDependenciesRequestSchema,\n GetProjectAgentContextByRoleRequestSchema,\n GetProjectAgentContextRequestSchema,\n GetProjectAttachmentRequestSchema,\n GetProjectChatHistoryRequestSchema,\n GetProjectCliHistoryRequestSchema,\n GetProjectFunctionConfigRequestSchema,\n GetProjectSummaryRequestSchema,\n GetProjectTaskChatRequestSchema,\n GetProjectTaskCliRequestSchema,\n GetProjectTaskDependenciesRequestSchema,\n GetProjectTaskRequestSchema,\n GetSuggestionsRequestSchema,\n GetTaskContextRequestSchema,\n GetTaskFileRequestSchema,\n GetTaskFilesRequestSchema,\n GetTaskPropertiesRequestSchema,\n GetTaskRequestSchema,\n GetUiCliHistoryRequestSchema,\n HeartbeatRequestSchema,\n HeartbeatResponseSchema,\n IDLE_HEARTBEAT_MS,\n ListIconsRequestSchema,\n ListManualTestsRequestSchema,\n ListProjectMembersRequestSchema,\n ListProjectSubtasksRequestSchema,\n ListProjectTagsRequestSchema,\n ListProjectTaskFilesRequestSchema,\n ListProjectTasksRequestSchema,\n ListSubtasksRequestSchema,\n MAX_FILE_SIZE_BYTES,\n MCP_TOOL_REGISTRY,\n MENTION_TOKEN_REGEX,\n ModelUsageEntrySchema,\n NotifyAgentVersionRequestSchema,\n PM_CHAT_HISTORY_LIMIT,\n PREVIEW_PORT_DENY_LIST,\n PROJECT_FUNCTION_DEFAULTS,\n PROJECT_TIMEZONE,\n PickFaIconRequestSchema,\n PostChildChatMessageRequestSchema,\n PostProjectAgentMessageRequestSchema,\n PostToChatInputSchema,\n PostToChatRequestSchema,\n PostToChatResponseSchema,\n PostToProjectTaskChatRequestSchema,\n ProjectRunnerHeartbeatRequestSchema,\n PtyAttachRequestSchema,\n PtyInputRequestSchema,\n PtyOutputRequestSchema,\n PtyResizeRequestSchema,\n RefreshGithubTokenRequestSchema,\n RefreshGithubTokenResponseSchema,\n RegisterProjectAgentRequestSchema,\n RegisterProjectAgentResponseSchema,\n RemoveDependencyRequestSchema,\n RemoveProjectTaskDependencyRequestSchema,\n RemoveProjectTaskReviewerRequestSchema,\n ReportAgentStatusRequestSchema,\n ReportEnvSwitchProgressRequestSchema,\n ReportEnvironmentReadyRequestSchema,\n ReportNewCommitsDetectedRequestSchema,\n ReportProjectAgentEventRequestSchema,\n ReportProjectAgentStatusRequestSchema,\n ReportTagAuditProgressRequestSchema,\n ReportTagAuditResultRequestSchema,\n ReportTaskAuditBatchCompleteRequestSchema,\n ReportTaskAuditProgressRequestSchema,\n ReportTaskAuditResultRequestSchema,\n RequestFileUploadRequestSchema,\n SIDECAR_OVERHEAD,\n STRANDED_RUNNER_STATUSES,\n SearchFaIconsRequestSchema,\n SearchProjectTasksRequestSchema,\n SendSoftStopRequestSchema,\n SessionStartRequestSchema,\n SessionStartResponseSchema,\n SessionStopRequestSchema,\n SessionStopResponseSchema,\n SetManualTestsRequestSchema,\n StartChildCloudBuildRequestSchema,\n StartProjectBuildRequestSchema,\n StartTaskAuditRequestSchema,\n StopChildBuildRequestSchema,\n StopProjectBuildRequestSchema,\n StoreSessionIdRequestSchema,\n StoreSessionIdResponseSchema,\n SubmitCodeReviewResultRequestSchema,\n TASK_CHAT_HISTORY_LIMIT,\n TASK_STATUS_ORDER,\n TERMINAL_TASK_STATUSES,\n TrackSpendingRequestSchema,\n TriggerIdentificationRequestSchema,\n UpdateChildStatusRequestSchema,\n UpdateProjectSubtaskRequestSchema,\n UpdateProjectTaskRequestSchema,\n UpdateSubtaskRequestSchema,\n UpdateTaskFieldsRequestSchema,\n UpdateTaskPropertiesRequestSchema,\n UpdateTaskStatusRequestSchema,\n UpdateTaskStatusResponseSchema,\n VoteProjectSuggestionRequestSchema,\n VoteSuggestionRequestSchema,\n buildMentionKey,\n cliRoom,\n computeMemoryBounds,\n computePodRatio,\n createAgentSessionRoom,\n createProjectRoom,\n deriveConnectionState,\n formatHeartbeatAge,\n generateDateRange,\n getToolsByCategory,\n isAllowablePreviewPort,\n isCuid,\n isEmbeddableFile,\n isValidAutopilotConfig,\n messageMatchesFilters,\n notificationUserRoom,\n parseMentions,\n pickPreferredPreviewPort,\n projectCliRoom,\n projectEventsRoom,\n resolveAllowedPreviewPorts,\n resolveCodeReviewMode,\n resolveMentions,\n resolveProjectFunctionConfig,\n resolveStatDateRange,\n sanitizeSessionPreviewPorts,\n serializeMention,\n serviceRoom,\n sidecarRequestTotals,\n todayInProjectTZ,\n userRoom,\n validateStatusForType\n};\n","import type { TaskContext, ChatMessage } from \"@project/shared\";\n\nfunction findLastAgentMessageIndex(history: ChatMessage[]): number {\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].role === \"assistant\") return i;\n }\n return -1;\n}\n\nfunction formatProjectAgents(projectAgents: NonNullable<TaskContext[\"projectAgents\"]>): string[] {\n const parts: string[] = [``, `## Project Agents`];\n for (const pa of projectAgents) {\n const role = pa.role ? `role: ${pa.role}` : \"role: unassigned\";\n const sp =\n pa.storyPoints === null || pa.storyPoints === undefined\n ? \"\"\n : `, story points: ${pa.storyPoints}`;\n parts.push(`- ${pa.agent.name} (${role}${sp})`);\n }\n return parts;\n}\n\nfunction formatStoryPoints(storyPoints: NonNullable<TaskContext[\"storyPoints\"]>): string[] {\n const parts: string[] = [``, `## Story Point Tiers`];\n for (const sp of storyPoints) {\n const desc = sp.description ? ` — ${sp.description}` : \"\";\n parts.push(`- Value ${sp.value}: \"${sp.name}\"${desc}`);\n }\n return parts;\n}\n\nexport function buildPackRunnerSystemPrompt(\n context: TaskContext,\n config: { instructions: string; workspaceDir: string },\n setupLog: string[],\n): string {\n const parts: string[] = [\n `You are an autonomous Pack Runner managing child tasks for the \"${context.title}\" project.`,\n `You are running locally with full access to the repository and task management tools.`,\n `Your job is to execute child tasks by firing cloud builds, reviewing their PRs, and merging them — respecting dependency chains for parallel execution.`,\n ``,\n `## Child Task Status Lifecycle`,\n `- \"Planning\" — Not ready for execution. Skip it (or escalate if blocking).`,\n `- \"Open\" — Ready to execute (if dependencies are met). Use start_child_cloud_build to fire it.`,\n `- \"InProgress\" — Currently being worked on by a Task Runner. Wait — it will move to ReviewPR when done.`,\n `- \"ReviewPR\" — Task Runner finished and opened a PR. Review and merge it.`,\n `- \"ReviewDev\" — PR was merged to dev. This child is complete. Move on.`,\n `- \"Complete\" — Fully done. Move on.`,\n ``,\n `## Autonomous Loop`,\n `Follow this loop each time you are launched or relaunched:`,\n ``,\n `1. Call list_subtasks to see the current state of all child tasks.`,\n ` The response includes PR info, agent assignment, and **dependency info** (dependencies array + allDependenciesMet flag).`,\n ``,\n `2. Evaluate children by status and dependency readiness:`,\n ` - \"ReviewPR\": Review and merge its PR with approve_and_merge_pr. (Highest priority)`,\n ` - If merge fails due to pending CI: post a status update to chat, state you are going idle.`,\n ` - If merge fails due to failed CI: use get_execution_logs(childTaskId) to check. Escalate to team.`,\n ` - \"InProgress\": A Task Runner is actively working. Do nothing — wait.`,\n ` - \"Open\" + allDependenciesMet=true: Ready to fire. Use start_child_cloud_build.`,\n ` - \"Open\" + allDependenciesMet=false: Blocked — skip for now. Will be unblocked when deps complete.`,\n ` - \"ReviewDev\" / \"Complete\": Already done. Skip.`,\n ` - \"Planning\": Not ready. If blocking progress, notify team.`,\n ``,\n `3. Fire ALL ready \"Open\" tasks whose dependencies are met, not just one. Independent tasks can run in parallel.`,\n ``,\n `4. After merging a PR: run \\`git pull origin ${context.baseBranch}\\` then re-check list_subtasks — previously blocked tasks may now be ready.`,\n ``,\n `5. After firing all ready tasks: report which tasks you fired to chat, then state you are going idle.`,\n ``,\n `6. When ALL children are in \"ReviewDev\" or \"Complete\" (no \"Open\", \"InProgress\", or \"ReviewPR\" remaining): do a final review, summarize results in chat, and mark this parent task complete with force_update_task_status(\"Complete\").`,\n ``,\n `## Important Rules`,\n `- When dependencies are set on children, use them to determine execution order. Fire all ready tasks in parallel.`,\n `- When NO dependencies are set on any children, fall back to ordinal order (one at a time). This preserves backward compatibility.`,\n `- After firing builds OR when waiting on CI, explicitly state you are going idle. The system will disconnect you and relaunch when there's a status change.`,\n `- Do NOT attempt to write code yourself. Your role is coordination only.`,\n `- If a child is stuck in \"InProgress\" for an unusually long time, use get_execution_logs(childTaskId) to check its logs and escalate to the team if it appears stuck.`,\n `- You can use get_task(childTaskId) to get a child's full details including PR URL and branch.`,\n `- list_subtasks returns PR info (githubPRNumber, githubPRUrl), agent assignment (agentId), and dependency info for each child — use this to verify readiness before firing builds.`,\n `- You can use read_task_chat to check for team messages.`,\n ];\n\n if (context.storyPoints && context.storyPoints.length > 0) {\n parts.push(...formatStoryPoints(context.storyPoints));\n }\n\n if (context.projectAgents && context.projectAgents.length > 0) {\n parts.push(...formatProjectAgents(context.projectAgents));\n }\n\n if (setupLog.length > 0) {\n parts.push(``, `## Environment setup log`, \"```\", ...setupLog, \"```\");\n }\n\n if (context.agentInstructions) {\n parts.push(``, `## Agent Instructions`, context.agentInstructions);\n }\n if (config.instructions) {\n parts.push(``, `## Additional Instructions`, config.instructions);\n }\n\n parts.push(\n ``,\n `Your responses are sent directly to the task chat — the team sees everything you say.`,\n `Do NOT call the post_to_chat tool for your own task; your replies already appear in chat automatically.`,\n `Only use post_to_chat if you need to message a different task's chat (e.g. a child task).`,\n `Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,\n );\n\n return parts.join(\"\\n\");\n}\n\nexport function buildPackRunnerInstructions(\n context: TaskContext,\n scenario: \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\",\n): string[] {\n const parts: string[] = [`\\n## Instructions`];\n\n if (scenario === \"fresh\") {\n parts.push(\n `You are the Pack Runner for this task and its subtasks.`,\n `Begin your autonomous loop immediately: call list_subtasks to assess the current state.`,\n `If any child is in \"ReviewPR\" status, review and merge its PR first.`,\n `Then fire the next \"Open\" child task.`,\n );\n } else if (scenario === \"idle_relaunch\") {\n parts.push(\n `You have been relaunched — a child task likely changed status.`,\n `Call list_subtasks to check the current state of all children.`,\n `Look for children in \"ReviewPR\" status first — review and merge their PRs.`,\n `Check if any previously blocked tasks now have allDependenciesMet=true — fire them.`,\n `If a child you previously fired is now in \"ReviewDev\", pull latest with \\`git pull origin ${context.baseBranch}\\`.`,\n `If no children need action, state you are going idle.`,\n );\n } else {\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .filter((m) => m.role === \"user\");\n parts.push(\n `You have been relaunched with new messages.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAfter addressing the feedback, resume your autonomous loop: call list_subtasks and proceed accordingly.`,\n );\n }\n\n return parts;\n}\n","import { PM_CHAT_HISTORY_LIMIT, type TaskContext } from \"@project/shared\";\n\nexport { PM_CHAT_HISTORY_LIMIT };\n\nexport function formatFileSize(bytes: number | undefined): string {\n if (bytes === undefined) return \"\";\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nexport interface FileAttachment {\n fileName: string;\n mimeType: string;\n fileSize?: number;\n content?: string;\n contentEncoding?: string;\n downloadUrl?: string;\n fileId?: string;\n}\n\nexport function formatChatFile(file: FileAttachment): string[] {\n const sizeStr = file.fileSize ? `, ${formatFileSize(file.fileSize)}` : \"\";\n if (file.content && file.contentEncoding === \"utf-8\") {\n return [\n `[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`,\n \"```\",\n file.content,\n \"```\",\n ];\n }\n if (!file.content) {\n return [`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]: ${file.downloadUrl}`];\n }\n if (file.content && file.contentEncoding === \"base64\") {\n return [\n `[Attached image: ${file.fileName} (${file.mimeType}${sizeStr}) — use get_attachment(\"${file.fileId}\") to view]`,\n ];\n }\n return [`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`];\n}\n\nexport function formatTaskFile(file: FileAttachment): string[] {\n if (file.content && file.contentEncoding === \"utf-8\") {\n return [`\\n### ${file.fileName} (${file.mimeType})`, \"```\", file.content, \"```\"];\n }\n if (file.content && file.contentEncoding === \"base64\") {\n const size = formatFileSize(file.fileSize);\n return [\n `- [Attached image: ${file.fileName} (${file.mimeType}${size ? `, ${size}` : \"\"}) — use get_attachment(\"${file.fileId}\") to view]`,\n ];\n }\n if (!file.content) {\n return [`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`];\n }\n return [];\n}\n\nexport function formatChatHistory(\n chatHistory: TaskContext[\"chatHistory\"],\n limit?: number,\n): string[] {\n const relevant = chatHistory.slice(-(limit ?? PM_CHAT_HISTORY_LIMIT));\n const parts = [`\\n## Recent Chat Context`];\n for (const msg of relevant) {\n const sender = msg.userName ?? msg.role;\n parts.push(`[${sender}]: ${msg.content}`);\n if (msg.files?.length) {\n for (const file of msg.files) {\n parts.push(...formatChatFile(file));\n }\n }\n }\n return parts;\n}\n\nexport function formatRepoRefs(repoRefs: NonNullable<TaskContext[\"repoRefs\"]>): string[] {\n const parts: string[] = [];\n parts.push(`\\n## Repository References`);\n for (const ref of repoRefs) {\n const icon = ref.refType === \"folder\" ? \"folder\" : \"file\";\n parts.push(`- [${icon}] \\`${ref.path}\\``);\n }\n return parts;\n}\n\nexport function formatReferenceProjects(\n referenceProjects: NonNullable<TaskContext[\"referenceProjects\"]>,\n): string[] {\n const parts: string[] = [];\n parts.push(`\\n## Reference Projects`);\n parts.push(\n `These sibling Conveyor projects have been shallow-cloned read-only into \\`/workspaces/references/<slug>/\\` for inspiration. You MAY grep/read them to compare approaches, but you MUST NOT modify them or commit anything from them into this task's repo.\\n`,\n );\n for (const ref of referenceProjects) {\n const repo =\n ref.githubRepoOwner && ref.githubRepoName\n ? ` (${ref.githubRepoOwner}/${ref.githubRepoName})`\n : \"\";\n parts.push(`- **${ref.name}**${repo} — \\`/workspaces/references/${ref.slug}/\\``);\n }\n return parts;\n}\n\nexport function formatProjectObjectives(\n objectives: NonNullable<TaskContext[\"projectObjectives\"]>,\n): string[] {\n const parts: string[] = [];\n parts.push(`\\n## Project Objectives`);\n for (const obj of objectives) {\n const dates = `${obj.startDate.split(\"T\")[0]} to ${obj.endDate.split(\"T\")[0]}`;\n parts.push(`- **${obj.name}** (${dates})${obj.description ? \": \" + obj.description : \"\"}`);\n }\n return parts;\n}\n\nexport function formatRecentRelatedTasks(\n tasks: NonNullable<TaskContext[\"recentRelatedTasks\"]>,\n): string[] {\n const parts: string[] = [];\n parts.push(`\\n## Recently Completed Related Tasks`);\n parts.push(\n `These tasks in the same domain were recently completed. Use them for context on recent changes and patterns.\\n`,\n );\n for (const task of tasks) {\n const tags = task.tagNames.length > 0 ? ` [${task.tagNames.join(\", \")}]` : \"\";\n const pr = task.githubPRUrl ? ` — PR: ${task.githubPRUrl}` : \"\";\n parts.push(`- **${task.title}**${tags}${pr}`);\n }\n return parts;\n}\n\nexport function formatIncidents(incidents: NonNullable<TaskContext[\"incidents\"]>): string[] {\n const parts: string[] = [];\n parts.push(`\\n## Linked Incidents`);\n parts.push(\n `This task has linked incidents. Review them for context on the problem being addressed.\\n`,\n );\n for (const inc of incidents) {\n const severity = inc.severity ? ` [${inc.severity}]` : \"\";\n const status = inc.status ? ` (${inc.status})` : \"\";\n parts.push(`### ${inc.title}${severity}${status}`);\n if (inc.description) parts.push(inc.description);\n if (inc.source) parts.push(`Source: ${inc.source}`);\n }\n return parts;\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport type { RunnerMode, TaskContext } from \"@project/shared\";\n\ninterface ResolvedEntry {\n type: \"rule\" | \"file\" | \"folder\" | \"doc\";\n path: string;\n label?: string;\n content: string | null;\n charCount: number;\n}\n\ninterface ResolvedTagContext {\n tagName: string;\n description: string | null;\n entries: ResolvedEntry[];\n}\n\nconst TYPE_PRIORITY: Record<string, number> = { rule: 0, file: 1, folder: 2, doc: 3 };\n\n// Binary file extensions to skip content injection\nconst BINARY_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".svg\",\n \".bmp\",\n \".mp3\",\n \".mp4\",\n \".wav\",\n \".avi\",\n \".mov\",\n \".pdf\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".otf\",\n \".exe\",\n \".dll\",\n \".so\",\n \".dylib\",\n \".wasm\",\n]);\n\nfunction isBinaryPath(filePath: string): boolean {\n const ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n return BINARY_EXTENSIONS.has(ext);\n}\n\n// Module-scope cache of rule/file contents keyed by absolute path.\n// Entries are invalidated when mtime changes (post-merge rule updates)\n// and can be cleared wholesale on session boundaries via clearTagContextCache().\nconst fileContentCache = new Map<string, { mtimeMs: number; content: string }>();\nconst folderListingCache = new Map<string, { mtimeMs: number; listing: string }>();\nlet fileReadCount = 0;\nlet folderReadCount = 0;\n\nexport function clearTagContextCache(): void {\n fileContentCache.clear();\n folderListingCache.clear();\n}\n\nexport function _getTagContextCacheStatsForTest(): {\n files: number;\n folders: number;\n fileReads: number;\n folderReads: number;\n} {\n return {\n files: fileContentCache.size,\n folders: folderListingCache.size,\n fileReads: fileReadCount,\n folderReads: folderReadCount,\n };\n}\n\nexport function _resetTagContextReadCountsForTest(): void {\n fileReadCount = 0;\n folderReadCount = 0;\n}\n\nfunction getContextBudgetChars(_model: string, betas?: string[], runnerMode?: RunnerMode): number {\n const contextWindow = betas?.some((b) => b.includes(\"context-1m\")) ? 1_000_000 : 200_000;\n // Task agents get 15% budget (plan already captures key context); PM/code-review get 25%\n const budgetPct = runnerMode === \"task\" ? 0.15 : 0.25;\n // ~4 chars per token\n return contextWindow * budgetPct * 4;\n}\n\nasync function readFileContent(filePath: string, maxChars: number): Promise<string | null> {\n try {\n if (isBinaryPath(filePath)) return null;\n let rawContent: string;\n let mtimeMs: number;\n try {\n const st = await stat(filePath);\n mtimeMs = st.mtimeMs;\n } catch {\n return null;\n }\n const cached = fileContentCache.get(filePath);\n if (cached && cached.mtimeMs === mtimeMs) {\n rawContent = cached.content;\n } else {\n rawContent = await readFile(filePath, \"utf-8\");\n fileReadCount++;\n fileContentCache.set(filePath, { mtimeMs, content: rawContent });\n }\n if (rawContent.length > maxChars) {\n const omitted = rawContent.length - maxChars;\n return rawContent.slice(0, maxChars) + `\\n[... truncated, ${omitted} chars omitted]`;\n }\n return rawContent;\n } catch {\n return null;\n }\n}\n\nasync function readFolderListing(folderPath: string): Promise<string | null> {\n try {\n let mtimeMs: number;\n try {\n const st = await stat(folderPath);\n mtimeMs = st.mtimeMs;\n } catch {\n return null;\n }\n const cached = folderListingCache.get(folderPath);\n if (cached && cached.mtimeMs === mtimeMs) {\n return cached.listing;\n }\n const entries = await readdir(folderPath);\n folderReadCount++;\n const listing = `Files: ${entries.join(\", \")}`;\n folderListingCache.set(folderPath, { mtimeMs, listing });\n return listing;\n } catch {\n return null;\n }\n}\n\nasync function resolveEntry(\n entry: { type: string; path: string; label?: string },\n budget: { remaining: number },\n): Promise<ResolvedEntry> {\n const result: ResolvedEntry = {\n type: entry.type as ResolvedEntry[\"type\"],\n path: entry.path,\n label: entry.label,\n content: null,\n charCount: 0,\n };\n\n if (budget.remaining <= 0) return result;\n\n if (entry.type === \"doc\") {\n // doc type references project documents in DB — skip content injection\n return result;\n }\n\n if (entry.type === \"folder\") {\n const listing = await readFolderListing(entry.path);\n if (listing) {\n result.content = listing;\n result.charCount = listing.length;\n budget.remaining -= listing.length;\n }\n return result;\n }\n\n // rule or file — read from disk\n // Single file cap: 50% of remaining budget\n const maxChars = Math.floor(budget.remaining * 0.5) || budget.remaining;\n const content = await readFileContent(entry.path, maxChars);\n if (content) {\n result.content = content;\n result.charCount = content.length;\n budget.remaining -= content.length;\n }\n return result;\n}\n\nfunction formatEntry(entry: ResolvedEntry): string {\n const label = entry.label ? ` (${entry.label})` : \"\";\n const header = `#### ${entry.path}${label} (${entry.type})`;\n\n if (entry.content === null) {\n return `> ${entry.type}: ${entry.path}${label}`;\n }\n\n if (entry.type === \"folder\") {\n return `${header}\\n${entry.content}`;\n }\n\n // rule or file — wrap in code fence\n return `${header}\\n\\`\\`\\`\\n${entry.content}\\n\\`\\`\\``;\n}\n\nfunction formatResolvedTags(resolved: ResolvedTagContext[]): string {\n const parts: string[] = [`\\n## Tag Context`];\n\n for (const tag of resolved) {\n if (tag.entries.length === 0) continue;\n const desc = tag.description ? ` — ${tag.description}` : \"\";\n parts.push(`\\n### Tag: \"${tag.tagName}\"${desc}`);\n\n const contentEntries = tag.entries.filter((e) => e.content !== null);\n const pointerEntries = tag.entries.filter((e) => e.content === null);\n\n for (const entry of contentEntries) {\n parts.push(`\\n${formatEntry(entry)}`);\n }\n\n if (pointerEntries.length > 0) {\n parts.push(``);\n parts.push(`> Budget limit reached. Remaining linked files (read manually if needed):`);\n for (const entry of pointerEntries) {\n parts.push(formatEntry(entry));\n }\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nexport async function resolveTagContext(\n projectTags: TaskContext[\"projectTags\"],\n taskTagIds: string[],\n model: string,\n betas?: string[],\n runnerMode?: RunnerMode,\n): Promise<{ injectedSection: string; stats: { injected: number; skipped: number } }> {\n if (!projectTags?.length || !taskTagIds.length) {\n return { injectedSection: \"\", stats: { injected: 0, skipped: 0 } };\n }\n\n const taskTagIdSet = new Set(taskTagIds);\n const assignedTags = projectTags.filter((t) => taskTagIdSet.has(t.id));\n\n if (assignedTags.length === 0) {\n return { injectedSection: \"\", stats: { injected: 0, skipped: 0 } };\n }\n\n // Collect all entries across tags, sorted by type priority\n const allEntries: { tagIndex: number; entry: { type: string; path: string; label?: string } }[] =\n [];\n for (let i = 0; i < assignedTags.length; i++) {\n const tag = assignedTags[i];\n if (!tag.contextPaths?.length) continue;\n const sorted = [...tag.contextPaths].sort(\n (a, b) => (TYPE_PRIORITY[a.type] ?? 99) - (TYPE_PRIORITY[b.type] ?? 99),\n );\n for (const entry of sorted) {\n allEntries.push({ tagIndex: i, entry });\n }\n }\n\n if (allEntries.length === 0) {\n return { injectedSection: \"\", stats: { injected: 0, skipped: 0 } };\n }\n\n const budgetChars = getContextBudgetChars(model, betas, runnerMode);\n const budget = { remaining: budgetChars };\n let injected = 0;\n let skipped = 0;\n\n // Resolve all entries\n const resolved: ResolvedTagContext[] = assignedTags.map((t) => ({\n tagName: t.name,\n description: t.description,\n entries: [],\n }));\n\n for (const { tagIndex, entry } of allEntries) {\n const result = await resolveEntry(entry, budget);\n resolved[tagIndex].entries.push(result);\n if (result.content === null) {\n skipped++;\n } else {\n injected++;\n }\n }\n\n return {\n injectedSection: formatResolvedTags(resolved),\n stats: { injected, skipped },\n };\n}\n","const PLAN_SOFT_CAP = 4000;\nconst PLAN_HEAD_CHARS = 3000;\nconst PLAN_TAIL_CHARS = 500;\nconst PLAN_TRUNCATION_MARKER =\n \"\\n\\n... plan truncated — call get_current_plan for full text ...\\n\\n\";\n\n/**\n * Soft-cap plan markdown to avoid duplicating 5–10K chars in every relaunch\n * context fetch. Agents that need the full plan can call `get_current_plan`\n * (or `get_task` with the current task's slug/id).\n */\nexport function truncatePlanForPrompt(plan: string): string {\n if (plan.length <= PLAN_SOFT_CAP) return plan;\n const head = plan.slice(0, PLAN_HEAD_CHARS);\n const tail = plan.slice(plan.length - PLAN_TAIL_CHARS);\n return `${head}${PLAN_TRUNCATION_MARKER}${tail}`;\n}\n\nexport const PLAN_TRUNCATION_CONSTANTS = {\n PLAN_SOFT_CAP,\n PLAN_HEAD_CHARS,\n PLAN_TAIL_CHARS,\n PLAN_TRUNCATION_MARKER,\n} as const;\n","import type { AgentMode, RunnerMode, TaskContext } from \"@project/shared\";\n\nconst SP_DESC_MAX_CHARS = 80;\n\nfunction truncateDescription(desc: string, maxChars: number): string {\n if (desc.length <= maxChars) return desc;\n return desc.slice(0, maxChars) + \"…\";\n}\n\ntype ProjectTag = NonNullable<TaskContext[\"projectTags\"]>[number];\n\nfunction formatTagWithContextPaths(tag: ProjectTag): string[] {\n const desc = tag.description ? ` — ${tag.description}` : \"\";\n const lines = [`- Name: \"${tag.name}\"${desc}`];\n for (const link of tag.contextPaths ?? []) {\n const label = link.label ? ` (${link.label})` : \"\";\n lines.push(` → ${link.type}: ${link.path}${label}`);\n }\n return lines;\n}\n\nfunction buildPropertyInstructions(context: TaskContext, runnerMode?: RunnerMode): string[] {\n const isTask = runnerMode === \"task\";\n const parts: string[] = [];\n parts.push(\n ``,\n `### Proactive Property Management`,\n `As you plan this task, proactively fill in task properties when you have enough context:`,\n `- Use update_task_properties to set any combination of: title, story points, and tags`,\n `- You can update all properties at once or just one at a time as needed`,\n `- Icons are assigned automatically during identification — do not set icons manually`,\n ``,\n `Don't wait for the user to ask — fill these in naturally as the plan takes shape.`,\n `If the user adjusts the plan significantly, update the properties to match.`,\n );\n\n // Story points — PM/code-review only\n if (!isTask && context.storyPoints && context.storyPoints.length > 0) {\n parts.push(``, `Available story point tiers:`);\n for (const sp of context.storyPoints) {\n const desc = sp.description\n ? ` — ${truncateDescription(sp.description, SP_DESC_MAX_CHARS)}`\n : \"\";\n parts.push(`- Value ${sp.value}: \"${sp.name}\"${desc}`);\n }\n }\n\n if (context.projectTags && context.projectTags.length > 0) {\n const assignedIds = new Set(context.taskTagIds ?? []);\n const assigned = context.projectTags.filter((t) => assignedIds.has(t.id));\n const unassigned = context.projectTags.filter((t) => !assignedIds.has(t.id));\n\n if (assigned.length > 0) {\n parts.push(``, `Assigned tags:`);\n for (const tag of assigned) parts.push(...formatTagWithContextPaths(tag));\n }\n\n // Unassigned tags — PM/code-review only, include context paths so agents can see linked files\n if (!isTask && unassigned.length > 0) {\n parts.push(``, `Available project tags:`);\n for (const tag of unassigned) parts.push(...formatTagWithContextPaths(tag));\n }\n }\n\n return parts;\n}\n\nfunction buildExplorationMethodology(): string[] {\n return [\n ``,\n `### Exploration Methodology`,\n `Investigate efficiently — do not read files aimlessly:`,\n `- Search first, read second: use grep/glob to locate relevant code, then read only the files that matter`,\n `- Never re-read a file already in your context — you have a large context window, scroll up instead`,\n `- Start with 3-5 critical files, form a hypothesis about the approach, then validate with targeted reads`,\n `- Stop exploring when you can cite specific \\`file.ts:line\\` locations and function names for every step in your plan — that's enough`,\n ];\n}\n\nfunction buildPlanCitationFormat(): string[] {\n return [\n ``,\n `### Plan Citation Format`,\n `Plans must ground each change in the code. For every step that touches code:`,\n `- Cite the exact location as \\`path/from/repo/root.ts:lineNumber\\` (e.g. \\`packages/conveyor-agent/src/execution/mode-prompt.ts:129\\`).`,\n `- Name the specific function, class, constant, or JSX element being touched.`,\n `- When behavior hinges on a short piece of code, quote 1–3 lines inline instead of paraphrasing.`,\n `- Ranges are fine for larger edits (\\`foo.ts:120-145\\`). Do not cite whole files without a line.`,\n `- If a file doesn't exist yet, write \\`NEW: path/to/new-file.ts\\` and describe the surrounding module it fits into.`,\n ];\n}\n\nfunction buildDiscoveryPrompt(context?: TaskContext, runnerMode?: RunnerMode): string {\n const parts = [\n `\\n## Mode: Discovery`,\n `You are in Discovery mode — helping plan and scope this task.`,\n `- You have read-only codebase access (can read files, run git commands, search code)`,\n `- You can write plan files in .claude/plans/ only — no other file writes`,\n `- Do NOT attempt to edit, write, or modify source code files — these operations will be denied`,\n `- If you identify code changes needed, describe them in the plan instead of implementing them`,\n `- You can create and manage subtasks`,\n `- Goal: collaborate with the user to create a clear plan`,\n `- Proactively fill task properties (SP, tags) as the plan takes shape`,\n ``,\n `### Planning Checklist (complete ALL before calling ExitPlanMode)`,\n `Your PRIMARY goal is to create a thorough plan. Complete these steps in order:`,\n `1. Read the task description and chat history — respond to what's been discussed`,\n `2. Investigate the codebase using the methodology below — search first, read targeted files`,\n `3. Save a detailed plan via \\`update_task_plan\\``,\n `4. Set story points, tags, and title via \\`update_task_properties\\` (icon is set automatically)`,\n `5. Discuss the plan with the team if they're engaged, incorporate feedback`,\n `6. THEN call ExitPlanMode — it is the LAST step, not the first`,\n ...buildExplorationMethodology(),\n ...buildPlanCitationFormat(),\n ``,\n `### Self-Identification Tools`,\n `Use these MCP tools to set your own task properties:`,\n `- \\`update_task_plan\\` — save your plan and description`,\n `- \\`update_task_properties\\` — set title, story points, and tags (any combination)`,\n `Note: Icons are assigned automatically during identification after planning is complete.`,\n ``,\n `### Tags & Context`,\n `- Early in discovery, identify relevant project tags that match this task's domain`,\n `- Add matching tags using \\`update_task_properties\\` — this links relevant documentation and rules that help you plan more effectively`,\n `- Tags accelerate discovery by surfacing domain-specific context automatically`,\n ``,\n ...(context?.isParentTask\n ? [\n `### Parent Task Coordination`,\n `You are a parent task with child tasks. Focus on breaking work into child tasks with detailed plans, not planning implementation for yourself.`,\n `- Use \\`list_subtasks\\` to review existing children. Create or update child tasks using \\`create_subtask\\` / \\`update_subtask\\`.`,\n `- Each child task should be a self-contained unit of work with a clear plan.`,\n ]\n : [\n `### Self-Update vs Subtasks`,\n `- If the work fits in a single task (1-3 SP), update YOUR OWN plan and properties — do not create subtasks`,\n `- Only create subtasks when the work genuinely requires multiple independent pieces (e.g., Pack-tier work, 8+ SP)`,\n ]),\n ``,\n `### Subtask Plan Requirements`,\n `When creating subtasks, each MUST include a detailed \\`plan\\` field:`,\n `- Plans should be multi-step implementation guides, not vague descriptions`,\n `- Include concrete \\`file.ts:line\\` citations, function/symbol names, and short code snippets where relevant`,\n `- Reference existing implementations when relevant (e.g., \"follow the pattern in src/services/foo.ts\")`,\n `- Include testing requirements and acceptance criteria`,\n `- Set \\`storyPointValue\\` based on estimated complexity`,\n ``,\n `### Plan Verification Requirements`,\n `Every plan MUST include a **Testing / Verification** section so the build agent has a clear definition of \"done\". Enumerate:`,\n `- The quality gates the build agent should run: \\`bun run lint\\`, \\`bun run typecheck\\`, \\`bun run test\\` (or scoped equivalents)`,\n `- Any task-specific end-to-end checks (manual UI walk-through, API smoke test, migration dry-run, etc.)`,\n `You are NOT expected to run these gates yourself — discovery is read-only. Just describe them in the plan.`,\n ``,\n `### Completing Planning`,\n `Once ALL checklist items above are done, call the **ExitPlanMode** tool.`,\n `- Required before ExitPlanMode will succeed: **plan** (via update_task_plan), **story points** (via update_task_properties), **title** (via update_task_properties)`,\n `- ExitPlanMode validates these properties and marks planning as complete`,\n `- It does NOT start building — the team controls when to switch to Build mode`,\n `- Do NOT call ExitPlanMode until you have thoroughly explored the codebase and saved a detailed plan`,\n ];\n if (context) parts.push(...buildPropertyInstructions(context, runnerMode));\n return parts.join(\"\\n\");\n}\n\nfunction buildAutoPrompt(context?: TaskContext, runnerMode?: RunnerMode): string {\n const parts = [\n `\\n## Mode: Auto`,\n `You are in Auto mode — operating autonomously through planning → building → PR.`,\n ``,\n `### Phase 1: Discovery & Planning (current)`,\n `- You are in the SDK's plan mode — read-only access is enforced automatically`,\n `- You have MCP tools for task properties: update_task_plan, update_task_properties`,\n ``,\n `### Required before transitioning:`,\n `Before calling ExitPlanMode, you MUST fill in ALL of these:`,\n `1. **Plan** — Save a clear implementation plan using update_task_plan`,\n `2. **Story Points** — Assign via update_task_properties`,\n `3. **Title** — Set an accurate title via update_task_properties (if the current one is vague or \"Untitled\")`,\n ``,\n `### Transitioning to Building:`,\n `When your plan is complete and all required properties are set, call the **ExitPlanMode** tool.`,\n `- If any required properties are missing, ExitPlanMode will be denied with details on what's missing`,\n `- Once ExitPlanMode succeeds, you will seamlessly transition to full build access within the same session`,\n `- Continue directly with implementation — no restart or waiting is needed`,\n ``,\n `### Subtask Plan Requirements`,\n `When creating subtasks, each MUST include a detailed \\`plan\\` field:`,\n `- Plans should be multi-step implementation guides, not vague descriptions`,\n `- Include concrete \\`file.ts:line\\` citations, function/symbol names, and short code snippets where relevant`,\n `- Reference existing implementations when relevant`,\n `- Include testing requirements and acceptance criteria`,\n `- Set \\`storyPointValue\\` based on estimated complexity`,\n ``,\n ...buildPlanCitationFormat(),\n ``,\n ...(context?.isParentTask\n ? [\n ``,\n `### Parent Task Guidance`,\n `You are a parent task. Your plan should define child tasks with detailed plans, not direct implementation steps.`,\n `After ExitPlanMode, you'll transition to Review mode to coordinate child task execution.`,\n `Child task status lifecycle: Open → InProgress → ReviewPR → ReviewDev → Complete.`,\n ]\n : []),\n ``,\n `### Autonomous Guidelines:`,\n `- Make decisions independently — do not ask the team for approval at each step`,\n `- Only escalate when genuinely blocked (ambiguous requirements, missing access, conflicting instructions)`,\n `- Investigate efficiently: search (grep/glob) to locate code, read only critical files, form a hypothesis, validate, then plan`,\n ];\n if (context) parts.push(...buildPropertyInstructions(context, runnerMode));\n return parts.join(\"\\n\");\n}\n\nexport function buildModePrompt(\n agentMode: AgentMode | null | undefined,\n context?: TaskContext,\n runnerMode?: RunnerMode,\n): string | null {\n switch (agentMode) {\n case \"discovery\":\n return buildDiscoveryPrompt(context, runnerMode);\n case \"building\": {\n const parts = [\n `\\n## Mode: Building`,\n `You are in Building mode — executing the plan.`,\n `- You have full coding access (read, write, edit, bash, git)`,\n `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,\n ...(context?.isParentTask\n ? [\n `- You are a parent task. Use \\`list_subtasks\\`, \\`start_child_cloud_build\\`, and subtask management tools to coordinate children.`,\n `- Do NOT implement code directly — fire child builds and review their work.`,\n `- Goal: coordinate child task execution and ensure all children complete successfully`,\n ]\n : [\n `- If this is a leaf task (no children): execute the plan directly`,\n `- Goal: implement the plan, verify quality gates, open a PR when done`,\n ``,\n `### Pre-PR Verification Checklist`,\n `Before calling \\`mcp__conveyor__create_pull_request\\`, verify ALL of the following pass:`,\n `1. \\`bun run lint\\` — no new lint errors`,\n `2. \\`bun run typecheck\\` — no new type errors`,\n `3. \\`bun run test\\` — relevant suites pass (scope to the affected package if the full run is prohibitively slow, and state the scope in the PR description)`,\n `If a gate fails, fix it before opening the PR. Do NOT open PRs with known failing gates.`,\n `For refactors: also run \\`git diff ${context?.baseBranch ?? \"dev\"}..HEAD\\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`,\n ]),\n ];\n return parts.join(\"\\n\");\n }\n case \"review\":\n return buildReviewPrompt(context);\n case \"auto\":\n return buildAutoPrompt(context, runnerMode);\n default:\n return null;\n }\n}\n\n// oxlint-disable-next-line max-lines-per-function -- prompt construction is a single cohesive block\nfunction buildReviewPrompt(context?: TaskContext): string {\n const parts = [\n `\\n## Mode: Review`,\n `You are in Review mode — performing code review with fix capability.`,\n `- You have full write access — you can audit code, make fixes, push changes, and run tests`,\n `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,\n ``,\n ];\n\n if (context?.isParentTask) {\n parts.push(\n `### Parent Task Review`,\n `You are reviewing and coordinating child tasks.`,\n `- Use \\`list_subtasks\\` to see current child task state and progress.`,\n `- For children in ReviewPR status: review their code quality and merge with \\`approve_and_merge_pr\\`.`,\n `- For children with failing CI: check with \\`get_execution_logs(childTaskId)\\` and escalate if stuck.`,\n `- Fire next child builds with \\`start_child_cloud_build\\` when ready.`,\n `- Create follow-up tasks for issues discovered during review.`,\n ``,\n `### Coordination Workflow`,\n `1. Check child task statuses with \\`list_subtasks\\``,\n `2. Review completed children — check PRs, run tests if needed`,\n `3. Approve and merge passing PRs`,\n `4. Fire builds for children that are ready`,\n `5. Create follow-up tasks for anything out of scope`,\n );\n } else {\n parts.push(\n `### Code Review Process`,\n `1. Run \\`git diff ${context?.baseBranch ?? \"dev\"}..HEAD\\` to see all changes in this PR`,\n `2. Read the task plan to understand the intended changes`,\n `3. Explore the surrounding codebase to verify pattern consistency`,\n `4. Review against the criteria below`,\n ``,\n `### Review Criteria`,\n `- **Correctness**: Does the code do what the plan says? Logic errors, off-by-one, race conditions?`,\n `- **Pattern Consistency**: Does the code follow existing patterns in the codebase? Check nearby files.`,\n `- **Security**: No hardcoded secrets, no injection vulnerabilities, proper input validation at boundaries.`,\n `- **Performance**: No unnecessary loops, no N+1 queries, no blocking in async contexts.`,\n `- **Error Handling**: Appropriate error handling at system boundaries. No swallowed errors.`,\n `- **Test Coverage**: Are new code paths tested? Edge cases covered?`,\n `- **TypeScript Best Practices**: Proper typing (no unnecessary \\`any\\`), correct React patterns, proper async/await.`,\n `- **Naming & Readability**: Clear names, no misleading comments, self-documenting code.`,\n ``,\n `### Fix Capability`,\n `You have full write access. If you find issues:`,\n `- **Small fixes**: Make the fix directly, commit, and push. Then re-review.`,\n `- **Larger issues**: Use \\`request_code_changes\\` to flag them for the team.`,\n `- After pushing fixes, wait for CI to pass before approving.`,\n ``,\n `### Output — You MUST do exactly ONE of:`,\n ``,\n `#### If code passes review (or after you've fixed all issues):`,\n `Use the \\`approve_code_review\\` tool with a brief summary of what looks good.`,\n ``,\n `#### If changes are needed that you cannot fix:`,\n `Use the \\`request_code_changes\\` tool with specific issues:`,\n `- Reference specific files and line numbers`,\n `- Explain what's wrong and suggest fixes`,\n `- Focus on substantive issues, not style nitpicks (linting handles that)`,\n ``,\n `### Previous Review Feedback`,\n `If previous review feedback is present in the chat history, verify those specific issues were addressed before raising new concerns.`,\n ``,\n `### Rules`,\n `- Do NOT re-review things CI already validates (formatting, lint rules).`,\n `- Be concise — actionable specifics over general observations.`,\n `- Max 5-7 issues per review. Prioritize the most important ones.`,\n );\n }\n\n return parts.join(\"\\n\");\n}\n","import type { RunnerMode, AgentMode, TaskContext } from \"@project/shared\";\nimport { buildPackRunnerSystemPrompt } from \"./pack-runner-prompt.js\";\nimport { buildModePrompt } from \"./mode-prompt.js\";\n\ninterface HypothesisTracker {\n isActive(): boolean;\n getDebugContext(): string | null;\n}\n\nfunction formatProjectAgentLine(pa: NonNullable<TaskContext[\"projectAgents\"]>[number]): string {\n const role = pa.role ? `role: ${pa.role}` : \"role: unassigned\";\n const sp =\n pa.storyPoints === null || pa.storyPoints === undefined\n ? \"\"\n : `, story points: ${pa.storyPoints}`;\n return `- ${pa.agent.name} (${role}${sp})`;\n}\n\nfunction buildPmPreamble(context: TaskContext): string[] {\n const parts = [\n `You are an AI project manager helping to plan tasks for the \"${context.title}\" project.`,\n `You are running locally with full access to the repository.`,\n `You can search code (grep, glob), read files, and run shell commands (e.g. git log, git diff). Search to locate relevant code before reading files. You cannot write or edit files.`,\n `\\nEnvironment (ready, no setup required):`,\n `- Repository is cloned at your current working directory.`,\n `- You can read files and run git commands to understand the codebase before writing task plans.`,\n `- Check the dev branch (e.g. run: git fetch && git checkout dev || git checkout main) to understand the current state of the codebase that agents will branch off of.`,\n `\\nWorkflow:`,\n `- You can draft and iterate on plans in .claude/plans/*.md — these files are automatically synced to the task.`,\n `- You can also use update_task_plan directly to save the plan to the task.`,\n `- After saving the plan, end your turn with a summary reply (the team sees your responses in chat automatically). Do NOT attempt to execute the plan yourself.`,\n `- A separate task agent will handle execution after the team reviews and approves your plan.`,\n ];\n if (context.isParentTask) {\n parts.push(\n `\\nYou are the Project Manager for this set of tasks.`,\n `This task has child tasks (subtasks) that are tracked on the board.`,\n `Your role is to coordinate, plan, and manage the subtasks — not to write code directly.`,\n `Use the subtask tools (create_subtask, update_subtask, list_subtasks) to manage work breakdown.`,\n );\n }\n if (context.projectAgents && context.projectAgents.length > 0) {\n parts.push(`\\nProject Agents:`);\n for (const pa of context.projectAgents) {\n parts.push(formatProjectAgentLine(pa));\n }\n }\n return parts;\n}\n\nfunction buildActivePreamble(context: TaskContext, workspaceDir: string): string[] {\n return [\n `You are an AI project manager in ACTIVE mode for the \"${context.title}\" project.`,\n `You have direct coding access to the repository at ${workspaceDir}.`,\n `You can edit files, run tests, and make commits.`,\n `You still have access to all PM tools (subtasks, update_task_plan, chat).`,\n `\\nEnvironment (ready, no setup required):`,\n `- Repository is cloned at your current working directory.`,\n `- You can read, write, and edit files directly.`,\n `- You can run shell commands including git, build tools, and test runners.`,\n context.githubBranch ? `- You are working on branch: \\`${context.githubBranch}\\`` : \"\",\n `\\nSafety rules:`,\n `- Stay within the project directory (${workspaceDir}).`,\n `- Do NOT run \\`git push --force\\` or \\`git reset --hard\\`. Use \\`--force-with-lease\\` if needed.`,\n `- Do NOT delete \\`.env\\` files or modify \\`node_modules\\`.`,\n `- Do NOT run destructive commands like \\`rm -rf /\\`.`,\n `\\nWorkflow:`,\n `- You can make code changes, fix bugs, run tests, and commit directly.`,\n `- When done with changes, summarize what you did in your reply.`,\n `- If you toggled into active mode temporarily, mention when you're done so the team can switch you back to planning mode.`,\n ].filter(Boolean);\n}\n\nfunction buildTaskAgentPreamble(context: TaskContext): string[] {\n return [\n `You are an AI agent working on a task for the \"${context.title}\" project.`,\n `You are running inside a GitHub Codespace with full access to the repository.`,\n `\\nEnvironment (fully ready — do NOT verify or set up):`,\n `- Repository is cloned at your current working directory.`,\n `- Branch \\`${context.githubBranch}\\` is already checked out.`,\n `- All dependencies are installed, database is migrated, and the dev server is running.`,\n `- Git is configured. Commit and push directly to this branch.`,\n `\\nIMPORTANT — Skip all environment verification. Do NOT run any of the following:`,\n `- bun/npm install, pip install, or any dependency installation`,\n `- bun build, bun lint, bun test, bun typecheck, or any build/check commands as a \"first step\"`,\n `- bun db:generate, bun db:push, prisma migrate, or any database setup`,\n `- bun dev, npm start, or any dev server startup commands`,\n `- pwd, ls, echo, or exploratory shell commands to \"check\" the environment`,\n `Only run these if you encounter a specific error that requires it.`,\n `Start reading the task plan and writing code immediately.`,\n `\\nGit safety — STRICT rules:`,\n `- NEVER run \\`git checkout main\\`, \\`git checkout dev\\`, or switch to any branch other than \\`${context.githubBranch}\\`.`,\n `- NEVER create new branches (no \\`git checkout -b\\`, \\`git switch -c\\`, etc.).`,\n `- This branch was created from \\`${context.baseBranch}\\`. PRs will automatically target that branch.`,\n `- If \\`git push\\` fails with \"non-fast-forward\", run \\`git push --force-with-lease origin ${context.githubBranch}\\`. This branch is exclusively yours — force-with-lease is safe.`,\n ];\n}\n\nfunction buildDebugModeSection(hypothesisTracker?: HypothesisTracker): string {\n const lines = [\n `\\n## Debug Mode`,\n `You have access to debug tools that let you set breakpoints, inspect live state,`,\n `and capture client-side behavior. Use these when:`,\n `- You can't find the bug from code reading alone`,\n `- The bug is state-dependent or timing-dependent`,\n `- You need to verify a hypothesis about runtime behavior`,\n ``,\n `Debugging workflow:`,\n `1. Form a hypothesis about the root cause`,\n `2. Identify 2-5 strategic locations to observe (don't over-instrument)`,\n `3. Set breakpoints or probes at those locations`,\n `4. Ask the user to reproduce on the preview link`,\n `5. Analyze the captured data — confirm or refute your hypothesis`,\n `6. If refuted, refine hypothesis and repeat (max 3 iterations)`,\n `7. Exit debug mode and implement the fix`,\n ``,\n `Keep debug sessions focused. You don't need to see everything —`,\n `just the data that tests your hypothesis.`,\n ];\n\n if (hypothesisTracker?.isActive()) {\n const debugContext = hypothesisTracker.getDebugContext();\n if (debugContext) {\n lines.push(``, debugContext);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function buildSystemPrompt(\n mode: RunnerMode | undefined,\n context: TaskContext,\n config: { instructions: string; workspaceDir: string; isAuto?: boolean },\n setupLog: string[],\n agentMode?: AgentMode | null,\n options?: { hasDebugTools?: boolean; hypothesisTracker?: HypothesisTracker },\n): string {\n const isPm = mode === \"pm\";\n const isPmActive = isPm && agentMode === \"building\";\n const isPackRunner = isPm && !!config.isAuto && !!context.isParentTask;\n\n if (isPackRunner) {\n return buildPackRunnerSystemPrompt(context, config, setupLog);\n }\n\n const parts = isPmActive\n ? buildActivePreamble(context, config.workspaceDir)\n : isPm\n ? buildPmPreamble(context)\n : buildTaskAgentPreamble(context);\n\n if (setupLog.length > 0) {\n parts.push(\n `\\nEnvironment setup log (already executed before you started — proof that setup succeeded):`,\n \"```\",\n ...setupLog,\n \"```\",\n );\n }\n\n if (context.agentInstructions) {\n parts.push(`\\nAgent Instructions:\\n${context.agentInstructions}`);\n }\n if (config.instructions) {\n parts.push(`\\nAdditional Instructions:\\n${config.instructions}`);\n }\n parts.push(\n `\\nYour responses are sent directly to the task chat — the team sees everything you say.`,\n `Do NOT call the post_to_chat tool for your own task; your replies already appear in chat automatically.`,\n `Only use post_to_chat if you need to message a different task's chat (e.g. a parent task via get_task).`,\n `Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,\n );\n if (!isPm || isPmActive) {\n parts.push(\n `Use the mcp__conveyor__create_pull_request tool to open PRs — it automatically stages, commits, and pushes changes before creating the PR. Do NOT use gh CLI or shell commands for PR creation.`,\n );\n }\n\n if (options?.hasDebugTools) {\n parts.push(buildDebugModeSection(options.hypothesisTracker));\n }\n\n const modePrompt = buildModePrompt(agentMode, context, mode);\n if (modePrompt) {\n parts.push(modePrompt);\n }\n\n return parts.join(\"\\n\");\n}\n","import {\n PM_CHAT_HISTORY_LIMIT,\n TASK_CHAT_HISTORY_LIMIT,\n type RunnerMode,\n type AgentMode,\n type TaskContext,\n type ChatMessage,\n} from \"@project/shared\";\nimport { buildPackRunnerInstructions } from \"./pack-runner-prompt.js\";\nimport {\n formatChatHistory,\n formatRepoRefs,\n formatReferenceProjects,\n formatProjectObjectives,\n formatRecentRelatedTasks,\n formatIncidents,\n formatTaskFile,\n} from \"./prompt-formatters.js\";\nimport { resolveTagContext } from \"./tag-context-resolver.js\";\nimport { truncatePlanForPrompt } from \"./prompt-truncation.js\";\n\nexport { buildSystemPrompt } from \"./system-prompt.js\";\n\nfunction findLastAgentMessageIndex(history: ChatMessage[]): number {\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i].role === \"assistant\") return i;\n }\n return -1;\n}\n\n/**\n * Messages newer than the relaunch cursor. The cursor is the id of the most\n * recent message in the chat at the end of the agent's last successful turn.\n *\n * - Cursor inside the visible window → everything after that index is new.\n * - Cursor older than the window (fell off the 20-msg tail) → the entire\n * window is newer than what the agent has seen, so treat all of it as new.\n * This is the bug the cursor fixes: urgent user messages outside the window\n * were previously invisible to `findLastAgentMessageIndex` and the agent\n * reported \"no new instructions.\"\n */\nfunction messagesAfterCursor(\n history: ChatMessage[],\n lastSeenMessageId: string | null | undefined,\n): ChatMessage[] {\n if (!lastSeenMessageId) return history;\n const idx = history.findIndex((m) => m.id === lastSeenMessageId);\n return idx === -1 ? history : history.slice(idx + 1);\n}\n\nfunction detectRelaunchScenario(\n context: TaskContext,\n trustChatHistory = false,\n): \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\" {\n // Cursor is the primary signal: if set, the agent has completed at least\n // one turn on this session, so this is a relaunch.\n if (context.lastSeenMessageId) {\n const newMessages = messagesAfterCursor(context.chatHistory, context.lastSeenMessageId);\n const hasNewUserMessages = newMessages.some((m) => m.role === \"user\");\n return hasNewUserMessages ? \"feedback_relaunch\" : \"idle_relaunch\";\n }\n\n // No cursor — fall back to chat-history heuristics for backward compatibility\n // with sessions that predate the cursor and for PM/Pack Runner agents whose\n // own prior chat messages are themselves a reliable \"prior work\" indicator.\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n if (lastAgentIdx === -1) return \"fresh\";\n\n // githubPRUrl signals prior work survived across restarts. claudeSessionId\n // is intentionally NOT consulted here: it persists across crashed sessions\n // and would cause a false \"prior work done\" reading on a fresh relaunch.\n const hasPriorWork = !!context.githubPRUrl || trustChatHistory;\n if (!hasPriorWork) return \"fresh\";\n\n const messagesAfterAgent = context.chatHistory.slice(lastAgentIdx + 1);\n const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === \"user\");\n return hasNewUserMessages ? \"feedback_relaunch\" : \"idle_relaunch\";\n}\n\nfunction buildPmRelaunchParts(\n context: TaskContext,\n lastAgentIdx: number,\n isAuto?: boolean,\n agentMode?: AgentMode | null,\n): string[] {\n const parts: string[] = [];\n const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === \"user\");\n if (newMessages.length > 0) {\n parts.push(\n `You have been relaunched. Here are new messages since your last session:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n );\n } else {\n parts.push(`You have been relaunched. No new messages since your last session.`);\n }\n // Check building/review mode FIRST, independently of isAuto — defense-in-depth\n // against stale isAuto (which can be frozen at pod startup before Build is clicked).\n if (agentMode === \"building\" || agentMode === \"review\") {\n parts.push(\n `\\nYour plan has been approved. Begin implementing it now.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Start by reading the relevant source files mentioned in the plan, then write code.`,\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n );\n if (isAuto) {\n parts.push(\n `\\nCRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,\n `Your FIRST action must be reading source files from the plan, then immediately writing code.`,\n `Do NOT summarize the plan or say \"ready to implement\" — start implementing.`,\n `If you are genuinely blocked, explain the specific blocker — do not go idle silently.`,\n );\n }\n } else if (isAuto) {\n if (context.plan?.trim()) {\n parts.push(\n `\\nYou are in auto mode. A plan already exists for this task.`,\n `Verify that story points, title, and tags are set via get_current_plan, then call ExitPlanMode immediately to transition to building.`,\n `Do NOT wait for team input — proceed autonomously.`,\n );\n } else {\n parts.push(\n `\\nYou are in auto mode. Continue planning autonomously.`,\n `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,\n `Do NOT wait for team input — proceed autonomously.`,\n );\n }\n } else {\n parts.push(\n `\\nYou are the project manager for this task.`,\n `Review the context above and wait for the team to provide instructions before taking action.`,\n );\n }\n return parts;\n}\n\nfunction buildRelaunchWithSession(\n mode: RunnerMode | undefined,\n context: TaskContext,\n agentMode?: AgentMode | null,\n isAuto?: boolean,\n): string | null {\n const scenario = detectRelaunchScenario(context);\n // Cursor is the authoritative relaunch signal; claudeSessionId is kept as a\n // fallback for sessions predating the cursor. Either proves the agent has\n // completed at least one turn on this session, so a \"relaunch\" prompt —\n // rather than the fresh-start prompt — is appropriate.\n const hasPriorTurn = !!context.lastSeenMessageId || !!context.claudeSessionId;\n if (!hasPriorTurn || scenario === \"fresh\") return null;\n\n const parts: string[] = [];\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n\n if (mode === \"pm\") {\n parts.push(...buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode));\n } else if (scenario === \"feedback_relaunch\") {\n const newMessages = (\n context.lastSeenMessageId\n ? messagesAfterCursor(context.chatHistory, context.lastSeenMessageId)\n : context.chatHistory.slice(lastAgentIdx + 1)\n ).filter((m) => m.role === \"user\");\n parts.push(\n `You have been relaunched with new feedback.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes. Do NOT re-investigate the codebase from scratch or write a new plan — review the feedback and implement the changes directly.`,\n `Commit and push your updates.`,\n );\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n );\n }\n } else {\n parts.push(\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Run \\`git log --oneline -10\\` to review what you already committed.`,\n `Review the current state of the codebase and verify everything is working correctly.`,\n );\n if (agentMode === \"auto\" || agentMode === \"building\" || isAuto) {\n parts.push(\n `If work is incomplete, continue implementing the plan. When finished, commit, push, and use mcp__conveyor__create_pull_request to open a PR.`,\n `Do NOT go idle or wait for instructions — you are in auto mode.`,\n );\n } else {\n parts.push(\n `Reply with a brief status update (visible in chat), then wait for further instructions.`,\n );\n }\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nasync function resolveTaskTagContext(\n context: TaskContext,\n runnerMode?: RunnerMode,\n): Promise<string | null> {\n if (!context.projectTags?.length || !context.taskTagIds?.length) return null;\n const { injectedSection } = await resolveTagContext(\n context.projectTags,\n context.taskTagIds,\n context.model,\n context.agentSettings?.betas,\n runnerMode,\n );\n return injectedSection || null;\n}\n\n// oxlint-disable-next-line complexity -- simple field mapping, not real branching complexity\nasync function buildTaskBody(context: TaskContext, runnerMode?: RunnerMode): Promise<string[]> {\n const parts: string[] = [];\n parts.push(`# Task: ${context.title}`);\n if (context.projectName) {\n const descLine = context.projectDescription ? `\\n${context.projectDescription}` : \"\";\n parts.push(`\\n## Project: ${context.projectName}${descLine}`);\n }\n if (context.description) {\n parts.push(`\\n## Description\\n${context.description}`);\n }\n if (context.plan) {\n parts.push(`\\n## Plan\\n${truncatePlanForPrompt(context.plan)}`);\n }\n\n if (context.files && context.files.length > 0) {\n parts.push(`\\n## Attached Files`);\n for (const file of context.files) {\n parts.push(...formatTaskFile(file));\n }\n }\n\n if (context.repoRefs && context.repoRefs.length > 0) {\n parts.push(...formatRepoRefs(context.repoRefs));\n }\n\n if (context.referenceProjects && context.referenceProjects.length > 0) {\n parts.push(...formatReferenceProjects(context.referenceProjects));\n }\n\n const tagSection = await resolveTaskTagContext(context, runnerMode);\n if (tagSection) parts.push(tagSection);\n\n // Project objectives and related tasks help PM planning but are redundant for task agents\n // (task agents already have a plan that incorporates this context)\n if (runnerMode !== \"task\") {\n if (context.projectObjectives && context.projectObjectives.length > 0) {\n parts.push(...formatProjectObjectives(context.projectObjectives));\n }\n if (context.recentRelatedTasks && context.recentRelatedTasks.length > 0) {\n parts.push(...formatRecentRelatedTasks(context.recentRelatedTasks));\n }\n }\n\n if (context.incidents && context.incidents.length > 0) {\n parts.push(...formatIncidents(context.incidents));\n }\n\n if (context.chatHistory.length > 0) {\n const chatLimit = runnerMode === \"task\" ? TASK_CHAT_HISTORY_LIMIT : PM_CHAT_HISTORY_LIMIT;\n parts.push(...formatChatHistory(context.chatHistory, chatLimit));\n }\n\n return parts;\n}\n\nfunction buildFreshInstructions(\n isPm: boolean,\n isAutoMode: boolean,\n context: TaskContext,\n agentMode?: AgentMode | null,\n): string[] {\n // After auto→building transition, agent needs building instructions\n // PM→building only happens through auto mode, so always include anti-idle guidance\n if (isPm && agentMode === \"building\") {\n return [\n `Your plan has been approved. Begin implementing it now.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Start by reading the relevant source files mentioned in the plan, then write code.`,\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n `\\nCRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,\n `Your FIRST action must be reading source files from the plan, then immediately writing code.`,\n `Do NOT summarize the plan or say \"ready to implement\" — start implementing.`,\n `When all changes are ready, use mcp__conveyor__create_pull_request to open a PR.`,\n `If you are genuinely blocked, explain the specific blocker — do not go idle silently.`,\n ];\n }\n if (isAutoMode && isPm) {\n if (context.plan?.trim()) {\n return [\n `You are operating autonomously. A plan already exists for this task.`,\n `Verify that story points, title, and tags are set, then call ExitPlanMode immediately to transition to building.`,\n `Do NOT re-plan or wait for team input — proceed autonomously.`,\n ];\n }\n return [\n `You are operating autonomously. Begin planning immediately.`,\n `1. Search the codebase (grep/glob) to locate relevant files, then read the critical ones`,\n `2. Draft a clear implementation plan and save it with update_task_plan`,\n `3. Set story points, tags, and title (update_task_properties)`,\n `4. When the plan and all required properties are set, call ExitPlanMode to transition to building`,\n `Do NOT wait for team input — proceed autonomously.`,\n ];\n }\n if (isPm && context.isParentTask) {\n return [\n `You are the project manager for this task and its subtasks.`,\n `Review existing subtasks via \\`list_subtasks\\` and the chat history before taking action.`,\n `Read the task description and chat history carefully — the team has provided the initial context below. Acknowledge what they've asked for and respond in chat before taking silent tool actions.`,\n `Start planning now — explore the codebase, ask clarifying questions if needed, and propose a subtask breakdown. Do not wait for additional team input before engaging.`,\n `When you finish planning, save the plan with update_task_plan and end your turn. Your reply will be visible to the team in chat.`,\n ];\n }\n if (isPm) {\n return [\n `You are the project manager for this task.`,\n `Read the task description and chat history carefully — the team has provided the initial context below. Acknowledge what they've asked for and respond in chat before taking silent tool actions.`,\n `Start planning now — explore the codebase, ask clarifying questions if needed, and draft a plan. Do not wait for additional team input before engaging; the initial message IS the team engaging.`,\n `When you finish planning, save the plan with update_task_plan and end your turn. Your reply summarizing the plan will be visible in chat. A separate task agent will execute the plan after review.`,\n ];\n }\n const parts = [\n `Begin executing the task plan above immediately.`,\n `Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first — the environment is already set up.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch for the entire task. Do not checkout or create other branches.`,\n `Your replies are visible to the team in chat — briefly describe what you're doing when you begin meaningful implementation, and again when the PR is ready.`,\n `Before opening the PR, run the quality gates: \\`bun run lint && bun run typecheck && bun run test\\`. Fix any failures. Do NOT open a PR with known failing gates — scope the test run to affected packages if the full suite is prohibitively slow, and state the scope in the PR body.`,\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n ];\n if (isAutoMode) {\n parts.push(\n `\\nCRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,\n `Do NOT summarize the plan or say \"ready to implement\" — start implementing immediately.`,\n `When all changes are ready, you MUST use mcp__conveyor__create_pull_request to open a PR before finishing.`,\n `If you are genuinely blocked, explain the specific blocker — do not go idle silently.`,\n );\n }\n return parts;\n}\n\nfunction buildFeedbackInstructions(\n context: TaskContext,\n isPm: boolean,\n agentMode?: AgentMode | null,\n isAuto?: boolean,\n): string[] {\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === \"user\");\n if (isPm) {\n const parts = [\n `You were relaunched with new feedback since your last run.`,\n `You are the project manager for this task.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n ];\n if (isAuto && (agentMode === \"building\" || agentMode === \"review\")) {\n parts.push(\n `\\nYour plan has been approved. Address the feedback above, then begin implementing.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Start by reading the relevant source files mentioned in the plan, then write code.`,\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,\n );\n } else if (isAuto) {\n parts.push(\n `\\nYou are in auto mode. Address the feedback above — update the plan accordingly using update_task_plan.`,\n `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,\n `Do NOT wait for additional team input — the messages above ARE the team's input. Proceed autonomously.`,\n );\n } else {\n parts.push(\n `\\nReview these messages and wait for the team to provide instructions before taking action.`,\n );\n }\n return parts;\n }\n const parts = [\n `You have been relaunched to address feedback on your previous work.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Start by running \\`git log --oneline -10\\` and \\`git diff HEAD~3 HEAD --stat\\` to review what you already committed.`,\n `\\nNew messages since your last run:`,\n ...newMessages.map((m) => `[${m.userName ?? \"user\"}]: ${m.content}`),\n `\\nAddress the requested changes directly. Do NOT re-investigate the codebase from scratch or write a new plan — go straight to implementing the feedback.`,\n `Before pushing or opening a PR, re-run the quality gates: \\`bun run lint && bun run typecheck && bun run test\\`. Fix any failures — relaunches are the most common place verification gets skipped.`,\n `Implement your updates and open a PR when finished.`,\n ];\n if (context.githubPRUrl) {\n parts.push(\n `An existing PR is open at ${context.githubPRUrl} — push to the same branch to update it. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n return parts;\n}\n\nfunction buildIdleRelaunchInstructions(\n context: TaskContext,\n isPm: boolean,\n agentMode?: AgentMode | null,\n isAuto?: boolean,\n): string[] {\n if (isPm && agentMode === \"auto\" && context.status === \"Planning\") {\n if (context.plan?.trim()) {\n return [\n `You were relaunched in auto mode. A plan already exists for this task.`,\n `Verify that story points, title, and tags are set, then call ExitPlanMode immediately to transition to building.`,\n `Do NOT wait for instructions or go idle — you are in auto mode.`,\n ];\n }\n return [\n `You were relaunched in auto mode. Continue planning autonomously.`,\n `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,\n `Do NOT wait for instructions or go idle — you are in auto mode.`,\n ];\n }\n\n if (isPm && !(agentMode === \"building\" || agentMode === \"review\" || agentMode === \"auto\")) {\n return [\n `You were relaunched but no new instructions have been given since your last run.`,\n `You are the project manager for this task.`,\n `Wait for the team to provide instructions before taking action.`,\n ];\n }\n\n // Task agent or PM in building/review/auto mode — check agentMode independently\n // of isAuto as defense-in-depth against stale isAuto values.\n const isAutoMode = agentMode === \"auto\" || agentMode === \"building\" || isAuto;\n const parts = [\n `You were relaunched but no new instructions have been given since your last run.`,\n `Work on the git branch \"${context.githubBranch}\". Stay on this branch — do not checkout or create other branches.`,\n `Run \\`git log --oneline -10\\` to review what you already committed, then verify the current state is correct.`,\n ];\n if (isAutoMode) {\n parts.push(\n `If work is incomplete, continue implementing the plan. When finished, use mcp__conveyor__create_pull_request to open a PR.`,\n `Do NOT go idle or wait for instructions — you are in auto mode.`,\n );\n } else {\n parts.push(\n `Reply with a brief status update summarizing where things stand (visible in chat).`,\n `Then wait for further instructions — do NOT redo work that was already completed.`,\n );\n }\n if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\n return parts;\n}\n\nfunction buildInstructions(\n mode: RunnerMode | undefined,\n context: TaskContext,\n scenario: \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\",\n agentMode?: AgentMode | null,\n isAuto?: boolean,\n): string[] {\n const parts: string[] = [`\\n## Instructions`];\n\n const isPm = mode === \"pm\";\n\n if (scenario === \"fresh\") {\n parts.push(...buildFreshInstructions(isPm, agentMode === \"auto\", context, agentMode));\n return parts;\n }\n\n if (scenario === \"idle_relaunch\") {\n parts.push(...buildIdleRelaunchInstructions(context, isPm, agentMode, isAuto));\n return parts;\n }\n\n parts.push(...buildFeedbackInstructions(context, isPm, agentMode, isAuto));\n return parts;\n}\n\nexport async function buildInitialPrompt(\n mode: RunnerMode | undefined,\n context: TaskContext,\n isAuto?: boolean,\n agentMode?: AgentMode | null,\n): Promise<string> {\n const isPackRunner = mode === \"pm\" && !!isAuto && !!context.isParentTask;\n\n if (!isPackRunner) {\n const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode, isAuto);\n if (sessionRelaunch) return sessionRelaunch;\n }\n\n const isPm = mode === \"pm\";\n let scenario = detectRelaunchScenario(context, isPm);\n\n // After auto-mode transition from planning to building, planning-phase chat\n // history causes \"idle_relaunch\" even though no building work has started.\n // Override to \"fresh\" so the agent gets \"begin implementing\" instructions.\n if (\n isPm &&\n agentMode === \"building\" &&\n isAuto &&\n !context.claudeSessionId &&\n !context.githubPRUrl &&\n scenario === \"idle_relaunch\"\n ) {\n scenario = \"fresh\";\n }\n const body = await buildTaskBody(context, mode);\n const instructions = isPackRunner\n ? buildPackRunnerInstructions(context, scenario)\n : buildInstructions(mode, context, scenario, agentMode, isAuto);\n return [...body, ...instructions].join(\"\\n\");\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult, imageBlock, isImageMimeType, formatCliEvent } from \"./helpers.js\";\n\ntype ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"image\"; data: string; mimeType: string };\n\nexport function buildReadTaskChatTool(connection: AgentConnection) {\n return defineTool(\n \"read_task_chat\",\n \"Read recent human/user chat messages for a task. Omit task_id for the current task; pass a child ID for a child's chat. For agent logs use get_execution_logs.\",\n {\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n task_id: z\n .string()\n .optional()\n .describe(\"Child task ID to read chat from. Omit to read the current task's chat.\"),\n },\n async ({ limit, task_id }) => {\n try {\n const messages = await connection.call(\"getChatMessages\", {\n sessionId: connection.sessionId,\n limit,\n taskId: task_id,\n });\n return textResult(JSON.stringify(messages, null, 2));\n } catch {\n return textResult(\n JSON.stringify({\n note: \"Could not fetch live chat. Chat history was provided in the initial context.\",\n }),\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildGetCurrentPlanTool(connection: AgentConnection) {\n return defineTool(\n \"get_current_plan\",\n \"Re-read the current task's plan. Use when the user updated the plan or asked you to re-read it — otherwise the plan is already in initial context. For task metadata use get_task.\",\n {},\n async () => {\n try {\n const ctx = await connection.call(\"getTaskContext\", {\n sessionId: connection.sessionId,\n });\n return textResult(ctx.plan ?? \"No plan available.\");\n } catch {\n return textResult(\"Could not fetch updated plan.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildGetTaskTool(connection: AgentConnection) {\n return defineTool(\n \"get_task\",\n \"Look up any task by slug or ID. Returns JSON with id, slug, title, description, plan, status, branch, githubPRNumber, githubPRUrl, storyPoints. For children use list_subtasks.\",\n {\n slug_or_id: z.string().describe(\"The task slug (e.g. 'my-task') or CUID\"),\n },\n async ({ slug_or_id }) => {\n try {\n const task = await connection.call(\"getTask\", {\n sessionId: connection.sessionId,\n taskSlugOrId: slug_or_id,\n });\n return textResult(JSON.stringify(task, null, 2));\n } catch (error) {\n return textResult(\n `Failed to get task: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildGetExecutionLogsTool(connection: AgentConnection) {\n return defineTool(\n \"get_execution_logs\",\n \"Read CLI execution logs — agent reasoning, tool calls, and setup/dev-server output. Filter via source='agent' or 'application'. For human chat use read_task_chat.\",\n {\n task_id: z\n .string()\n .optional()\n .describe(\"Task ID or slug. Omit to read logs from the current task.\"),\n source: z\n .enum([\"agent\", \"application\"])\n .optional()\n .describe(\"Filter by log source. Omit for all logs.\"),\n limit: z\n .number()\n .optional()\n .describe(\"Max number of log entries to return (default 50, max 500).\"),\n },\n async ({ task_id, source, limit }) => {\n try {\n const effectiveLimit = Math.min(limit ?? 50, 500);\n const result = await connection.call(\"getCliHistory\", {\n sessionId: connection.sessionId,\n limit: effectiveLimit,\n taskId: task_id,\n source,\n });\n const formatted = (result as Array<Record<string, unknown>>)\n .map((entry) => {\n const type = entry.type as string;\n const time = entry.timestamp as string;\n return `[${time}] [${type}] ${formatCliEvent(entry as Record<string, unknown>)}`;\n })\n .join(\"\\n\");\n return textResult(formatted || \"No CLI logs found.\");\n } catch (error) {\n return textResult(\n `Failed to fetch CLI logs: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildListTaskFilesTool(connection: AgentConnection) {\n return defineTool(\n \"list_task_files\",\n \"List all files attached to this task with metadata. Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.\",\n {},\n async () => {\n try {\n const files = await connection.call(\"getTaskFiles\", {\n sessionId: connection.sessionId,\n });\n const metadata = files.map((file) => {\n const { content: _c, ...rest } = file;\n return rest;\n });\n const content: ContentBlock[] = [\n { type: \"text\" as const, text: JSON.stringify(metadata, null, 2) },\n ];\n for (const file of files) {\n if (file.content && file.contentEncoding === \"base64\" && isImageMimeType(file.mimeType)) {\n content.push(imageBlock(file.content, file.mimeType));\n }\n }\n return { content };\n } catch {\n return textResult(\"Failed to list task files.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildGetAttachmentTool(connection: AgentConnection) {\n return defineTool(\n \"get_attachment\",\n \"Fetch one task file's content plus metadata by file ID. Call list_task_files first to discover IDs and check sizes — large binaries may be truncated by the service's size limit.\",\n { fileId: z.string().describe(\"The file ID to retrieve\") },\n async ({ fileId }) => {\n try {\n const file = await connection.call(\"getTaskFile\", {\n sessionId: connection.sessionId,\n fileId,\n });\n const { content: rawContent, ...metadata } = file;\n const content: ContentBlock[] = [\n { type: \"text\" as const, text: JSON.stringify(metadata, null, 2) },\n ];\n if (rawContent && file.contentEncoding === \"base64\" && isImageMimeType(file.mimeType)) {\n content.push(imageBlock(rawContent, file.mimeType));\n } else if (rawContent) {\n content[0] = { type: \"text\" as const, text: JSON.stringify(file, null, 2) };\n }\n return { content };\n } catch (error) {\n return textResult(\n `Failed to get task file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\n/** All read-only task context tools. */\nexport function buildTaskContextTools(connection: AgentConnection) {\n return [\n buildReadTaskChatTool(connection),\n buildGetCurrentPlanTool(connection),\n buildGetTaskTool(connection),\n buildGetExecutionLogsTool(connection),\n buildListTaskFilesTool(connection),\n buildGetAttachmentTool(connection),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult } from \"./helpers.js\";\n\nexport function buildGetDependenciesTool(connection: AgentConnection) {\n return defineTool(\n \"get_dependencies\",\n \"Get this task's dependencies and their met/unmet status (met = merged to dev). Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.\",\n {},\n async () => {\n try {\n const deps = await connection.call(\"getDependencies\", {\n sessionId: connection.sessionId,\n });\n return textResult(JSON.stringify(deps, null, 2));\n } catch (error) {\n return textResult(\n `Failed to get dependencies: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildGetSuggestionsTool(connection: AgentConnection) {\n return defineTool(\n \"get_suggestions\",\n \"List project suggestions sorted by vote score. Filter by status or cap with limit (default 20). Suggestions are project-level ideas, not tasks — use get_task for tasks.\",\n {\n status: z\n .string()\n .optional()\n .describe(\n \"Filter by status: Planning, Open, InProgress, ReviewPR, ReviewDev, ReviewLive, Complete, Cancelled\",\n ),\n limit: z.number().int().min(1).max(100).optional().describe(\"Max results (default 20)\"),\n },\n async ({ status, limit }) => {\n try {\n const suggestions = await connection.call(\"getSuggestions\", {\n sessionId: connection.sessionId,\n status,\n limit,\n });\n if (suggestions.length === 0) {\n return textResult(\"No suggestions found.\");\n }\n return textResult(JSON.stringify(suggestions, null, 2));\n } catch (error) {\n return textResult(\n `Failed to get suggestions: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport { textResult } from \"./helpers.js\";\nimport {\n hasUncommittedChanges,\n stageAndCommit,\n hasUnpushedCommits,\n pushToOrigin,\n} from \"../runner/git-utils.js\";\n\nexport function buildPostToChatTool(connection: AgentConnection) {\n return defineTool(\n \"post_to_chat\",\n \"Post an out-of-band chat message to a task. Use only when explicitly asked, or to message a child's chat (pass its ID). Normal replies already appear in chat automatically.\",\n {\n message: z.string().describe(\"The message to post to the team\"),\n task_id: z\n .string()\n .optional()\n .describe(\"Child task ID to post to. Omit to post to the current task's chat.\"),\n },\n async ({ message, task_id }) => {\n try {\n if (task_id) {\n await connection.call(\"postChildChatMessage\", {\n sessionId: connection.sessionId,\n childTaskId: task_id,\n message,\n });\n return textResult(JSON.stringify({ posted: true, target: `child:${task_id}` }));\n }\n const dedup = connection.checkAndTrackDuplicate(message);\n if (dedup.duplicate) {\n return textResult(\n JSON.stringify({\n posted: false,\n reason: \"duplicate\",\n matchedMessagePreview: dedup.matchedMessagePreview,\n hint: \"A near-identical message (>70% word overlap) was posted within the last 30s. Rephrase with new information or skip this post.\",\n }),\n );\n }\n await connection.call(\"postToChat\", { message });\n return textResult(JSON.stringify({ posted: true }));\n } catch (error) {\n return textResult(\n `Failed to post message: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nexport function buildForceUpdateTaskStatusTool(connection: AgentConnection) {\n return defineTool(\n \"force_update_task_status\",\n \"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.\",\n {\n status: z\n .enum([\"InProgress\", \"ReviewPR\", \"ReviewDev\", \"Complete\"])\n .describe(\"The new status for the task\"),\n task_id: z\n .string()\n .optional()\n .describe(\"Child task ID to update. Omit to update the current task.\"),\n },\n async ({ status, task_id }) => {\n try {\n if (task_id) {\n await connection.call(\"updateChildStatus\", {\n sessionId: connection.sessionId,\n childTaskId: task_id,\n status,\n });\n return textResult(`Child task ${task_id} status updated to ${status}.`);\n }\n await connection.call(\"updateTaskStatus\", {\n sessionId: connection.sessionId,\n status,\n force: true,\n });\n return textResult(`Task status updated to ${status}.`);\n } catch (error) {\n return textResult(\n `Failed to update status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\n// oxlint-disable-next-line max-lines-per-function -- PR creation involves git staging, committing, pushing, and API call\nexport function buildCreatePullRequestTool(connection: AgentConnection, config: AgentRunnerConfig) {\n return defineTool(\n \"create_pull_request\",\n \"Create a GitHub PR for this task. Auto-stages, commits (commitMessage or title default), pushes to origin, then opens the PR. Always use this instead of gh CLI or raw git.\",\n {\n title: z.string().describe(\"The PR title\"),\n body: z.string().describe(\"The PR description/body in markdown\"),\n branch: z\n .string()\n .optional()\n .describe(\n \"The head branch name for the PR. If the task doesn't have a branch set, this will be used. Defaults to the task's existing branch.\",\n ),\n baseBranch: z\n .string()\n .optional()\n .describe(\n \"The base branch to target for the PR (e.g. 'main', 'develop'). Defaults to the project's configured dev branch.\",\n ),\n commitMessage: z\n .string()\n .optional()\n .describe(\n \"Commit message for staging uncommitted changes. If not provided, a default message based on the PR title will be used.\",\n ),\n },\n async ({ title, body, branch, baseBranch, commitMessage }) => {\n try {\n const cwd = config.workspaceDir;\n\n if (hasUncommittedChanges(cwd)) {\n const message =\n commitMessage || `${title}\\n\\nCo-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>`;\n const commitHash = stageAndCommit(cwd, message);\n if (commitHash) {\n connection.sendEvent({\n type: \"message\",\n content: `Auto-committed changes: ${commitHash.slice(0, 7)}`,\n });\n } else {\n return textResult(\n \"Failed to stage and commit changes. Please check git status and commit manually before creating PR.\",\n );\n }\n }\n\n if (hasUnpushedCommits(cwd)) {\n const pushSuccess = await pushToOrigin(cwd, async () => {\n try {\n const result = await connection.call(\"refreshGithubToken\", {\n sessionId: connection.sessionId,\n });\n return result.token;\n } catch {\n return undefined;\n }\n });\n if (pushSuccess) {\n connection.sendEvent({\n type: \"message\",\n content: \"Auto-pushed committed changes to origin\",\n });\n } else {\n return textResult(\n \"Failed to push changes to origin. Please check git status and push manually before creating PR.\",\n );\n }\n }\n\n const result = await connection.call(\"createPullRequest\", {\n sessionId: connection.sessionId,\n title,\n body,\n head: branch,\n base: baseBranch,\n });\n connection.sendEvent({\n type: \"pr_created\",\n url: result.prUrl,\n number: result.prNumber,\n });\n return textResult(`Pull request #${result.prNumber} created: ${result.prUrl}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(\n `Failed to create pull request: ${msg}\\n\\nTroubleshooting:\\n- Ensure all changes are committed and pushed to the remote branch\\n- Check that the branch exists on the remote (run: git push -u origin HEAD)\\n- Verify there isn't already an open PR for this branch\\n- If git auth fails, the token may have expired — retry the operation`,\n );\n }\n },\n );\n}\n\nexport function buildAddDependencyTool(connection: AgentConnection) {\n return defineTool(\n \"add_dependency\",\n \"Add a blocking dependency — this task cannot start until the named task is merged to dev. For post-task follow-ups use create_follow_up_task instead.\",\n {\n depends_on_slug_or_id: z.string().describe(\"Slug or ID of the task this task depends on\"),\n },\n async ({ depends_on_slug_or_id }) => {\n try {\n await connection.call(\"addDependency\", {\n sessionId: connection.sessionId,\n dependsOnSlugOrId: depends_on_slug_or_id,\n });\n return textResult(`Dependency added: this task now depends on \"${depends_on_slug_or_id}\"`);\n } catch (error) {\n return textResult(\n `Failed to add dependency: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nexport function buildRemoveDependencyTool(connection: AgentConnection) {\n return defineTool(\n \"remove_dependency\",\n \"Remove a previously added dependency from this task. When to use: the dependency was added in error or is no longer relevant. Returns: confirmation string.\",\n {\n depends_on_slug_or_id: z.string().describe(\"Slug or ID of the task to remove as dependency\"),\n },\n async ({ depends_on_slug_or_id }) => {\n try {\n await connection.call(\"removeDependency\", {\n sessionId: connection.sessionId,\n dependsOnSlugOrId: depends_on_slug_or_id,\n });\n return textResult(\"Dependency removed\");\n } catch (error) {\n return textResult(\n `Failed to remove dependency: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nexport function buildCreateFollowUpTaskTool(connection: AgentConnection) {\n return defineTool(\n \"create_follow_up_task\",\n \"Create a follow-up task that depends on the current task. Use for out-of-scope work or cleanup that should land after this task merges. For blockers use add_dependency.\",\n {\n title: z.string().describe(\"Follow-up task title\"),\n description: z.string().optional().describe(\"Brief description of the follow-up work\"),\n plan: z.string().optional().describe(\"Implementation plan if known\"),\n story_point_value: z\n .number()\n .optional()\n .describe(\"Story point estimate (1=Common, 2=Magic, 3=Rare, 5=Unique)\"),\n },\n async ({ title, description, plan, story_point_value }) => {\n try {\n const result = await connection.call(\"createFollowUpTask\", {\n sessionId: connection.sessionId,\n title,\n description,\n plan,\n storyPointValue: story_point_value,\n });\n return textResult(\n `Follow-up task created: \"${title}\" (slug: ${result.slug}). It depends on the current task and will be unblocked when this task is merged.`,\n );\n } catch (error) {\n return textResult(\n `Failed to create follow-up task: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nexport function buildCreateSuggestionTool(connection: AgentConnection) {\n return defineTool(\n \"create_suggestion\",\n \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded. For actionable work on this task open a follow-up task.\",\n {\n title: z.string().describe(\"Short title for the suggestion\"),\n description: z\n .string()\n .optional()\n .describe(\n \"1-2 sentence description of what should change and why. Keep concise and project-focused.\",\n ),\n tag_names: z.array(z.string()).optional().describe(\"Tag names to categorize the suggestion\"),\n },\n async ({ title, description, tag_names }) => {\n try {\n const result = await connection.call(\"createSuggestion\", {\n sessionId: connection.sessionId,\n title,\n description,\n tagNames: tag_names,\n });\n if (result.merged) {\n return textResult(\n `Your suggestion was merged into an existing one (ID: ${result.mergedIntoId ?? result.id}). Your upvote has been recorded.`,\n );\n }\n return textResult(`Suggestion created (ID: ${result.id}).`);\n } catch (error) {\n return textResult(\n `Failed to create suggestion: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nexport function buildVoteSuggestionTool(connection: AgentConnection) {\n return defineTool(\n \"vote_suggestion\",\n \"Vote +1 or -1 on a project suggestion. Use to express support or disagreement with a specific suggestion returned by get_suggestions.\",\n {\n suggestion_id: z.string().describe(\"The suggestion ID to vote on\"),\n value: z\n .number()\n .refine((v) => v === 1 || v === -1, { message: \"Value must be 1 or -1\" })\n .describe(\"+1 to upvote, -1 to downvote\"),\n },\n async ({ suggestion_id, value }) => {\n try {\n const result = await connection.call(\"voteSuggestion\", {\n sessionId: connection.sessionId,\n suggestionId: suggestion_id,\n value: value as 1 | -1,\n });\n return textResult(`Vote recorded. Current score: ${result.score}`);\n } catch (error) {\n return textResult(\n `Failed to vote: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\n/** All write/mutation tools (excluding PR creation which needs config). */\nexport function buildMutationTools(connection: AgentConnection, config: AgentRunnerConfig) {\n return [\n buildPostToChatTool(connection),\n buildCreatePullRequestTool(connection, config),\n buildAddDependencyTool(connection),\n buildRemoveDependencyTool(connection),\n buildCreateFollowUpTaskTool(connection),\n buildCreateSuggestionTool(connection),\n buildVoteSuggestionTool(connection),\n ];\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, extname, isAbsolute, join } from \"node:path\";\nimport { z } from \"zod\";\nimport { MAX_FILE_SIZE_BYTES } from \"@project/shared\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport { textResult } from \"./helpers.js\";\n\nconst IMAGE_MIME_BY_EXT: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n};\n\nexport function buildUploadAttachmentTool(connection: AgentConnection, config: AgentRunnerConfig) {\n return defineTool(\n \"upload_attachment\",\n \"Upload an image file (e.g. a Playwright screenshot) as a task attachment AND post it to the task chat in one step — no follow-up post_to_chat call needed. Supports png/jpg/gif/webp.\",\n {\n path: z\n .string()\n .describe(\"Path to the image file — absolute, or relative to the workspace root\"),\n title: z\n .string()\n .optional()\n .describe(\"Short caption posted with the image (defaults to the file name)\"),\n },\n async ({ path, title }) => {\n try {\n const filePath = isAbsolute(path) ? path : join(config.workspaceDir, path);\n const mimeType = IMAGE_MIME_BY_EXT[extname(filePath).toLowerCase()];\n if (!mimeType) {\n return textResult(\n `Unsupported file type \"${extname(filePath) || \"(none)\"}\". Supported: ${Object.keys(IMAGE_MIME_BY_EXT).join(\", \")}`,\n );\n }\n\n const info = await stat(filePath).catch(() => null);\n if (!info?.isFile()) {\n return textResult(`File not found: ${filePath}`);\n }\n if (info.size > MAX_FILE_SIZE_BYTES) {\n return textResult(\n `File is ${info.size} bytes — exceeds the ${MAX_FILE_SIZE_BYTES} byte upload limit. Resize or crop the image first.`,\n );\n }\n\n const fileName = basename(filePath);\n const { fileId, uploadUrl } = await connection.call(\"requestFileUpload\", {\n sessionId: connection.sessionId,\n fileName,\n mimeType,\n fileSize: info.size,\n });\n\n const body = await readFile(filePath);\n const res = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": mimeType },\n body,\n });\n if (!res.ok) {\n return textResult(\n `Upload to storage failed: HTTP ${res.status} ${await res.text().catch(() => \"\")}`,\n );\n }\n\n const result = await connection.call(\"confirmFileUpload\", {\n sessionId: connection.sessionId,\n fileId,\n title,\n });\n\n return textResult(\n `Uploaded ${fileName} (${info.size} bytes) and posted it to the task chat${title ? ` with caption \"${title}\"` : \"\"}. File ID: ${result.fileId}`,\n );\n } catch (error) {\n return textResult(\n `Failed to upload attachment: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult } from \"./helpers.js\";\n\nexport function buildListManualTestsTool(connection: AgentConnection) {\n return defineTool(\n \"list_manual_tests\",\n \"List the manual test checklist items for the current task. Use to see what manual verification steps have already been recorded.\",\n {},\n async () => {\n try {\n const items = await connection.call(\"listManualTests\", {\n sessionId: connection.sessionId,\n });\n if (items.length === 0) return textResult(\"No manual tests recorded for this task.\");\n const lines = items.map((item, i) => {\n const checked = item.checked ? \"[x]\" : \"[ ]\";\n return `${i + 1}. ${checked} ${item.title}`;\n });\n return textResult(lines.join(\"\\n\"));\n } catch {\n return textResult(\"Failed to list manual tests.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildSetManualTestsTool(connection: AgentConnection) {\n return defineTool(\n \"set_manual_tests\",\n \"Add manual test steps to the task checklist. Existing items with the same title are automatically skipped (deduplication). Use to record specific manual verification steps that reviewers should follow when testing this PR.\",\n {\n items: z\n .array(z.object({ title: z.string().min(1).describe(\"A concise, actionable test step\") }))\n .min(1)\n .describe(\"List of manual test steps to add\"),\n },\n async ({ items }) => {\n try {\n const result = await connection.call(\"setManualTests\", {\n sessionId: connection.sessionId,\n items,\n });\n const parts = [`Created ${result.created} manual test item(s).`];\n if (result.skipped > 0) parts.push(`Skipped ${result.skipped} duplicate(s).`);\n return textResult(parts.join(\" \"));\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(`Failed to set manual tests: ${msg}`);\n }\n },\n );\n}\n","import type { AgentConnection } from \"../connection/agent-connection.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport { buildTaskContextTools } from \"./task-context-tools.js\";\nimport {\n buildGetDependenciesTool,\n buildGetSuggestionsTool,\n} from \"./dependency-suggestion-tools.js\";\nimport { buildMutationTools } from \"./mutation-tools.js\";\nimport { buildUploadAttachmentTool } from \"./attachment-tools.js\";\nimport { buildListManualTestsTool, buildSetManualTestsTool } from \"./checklist-tools.js\";\n\n// Re-export individual builders for selective use\nexport {\n buildReadTaskChatTool,\n buildGetCurrentPlanTool,\n buildGetTaskTool,\n buildGetExecutionLogsTool,\n buildListTaskFilesTool,\n buildGetAttachmentTool,\n} from \"./task-context-tools.js\";\n\nexport { buildForceUpdateTaskStatusTool } from \"./mutation-tools.js\";\nexport { buildUploadAttachmentTool } from \"./attachment-tools.js\";\n\n// ── Aggregator ───────────────────────────────────────────────────────\n\nexport function buildCommonTools(connection: AgentConnection, config: AgentRunnerConfig) {\n return [\n ...buildTaskContextTools(connection),\n buildGetDependenciesTool(connection),\n buildGetSuggestionsTool(connection),\n buildListManualTestsTool(connection),\n buildSetManualTestsTool(connection),\n ...buildMutationTools(connection, config),\n buildUploadAttachmentTool(connection, config),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult } from \"./helpers.js\";\n\nconst SP_DESCRIPTION = \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n\nexport function buildUpdateTaskTool(connection: AgentConnection) {\n return defineTool(\n \"update_task_plan\",\n \"Save the finalized plan and/or description to the current task. Use in Plan mode after alignment. For children use update_subtask; for title/tags/PR use update_task_properties.\",\n {\n plan: z.string().optional().describe(\"The task plan in markdown\"),\n description: z.string().optional().describe(\"Updated task description\"),\n },\n async ({ plan, description }) => {\n try {\n await connection.call(\"updateTaskFields\", {\n sessionId: connection.sessionId,\n plan,\n description,\n });\n return textResult(\"Task updated successfully.\");\n } catch {\n return textResult(\"Failed to update task.\");\n }\n },\n );\n}\n\nfunction buildCreateSubtaskTool(connection: AgentConnection) {\n return defineTool(\n \"create_subtask\",\n \"Create a subtask under the current parent task. Use when breaking a complex parent into smaller pieces during planning. For post-task follow-ups use create_follow_up_task.\",\n {\n title: z.string().describe(\"Subtask title\"),\n description: z.string().optional().describe(\"Brief description\"),\n plan: z.string().optional().describe(\"Implementation plan in markdown\"),\n ordinal: z.number().optional().describe(\"Step/order number (0-based)\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async ({ title, description, plan, ordinal, storyPointValue }) => {\n try {\n const result = await connection.call(\"createSubtask\", {\n sessionId: connection.sessionId,\n title,\n ...(description !== undefined && { description }),\n ...(plan !== undefined && { plan }),\n ...(storyPointValue !== undefined && { storyPointValue }),\n ...(ordinal !== undefined && { ordinal }),\n });\n return textResult(`Subtask created with ID: ${result.id}`);\n } catch (error) {\n return textResult(\n `Failed to create subtask: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n );\n}\n\nfunction buildUpdateSubtaskTool(connection: AgentConnection) {\n return defineTool(\n \"update_subtask\",\n \"Update an existing subtask's fields (title, description, plan, ordinal, storyPointValue). Use when refining a child's plan or reordering. For the current task use update_task_plan.\",\n {\n subtaskId: z.string().describe(\"The subtask ID to update\"),\n title: z.string().optional(),\n description: z.string().optional(),\n plan: z.string().optional(),\n ordinal: z.number().optional(),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async ({ subtaskId, title, description, plan, storyPointValue }) => {\n try {\n await connection.call(\"updateSubtask\", {\n sessionId: connection.sessionId,\n subtaskId,\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(plan !== undefined && { plan }),\n ...(storyPointValue !== undefined && { storyPointValue }),\n });\n return textResult(\"Subtask updated.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n );\n}\n\nfunction buildDeleteSubtaskTool(connection: AgentConnection) {\n return defineTool(\n \"delete_subtask\",\n \"Delete a subtask by id. When to use: a subtask was created in error or is no longer needed. Returns: confirmation string.\",\n { subtaskId: z.string().describe(\"The subtask ID to delete\") },\n async ({ subtaskId }) => {\n try {\n await connection.call(\"deleteSubtask\", {\n sessionId: connection.sessionId,\n subtaskId,\n });\n return textResult(\"Subtask deleted.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n );\n}\n\nfunction buildListSubtasksTool(connection: AgentConnection) {\n return defineTool(\n \"list_subtasks\",\n \"List all subtasks under the current parent task. Use to coordinate child work — check who is running, ready for review, or blocked. For non-child tasks use get_task.\",\n {},\n async () => {\n try {\n const subtasks = await connection.call(\"listSubtasks\", {\n sessionId: connection.sessionId,\n });\n return textResult(JSON.stringify(subtasks, null, 2));\n } catch {\n return textResult(\"Failed to list subtasks.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildPackTools(connection: AgentConnection) {\n return [\n defineTool(\n \"start_child_cloud_build\",\n \"Start a cloud build (codespace) for a child task. Preconditions: child is in Open status, has a story point value, and has an agent assigned.\",\n {\n childTaskId: z.string().describe(\"The child task ID to start a cloud build for\"),\n },\n async ({ childTaskId }) => {\n try {\n const result = await connection.call(\"startChildCloudBuild\", {\n sessionId: connection.sessionId,\n childTaskId,\n });\n return textResult(`Cloud build started for child task: ${result.childTaskId}`);\n } catch (error) {\n return textResult(\n `Failed to start child cloud build: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n ),\n defineTool(\n \"stop_child_build\",\n \"Send a graceful stop signal to a running child build's agent. Not a force-kill — the agent may take a moment to wind down.\",\n {\n childTaskId: z.string().describe(\"The child task ID whose build should be stopped\"),\n },\n async ({ childTaskId }) => {\n try {\n await connection.call(\"stopChildBuild\", {\n sessionId: connection.sessionId,\n childTaskId,\n });\n return textResult(`Stop signal sent to child task: ${childTaskId}`);\n } catch (error) {\n return textResult(\n `Failed to stop child build: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n ),\n defineTool(\n \"approve_and_merge_pr\",\n \"Approve and merge a child task's PR. Preconditions: child in ReviewPR. Returns { merged }: true = merged (status→ReviewDev); false = automerge queued, wait for ReviewDev.\",\n {\n childTaskId: z\n .string()\n .describe(\"The child task ID whose PR should be approved and merged\"),\n },\n async ({ childTaskId }) => {\n try {\n const result = await connection.call(\"approveAndMergePR\", {\n sessionId: connection.sessionId,\n childTaskId,\n });\n if (result.merged) {\n return textResult(\n `PR #${result.prNumber} approved and merged for task ${result.childTaskId}. Task status updated to ReviewDev.`,\n );\n }\n return textResult(\n `PR #${result.prNumber} merge queued for task ${result.childTaskId} — CI checks still in progress. The PR will auto-merge when all checks pass. Do NOT proceed as if merged. Wait for the child task status to change to ReviewDev before continuing.`,\n );\n } catch (error) {\n return textResult(\n `Failed to approve and merge PR: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n ),\n ];\n}\n\nexport function buildPmTools(\n connection: AgentConnection,\n options?: { includePackTools?: boolean },\n) {\n const tools = [\n buildUpdateTaskTool(connection),\n buildCreateSubtaskTool(connection),\n buildUpdateSubtaskTool(connection),\n buildDeleteSubtaskTool(connection),\n buildListSubtasksTool(connection),\n ];\n if (!options?.includePackTools) return tools;\n return [...tools, ...buildPackTools(connection)];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult } from \"./helpers.js\";\n\nconst SP_DESCRIPTION = \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n\nexport function buildDiscoveryTools(connection: AgentConnection) {\n return [\n defineTool(\n \"update_task_properties\",\n \"Set one or more task properties in a single call. All fields are optional — only include the fields you want to update.\",\n {\n title: z.string().optional().describe(\"The new task title\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n tagNames: z.array(z.string()).optional().describe(\"Array of tag names to assign\"),\n githubPRUrl: z\n .string()\n .url()\n .optional()\n .describe(\"GitHub pull request URL to link to this task\"),\n githubBranch: z\n .string()\n .optional()\n .describe(\"Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')\"),\n },\n async ({ title, storyPointValue, tagNames, githubPRUrl, githubBranch }) => {\n try {\n await connection.call(\"updateTaskProperties\", {\n sessionId: connection.sessionId,\n title,\n storyPointValue,\n tagNames,\n githubPRUrl,\n githubBranch,\n });\n\n const updatedFields = [];\n if (title !== undefined) updatedFields.push(`title to \"${title}\"`);\n if (storyPointValue !== undefined)\n updatedFields.push(`story points to ${storyPointValue}`);\n if (tagNames !== undefined) updatedFields.push(`tags (${tagNames.length} tag(s))`);\n if (githubPRUrl !== undefined) updatedFields.push(`PR link to \"${githubPRUrl}\"`);\n if (githubBranch !== undefined) updatedFields.push(`branch to \"${githubBranch}\"`);\n\n return textResult(`Task properties updated: ${updatedFields.join(\", \")}`);\n } catch (error) {\n return textResult(\n `Failed to update task properties: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n },\n ),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport { textResult } from \"./helpers.js\";\n\nexport function buildCodeReviewTools(connection: AgentConnection) {\n return [\n defineTool(\n \"approve_code_review\",\n \"Approve the code review and exit. Use when the diff passes all review criteria. Takes only a summary — for changes, use request_code_changes with a structured issues[] list.\",\n {\n summary: z.string().describe(\"Brief summary of what was reviewed and why it looks good\"),\n },\n async ({ summary }) => {\n const content = `**Code Review: Approved** :white_check_mark:\\n\\n${summary}`;\n await connection.call(\"submitCodeReviewResult\", {\n sessionId: connection.sessionId,\n approved: true,\n content,\n });\n connection.sendEvent({\n type: \"code_review_complete\",\n result: \"approved\",\n summary,\n });\n return textResult(\"Code review approved. Exiting.\");\n },\n ),\n defineTool(\n \"request_code_changes\",\n \"Request changes during code review and exit. Use when substantive issues must be fixed before merge. Each issue: { file, line?, severity: critical|major|minor, description }.\",\n {\n issues: z\n .array(\n z.object({\n file: z.string().describe(\"File path where the issue was found\"),\n line: z.number().optional().describe(\"Line number (if applicable)\"),\n severity: z.enum([\"critical\", \"major\", \"minor\"]).describe(\"Issue severity\"),\n description: z.string().describe(\"What is wrong and how to fix it\"),\n }),\n )\n .describe(\"List of issues found during review\"),\n summary: z.string().describe(\"Brief overall summary of the review findings\"),\n },\n async ({ issues, summary }) => {\n const issueLines = issues\n .map((issue) => {\n const loc = issue.line ? `:${issue.line}` : \"\";\n return `- **[${issue.severity}]** \\`${issue.file}${loc}\\`: ${issue.description}`;\n })\n .join(\"\\n\");\n\n const content = `**Code Review: Changes Requested** :warning:\\n\\n${summary}\\n\\n${issueLines}`;\n await connection.call(\"submitCodeReviewResult\", {\n sessionId: connection.sessionId,\n approved: false,\n content,\n });\n connection.sendEvent({\n type: \"code_review_complete\",\n result: \"changes_requested\",\n summary,\n issues,\n });\n return textResult(\"Code review complete — changes requested. Exiting.\");\n },\n ),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { DebugManager } from \"../debug/debug-manager.js\";\nimport { textResult } from \"./index.js\";\n\nimport type { CdpDebugClient } from \"../debug/cdp-client.js\";\nimport { buildTelemetryTools } from \"./telemetry-tools.js\";\nimport { buildClientDebugTools } from \"./client-debug-tools.js\";\n\nfunction requireDebugClient(manager: DebugManager): CdpDebugClient | string {\n if (!manager.isDebugMode()) {\n return \"Debug mode is not active. Use debug_enter_mode first.\";\n }\n const client = manager.getClient();\n if (!client?.isConnected()) {\n return \"CDP client is not connected. Try exiting and re-entering debug mode.\";\n }\n return client;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : \"Unknown error\";\n}\n\nasync function handleEnterDebugMode(\n manager: DebugManager,\n {\n hypothesis,\n serverSide,\n clientSide,\n previewUrl,\n }: {\n hypothesis?: string;\n serverSide?: boolean;\n clientSide?: boolean;\n previewUrl?: string;\n },\n) {\n const wantServer = serverSide ?? !clientSide;\n const wantClient = clientSide ?? false;\n\n const alreadyMsg = checkAlreadyActive(manager, wantServer, wantClient);\n if (alreadyMsg) return textResult(alreadyMsg);\n\n await manager.enterDebugMode(undefined, {\n serverSide: wantServer && !manager.isDebugMode(),\n clientSide: wantClient && !manager.isClientDebugMode(),\n previewUrl,\n });\n\n return textResult(buildActivationMessage(manager, hypothesis));\n}\n\nfunction checkAlreadyActive(\n manager: DebugManager,\n wantServer: boolean,\n wantClient: boolean,\n): string | null {\n if (wantServer && manager.isDebugMode() && !wantClient) return \"Already in server debug mode.\";\n if (wantClient && manager.isClientDebugMode() && !wantServer)\n return \"Already in client debug mode.\";\n if (wantServer && manager.isDebugMode() && wantClient && manager.isClientDebugMode()) {\n return \"Already in both server and client debug mode.\";\n }\n return null;\n}\n\nfunction buildActivationMessage(manager: DebugManager, hypothesis?: string): string {\n const modes: string[] = [];\n if (manager.isDebugMode()) modes.push(\"server\");\n if (manager.isClientDebugMode()) modes.push(\"client\");\n const modeStr = modes.join(\" + \");\n\n const sourceMapWarning =\n manager.getPlaywrightClient()?.hasSourceMaps() === false\n ? \"\\n⚠️ Source maps not detected in the client — client breakpoints will reference bundled code.\"\n : \"\";\n\n return hypothesis\n ? `Debug mode activated (${modeStr}). Hypothesis: ${hypothesis}\\nSet breakpoints to test your hypothesis.${sourceMapWarning}`\n : `Debug mode activated (${modeStr}). Set breakpoints to begin debugging.${sourceMapWarning}`;\n}\n\nfunction buildDebugLifecycleTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_enter_mode\",\n \"Activate debug mode. Default: server-only (Node --inspect via CDP). Set clientSide=true (previewUrl required) or both flags for full-stack (adds headless Chromium via Playwright).\",\n {\n hypothesis: z\n .string()\n .optional()\n .describe(\"Your hypothesis about the bug — helps track debugging intent\"),\n serverSide: z\n .boolean()\n .optional()\n .describe(\n \"Enable server-side Node.js debugging (default: true if clientSide is not set)\",\n ),\n clientSide: z\n .boolean()\n .optional()\n .describe(\"Enable client-side browser debugging via headless Chromium + Playwright\"),\n previewUrl: z\n .string()\n .optional()\n .describe(\n \"Preview URL for client-side debugging (e.g., http://localhost:3000). Required when clientSide is true.\",\n ),\n },\n async (params) => {\n try {\n return await handleEnterDebugMode(manager, params);\n } catch (error) {\n return textResult(`Failed to enter debug mode: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_exit_mode\",\n \"Exit debug mode: removes all breakpoints, disconnects the debugger, and restarts the dev server normally.\",\n {},\n async () => {\n try {\n if (!manager.isDebugMode()) {\n return textResult(\"Not in debug mode.\");\n }\n await manager.exitDebugMode();\n return textResult(\"Debug mode deactivated. Dev server restarted normally.\");\n } catch (error) {\n return textResult(`Failed to exit debug mode: ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\nfunction buildBreakpointTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_set_breakpoint\",\n \"Set a breakpoint at the specified file and line number. Optionally provide a condition expression that must evaluate to true for the breakpoint to pause execution.\",\n {\n file: z.string().describe(\"Absolute or relative file path to set the breakpoint in\"),\n line: z.number().describe(\"Line number (1-based) to set the breakpoint on\"),\n condition: z\n .string()\n .optional()\n .describe(\"JavaScript condition expression — breakpoint only triggers when truthy\"),\n },\n async ({ file, line, condition }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const client = clientOrErr;\n const breakpointId = await client.setBreakpoint(file, line, condition);\n const condStr = condition ? ` (condition: ${condition})` : \"\";\n return textResult(\n `Breakpoint set: ${file}:${line}${condStr}\\nBreakpoint ID: ${breakpointId}`,\n );\n } catch (error) {\n return textResult(`Failed to set breakpoint: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_remove_breakpoint\",\n \"Remove a previously set breakpoint by its ID.\",\n {\n breakpointId: z.string().describe(\"The breakpoint ID returned by debug_set_breakpoint\"),\n },\n async ({ breakpointId }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const client = clientOrErr;\n await client.removeBreakpoint(breakpointId);\n return textResult(`Breakpoint ${breakpointId} removed.`);\n } catch (error) {\n return textResult(`Failed to remove breakpoint: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_list_breakpoints\",\n \"List all currently active breakpoints with their file, line, and condition.\",\n {},\n // oxlint-disable-next-line require-await\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const breakpoints = clientOrErr.listBreakpoints();\n if (breakpoints.length === 0) {\n return textResult(\"No breakpoints set.\");\n }\n return textResult(JSON.stringify(breakpoints, null, 2));\n },\n { annotations: { readOnlyHint: true } },\n ),\n ];\n}\n\nfunction buildInspectionTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_inspect_paused\",\n \"When the debugger is paused at a breakpoint, returns the call stack and local variables. Check this after a breakpoint is hit to understand the current execution state.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n const client = clientOrErr;\n\n const queuedHits = manager.drainBreakpointHitQueue();\n\n if (!client.isPaused()) {\n if (queuedHits.length > 0) {\n return textResult(\n `Debugger was paused but has since resumed. Recent breakpoint hits:\\n${JSON.stringify(queuedHits, null, 2)}`,\n );\n }\n return textResult(\n \"Debugger is not currently paused. Set breakpoints and trigger the code path to pause execution.\",\n );\n }\n\n try {\n const callStack = client.getCallStack();\n const topFrame = callStack[0];\n let variables: { name: string; type: string; value: string }[] = [];\n\n if (topFrame) {\n try {\n variables = await client.getScopeVariables(topFrame.callFrameId);\n } catch {\n // Scope inspection can fail for some frames\n }\n }\n\n const result = {\n reason: client.getPausedState()?.reason,\n hitBreakpoints: client.getPausedState()?.hitBreakpoints,\n callStack,\n localVariables: variables,\n };\n\n return textResult(JSON.stringify(result, null, 2));\n } catch (error) {\n return textResult(`Failed to inspect paused state: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n\n defineTool(\n \"debug_evaluate\",\n \"Evaluate a JavaScript expression server-side in the Node process. When paused, runs in the frame's scope (frameIndex selects frame). Side effects execute — prefer read-only.\",\n {\n expression: z.string().describe(\"The JavaScript expression to evaluate\"),\n frameIndex: z\n .number()\n .optional()\n .describe(\"Call stack frame index (0 = top frame). Defaults to the top frame.\"),\n },\n async ({ expression, frameIndex }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const client = clientOrErr;\n let callFrameId: string | undefined;\n\n if (client.isPaused()) {\n const callStack = client.getCallStack();\n const frame = callStack[frameIndex ?? 0];\n callFrameId = frame?.callFrameId;\n }\n\n const result = await client.evaluate(expression, callFrameId);\n return textResult(`(${result.type}) ${result.value}`);\n } catch (error) {\n return textResult(`Evaluation failed: ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\nfunction buildProbeManagementTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_add_probe\",\n \"Add a debug probe at a code location. Captures expression values each time the line executes, without pausing or modifying source. Auto-cleaned on debug exit.\",\n {\n file: z.string().describe(\"File path to probe\"),\n line: z.number().describe(\"Line number (1-based) to probe\"),\n expressions: z\n .array(z.string())\n .describe(\n 'JavaScript expressions to capture when the line executes (e.g., [\"req.params.id\", \"user.role\"])',\n ),\n label: z\n .string()\n .optional()\n .describe(\"Optional label for this probe (defaults to file:line)\"),\n },\n async ({ file, line, expressions, label }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const probeId = await clientOrErr.setLogpoint(file, line, expressions, label);\n const probeLabel = label ?? `${file}:${line}`;\n const exprList = expressions.join(\", \");\n return textResult(\n `Probe \"${probeLabel}\" set at ${file}:${line}\\nCapturing: ${exprList}\\nProbe ID: ${probeId}\\n\\nTrigger the code path, then use debug_get_probe_results to see captured values.`,\n );\n } catch (error) {\n return textResult(`Failed to add probe: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_remove_probe\",\n \"Remove a previously set debug probe by its ID.\",\n {\n probeId: z.string().describe(\"The probe ID returned by debug_add_probe\"),\n },\n async ({ probeId }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n await clientOrErr.removeProbe(probeId);\n return textResult(`Probe ${probeId} removed.`);\n } catch (error) {\n return textResult(`Failed to remove probe: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_list_probes\",\n \"List all active debug probes with their file, line, expressions, and labels.\",\n {},\n // oxlint-disable-next-line require-await\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const probes = clientOrErr.listProbes();\n if (probes.length === 0) {\n return textResult(\"No probes set.\");\n }\n\n const lines = probes.map(\n (p) =>\n `${p.probeId}: \"${p.label}\" at ${p.file}:${p.line} — [${p.expressions.join(\", \")}]`,\n );\n return textResult(lines.join(\"\\n\"));\n },\n { annotations: { readOnlyHint: true } },\n ),\n ];\n}\n\nfunction buildProbeResultTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_get_probe_results\",\n \"Fetch captured probe hit data. Filter by label (wins) or probeId. Returns grouped text with per-probe hit count, timestamps, and captured expression values.\",\n {\n probeId: z\n .string()\n .optional()\n .describe(\"Filter results by probe ID (resolves to its label)\"),\n label: z.string().optional().describe(\"Filter results by probe label\"),\n limit: z\n .number()\n .optional()\n .describe(\"Maximum number of recent hits to return (default: all)\"),\n },\n async ({ probeId, label, limit }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n // Resolve probeId to label if provided\n let filterLabel = label;\n if (probeId && !filterLabel) {\n const probe = clientOrErr.listProbes().find((p) => p.probeId === probeId);\n if (probe) filterLabel = probe.label;\n }\n\n const hits = await clientOrErr.getProbeResults(filterLabel, limit);\n\n if (hits.length === 0) {\n const filterDesc = filterLabel ? ` for \"${filterLabel}\"` : \"\";\n return textResult(\n `No probe hits${filterDesc}. Make sure the probed code path has been triggered.`,\n );\n }\n\n // Format hits for LLM readability\n const formatted = formatProbeHits(hits);\n return textResult(formatted);\n } catch (error) {\n return textResult(`Failed to get probe results: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n ];\n}\n\nfunction formatProbeHits(\n hits: { label: string; data: Record<string, unknown>; timestamp: number }[],\n): string {\n // Group by label\n const grouped = new Map<string, typeof hits>();\n for (const hit of hits) {\n const group = grouped.get(hit.label) ?? [];\n group.push(hit);\n grouped.set(hit.label, group);\n }\n\n const sections: string[] = [];\n for (const [label, labelHits] of grouped) {\n const header = `Probe \"${label}\" — hit ${labelHits.length} time${labelHits.length === 1 ? \"\" : \"s\"}:`;\n const lines = labelHits.map((hit) => {\n const time = new Date(hit.timestamp).toLocaleTimeString(\"en-US\", { hour12: false });\n const entries = Object.entries(hit.data)\n .map(([key, val]) => `${key}=${formatProbeValue(val)}`)\n .join(\", \");\n return ` [${time}] ${entries}`;\n });\n sections.push([header, ...lines].join(\"\\n\"));\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nfunction formatProbeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") {\n return value.length > 100 ? `\"${value.slice(0, 97)}...\"` : `\"${value}\"`;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (Array.isArray(value)) {\n return `Array(${value.length})`;\n }\n if (typeof value === \"object\") {\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length <= 3) {\n const preview = keys\n .map((k) => `${k}: ${formatProbeValue((value as Record<string, unknown>)[k])}`)\n .join(\", \");\n return `{${preview}}`;\n }\n return `Object(${keys.length} keys)`;\n }\n return String(value);\n}\n\nfunction buildExecutionControlTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_continue\",\n \"Resume execution after the debugger has paused at a breakpoint.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n if (!clientOrErr.isPaused()) {\n return textResult(\"Debugger is not paused.\");\n }\n\n try {\n await clientOrErr.resume();\n return textResult(\"Execution resumed.\");\n } catch (error) {\n return textResult(`Failed to resume: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_step_over\",\n \"Step over the current line while paused at a breakpoint. Executes the current line and pauses at the next line in the same function.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n if (!clientOrErr.isPaused()) {\n return textResult(\"Debugger is not paused.\");\n }\n\n try {\n await clientOrErr.stepOver();\n return textResult(\"Stepped over. Use debug_inspect_paused to see current state.\");\n } catch (error) {\n return textResult(`Failed to step over: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_step_into\",\n \"Step into the function call on the current line while paused at a breakpoint. Pauses at the first line inside the called function.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n if (!clientOrErr.isPaused()) {\n return textResult(\"Debugger is not paused.\");\n }\n\n try {\n await clientOrErr.stepInto();\n return textResult(\"Stepped into. Use debug_inspect_paused to see current state.\");\n } catch (error) {\n return textResult(`Failed to step into: ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\nexport function buildDebugTools(manager: DebugManager) {\n return [\n ...buildDebugLifecycleTools(manager),\n ...buildBreakpointTools(manager),\n ...buildProbeManagementTools(manager),\n ...buildProbeResultTools(manager),\n ...buildInspectionTools(manager),\n ...buildExecutionControlTools(manager),\n ...buildTelemetryTools(manager),\n ...buildClientDebugTools(manager),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { DebugManager } from \"../debug/debug-manager.js\";\nimport { textResult } from \"./index.js\";\n\nimport type { CdpDebugClient } from \"../debug/cdp-client.js\";\nimport { queryTelemetry, clearTelemetry, getTelemetryStatus } from \"../debug/telemetry-injector.js\";\n\nfunction requireDebugClient(manager: DebugManager): CdpDebugClient | string {\n if (!manager.isDebugMode()) {\n return \"Debug mode is not active. Use debug_enter_mode first.\";\n }\n const client = manager.getClient();\n if (!client?.isConnected()) {\n return \"CDP client is not connected. Try exiting and re-entering debug mode.\";\n }\n return client;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : \"Unknown error\";\n}\n\nfunction buildGetTelemetryTool(manager: DebugManager) {\n return defineTool(\n \"debug_get_telemetry\",\n \"Query structured telemetry events (HTTP, DB, Socket.IO, errors) captured from the dev server. Returns filtered structured data instead of raw logs.\",\n {\n type: z.enum([\"http\", \"db\", \"socket\", \"error\"]).optional().describe(\"Filter by event type\"),\n urlPattern: z.string().optional().describe(\"Regex pattern to filter HTTP events by URL\"),\n minDuration: z\n .number()\n .optional()\n .describe(\"Minimum duration in ms — only return events slower than this\"),\n errorOnly: z\n .boolean()\n .optional()\n .describe(\"Only return error events and HTTP 4xx/5xx responses\"),\n since: z\n .number()\n .optional()\n .describe(\"Only return events after this timestamp (ms since epoch)\"),\n limit: z.number().optional().describe(\"Max events to return (default: 20, from most recent)\"),\n },\n async ({ type, urlPattern, minDuration, errorOnly, since, limit }) => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const filter = {\n ...(type && { type }),\n ...(urlPattern && { urlPattern }),\n ...(minDuration && { minDuration }),\n ...(errorOnly && { errorOnly }),\n ...(since && { since }),\n };\n const hasFilter = Object.keys(filter).length > 0;\n const events = await queryTelemetry(clientOrErr, hasFilter ? filter : undefined, limit);\n\n if (events.length === 0) {\n return textResult(\"No telemetry events found matching the filter.\");\n }\n\n return textResult(JSON.stringify(events, null, 2));\n } catch (error) {\n return textResult(`Failed to query telemetry: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildClearTelemetryTool(manager: DebugManager) {\n return defineTool(\n \"debug_clear_telemetry\",\n \"Clear all captured telemetry events from the buffer. Useful to reset before reproducing a specific issue.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n await clearTelemetry(clientOrErr);\n return textResult(\"Telemetry buffer cleared.\");\n } catch (error) {\n return textResult(`Failed to clear telemetry: ${formatError(error)}`);\n }\n },\n );\n}\n\nfunction buildTelemetryStatusTool(manager: DebugManager) {\n return defineTool(\n \"debug_telemetry_status\",\n \"Check if telemetry is active, how many events have been captured, and which framework patches (Express, Prisma, Socket.IO) were successfully applied.\",\n {},\n async () => {\n const clientOrErr = requireDebugClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const status = await getTelemetryStatus(clientOrErr);\n return textResult(JSON.stringify(status, null, 2));\n } catch (error) {\n return textResult(`Failed to get telemetry status: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nexport function buildTelemetryTools(manager: DebugManager) {\n return [\n buildGetTelemetryTool(manager),\n buildClearTelemetryTool(manager),\n buildTelemetryStatusTool(manager),\n ];\n}\n","import type { CdpDebugClient } from \"./cdp-client.js\";\nimport type { TelemetryEvent, TelemetryFilter, TelemetryStatus } from \"./telemetry-types.js\";\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\nconst BUFFER_SIZE = 200;\nconst BODY_MAX_BYTES = 1024;\nconst MAX_DEPTH = 3;\n\n// ── Static asset / noise exclusion patterns ───────────────────────────────\n\nconst EXCLUDED_EXTENSIONS = [\n \".js\",\n \".css\",\n \".ico\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".map\",\n \".webp\",\n];\nconst EXCLUDED_PATHS = [\"/_next/\", \"/__nextjs\", \"/favicon\", \"/_healthz\", \"/healthz\", \"/health\"];\nconst EXCLUDED_SOCKET_EVENTS = [\"ping\", \"pong\", \"connection\", \"disconnect\", \"websocket\", \"upgrade\"];\n\n// ── Script Section Builders ──────────────────────────────────────────────\n\nfunction scriptPreamble(): string {\n return `(function() {\n if (globalThis.__conveyorTelemetry) {\n return JSON.stringify({ success: true, alreadyInjected: true, patches: globalThis.__conveyorTelemetry._patches });\n }\n\n var BUFFER_SIZE = ${BUFFER_SIZE};\n var BODY_MAX_BYTES = ${BODY_MAX_BYTES};\n var MAX_DEPTH = ${MAX_DEPTH};\n var excludedExtensions = ${JSON.stringify(EXCLUDED_EXTENSIONS)};\n var excludedPaths = ${JSON.stringify(EXCLUDED_PATHS)};\n var excludedSocketEvents = ${JSON.stringify(EXCLUDED_SOCKET_EVENTS)};`;\n}\n\nfunction scriptHelpers(): string {\n return `\n function truncate(str, max) {\n if (typeof str !== 'string') return '';\n if (str.length <= max) return str;\n return str.slice(0, max) + '...[truncated]';\n }\n\n function safeStringify(obj, depth) {\n if (depth === undefined) depth = MAX_DEPTH;\n try {\n if (obj === null || obj === undefined) return String(obj);\n if (typeof obj === 'string') return obj;\n if (typeof obj !== 'object') return String(obj);\n if (depth <= 0) return '[Object]';\n var seen = new Set();\n return JSON.stringify(obj, function(key, value) {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) return '[Circular]';\n seen.add(value);\n }\n return value;\n }, 0).slice(0, BODY_MAX_BYTES);\n } catch (e) {\n return '[unserializable]';\n }\n }\n\n function isExcludedUrl(url) {\n if (!url) return false;\n var lower = url.toLowerCase();\n for (var i = 0; i < excludedExtensions.length; i++) {\n if (lower.endsWith(excludedExtensions[i])) return true;\n }\n for (var j = 0; j < excludedPaths.length; j++) {\n if (lower.indexOf(excludedPaths[j]) !== -1) return true;\n }\n return false;\n }\n\n function isExcludedSocketEvent(event) {\n return excludedSocketEvents.indexOf(event) !== -1;\n }\n\n function nowMs() { return Date.now(); }`;\n}\n\nfunction scriptBuffer(): string {\n return `\n var buffer = [];\n\n function pushEvent(event) {\n buffer.push(event);\n if (buffer.length > BUFFER_SIZE) { buffer.shift(); }\n }\n\n function getEvents(filter, limit) {\n var result = buffer;\n if (filter) {\n if (filter.type) {\n result = result.filter(function(e) { return e.type === filter.type; });\n }\n if (filter.urlPattern) {\n var re;\n try { re = new RegExp(filter.urlPattern, 'i'); } catch(e) { re = null; }\n if (re) {\n result = result.filter(function(e) { return e.type === 'http' && re.test(e.url); });\n }\n }\n if (filter.minDuration) {\n var minD = filter.minDuration;\n result = result.filter(function(e) { return ('duration' in e) && e.duration >= minD; });\n }\n if (filter.errorOnly) {\n result = result.filter(function(e) {\n return e.type === 'error' || (e.type === 'http' && e.status >= 400);\n });\n }\n if (filter.since) {\n var since = filter.since;\n result = result.filter(function(e) { return e.timestamp >= since; });\n }\n }\n if (limit && limit > 0) { result = result.slice(-limit); }\n return result;\n }\n\n function clear() { buffer = []; }\n\n var patches = { express: false, prisma: false, socketIo: false, errorHandler: false };`;\n}\n\nfunction scriptPatchExpress(): string {\n return `\n function patchExpress() {\n try {\n var http = require('http');\n var originalEmit = http.Server.prototype.emit;\n http.Server.prototype.emit = function(event) {\n if (event === 'request') {\n var req = arguments[1];\n var res = arguments[2];\n if (req && res && !isExcludedUrl(req.url)) {\n var start = nowMs();\n var reqBody = '';\n if (req.readable) {\n var chunks = [];\n var origPush = req.push;\n req.push = function(chunk) {\n if (chunk) { chunks.push(typeof chunk === 'string' ? chunk : chunk.toString()); }\n return origPush.apply(this, arguments);\n };\n var origReqEmit = req.emit;\n req.emit = function(evt) {\n if (evt === 'end') { reqBody = truncate(chunks.join(''), BODY_MAX_BYTES); }\n return origReqEmit.apply(this, arguments);\n };\n }\n var origEnd = res.end;\n res.end = function(chunk) {\n var resBody = '';\n if (chunk) { resBody = truncate(typeof chunk === 'string' ? chunk : chunk.toString(), BODY_MAX_BYTES); }\n var duration = nowMs() - start;\n pushEvent({\n type: 'http', timestamp: start, method: req.method || 'UNKNOWN',\n url: req.url || '/', status: res.statusCode || 0, duration: duration,\n requestBody: reqBody || undefined, responseBody: resBody || undefined,\n error: res.statusCode >= 400 ? ('HTTP ' + res.statusCode) : undefined\n });\n return origEnd.apply(this, arguments);\n };\n }\n }\n return originalEmit.apply(this, arguments);\n };\n patches.express = true;\n } catch (e) {}\n }`;\n}\n\nfunction scriptPatchPrisma(): string {\n return `\n function patchPrisma() {\n try {\n var prismaClient = globalThis.prisma || globalThis.__prisma;\n if (!prismaClient) {\n var cacheKeys = Object.keys(require.cache || {});\n for (var i = 0; i < cacheKeys.length; i++) {\n var mod = require.cache[cacheKeys[i]];\n if (mod && mod.exports && typeof mod.exports.$on === 'function') {\n prismaClient = mod.exports;\n break;\n }\n }\n }\n if (prismaClient && typeof prismaClient.$on === 'function') {\n prismaClient.$on('query', function(e) {\n pushEvent({\n type: 'db', timestamp: nowMs(),\n query: truncate(e.query || '', BODY_MAX_BYTES),\n params: truncate(safeStringify(e.params), BODY_MAX_BYTES),\n duration: e.duration || 0\n });\n });\n patches.prisma = true;\n }\n } catch (e) {}\n }`;\n}\n\nfunction scriptPatchSocketIo(): string {\n return `\n function patchSocketIo() {\n try {\n var io = globalThis.io || globalThis.__io;\n if (io && io.sockets) {\n var origOn = io.sockets.constructor.prototype.on;\n if (origOn) {\n io.sockets.constructor.prototype.on = function(event, handler) {\n if (!isExcludedSocketEvent(event)) {\n var wrappedHandler = function() {\n var args = Array.prototype.slice.call(arguments);\n pushEvent({\n type: 'socket', timestamp: nowMs(), event: event, direction: 'in',\n data: truncate(safeStringify(args[0]), BODY_MAX_BYTES),\n namespace: (this.nsp && this.nsp.name) || '/'\n });\n return handler.apply(this, arguments);\n };\n return origOn.call(this, event, wrappedHandler);\n }\n return origOn.call(this, event, handler);\n };\n }\n var origEmit = io.sockets.constructor.prototype.emit;\n if (origEmit) {\n io.sockets.constructor.prototype.emit = function(event) {\n if (!isExcludedSocketEvent(event)) {\n var args = Array.prototype.slice.call(arguments, 1);\n pushEvent({\n type: 'socket', timestamp: nowMs(), event: event, direction: 'out',\n data: truncate(safeStringify(args[0]), BODY_MAX_BYTES),\n namespace: (this.nsp && this.nsp.name) || '/'\n });\n }\n return origEmit.apply(this, arguments);\n };\n }\n patches.socketIo = true;\n }\n } catch (e) {}\n }`;\n}\n\nfunction scriptPatchErrors(): string {\n return `\n function patchErrorHandler() {\n try {\n process.on('uncaughtException', function(err) {\n pushEvent({\n type: 'error', timestamp: nowMs(),\n message: err.message || String(err),\n stack: truncate(err.stack || '', BODY_MAX_BYTES),\n context: 'uncaughtException'\n });\n });\n process.on('unhandledRejection', function(reason) {\n var msg = (reason && reason.message) ? reason.message : String(reason);\n var stack = (reason && reason.stack) ? reason.stack : '';\n pushEvent({\n type: 'error', timestamp: nowMs(), message: msg,\n stack: truncate(stack, BODY_MAX_BYTES), context: 'unhandledRejection'\n });\n });\n patches.errorHandler = true;\n } catch (e) {}\n }`;\n}\n\nfunction scriptInit(): string {\n return `\n patchExpress();\n patchPrisma();\n patchSocketIo();\n patchErrorHandler();\n\n globalThis.__conveyorTelemetry = {\n getEvents: getEvents,\n clear: clear,\n getStatus: function() {\n return { active: true, eventCount: buffer.length, patches: patches };\n },\n _patches: patches,\n _buffer: buffer\n };\n\n return JSON.stringify({ success: true, alreadyInjected: false, patches: patches });\n})();`;\n}\n\n// ── Public Script Generator ──────────────────────────────────────────────\n\n/**\n * Generates the JavaScript code that will be injected into the running\n * dev server's V8 context via CDP Runtime.evaluate.\n *\n * Creates a global `__conveyorTelemetry` object with:\n * - Circular buffer of recent events\n * - Framework patching (Express, Prisma, Socket.IO)\n * - Query/filter/clear API\n */\nexport function generateTelemetryScript(): string {\n return [\n scriptPreamble(),\n scriptHelpers(),\n scriptBuffer(),\n scriptPatchExpress(),\n scriptPatchPrisma(),\n scriptPatchSocketIo(),\n scriptPatchErrors(),\n scriptInit(),\n ].join(\"\\n\");\n}\n\n// ── Injection via CDP ─────────────────────────────────────────────────────\n\n/**\n * Injects the telemetry runtime into the dev server process via CDP\n * Runtime.evaluate. Non-fatal — if injection fails, telemetry is just\n * unavailable.\n */\nexport async function injectTelemetry(\n cdpClient: CdpDebugClient,\n): Promise<{ success: boolean; patches?: Record<string, boolean>; error?: string }> {\n try {\n const script = generateTelemetryScript();\n const result = await cdpClient.evaluate(script);\n\n if (result.type === \"error\") {\n return { success: false, error: result.value };\n }\n\n // Parse the JSON response from the injection script\n try {\n let parsed = JSON.parse(result.value);\n // CdpDebugClient.evaluate() wraps string values with JSON.stringify,\n // so the result may need a second parse if it came back as a string\n if (typeof parsed === \"string\") parsed = JSON.parse(parsed);\n return {\n success: parsed.success === true,\n patches: parsed.patches,\n };\n } catch {\n // Script returned something unexpected but didn't error\n return { success: true };\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown injection error\",\n };\n }\n}\n\n// ── Query Helpers (used by MCP tools) ─────────────────────────────────────\n\n/**\n * Queries the injected telemetry buffer via CDP Runtime.evaluate.\n */\nexport async function queryTelemetry(\n cdpClient: CdpDebugClient,\n filter?: TelemetryFilter,\n limit?: number,\n): Promise<TelemetryEvent[]> {\n const filterJson = JSON.stringify(filter ?? {});\n const limitVal = limit ?? 20;\n\n const result = await cdpClient.evaluate(\n `JSON.stringify(globalThis.__conveyorTelemetry ? globalThis.__conveyorTelemetry.getEvents(${filterJson}, ${limitVal}) : [])`,\n );\n\n if (result.type === \"error\") {\n throw new Error(`Telemetry query failed: ${result.value}`);\n }\n\n try {\n // The evaluate result value may be JSON-stringified with extra quotes\n let val = result.value;\n // Strip outer quotes if the CDP evaluate returned a string value\n if (val.startsWith('\"') && val.endsWith('\"')) {\n val = JSON.parse(val);\n }\n return JSON.parse(val) as TelemetryEvent[];\n } catch {\n return [];\n }\n}\n\n/**\n * Clears the telemetry buffer via CDP.\n */\nexport async function clearTelemetry(cdpClient: CdpDebugClient): Promise<void> {\n await cdpClient.evaluate(\n `globalThis.__conveyorTelemetry ? (globalThis.__conveyorTelemetry.clear(), 'cleared') : 'not active'`,\n );\n}\n\n/**\n * Gets telemetry status via CDP.\n */\nexport async function getTelemetryStatus(cdpClient: CdpDebugClient): Promise<TelemetryStatus> {\n const result = await cdpClient.evaluate(\n `JSON.stringify(globalThis.__conveyorTelemetry ? globalThis.__conveyorTelemetry.getStatus() : { active: false, eventCount: 0, patches: { express: false, prisma: false, socketIo: false, errorHandler: false } })`,\n );\n\n if (result.type === \"error\") {\n return {\n active: false,\n eventCount: 0,\n patches: { express: false, prisma: false, socketIo: false, errorHandler: false },\n };\n }\n\n try {\n let val = result.value;\n if (val.startsWith('\"') && val.endsWith('\"')) {\n val = JSON.parse(val);\n }\n return JSON.parse(val) as TelemetryStatus;\n } catch {\n return {\n active: false,\n eventCount: 0,\n patches: { express: false, prisma: false, socketIo: false, errorHandler: false },\n };\n }\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { DebugManager } from \"../debug/debug-manager.js\";\nimport type { PlaywrightDebugClient } from \"../debug/playwright-client.js\";\nimport { textResult, imageBlock } from \"./index.js\";\n\nfunction requirePlaywrightClient(manager: DebugManager): PlaywrightDebugClient | string {\n if (!manager.isClientDebugMode()) {\n return \"Client debug mode is not active. Use debug_enter_mode with clientSide: true first.\";\n }\n const client = manager.getPlaywrightClient();\n if (!client?.isConnected()) {\n return \"Playwright client is not connected. Try exiting and re-entering debug mode.\";\n }\n return client;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : \"Unknown error\";\n}\n\n// ── Breakpoint Tools ────────────────────────────────────────────────────\n\nfunction buildClientBreakpointTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_set_client_breakpoint\",\n \"Set a breakpoint in client-side code running in headless Chromium. V8 resolves source maps automatically — use original .tsx/.ts file paths.\",\n {\n file: z\n .string()\n .describe(\n \"Original source file path (e.g., src/components/App.tsx) — source maps resolve automatically\",\n ),\n line: z.number().describe(\"Line number (1-based) in the original source file\"),\n condition: z\n .string()\n .optional()\n .describe(\"JavaScript condition expression — breakpoint only triggers when truthy\"),\n },\n async ({ file, line, condition }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const breakpointId = await clientOrErr.setBreakpoint(file, line, condition);\n const condStr = condition ? ` (condition: ${condition})` : \"\";\n const sourceMapNote =\n clientOrErr.hasSourceMaps() === false\n ? \"\\n⚠️ Source maps not detected — breakpoints will reference bundled code.\"\n : \"\";\n return textResult(\n `Client breakpoint set: ${file}:${line}${condStr}\\nBreakpoint ID: ${breakpointId}${sourceMapNote}`,\n );\n } catch (error) {\n return textResult(`Failed to set client breakpoint: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_remove_client_breakpoint\",\n \"Remove a previously set client-side breakpoint by its ID.\",\n {\n breakpointId: z\n .string()\n .describe(\"The breakpoint ID returned by debug_set_client_breakpoint\"),\n },\n async ({ breakpointId }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n await clientOrErr.removeBreakpoint(breakpointId);\n return textResult(`Client breakpoint ${breakpointId} removed.`);\n } catch (error) {\n return textResult(`Failed to remove client breakpoint: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_list_client_breakpoints\",\n \"List all active client-side breakpoints with their file, line, and condition.\",\n {},\n // oxlint-disable-next-line require-await\n async () => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const breakpoints = clientOrErr.listBreakpoints();\n if (breakpoints.length === 0) {\n return textResult(\"No client breakpoints set.\");\n }\n return textResult(JSON.stringify(breakpoints, null, 2));\n },\n { annotations: { readOnlyHint: true } },\n ),\n ];\n}\n\n// ── Inspection Tools ────────────────────────────────────────────────────\n\nfunction buildClientInspectionTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_inspect_client_paused\",\n \"When the client (browser) debugger is paused, returns call stack and local variables. For server pauses use debug_inspect_paused. Queued hits returned if already resumed.\",\n {},\n async () => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const queuedHits = manager.drainClientBreakpointHitQueue();\n\n if (!clientOrErr.isPaused()) {\n if (queuedHits.length > 0) {\n return textResult(\n `Client debugger was paused but has since resumed. Recent breakpoint hits:\\n${JSON.stringify(queuedHits, null, 2)}`,\n );\n }\n return textResult(\n \"Client debugger is not currently paused. Set client breakpoints and trigger the code path in the browser to pause execution.\",\n );\n }\n\n try {\n const callStack = clientOrErr.getCallStack();\n const topFrame = callStack[0];\n let variables: { name: string; type: string; value: string }[] = [];\n\n if (topFrame) {\n try {\n variables = await clientOrErr.getScopeVariables(topFrame.callFrameId);\n } catch {\n // Scope inspection can fail for some frames\n }\n }\n\n const result = {\n side: \"client\",\n reason: clientOrErr.getPausedState()?.reason,\n hitBreakpoints: clientOrErr.getPausedState()?.hitBreakpoints,\n callStack,\n localVariables: variables,\n };\n\n return textResult(JSON.stringify(result, null, 2));\n } catch (error) {\n return textResult(`Failed to inspect client paused state: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n\n defineTool(\n \"debug_evaluate_client\",\n \"Evaluate a JavaScript expression in the browser context. When paused, runs in the paused frame's scope; otherwise the page's global scope. Side effects execute — prefer read-only.\",\n {\n expression: z.string().describe(\"JavaScript expression to evaluate in the browser context\"),\n frameIndex: z\n .number()\n .optional()\n .describe(\"Call stack frame index (0 = top frame). Defaults to the top frame.\"),\n },\n async ({ expression, frameIndex }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n let callFrameId: string | undefined;\n\n if (clientOrErr.isPaused()) {\n const callStack = clientOrErr.getCallStack();\n const frame = callStack[frameIndex ?? 0];\n callFrameId = frame?.callFrameId;\n }\n\n const result = await clientOrErr.evaluate(expression, callFrameId);\n return textResult(`(${result.type}) ${result.value}`);\n } catch (error) {\n return textResult(`Client evaluation failed: ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\n// ── Execution Control Tools ─────────────────────────────────────────────\n\nfunction buildClientExecutionTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_continue_client\",\n \"Resume client-side execution after the browser debugger has paused at a breakpoint.\",\n {},\n async () => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n if (!clientOrErr.isPaused()) {\n return textResult(\"Client debugger is not paused.\");\n }\n\n try {\n await clientOrErr.resume();\n return textResult(\"Client execution resumed.\");\n } catch (error) {\n return textResult(`Failed to resume client: ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\n// ── Page Interaction Tools ──────────────────────────────────────────────\n\nfunction buildClientInteractionTools(manager: DebugManager) {\n return [\n defineTool(\n \"debug_client_screenshot\",\n \"Take a screenshot of the current page state in the headless browser. Returns the image as base64-encoded PNG.\",\n {},\n async () => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n const base64 = await clientOrErr.screenshot();\n return {\n content: [\n imageBlock(base64, \"image/png\"),\n {\n type: \"text\" as const,\n text: `Screenshot captured (${clientOrErr.getCurrentUrl()})`,\n },\n ],\n };\n } catch (error) {\n return textResult(`Failed to capture screenshot: ${formatError(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n\n defineTool(\n \"debug_navigate_client\",\n \"Navigate the headless browser to a URL. Waits for domcontentloaded (Playwright's default ~30s timeout applies).\",\n {\n url: z.string().describe(\"URL to navigate to (e.g., http://localhost:3000/dashboard)\"),\n },\n async ({ url }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n await clientOrErr.navigate(url);\n return textResult(`Navigated to: ${clientOrErr.getCurrentUrl()}`);\n } catch (error) {\n return textResult(`Failed to navigate: ${formatError(error)}`);\n }\n },\n ),\n\n defineTool(\n \"debug_click_client\",\n \"Click an element in the headless browser by CSS selector. Playwright auto-waits for visibility/stability/enabled up to 10s — a miss throws with a failure message.\",\n {\n selector: z\n .string()\n .describe(\n \"CSS selector of the element to click (e.g., 'button.submit', '#login-form input[type=submit]')\",\n ),\n },\n async ({ selector }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n try {\n await clientOrErr.click(selector);\n return textResult(`Clicked: ${selector}`);\n } catch (error) {\n return textResult(`Failed to click \"${selector}\": ${formatError(error)}`);\n }\n },\n ),\n ];\n}\n\n// ── Passive Capture Tools ───────────────────────────────────────────────\n\nfunction buildClientConsoleTool(manager: DebugManager) {\n return defineTool(\n \"debug_get_client_console\",\n \"Get console messages captured from the headless browser. Includes console.log, warn, error, etc.\",\n {\n level: z\n .string()\n .optional()\n .describe(\"Filter by console level: log, warn, error, info, debug\"),\n limit: z\n .number()\n .optional()\n .describe(\"Maximum number of recent messages to return (default: all)\"),\n },\n // oxlint-disable-next-line require-await\n async ({ level, limit }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const messages = clientOrErr.getConsoleMessages(level, limit);\n if (messages.length === 0) {\n const filterDesc = level ? ` (level: ${level})` : \"\";\n return textResult(`No console messages captured${filterDesc}.`);\n }\n\n const formatted = messages\n .map((m) => {\n const time = new Date(m.timestamp).toLocaleTimeString(\"en-US\", { hour12: false });\n const loc = m.url ? ` [${m.url}${m.line ? `:${m.line}` : \"\"}]` : \"\";\n return `[${time}] ${m.level.toUpperCase()}: ${m.text}${loc}`;\n })\n .join(\"\\n\");\n\n return textResult(`${messages.length} console message(s):\\n${formatted}`);\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildClientNetworkTool(manager: DebugManager) {\n return defineTool(\n \"debug_get_client_network\",\n \"Get network requests captured from the headless browser. Shows URLs, methods, status codes, and timing.\",\n {\n filter: z.string().optional().describe(\"Regex pattern to filter requests by URL\"),\n limit: z\n .number()\n .optional()\n .describe(\"Maximum number of recent requests to return (default: all)\"),\n },\n // oxlint-disable-next-line require-await\n async ({ filter, limit }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const requests = clientOrErr.getNetworkRequests(filter, limit);\n if (requests.length === 0) {\n const filterDesc = filter ? ` matching \"${filter}\"` : \"\";\n return textResult(`No network requests captured${filterDesc}.`);\n }\n\n const formatted = requests\n .map((r) => {\n const time = new Date(r.timestamp).toLocaleTimeString(\"en-US\", { hour12: false });\n const status = r.status ? ` → ${r.status}` : \" → (pending)\";\n const dur = r.duration ? ` (${r.duration}ms)` : \"\";\n return `[${time}] ${r.method} ${r.url}${status}${dur}`;\n })\n .join(\"\\n\");\n\n return textResult(`${requests.length} network request(s):\\n${formatted}`);\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildClientErrorsTool(manager: DebugManager) {\n return defineTool(\n \"debug_get_client_errors\",\n \"Get uncaught errors captured from the headless browser. Includes error messages and source-mapped stack traces.\",\n {\n limit: z\n .number()\n .optional()\n .describe(\"Maximum number of recent errors to return (default: all)\"),\n },\n // oxlint-disable-next-line require-await\n async ({ limit }) => {\n const clientOrErr = requirePlaywrightClient(manager);\n if (typeof clientOrErr === \"string\") return textResult(clientOrErr);\n\n const errors = clientOrErr.getPageErrors(limit);\n if (errors.length === 0) {\n return textResult(\"No uncaught page errors captured.\");\n }\n\n const formatted = errors\n .map((e) => {\n const time = new Date(e.timestamp).toLocaleTimeString(\"en-US\", { hour12: false });\n const stack = e.stack ? `\\n ${e.stack.split(\"\\n\").slice(0, 5).join(\"\\n \")}` : \"\";\n return `[${time}] ${e.message}${stack}`;\n })\n .join(\"\\n\\n\");\n\n return textResult(`${errors.length} page error(s):\\n${formatted}`);\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildClientCaptureTools(manager: DebugManager) {\n return [\n buildClientConsoleTool(manager),\n buildClientNetworkTool(manager),\n buildClientErrorsTool(manager),\n ];\n}\n\n// ── Export ───────────────────────────────────────────────────────────────\n\nexport function buildClientDebugTools(manager: DebugManager) {\n return [\n ...buildClientBreakpointTools(manager),\n ...buildClientInspectionTools(manager),\n ...buildClientExecutionTools(manager),\n ...buildClientInteractionTools(manager),\n ...buildClientCaptureTools(manager),\n ];\n}\n","import type { AgentHarness, HarnessToolDefinition } from \"../harness/index.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport type { AgentMode, TaskContext } from \"@project/shared\";\nimport { buildCommonTools, buildForceUpdateTaskStatusTool } from \"./common-tools.js\";\nimport { buildPmTools, buildUpdateTaskTool } from \"./pm-tools.js\";\nimport { buildDiscoveryTools } from \"./discovery-tools.js\";\nimport { buildCodeReviewTools } from \"./code-review-tools.js\";\nimport { buildDebugTools } from \"./debug-tools.js\";\nimport type { DebugManager } from \"../debug/debug-manager.js\";\n\n// Re-export helpers\nexport { textResult, imageBlock } from \"./helpers.js\";\n\n// ── Mode-based tool selection ─────────────────────────────────────────\n\nfunction getTaskModeTools(agentMode: AgentMode | undefined, connection: AgentConnection) {\n if (agentMode === \"discovery\" || agentMode === \"auto\") {\n return [buildUpdateTaskTool(connection)];\n }\n return [];\n}\n\nfunction getModeTools(\n agentMode: AgentMode | undefined,\n connection: AgentConnection,\n config: AgentRunnerConfig,\n context?: TaskContext,\n) {\n if (config.mode === \"task\") return getTaskModeTools(agentMode, connection);\n\n switch (agentMode) {\n case \"building\":\n return context?.isParentTask ? buildPmTools(connection, { includePackTools: true }) : [];\n case \"review\":\n case \"auto\":\n case \"discovery\":\n case \"help\":\n return buildPmTools(connection, {\n includePackTools: !!context?.isParentTask,\n });\n default:\n return config.mode === \"pm\" ? buildPmTools(connection, { includePackTools: false }) : [];\n }\n}\n\n// ── Tool assembly ─────────────────────────────────────────────────────\n\n/** Collect all tools for the current mode as harness-neutral definitions. */\nexport function buildConveyorTools(\n connection: AgentConnection,\n config: AgentRunnerConfig,\n context?: TaskContext,\n agentMode?: AgentMode,\n debugManager?: DebugManager,\n): HarnessToolDefinition[] {\n const effectiveMode = agentMode ?? context?.agentMode ?? undefined;\n\n const commonTools = buildCommonTools(connection, config);\n const modeTools = getModeTools(effectiveMode, connection, config, context);\n\n const discoveryTools =\n effectiveMode === \"discovery\" || effectiveMode === \"auto\"\n ? buildDiscoveryTools(connection)\n : [];\n\n // Code review tools available in review mode\n const codeReviewTools = effectiveMode === \"review\" ? buildCodeReviewTools(connection) : [];\n\n const emergencyTools = [buildForceUpdateTaskStatusTool(connection)];\n\n // Debug tools only available in building mode\n const debugTools =\n debugManager && effectiveMode === \"building\" ? buildDebugTools(debugManager) : [];\n\n return [\n ...commonTools,\n ...modeTools,\n ...discoveryTools,\n ...codeReviewTools,\n ...emergencyTools,\n ...debugTools,\n ];\n}\n\n// ── MCP server factory ────────────────────────────────────────────────\n\n// oxlint-disable-next-line typescript/explicit-function-return-type\nexport function createConveyorMcpServer(\n harness: AgentHarness,\n connection: AgentConnection,\n config: AgentRunnerConfig,\n context?: TaskContext,\n agentMode?: AgentMode,\n debugManager?: DebugManager,\n) {\n return harness.createMcpServer({\n name: \"conveyor\",\n tools: buildConveyorTools(connection, config, context, agentMode, debugManager),\n });\n}\n","import type {\n HarnessAssistantEvent,\n HarnessResultEvent,\n HarnessResultSuccessEvent,\n HarnessResultErrorEvent,\n HarnessSystemInitEvent,\n HarnessCompactBoundaryEvent,\n HarnessTaskStartedEvent,\n HarnessTaskProgressEvent,\n HarnessRateLimitEvent,\n} from \"../harness/index.js\";\nimport type { TaskContext, ActivityEventSummary } from \"@project/shared\";\nimport type { QueryHost } from \"./query-executor.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"event-handlers\");\n\nfunction safeVoid(promise: void | Promise<unknown>, context: string): void {\n if (promise && typeof (promise as Promise<unknown>).catch === \"function\") {\n (promise as Promise<unknown>).catch((err) => {\n process.stderr.write(`[safeVoid] ${context}: ${err}\\n`);\n });\n }\n}\n\nexport type UsageInfo = {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n};\n\n/** Convert a resetsAt value (epoch seconds, epoch ms, or ISO string) to an ISO string. */\nfunction epochSecondsToISO(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n if (typeof value !== \"number\" || value <= 0) return undefined;\n // Heuristic: epoch seconds for dates after 2000 are < 1e12; milliseconds are >= 1e12\n const ms = value < 1e12 ? value * 1000 : value;\n return new Date(ms).toISOString();\n}\n\nexport async function processAssistantEvent(\n event: HarnessAssistantEvent,\n host: QueryHost,\n turnToolCalls: ActivityEventSummary[],\n): Promise<void> {\n const { content } = event.message;\n const turnTextParts: string[] = [];\n\n for (const block of content) {\n if (block.type === \"text\" && block.text) {\n turnTextParts.push(block.text);\n host.connection.sendEvent({ type: \"message\", content: block.text });\n await host.callbacks.onEvent({ type: \"message\", content: block.text });\n } else if (block.type === \"tool_use\" && block.name) {\n const inputStr = typeof block.input === \"string\" ? block.input : JSON.stringify(block.input);\n const isContentTool = [\"edit\", \"write\"].includes(block.name.toLowerCase());\n const inputLimit = isContentTool ? 10_000 : 500;\n const summary: ActivityEventSummary = {\n tool: block.name,\n input: inputStr.slice(0, inputLimit),\n timestamp: new Date().toISOString(),\n };\n turnToolCalls.push(summary);\n host.connection.sendEvent({ type: \"tool_use\", tool: block.name, input: inputStr });\n await host.callbacks.onEvent({ type: \"tool_use\", tool: block.name, input: inputStr });\n }\n }\n}\n\nexport const API_ERROR_PATTERN = /API Error: (?:[45]\\d\\d|terminated)/;\nconst IMAGE_ERROR_PATTERN = /Could not process image/i;\nconst AUTH_ERROR_PATTERN =\n /Not logged in|Please run \\/login|authentication failed|invalid.*token|unauthorized/i;\n\nexport function isAuthError(msg: string): boolean {\n return AUTH_ERROR_PATTERN.test(msg);\n}\n\nfunction isRetriableMessage(msg: string): boolean {\n if (IMAGE_ERROR_PATTERN.test(msg)) return true;\n if (API_ERROR_PATTERN.test(msg)) return true;\n return false;\n}\n\nfunction aggregateModelUsage(modelUsage: Record<string, unknown>): {\n queryInputTokens: number;\n contextWindow: number;\n totalInputTokens: number;\n totalCacheRead: number;\n totalCacheCreation: number;\n} {\n let queryInputTokens = 0;\n let contextWindow = 0;\n let totalInputTokens = 0;\n let totalCacheRead = 0;\n let totalCacheCreation = 0;\n for (const data of Object.values(modelUsage)) {\n const d = data as {\n inputTokens?: number;\n cacheReadInputTokens?: number;\n cacheCreationInputTokens?: number;\n };\n const input = d.inputTokens ?? 0;\n const cacheRead = d.cacheReadInputTokens ?? 0;\n const cacheCreation = d.cacheCreationInputTokens ?? 0;\n totalInputTokens += input;\n totalCacheRead += cacheRead;\n totalCacheCreation += cacheCreation;\n queryInputTokens += input + cacheRead + cacheCreation;\n const cw = (data as { contextWindow?: number }).contextWindow ?? 0;\n if (cw > contextWindow) contextWindow = cw;\n }\n return { queryInputTokens, contextWindow, totalInputTokens, totalCacheRead, totalCacheCreation };\n}\n\nfunction emitContextUpdate(\n modelUsage: Record<string, unknown>,\n host: QueryHost,\n context: TaskContext,\n lastAssistantUsage?: UsageInfo,\n): void {\n const usage = aggregateModelUsage(modelUsage);\n let { contextWindow } = usage;\n\n // Override contextWindow when 1M beta is enabled but SDK reports ≤200K\n const settings = context.agentSettings ?? host.config.agentSettings ?? {};\n const has1mBeta = (settings.betas as string[] | undefined)?.includes(\"context-1m-2025-08-07\");\n if (has1mBeta && contextWindow > 0 && contextWindow <= 200_000) {\n contextWindow = 1_000_000;\n }\n\n if (contextWindow > 0) {\n // Current context fill = last API call's input tokens (per-call, not cumulative)\n const currentContextTokens = lastAssistantUsage\n ? (lastAssistantUsage.input_tokens ?? 0) +\n (lastAssistantUsage.cache_read_input_tokens ?? 0) +\n (lastAssistantUsage.cache_creation_input_tokens ?? 0)\n : usage.queryInputTokens;\n\n host.connection.sendEvent({\n type: \"context_update\",\n contextTokens: currentContextTokens,\n contextWindow,\n inputTokens: usage.totalInputTokens,\n cacheReadInputTokens: usage.totalCacheRead,\n cacheCreationInputTokens: usage.totalCacheCreation,\n totalTokensUsed: usage.queryInputTokens,\n });\n }\n}\n\nfunction trackCostSpending(host: QueryHost, context: TaskContext, cumulativeTotal: number): void {\n if (cumulativeTotal > 0 && context.agentId && context._runnerSessionId) {\n const breakdown = host.costTracker.modelBreakdown;\n host.connection.trackSpending({\n agentId: context.agentId,\n sessionId: context._runnerSessionId,\n totalCostUsd: cumulativeTotal,\n onSubscription: host.config.mode === \"pm\" || !!process.env.CLAUDE_CODE_OAUTH_TOKEN,\n modelUsage: breakdown.length > 0 ? breakdown : undefined,\n });\n }\n}\n\nfunction handleSuccessResult(\n event: HarnessResultSuccessEvent,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n lastAssistantUsage?: UsageInfo,\n): { totalCostUsd: number; retriable: boolean } {\n const durationMs = Date.now() - startTime;\n const summary = event.result || \"Task completed.\";\n const retriable = isRetriableMessage(summary);\n\n const cumulativeTotal = host.costTracker.addQueryCost(event.total_cost_usd);\n\n const { modelUsage } = event;\n if (modelUsage && typeof modelUsage === \"object\") {\n host.costTracker.addModelUsage(\n modelUsage as Parameters<typeof host.costTracker.addModelUsage>[0],\n );\n }\n\n host.connection.sendEvent({ type: \"completed\", summary, costUsd: cumulativeTotal, durationMs });\n\n if (modelUsage && typeof modelUsage === \"object\") {\n emitContextUpdate(modelUsage as Record<string, unknown>, host, context, lastAssistantUsage);\n }\n\n trackCostSpending(host, context, cumulativeTotal);\n\n return { totalCostUsd: cumulativeTotal, retriable };\n}\n\nfunction handleErrorResult(\n event: HarnessResultErrorEvent,\n host: QueryHost,\n): { retriable: boolean; staleSession?: boolean; authError?: boolean } {\n const errorMsg =\n event.errors.length > 0 ? event.errors.join(\", \") : `Agent stopped: ${event.subtype}`;\n\n // Check for stale session error pattern\n const isStaleSession = errorMsg.includes(\"No conversation found with session ID\");\n\n if (isStaleSession) {\n // Suppress the error event for stale session - this will be handled by session recovery\n return { retriable: false, staleSession: true };\n }\n\n // Check for auth error pattern — will be handled by auth recovery\n if (isAuthError(errorMsg)) {\n host.connection.sendEvent({ type: \"error\", message: errorMsg });\n return { retriable: false, authError: true };\n }\n\n const retriable = isRetriableMessage(errorMsg);\n host.connection.sendEvent({ type: \"error\", message: errorMsg });\n return { retriable };\n}\n\nfunction handleResultEvent(\n event: HarnessResultEvent,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n lastAssistantUsage?: UsageInfo,\n): {\n totalCostUsd: number;\n retriable: boolean;\n resultSummary?: string;\n staleSession?: boolean;\n authError?: boolean;\n} {\n const resultSummary =\n event.subtype === \"success\"\n ? (event as HarnessResultSuccessEvent).result\n : (event as HarnessResultErrorEvent).errors.join(\", \");\n\n if (event.subtype === \"success\") {\n const result = handleSuccessResult(\n event as HarnessResultSuccessEvent,\n host,\n context,\n startTime,\n lastAssistantUsage,\n );\n return { ...result, resultSummary };\n }\n\n const result = handleErrorResult(event as HarnessResultErrorEvent, host);\n return { totalCostUsd: 0, ...result, resultSummary };\n}\n\nexport async function emitResultEvent(\n event: HarnessResultEvent,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n lastAssistantUsage?: UsageInfo,\n): Promise<{\n retriable: boolean;\n resultSummary?: string;\n staleSession?: boolean;\n authError?: boolean;\n}> {\n const result = handleResultEvent(event, host, context, startTime, lastAssistantUsage);\n const durationMs = Date.now() - startTime;\n\n if (event.subtype === \"success\") {\n const successEvent = event as HarnessResultSuccessEvent;\n const summary = successEvent.result || \"Task completed.\";\n await host.callbacks.onEvent({\n type: \"completed\",\n summary,\n costUsd: result.totalCostUsd,\n durationMs,\n });\n } else if (!result.staleSession) {\n // Only emit error event if it's not a stale session (which is handled by recovery logic)\n const errorEvent = event as HarnessResultErrorEvent;\n const errorMsg =\n errorEvent.errors.length > 0\n ? errorEvent.errors.join(\", \")\n : `Agent stopped: ${errorEvent.subtype}`;\n await host.callbacks.onEvent({ type: \"error\", message: errorMsg });\n }\n\n return {\n retriable: result.retriable,\n resultSummary: result.resultSummary,\n staleSession: result.staleSession,\n authError: result.authError,\n };\n}\n\nexport function handleRateLimitEvent(\n event: HarnessRateLimitEvent,\n host: QueryHost,\n): string | undefined {\n const { rate_limit_info } = event;\n logger.info(\"Rate limit event received\", { rate_limit_info });\n const status = rate_limit_info.status;\n\n // Send structured rate limit update for persistence\n // On rejection without explicit utilization, default to 1.0 (fully consumed)\n const utilization = rate_limit_info.utilization ?? (status === \"rejected\" ? 1.0 : undefined);\n if (utilization !== undefined && rate_limit_info.rateLimitType) {\n host.connection.sendEvent({\n type: \"rate_limit_update\",\n rateLimitType: rate_limit_info.rateLimitType,\n utilization,\n status,\n });\n }\n\n if (status === \"rejected\") {\n const resetsAt = epochSecondsToISO(rate_limit_info.resetsAt);\n const resetsAtDisplay = resetsAt ?? \"unknown\";\n const message = `Rate limit rejected (type: ${rate_limit_info.rateLimitType ?? \"unknown\"}, resets at: ${resetsAtDisplay})`;\n host.connection.sendEvent({ type: \"error\", message });\n safeVoid(host.callbacks.onEvent({ type: \"error\", message }), \"rateLimitRejected\");\n return resetsAt;\n } else if (status === \"allowed_warning\") {\n const utilizationLabel = rate_limit_info.utilization\n ? `${Math.round(rate_limit_info.utilization * 100)}%`\n : \"high\";\n const message = `Rate limit warning: ${utilizationLabel} utilization (type: ${rate_limit_info.rateLimitType ?? \"unknown\"})`;\n host.connection.sendEvent({ type: \"thinking\", message });\n safeVoid(host.callbacks.onEvent({ type: \"thinking\", message }), \"rateLimitWarning\");\n }\n return undefined;\n}\n\nexport async function handleSystemEvent(\n event: HarnessSystemInitEvent,\n host: QueryHost,\n context: TaskContext,\n sessionIdStored: boolean,\n): Promise<boolean> {\n if (event.subtype !== \"init\") return false;\n if (event.session_id && !sessionIdStored) {\n host.connection.storeSessionId(event.session_id);\n context.claudeSessionId = event.session_id;\n }\n await host.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${event.model})`,\n });\n return !!(event.session_id && !sessionIdStored);\n}\n\nexport function handleSystemSubevents(\n systemEvent: HarnessCompactBoundaryEvent | HarnessTaskStartedEvent | HarnessTaskProgressEvent,\n host: QueryHost,\n): void {\n if (systemEvent.subtype === \"compact_boundary\") {\n safeVoid(\n host.callbacks.onEvent({\n type: \"context_compacted\",\n trigger: systemEvent.compact_metadata.trigger,\n preTokens: systemEvent.compact_metadata.pre_tokens,\n }),\n \"compactBoundary\",\n );\n } else if (systemEvent.subtype === \"task_started\") {\n safeVoid(\n host.callbacks.onEvent({\n type: \"subagent_started\",\n sdkTaskId: systemEvent.task_id,\n description: systemEvent.description,\n }),\n \"taskStarted\",\n );\n } else if (systemEvent.subtype === \"task_progress\") {\n safeVoid(\n host.callbacks.onEvent({\n type: \"subagent_progress\",\n sdkTaskId: systemEvent.task_id,\n description: systemEvent.description,\n toolUses: systemEvent.usage?.tool_uses ?? 0,\n durationMs: systemEvent.usage?.duration_ms ?? 0,\n }),\n \"taskProgress\",\n );\n }\n}\n\nexport function handleToolProgressEvent(event: unknown, host: QueryHost): void {\n const msg = event as { tool_name?: string; elapsed_time_seconds?: number };\n safeVoid(\n host.callbacks.onEvent({\n type: \"tool_progress\",\n toolName: msg.tool_name ?? \"\",\n elapsedSeconds: msg.elapsed_time_seconds ?? 0,\n }),\n \"toolProgress\",\n );\n}\n\nexport async function handleAssistantCase(\n event: HarnessAssistantEvent,\n host: QueryHost,\n turnToolCalls: ActivityEventSummary[],\n): Promise<UsageInfo | undefined> {\n await processAssistantEvent(event, host, turnToolCalls);\n const msgUsage = (event.message as { usage?: UsageInfo }).usage;\n return msgUsage ?? undefined;\n}\n\nexport async function handleResultCase(\n event: HarnessResultEvent,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n isTyping: boolean,\n lastAssistantUsage: UsageInfo | undefined,\n): Promise<{\n retriable: boolean;\n resultSummary?: string;\n staleSession?: boolean;\n authError?: boolean;\n stoppedTyping: boolean;\n}> {\n let stoppedTyping = false;\n if (isTyping) {\n host.connection.sendTypingStop();\n stoppedTyping = true;\n }\n const resultInfo = await emitResultEvent(event, host, context, startTime, lastAssistantUsage);\n return {\n retriable: resultInfo.retriable,\n resultSummary: resultInfo.resultSummary,\n staleSession: resultInfo.staleSession,\n authError: resultInfo.authError,\n stoppedTyping,\n };\n}\n","import type {\n HarnessEvent,\n HarnessAssistantEvent,\n HarnessResultEvent,\n HarnessSystemInitEvent,\n HarnessCompactBoundaryEvent,\n HarnessTaskStartedEvent,\n HarnessTaskProgressEvent,\n HarnessRateLimitEvent,\n} from \"../harness/index.js\";\nimport type { TaskContext, ActivityEventSummary } from \"@project/shared\";\nimport type { QueryHost } from \"./query-executor.js\";\nimport type { UsageInfo } from \"./event-handlers.js\";\nimport {\n API_ERROR_PATTERN,\n handleAssistantCase,\n handleResultCase,\n handleRateLimitEvent,\n handleSystemEvent,\n handleSystemSubevents,\n handleToolProgressEvent,\n} from \"./event-handlers.js\";\n\n/** Mutable state bag threaded through the event loop. */\ninterface EventLoopState {\n sessionIdStored: boolean;\n isTyping: boolean;\n retriable: boolean;\n sawApiError: boolean;\n resultSummary: string | undefined;\n rateLimitResetsAt: string | undefined;\n staleSession: boolean | undefined;\n authError: boolean | undefined;\n lastAssistantUsage: UsageInfo | undefined;\n turnToolCalls: ActivityEventSummary[];\n}\n\nfunction stopTypingIfNeeded(host: QueryHost, isTyping: boolean): void {\n if (isTyping) host.connection.sendTypingStop();\n}\n\n/** Merge pending tool outputs into accumulated tool call summaries and emit turn_end. */\nfunction flushPendingToolCalls(host: QueryHost, turnToolCalls: ActivityEventSummary[]): void {\n if (turnToolCalls.length === 0) {\n // Clear any orphaned outputs that arrived without matching tool_use blocks\n host.pendingToolOutputs.length = 0;\n return;\n }\n // Match outputs to tool calls by tool name (handles duplicate names via queue)\n const outputsByTool = new Map<string, string[]>();\n for (const entry of host.pendingToolOutputs) {\n const list = outputsByTool.get(entry.tool) ?? [];\n list.push(entry.output);\n outputsByTool.set(entry.tool, list);\n }\n for (const call of turnToolCalls) {\n const list = outputsByTool.get(call.tool);\n if (list && list.length > 0) {\n call.output = list.shift();\n }\n }\n host.connection.sendEvent({ type: \"turn_end\", toolCalls: [...turnToolCalls] });\n turnToolCalls.length = 0;\n host.pendingToolOutputs.length = 0;\n}\n\nasync function processSystemCase(\n event:\n | HarnessSystemInitEvent\n | HarnessCompactBoundaryEvent\n | HarnessTaskStartedEvent\n | HarnessTaskProgressEvent,\n host: QueryHost,\n context: TaskContext,\n state: EventLoopState,\n): Promise<void> {\n if (event.subtype === \"init\") {\n const stored = await handleSystemEvent(event, host, context, state.sessionIdStored);\n if (stored) state.sessionIdStored = true;\n } else {\n handleSystemSubevents(\n event as HarnessCompactBoundaryEvent | HarnessTaskStartedEvent | HarnessTaskProgressEvent,\n host,\n );\n }\n}\n\nasync function processAssistantCase(\n event: HarnessAssistantEvent,\n host: QueryHost,\n state: EventLoopState,\n): Promise<void> {\n if (!state.isTyping) {\n setTimeout(() => host.connection.sendTypingStart(), 200);\n state.isTyping = true;\n }\n const usage = await handleAssistantCase(event, host, state.turnToolCalls);\n if (usage) state.lastAssistantUsage = usage;\n\n // Check for API error patterns in assistant message text.\n // The SDK may emit API errors as assistant message content before ending\n // with a clean success result, which would bypass the result-level retry check.\n if (!state.sawApiError) {\n const fullText = event.message.content\n .filter((b: { type: string }) => b.type === \"text\")\n .map((b: { type: string; text?: string }) => (b as { text: string }).text)\n .join(\" \");\n if (API_ERROR_PATTERN.test(fullText)) {\n state.sawApiError = true;\n }\n }\n}\n\nasync function processResultCase(\n event: HarnessResultEvent,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n state: EventLoopState,\n): Promise<void> {\n const info = await handleResultCase(\n event,\n host,\n context,\n startTime,\n state.isTyping,\n state.lastAssistantUsage,\n );\n if (info.stoppedTyping) state.isTyping = false;\n state.retriable = info.retriable;\n // If the result itself is clean (not retriable), any API error the agent\n // mentioned in assistant text was already recovered from — don't retry.\n if (!info.retriable) state.sawApiError = false;\n state.resultSummary = info.resultSummary;\n if (info.staleSession) state.staleSession = true;\n if (info.authError) state.authError = true;\n}\n\nexport async function processEvents(\n events: AsyncGenerator<HarnessEvent, void>,\n context: TaskContext,\n host: QueryHost,\n): Promise<{\n retriable: boolean;\n resultSummary?: string;\n modeRestart?: boolean;\n rateLimitResetsAt?: string;\n staleSession?: boolean;\n authError?: boolean;\n}> {\n const startTime = Date.now();\n let lastStatusEmit = Date.now();\n const STATUS_REEMIT_INTERVAL_MS = 5_000;\n\n const state: EventLoopState = {\n sessionIdStored: false,\n isTyping: false,\n retriable: false,\n sawApiError: false,\n resultSummary: undefined,\n rateLimitResetsAt: undefined,\n staleSession: undefined,\n authError: undefined,\n lastAssistantUsage: undefined,\n turnToolCalls: [],\n };\n\n for await (const event of events) {\n if (host.isStopped()) break;\n\n // Flush any pending tool calls from the previous assistant turn\n // (tool outputs have been collected by PostToolUse hooks between events)\n flushPendingToolCalls(host, state.turnToolCalls);\n\n // Re-emit \"running\" periodically so missed status events self-correct\n const now = Date.now();\n if (now - lastStatusEmit >= STATUS_REEMIT_INTERVAL_MS) {\n host.connection.emitStatus(\"running\");\n lastStatusEmit = now;\n }\n\n if (host.pendingModeRestart) {\n stopTypingIfNeeded(host, state.isTyping);\n return { retriable: false, modeRestart: true };\n }\n\n switch (event.type) {\n case \"system\":\n await processSystemCase(event as HarnessSystemInitEvent, host, context, state);\n break;\n case \"assistant\":\n await processAssistantCase(event as HarnessAssistantEvent, host, state);\n break;\n case \"result\":\n await processResultCase(event as HarnessResultEvent, host, context, startTime, state);\n break;\n case \"rate_limit_event\": {\n const resetsAt = handleRateLimitEvent(event as HarnessRateLimitEvent, host);\n if (resetsAt) state.rateLimitResetsAt = resetsAt;\n break;\n }\n case \"tool_progress\":\n handleToolProgressEvent(event, host);\n break;\n }\n }\n\n flushPendingToolCalls(host, state.turnToolCalls);\n stopTypingIfNeeded(host, state.isTyping);\n\n return {\n retriable: state.retriable || state.sawApiError,\n resultSummary: state.resultSummary,\n rateLimitResetsAt: state.rateLimitResetsAt,\n ...(state.staleSession && { staleSession: state.staleSession }),\n ...(state.authError && { authError: state.authError }),\n };\n}\n","/**\n * Shared utility for checking missing task properties.\n * Used by both ExitPlanMode validation and post-PR backfill nudge.\n */\n\nexport function collectMissingProps(taskProps: {\n plan?: string | null;\n storyPointId?: string | null;\n title?: string | null;\n}): string[] {\n const missing: string[] = [];\n if (!taskProps.plan?.trim()) missing.push(\"plan (save via update_task_plan)\");\n if (!taskProps.storyPointId) missing.push(\"story points (use update_task_properties)\");\n if (!taskProps.title || taskProps.title === \"Untitled\")\n missing.push(\"title (use update_task_properties)\");\n return missing;\n}\n","import type { QueryHost } from \"./query-executor.js\";\nimport { collectMissingProps } from \"./task-property-utils.js\";\nimport type { ExplorationTracker, StalenessSignal } from \"./exploration-tracker.js\";\n\nconst PM_PLAN_FILE_TOOLS = new Set([\"Write\", \"Edit\", \"MultiEdit\"]);\n\nconst DESTRUCTIVE_PATTERNS: { name: string; re: RegExp }[] = [\n {\n name: \"git push --force (without --force-with-lease)\",\n re: /git\\s+push\\s+(?:-f\\b|--force(?!-with-lease))/,\n },\n { name: \"git push --delete\", re: /git\\s+push\\s+(?:-d\\b|--delete\\b)/ },\n { name: \"git reset --hard\", re: /git\\s+reset\\s+--hard\\b/ },\n {\n name: \"rm -rf /\",\n re: /rm\\s+(?:-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r|--recursive\\s+--force)\\s+\\/(?!\\S)/,\n },\n { name: \"sudo rm\", re: /\\bsudo\\s+rm\\b/ },\n { name: \"chmod world-writable\", re: /\\bchmod\\s+(?:-R\\s+)?[0-7]*7{2,3}\\b/ },\n { name: \"dd to device\", re: /\\bdd\\s+.*\\bof=\\/dev\\// },\n { name: \"redirect to block device\", re: />\\s*\\/dev\\/(?:sd[a-z]|nvme\\d|xvd[a-z])/ },\n { name: \"mkfs filesystem creation\", re: /\\bmkfs(?:\\.|\\s)/ },\n { name: \"shutdown/poweroff/halt/reboot\", re: /\\b(?:shutdown|poweroff|halt|reboot)\\b/ },\n { name: \"fork bomb\", re: /:\\(\\)\\s*\\{\\s*:\\|\\s*:&\\s*\\}\\s*;\\s*:/ },\n];\n\nfunction matchesDestructive(cmd: string): string | null {\n for (const { name, re } of DESTRUCTIVE_PATTERNS) {\n if (re.test(cmd)) return name;\n }\n return null;\n}\n\ntype ToolResult =\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string };\n\nfunction isPlanFile(input: Record<string, unknown>): boolean {\n const filePath = String(input.file_path ?? input.path ?? \"\");\n return filePath.includes(\".claude/plans/\");\n}\n\nfunction handleDiscoveryToolAccess(toolName: string, input: Record<string, unknown>): ToolResult {\n if (PM_PLAN_FILE_TOOLS.has(toolName)) {\n if (isPlanFile(input)) {\n return { behavior: \"allow\", updatedInput: input };\n }\n return {\n behavior: \"deny\",\n message: \"Discovery mode is read-only. File writes are restricted to plan files.\",\n };\n }\n return { behavior: \"allow\", updatedInput: input };\n}\n\nfunction handleBuildingToolAccess(toolName: string, input: Record<string, unknown>): ToolResult {\n if (toolName === \"Bash\") {\n const cmd = String(input.command ?? \"\");\n const matched = matchesDestructive(cmd);\n if (matched) {\n return {\n behavior: \"deny\",\n message: `Destructive operation blocked (${matched}). Use safer alternatives.`,\n };\n }\n }\n return { behavior: \"allow\", updatedInput: input };\n}\n\nfunction handleReviewToolAccess(toolName: string, input: Record<string, unknown>): ToolResult {\n // Review mode has full write access — reviewer can make direct fixes\n return handleBuildingToolAccess(toolName, input);\n}\n\nfunction handleAutoToolAccess(\n toolName: string,\n input: Record<string, unknown>,\n hasExitedPlanMode: boolean,\n isParentTask: boolean,\n): ToolResult {\n if (hasExitedPlanMode) {\n return isParentTask\n ? handleReviewToolAccess(toolName, input)\n : handleBuildingToolAccess(toolName, input);\n }\n // Pre-ExitPlanMode: trust the SDK's native plan mode for restrictions.\n return { behavior: \"allow\", updatedInput: input };\n}\n\nfunction enforceMissingProps(\n host: QueryHost,\n input: Record<string, unknown>,\n missingProps: string[],\n): ToolResult | null {\n if (missingProps.length === 0) return null;\n if (input.bypassValidation !== true) {\n return {\n behavior: \"deny\" as const,\n message: [\n \"Cannot exit plan mode. Required task properties are missing:\",\n ...missingProps.map((p) => `- ${p}`),\n \"\",\n \"Fill these in using MCP tools (e.g. update_task_plan, update_task_properties), then call ExitPlanMode again.\",\n \"\",\n \"If you have a deliberate reason to proceed without them, you must explicitly bypass validation by calling ExitPlanMode with `bypassValidation: true` as a tool argument. Do not bypass unless the team has asked you to — it will be surfaced in chat.\",\n ].join(\"\\n\"),\n };\n }\n host.connection.postChatMessage(\n `⚠️ [BYPASS] ExitPlanMode forced through with \\`bypassValidation: true\\` despite missing required properties: ${missingProps.join(\", \")}. Please backfill these.`,\n );\n return null;\n}\n\nasync function handleExitPlanMode(\n host: QueryHost,\n input: Record<string, unknown>,\n): Promise<ToolResult> {\n if (host.hasExitedPlanMode) {\n return { behavior: \"allow\" as const, updatedInput: input };\n }\n\n try {\n // Flush any locally-written plan files to the server before validation.\n // Awaited so a failed sync surfaces in chat before getTaskProperties is\n // consulted — otherwise we'd validate against stale server-side plan state.\n await host.syncPlanFile();\n\n const taskProps = await host.connection.getTaskProperties();\n const missingProps = collectMissingProps(taskProps);\n\n // Validate subtasks have plans if this is a parent task\n if (host.isParentTask) {\n try {\n const subtasks = await host.connection.call(\"listSubtasks\", {\n sessionId: host.connection.sessionId,\n });\n const subtasksWithoutPlans = subtasks.filter(\n (s: { plan?: string | null; title: string }) => !s.plan?.trim(),\n );\n if (subtasksWithoutPlans.length > 0) {\n const names = subtasksWithoutPlans.map((s: { title: string }) => s.title).join(\", \");\n missingProps.push(\n `subtask plans — these subtasks are missing plans: ${names} (use update_subtask with plan field)`,\n );\n }\n } catch {\n // If we can't list subtasks, skip this validation\n }\n }\n\n const gate = enforceMissingProps(host, input, missingProps);\n if (gate) return gate;\n\n if (host.agentMode === \"discovery\") {\n host.hasExitedPlanMode = true;\n host.discoveryCompleted = true;\n // Await both the identification trigger and the confirmation chat post\n // before requesting stop. Previously these were fire-and-forget, so a\n // connection drop between the ExitPlanMode call and the stop could lose\n // either the identification event or the confirmation message, leaving\n // the agent with no visible signal that planning actually completed.\n try {\n await host.connection.triggerIdentification();\n } catch (triggerErr) {\n host.connection.postChatMessage(\n `Identification trigger encountered an issue (${triggerErr instanceof Error ? triggerErr.message : \"unknown error\"}). Icon and agent assignment may use fallbacks.`,\n );\n }\n await host.connection.postChatMessageAwait(\n \"Planning complete — awaiting team approval. Icon and agent assignment will be set automatically.\",\n );\n // requestStop aborts the SDK event loop only after the above acks land,\n // guaranteeing the team sees a confirmation message for this session.\n host.requestStop();\n return { behavior: \"allow\" as const, updatedInput: input };\n }\n\n // Auto mode: trigger identification but don't let it block ExitPlanMode.\n // Identification runs asynchronously server-side with fallbacks,\n // and the agent should proceed to building mode regardless.\n try {\n await host.connection.triggerIdentification();\n } catch (triggerErr) {\n host.connection.postChatMessage(\n `Identification trigger encountered an issue (${triggerErr instanceof Error ? triggerErr.message : \"unknown error\"}). Proceeding to build phase — identification will use fallbacks.`,\n );\n }\n\n host.hasExitedPlanMode = true;\n\n const newMode = host.isParentTask ? \"review\" : \"building\";\n host.connection.sendEvent({ type: \"mode_transition\", from: \"auto\", to: newMode });\n host.connection.emitModeChanged(newMode);\n\n return { behavior: \"allow\" as const, updatedInput: input };\n } catch (err) {\n return {\n behavior: \"deny\" as const,\n message: `Identification failed: ${err instanceof Error ? err.message : String(err)}. Fix the issue and try again.`,\n };\n }\n}\n\nasync function handleAskUserQuestion(\n host: QueryHost,\n input: Record<string, unknown>,\n): Promise<ToolResult> {\n const QUESTION_TIMEOUT_MS = 5 * 60 * 1000;\n const questions = input.questions as {\n question: string;\n header: string;\n options: { label: string; description: string; preview?: string }[];\n multiSelect?: boolean;\n }[];\n\n host.connection.emitStatus(\"waiting_for_input\");\n host.connection.sendEvent({\n type: \"tool_use\",\n tool: \"AskUserQuestion\",\n input: JSON.stringify(input),\n });\n\n const answerPromise = host.connection.askUserQuestion(questions);\n const timeoutPromise = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), QUESTION_TIMEOUT_MS);\n });\n\n const answers = await Promise.race([answerPromise, timeoutPromise]);\n host.connection.emitStatus(\"running\");\n\n if (!answers || Object.keys(answers).length === 0) {\n return {\n behavior: \"deny\",\n message:\n \"User did not respond to clarifying questions in time. Proceed with your best judgment.\",\n };\n }\n\n return { behavior: \"allow\", updatedInput: { questions: input.questions, answers } };\n}\n\nconst EXPLORATION_TOOLS = new Set([\"Read\", \"Grep\", \"Glob\"]);\n\nfunction trackExploration(\n tracker: ExplorationTracker,\n toolName: string,\n input: Record<string, unknown>,\n): StalenessSignal | null {\n if (!EXPLORATION_TOOLS.has(toolName)) return null;\n\n if (toolName === \"Read\") {\n const filePath = String(input.file_path ?? \"\");\n if (filePath) return tracker.recordFileRead(filePath);\n }\n\n if (toolName === \"Grep\" || toolName === \"Glob\") {\n const pattern = String(input.pattern ?? \"\");\n if (pattern) return tracker.recordSearch(pattern);\n }\n\n return null;\n}\n\nconst DENIAL_WARNING_THRESHOLD = 3;\nconst DENIAL_FORCE_STOP_THRESHOLD = 8;\n\nfunction handleDenialEscalation(host: QueryHost, consecutiveDenials: number): void {\n if (consecutiveDenials === DENIAL_WARNING_THRESHOLD) {\n host.connection.postChatMessage(\n `⚠️ Multiple tool denials detected. You are in ${host.agentMode} mode — ` +\n `file writes outside .claude/plans/ are not permitted. ` +\n `Focus on creating a plan instead of implementing code changes.`,\n );\n }\n if (consecutiveDenials >= DENIAL_FORCE_STOP_THRESHOLD) {\n host.connection.postChatMessage(\n `Agent force-stopped after ${DENIAL_FORCE_STOP_THRESHOLD} consecutive tool denials. ` +\n `The agent appears stuck — send a message to resume.`,\n );\n host.requestStop();\n }\n}\n\nfunction resolveToolAccess(\n host: QueryHost,\n toolName: string,\n input: Record<string, unknown>,\n): ToolResult {\n switch (host.agentMode) {\n case \"discovery\":\n return handleDiscoveryToolAccess(toolName, input);\n case \"building\":\n return handleBuildingToolAccess(toolName, input);\n case \"review\":\n return handleReviewToolAccess(toolName, input);\n case \"auto\":\n return handleAutoToolAccess(toolName, input, host.hasExitedPlanMode, host.isParentTask);\n default:\n return { behavior: \"allow\", updatedInput: input };\n }\n}\n\nexport function buildCanUseTool(\n host: QueryHost,\n): (toolName: string, input: Record<string, unknown>) => Promise<ToolResult> {\n let consecutiveDenials = 0;\n\n return async (toolName, input) => {\n if (\n toolName === \"ExitPlanMode\" &&\n (host.agentMode === \"auto\" || host.agentMode === \"discovery\") &&\n !host.hasExitedPlanMode\n ) {\n return await handleExitPlanMode(host, input);\n }\n\n // Repeated ExitPlanMode calls after plan mode was already exited in discovery\n // mode should be denied to prevent burning budget without triggering force-stop.\n if (toolName === \"ExitPlanMode\" && host.agentMode === \"discovery\" && host.hasExitedPlanMode) {\n return {\n behavior: \"deny\" as const,\n message:\n \"Plan mode has already been exited. The team will transition you to Building mode when ready.\",\n };\n }\n\n if (toolName === \"AskUserQuestion\") {\n return await handleAskUserQuestion(host, input);\n }\n\n const result = resolveToolAccess(host, toolName, input);\n\n // Track exploration patterns during planning to detect analysis paralysis.\n // Only active when tracker exists (discovery/auto-planning) and plan mode hasn't been exited.\n if (result.behavior === \"allow\" && host.explorationTracker && !host.hasExitedPlanMode) {\n const signal = trackExploration(host.explorationTracker, toolName, input);\n if (signal) {\n host.connection.postChatMessage(signal.message);\n }\n }\n\n if (result.behavior === \"deny\") {\n consecutiveDenials++;\n handleDenialEscalation(host, consecutiveDenials);\n } else {\n consecutiveDenials = 0;\n }\n\n return result;\n };\n}\n","/**\n * Pure, dependency-free secret redactor for tool output.\n *\n * Applied in the PostToolUse hook before forwarding `tool_result` events to\n * the API and before buffering into `pendingToolOutputs`. Defense-in-depth\n * only — server-side must still treat tool output as potentially tainted.\n *\n * Patterns are intentionally conservative: we prefer false negatives over\n * false positives because agents rely on reading tool output to do work.\n * Commit SHAs (`[a-f0-9]{7,40}`) are deliberately NOT redacted.\n */\n\nconst REDACTED = \"<redacted>\";\n\nconst BEARER_RE = /\\b(Bearer\\s+)[A-Za-z0-9_\\-.]{20,}/g;\n\nconst VENDOR_KEY_RE =\n /\\b(?:sk-[a-zA-Z0-9_-]{20,}|ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{22,}|xoxb-[A-Za-z0-9-]+|xai-[A-Za-z0-9-]{20,})\\b/g;\n\nconst AWS_ACCESS_KEY_RE = /\\bAKIA[0-9A-Z]{16}\\b/g;\n\n// JWTs: three base64url segments separated by dots, starting with the\n// ubiquitous `eyJ` header prefix.\nconst JWT_RE = /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g;\n\n// KEY=VALUE lines where KEY looks like a secret name. Matches optional\n// `export ` prefix and quoted or bare values. Captures KEY separately so we\n// preserve it in the replacement.\nconst ENV_SECRET_RE =\n /^(\\s*(?:export\\s+)?([A-Z][A-Z0-9_]*(?:TOKEN|SECRET|KEY|PASSWORD|PASS|CREDENTIAL|CREDENTIALS)[A-Z0-9_]*)\\s*=\\s*)['\"]?([^\\s'\"]+)['\"]?/gm;\n\nconst COOKIE_HEADER_RE = /(Cookie:\\s*)[^\\r\\n]+/gi;\n\n// Basic-auth URLs: keep the user visible, mask the password.\nconst BASIC_AUTH_URL_RE = /(https?:\\/\\/)([^:@\\s/]+):([^@\\s]+)@/g;\n\n// AWS secret access keys don't have a distinctive prefix. Apply only on\n// lines that mention \"secret\" / \"aws_secret\" to avoid matching commit SHAs,\n// base64 payloads, etc.\nconst AWS_SECRET_LINE_RE = /^.*(?:secret|aws_secret).*$/gim;\nconst AWS_SECRET_VALUE_RE = /\\b([A-Za-z0-9/+=]{40})\\b/g;\n\n// Strip prompt-injection attempts from tool output: we observed `<system-reminder>`\n// blocks being smuggled through bash output during discovery of this pipeline.\nconst SYSTEM_REMINDER_RE = /<system-reminder>[\\s\\S]*?<\\/system-reminder>/gi;\n\nexport interface RedactResult {\n output: string;\n redacted: number;\n}\n\nexport function redact(input: string): RedactResult {\n if (!input) return { output: input, redacted: 0 };\n\n let count = 0;\n let output = input;\n\n output = output.replace(SYSTEM_REMINDER_RE, () => {\n count++;\n return \"<!-- stripped injection -->\";\n });\n\n output = output.replace(BEARER_RE, (_match, prefix: string) => {\n count++;\n return `${prefix}${REDACTED}`;\n });\n\n output = output.replace(VENDOR_KEY_RE, () => {\n count++;\n return REDACTED;\n });\n\n output = output.replace(AWS_ACCESS_KEY_RE, () => {\n count++;\n return REDACTED;\n });\n\n output = output.replace(JWT_RE, () => {\n count++;\n return REDACTED;\n });\n\n output = output.replace(AWS_SECRET_LINE_RE, (line) =>\n line.replace(AWS_SECRET_VALUE_RE, (match) => {\n // Skip pure hex (commit SHAs, etc.) — AWS secrets use the full\n // base64 alphabet, so a match that's all-hex is almost certainly\n // not a secret.\n if (/^[a-f0-9]+$/i.test(match)) return match;\n count++;\n return REDACTED;\n }),\n );\n\n output = output.replace(ENV_SECRET_RE, (_match, prefix: string, _key: string, _value: string) => {\n count++;\n return `${prefix}${REDACTED}`;\n });\n\n output = output.replace(COOKIE_HEADER_RE, (_match, prefix: string) => {\n count++;\n return `${prefix}${REDACTED}`;\n });\n\n output = output.replace(BASIC_AUTH_URL_RE, (_match, scheme: string, user: string) => {\n count++;\n return `${scheme}${user}:${REDACTED}@`;\n });\n\n return { output, redacted: count };\n}\n","export interface ModelUsageEntry {\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadInputTokens: number;\n cacheCreationInputTokens: number;\n costUSD: number;\n}\n\nexport class CostTracker {\n private cumulativeCostUsd = 0;\n private modelUsage = new Map<string, ModelUsageEntry>();\n private seeded = false;\n\n /**\n * Rehydrate cumulative spend from the server so `maxBudgetUsd` enforcement\n * accounts for costs incurred by prior agent runs on the same task. Must be\n * called before any `addQueryCost` / `addModelUsage` — re-seeding after\n * costs have accumulated would clobber in-process totals.\n */\n seed(totalCostUsd: number, modelUsage: ModelUsageEntry[]): void {\n if (this.seeded) return;\n if (this.cumulativeCostUsd > 0 || this.modelUsage.size > 0) return;\n this.cumulativeCostUsd = totalCostUsd;\n for (const entry of modelUsage) {\n this.modelUsage.set(entry.model, { ...entry });\n }\n this.seeded = true;\n }\n\n /** Add cost from a completed query and return the running total */\n addQueryCost(queryCostUsd: number): number {\n this.cumulativeCostUsd += queryCostUsd;\n return this.cumulativeCostUsd;\n }\n\n /** Merge per-model usage from a completed query */\n addModelUsage(\n usage: Record<\n string,\n {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadInputTokens?: number;\n cacheCreationInputTokens?: number;\n costUSD?: number;\n }\n >,\n ): void {\n for (const [model, data] of Object.entries(usage)) {\n const existing = this.modelUsage.get(model) ?? {\n model,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n costUSD: 0,\n };\n existing.inputTokens += data.inputTokens ?? 0;\n existing.outputTokens += data.outputTokens ?? 0;\n existing.cacheReadInputTokens += data.cacheReadInputTokens ?? 0;\n existing.cacheCreationInputTokens += data.cacheCreationInputTokens ?? 0;\n existing.costUSD += data.costUSD ?? 0;\n this.modelUsage.set(model, existing);\n }\n }\n\n get totalCostUsd(): number {\n return this.cumulativeCostUsd;\n }\n\n get modelBreakdown(): ModelUsageEntry[] {\n return [...this.modelUsage.values()];\n }\n}\n","/**\n * ExplorationTracker — detects repetitive file reads and search patterns\n * during planning-mode queries to nudge agents past analysis paralysis.\n *\n * Follows the CostTracker pattern: stateful accumulator with read-only getters.\n * Instantiated per-query in QueryBridge.buildHost() for discovery/auto-planning\n * modes only. Building/review modes set this to null on QueryHost.\n */\n\nexport type NudgeLevel = 1 | 2;\n\nexport interface StalenessSignal {\n level: NudgeLevel;\n message: string;\n}\n\n// Base thresholds (before complexity scaling)\nconst FILE_REREAD_NUDGE_L1 = 3;\nconst FILE_REREAD_NUDGE_L2 = 5;\nconst SEARCH_REPEAT_NUDGE_L1 = 3;\nconst SEARCH_REPEAT_NUDGE_L2 = 5;\nconst RATIO_MIN_READS_L1 = 10;\nconst RATIO_THRESHOLD_L1 = 0.4;\nconst RATIO_MIN_READS_L2 = 15;\nconst RATIO_THRESHOLD_L2 = 0.3;\n\nfunction normalizePath(filePath: string): string {\n // Strip leading ./ for consistent tracking\n let normalized = filePath.replace(/^\\.\\//, \"\");\n // Collapse consecutive slashes\n normalized = normalized.replace(/\\/+/g, \"/\");\n return normalized;\n}\n\nexport class ExplorationTracker {\n private fileReadCounts = new Map<string, number>();\n private searchCounts = new Map<string, number>();\n private totalReads = 0;\n private highestNudgeEmitted: NudgeLevel | 0 = 0;\n private readonly complexityMultiplier: number;\n\n constructor(isParentTask: boolean) {\n this.complexityMultiplier = isParentTask ? 1.5 : 1.0;\n }\n\n /** Record a file read and return a staleness signal if thresholds are crossed. */\n recordFileRead(filePath: string): StalenessSignal | null {\n const normalized = normalizePath(filePath);\n const count = (this.fileReadCounts.get(normalized) ?? 0) + 1;\n this.fileReadCounts.set(normalized, count);\n this.totalReads++;\n\n // Check file re-read thresholds (higher level first for priority)\n return this.checkFileRereadSignal(normalized, count) ?? this.checkExplorationRatio();\n }\n\n /** Record a search pattern and return a staleness signal if thresholds are crossed. */\n recordSearch(pattern: string): StalenessSignal | null {\n const count = (this.searchCounts.get(pattern) ?? 0) + 1;\n this.searchCounts.set(pattern, count);\n\n return this.checkSearchRepeatSignal(pattern, count);\n }\n\n private scaledThreshold(base: number): number {\n return Math.ceil(base * this.complexityMultiplier);\n }\n\n private checkFileRereadSignal(filePath: string, count: number): StalenessSignal | null {\n const l2 = this.scaledThreshold(FILE_REREAD_NUDGE_L2);\n const l1 = this.scaledThreshold(FILE_REREAD_NUDGE_L1);\n\n if (count >= l2 && this.highestNudgeEmitted < 2) {\n this.highestNudgeEmitted = 2;\n return {\n level: 2,\n message:\n `⚠️ Exploration warning: You've read \"${filePath}\" ${count} times, suggesting analysis paralysis. ` +\n `Write your plan with the context you have and call ExitPlanMode. ` +\n `If something specific is blocking you, describe the blocker in your plan.`,\n };\n }\n\n if (count >= l1 && this.highestNudgeEmitted < 1) {\n this.highestNudgeEmitted = 1;\n return {\n level: 1,\n message:\n `Exploration note: You've read \"${filePath}\" ${count} times. ` +\n `Consider whether you have enough context to start writing your plan. ` +\n `If you're still exploring, try looking at different files.`,\n };\n }\n\n return null;\n }\n\n private checkSearchRepeatSignal(pattern: string, count: number): StalenessSignal | null {\n const l2 = this.scaledThreshold(SEARCH_REPEAT_NUDGE_L2);\n const l1 = this.scaledThreshold(SEARCH_REPEAT_NUDGE_L1);\n\n // Truncate pattern for display\n const displayPattern = pattern.length > 60 ? pattern.slice(0, 57) + \"...\" : pattern;\n\n if (count >= l2 && this.highestNudgeEmitted < 2) {\n this.highestNudgeEmitted = 2;\n return {\n level: 2,\n message:\n `⚠️ Exploration warning: You've searched for \"${displayPattern}\" ${count} times. ` +\n `Repeated searches for the same pattern suggest you may be stuck. ` +\n `Proceed with the information you have.`,\n };\n }\n\n if (count >= l1 && this.highestNudgeEmitted < 1) {\n this.highestNudgeEmitted = 1;\n return {\n level: 1,\n message:\n `Exploration note: You've searched for \"${displayPattern}\" ${count} times. ` +\n `If you're not finding what you need, try a different approach or broader pattern.`,\n };\n }\n\n return null;\n }\n\n private checkExplorationRatio(): StalenessSignal | null {\n const uniqueReads = this.fileReadCounts.size;\n const ratio = this.totalReads > 0 ? uniqueReads / this.totalReads : 1;\n\n const minReadsL2 = this.scaledThreshold(RATIO_MIN_READS_L2);\n if (\n this.totalReads >= minReadsL2 &&\n ratio < RATIO_THRESHOLD_L2 &&\n this.highestNudgeEmitted < 2\n ) {\n this.highestNudgeEmitted = 2;\n return {\n level: 2,\n message:\n `⚠️ Exploration warning: Only ${Math.round(ratio * 100)}% of your ${this.totalReads} file reads are unique. ` +\n `This indicates significant re-reading. Write your plan with the context you have.`,\n };\n }\n\n const minReadsL1 = this.scaledThreshold(RATIO_MIN_READS_L1);\n if (\n this.totalReads >= minReadsL1 &&\n ratio < RATIO_THRESHOLD_L1 &&\n this.highestNudgeEmitted < 1\n ) {\n this.highestNudgeEmitted = 1;\n return {\n level: 1,\n message:\n `Exploration note: ${Math.round(ratio * 100)}% of your ${this.totalReads} file reads are unique. ` +\n `You're re-reading files more than exploring new ones. Consider starting your plan.`,\n };\n }\n\n return null;\n }\n}\n","/**\n * QueryBridge — wires SessionRunner lifecycle state to QueryExecutor execution.\n *\n * SessionRunner handles connect/idle/message lifecycle.\n * QueryExecutor handles Claude SDK query orchestration.\n * QueryBridge adapts between them by constructing the QueryHost interface\n * that QueryExecutor expects, using live references to ModeController state.\n */\n\nimport type { HarnessEvent, HarnessUserMessage, PtyBridge } from \"../harness/index.js\";\nimport { createHarness, type HarnessKind } from \"../harness/index.js\";\nimport {\n runSdkQuery,\n resolvePromptDelivery,\n hasExistingSessionFile,\n type QueryHost,\n} from \"../execution/query-executor.js\";\nimport { CostTracker, type ModelUsageEntry } from \"../execution/cost-tracker.js\";\nimport { ExplorationTracker } from \"../execution/exploration-tracker.js\";\nimport { PlanSync } from \"./plan-sync.js\";\nimport type { AgentConnection } from \"../connection/agent-connection.js\";\nimport type { ModeController } from \"./mode-controller.js\";\nimport type { AgentRunnerConfig, AgentRunnerCallbacks } from \"../types.js\";\nimport type { TaskContext, AgentMode, MultimodalBlock } from \"@project/shared\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"QueryBridge\");\n\n/**\n * Pick the harness implementation for the task chat path.\n *\n * As of conveyor-agent v8 the per-task agent chat defaults to the PTY harness\n * (drives the `claude` CLI under a pseudo-terminal). Set `CONVEYOR_HARNESS=sdk`\n * to roll back to the SDK harness (`@anthropic-ai/claude-agent-sdk`).\n *\n * Scope: this default governs ONLY the task chat. The audit and project-chat\n * paths construct the SDK harness directly via `createHarness()` (no-arg) and\n * are unaffected by this env var.\n */\nexport function resolveHarnessKind(): HarnessKind {\n return process.env.CONVEYOR_HARNESS === \"sdk\" ? \"sdk\" : \"pty\";\n}\n\n/**\n * Adapt an AgentConnection into the harness-neutral PtyBridge consumed by the\n * PTY harness. Keeps the harness package free of any connection-layer import.\n */\nfunction buildPtyBridge(connection: AgentConnection): PtyBridge {\n return {\n sendOutput: (data, dims) => connection.sendPtyOutput(data, dims),\n onInput: (handler) => connection.onPtyInput(handler),\n onResize: (handler) => connection.onPtyResize(handler),\n };\n}\n\nexport class QueryBridge {\n private readonly harness;\n private readonly harnessKind: HarnessKind;\n private readonly costTracker: CostTracker;\n private readonly planSync: PlanSync;\n private readonly sessionIds = new Map<string, string>();\n private activeQuery: AsyncGenerator<HarnessEvent, void> | null = null;\n private readonly pendingToolOutputs: { tool: string; output: string }[] = [];\n private _stopped = false;\n private _discoveryCompleted = false;\n private _isParentTask = false;\n private _wasRateLimited = false;\n private _abortController: AbortController | null = null;\n\n /** Called by SessionRunner when ExitPlanMode triggers a mode transition. */\n onModeTransition?: (newMode: AgentMode) => void;\n\n /** Called by tool handlers to soft-stop (abort query, keep session alive). */\n onSoftStop?: () => void;\n\n constructor(\n private readonly connection: AgentConnection,\n private readonly mode: ModeController,\n private readonly runnerConfig: AgentRunnerConfig,\n private readonly callbacks: AgentRunnerCallbacks,\n workspaceDir: string,\n ) {\n const harnessKind = resolveHarnessKind();\n this.harnessKind = harnessKind;\n this.harness = createHarness(\n harnessKind,\n harnessKind === \"pty\" ? buildPtyBridge(connection) : undefined,\n );\n this.costTracker = new CostTracker();\n this.planSync = new PlanSync(workspaceDir, connection);\n }\n\n get isStopped(): boolean {\n return this._stopped;\n }\n\n get isDiscoveryCompleted(): boolean {\n return this._discoveryCompleted;\n }\n\n set isDiscoveryCompleted(val: boolean) {\n this._discoveryCompleted = val;\n }\n\n get isParentTask(): boolean {\n return this._isParentTask;\n }\n\n set isParentTask(val: boolean) {\n this._isParentTask = val;\n }\n\n get wasRateLimited(): boolean {\n return this._wasRateLimited;\n }\n\n stop(): void {\n this._stopped = true;\n this._abortController?.abort();\n }\n\n resume(): void {\n this._stopped = false;\n }\n\n /** Rehydrate CostTracker from server-side cumulative spend on agent boot. */\n seedCostTracker(totalCostUsd: number, modelUsage: ModelUsageEntry[]): void {\n this.costTracker.seed(totalCostUsd, modelUsage);\n }\n\n /**\n * How the INITIAL instructions for this task would be delivered — \"prefill\"\n * means the TUI input is pre-filled but unsubmitted, awaiting the human.\n * Mirrors the decision runSdkQuery makes for the initial (non-follow-up)\n * query so SessionRunner can pick the matching state/timers.\n */\n initialPromptDelivery(context: TaskContext): \"submit\" | \"prefill\" {\n return resolvePromptDelivery({\n harnessKind: this.harnessKind,\n runnerMode: this.runnerConfig.mode,\n isAuto: this.mode.isAuto,\n agentMode: this.mode.effectiveMode,\n isFollowUp: false,\n hasExistingSession: hasExistingSessionFile(context.taskId, this.runnerConfig.workspaceDir, {\n agentMode: this.mode.effectiveMode,\n runnerMode: this.runnerConfig.mode,\n }),\n });\n }\n\n /**\n * Execute a Claude SDK query.\n * Without followUpContent: runs initial mode execution (build/plan).\n * With followUpContent: processes a follow-up user message.\n * `promptDelivery` overrides the executor's submit-vs-prefill resolution —\n * SessionRunner forces \"submit\" when pending chat messages already direct\n * the agent (prefilling would park them until a human touched the TUI).\n */\n async execute(\n context: TaskContext,\n followUpContent?: string | MultimodalBlock[],\n promptDelivery?: \"submit\" | \"prefill\",\n ): Promise<void> {\n this._stopped = false;\n this._wasRateLimited = false;\n this._abortController = new AbortController();\n const host = this.buildHost();\n try {\n await runSdkQuery(host, context, followUpContent, promptDelivery);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isAbort = this._stopped || /abort/i.test(msg);\n if (isAbort) {\n logger.info(\"Query stopped by user\", { error: msg });\n } else {\n logger.error(\"Query execution failed\", { error: msg });\n this.connection.sendEvent({ type: \"error\", message: msg });\n }\n } finally {\n this.mode.pendingModeRestart = false;\n this._abortController = null;\n }\n }\n\n // ── QueryHost construction ──────────────────────────────────────────\n\n private buildHost(): QueryHost {\n // oxlint-disable-next-line no-this-alias -- closure needed for live getter/setter delegation\n const bridge = this;\n return {\n config: this.runnerConfig,\n connection: this.connection,\n callbacks: this.callbacks,\n harness: this.harness,\n harnessKind: this.harnessKind,\n setupLog: [],\n costTracker: this.costTracker,\n explorationTracker:\n bridge.mode.effectiveMode === \"discovery\" ||\n (bridge.mode.effectiveMode === \"auto\" && !bridge.mode.hasExitedPlanMode)\n ? new ExplorationTracker(bridge._isParentTask)\n : null,\n sessionIds: this.sessionIds,\n pendingToolOutputs: this.pendingToolOutputs,\n\n // Live getters/setters delegating to ModeController + bridge state\n get agentMode() {\n return bridge.mode.effectiveMode;\n },\n get isAuto() {\n return bridge.mode.isAuto;\n },\n get isParentTask() {\n return bridge._isParentTask;\n },\n get hasExitedPlanMode() {\n return bridge.mode.hasExitedPlanMode;\n },\n set hasExitedPlanMode(val: boolean) {\n bridge.mode.hasExitedPlanMode = val;\n },\n get pendingModeRestart() {\n return bridge.mode.pendingModeRestart;\n },\n set pendingModeRestart(val: boolean) {\n bridge.mode.pendingModeRestart = val;\n },\n get discoveryCompleted() {\n return bridge._discoveryCompleted;\n },\n set discoveryCompleted(val: boolean) {\n bridge._discoveryCompleted = val;\n },\n get wasRateLimited() {\n return bridge._wasRateLimited;\n },\n set wasRateLimited(val: boolean) {\n bridge._wasRateLimited = val;\n },\n get activeQuery() {\n return bridge.activeQuery;\n },\n set activeQuery(val: AsyncGenerator<HarnessEvent, void> | null) {\n bridge.activeQuery = val;\n },\n get abortController() {\n return bridge._abortController;\n },\n\n isStopped: () => bridge._stopped,\n requestStop: () => bridge.stop(),\n requestSoftStop: () => {\n if (bridge.onSoftStop) bridge.onSoftStop();\n },\n createInputStream: (prompt) => bridge.createInputStream(prompt),\n snapshotPlanFiles: () => bridge.planSync.snapshotPlanFiles(),\n syncPlanFile: () => bridge.planSync.syncPlanFile(),\n onModeTransition: bridge.onModeTransition,\n };\n }\n\n // ── Input stream for Claude SDK ─────────────────────────────────────\n\n private async *createInputStream(\n prompt: string | MultimodalBlock[],\n ): AsyncGenerator<HarnessUserMessage, void, unknown> {\n yield {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content: prompt },\n parent_tool_use_id: null,\n };\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ChatMessage, TaskContextDTO } from \"@project/shared\";\n\nexport function mapChatHistory(\n messages: TaskContextDTO[\"chatHistory\"] | undefined | null,\n): ChatMessage[] {\n if (!messages) return [];\n return messages.map((m) => ({\n id: m.id,\n role: (m.role ?? \"user\") as \"user\" | \"assistant\" | \"system\",\n content: m.content ?? \"\",\n userId: m.userId,\n userName: m.user?.name ?? undefined,\n createdAt: m.createdAt,\n ...(m.files && m.files.length > 0\n ? {\n files: m.files.map((f) => ({\n fileId: f.id,\n fileName: f.fileName,\n mimeType: f.mimeType,\n fileSize: f.fileSize,\n downloadUrl: f.downloadUrl ?? \"\",\n content: f.content,\n contentEncoding: f.contentEncoding,\n })),\n }\n : {}),\n }));\n}\n\n/** Read this agent's version from its bundled package.json. */\nexport function readAgentVersion(): string | null {\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n // Walk up: dist/runner/session-runner.js → dist/ → package.json\n for (const rel of [\"../package.json\", \"../../package.json\"]) {\n try {\n const pkg = JSON.parse(readFileSync(join(here, rel), \"utf-8\")) as { version?: string };\n if (pkg.version) return pkg.version;\n } catch {\n /* try next candidate */\n }\n }\n } catch {\n /* ignore */\n }\n return null;\n}\n","import { execSync } from \"node:child_process\";\nimport { getCurrentBranch, hasUncommittedChanges } from \"./git-utils.js\";\n\n/**\n * Handler for `session:pullBranch` events. Fired against a parent task's\n * connected session when a child PR merges into the parent's branch (feature\n * branch packs). Performs a fast-forward `git pull` of the parent's own\n * branch so the workspace and preview reflect merged child work.\n *\n * No-op (with a warning) if the workspace is dirty or on a different branch —\n * we never want to surprise the agent or the user by overwriting in-flight work.\n */\nexport function handlePullBranch(workDir: string, branch: string): void {\n if (!branch) return;\n\n const current = getCurrentBranch(workDir);\n if (current !== branch) {\n process.stderr.write(\n `[conveyor-agent] pull_branch ignored — current branch ${current ?? \"(detached)\"} != ${branch}\\n`,\n );\n return;\n }\n\n if (hasUncommittedChanges(workDir)) {\n process.stderr.write(\n `[conveyor-agent] pull_branch ignored — uncommitted changes on ${branch}\\n`,\n );\n return;\n }\n\n try {\n execSync(`git fetch origin ${branch}`, { cwd: workDir, stdio: \"ignore\", timeout: 60_000 });\n } catch {\n process.stderr.write(`[conveyor-agent] pull_branch: fetch failed for ${branch}\\n`);\n return;\n }\n\n try {\n execSync(`git pull --ff-only origin ${branch}`, {\n cwd: workDir,\n stdio: \"ignore\",\n timeout: 60_000,\n });\n process.stderr.write(`[conveyor-agent] pull_branch: pulled origin/${branch}\\n`);\n } catch {\n process.stderr.write(\n `[conveyor-agent] pull_branch: ff-only pull failed for ${branch} (likely diverged)\\n`,\n );\n }\n}\n","/* oxlint-disable max-lines -- lifecycle orchestrator, splitting would scatter tightly-coupled control flow */\nimport type { AgentRunnerStatus, AgentMode, TaskContext, TaskContextDTO } from \"@project/shared\";\nimport {\n AgentConnection,\n type AgentConnectionConfig,\n type IncomingMessage,\n} from \"../connection/agent-connection.js\";\nimport { ModeController, type ModeTaskContext } from \"./mode-controller.js\";\nimport { Lifecycle, DEFAULT_LIFECYCLE_CONFIG, type LifecycleConfig } from \"./lifecycle.js\";\nimport { QueryBridge } from \"./query-bridge.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport {\n syncWithBaseBranch,\n ensureOnTaskBranch,\n flushPendingChanges,\n restoreWipSnapshot,\n updateRemoteToken,\n} from \"./git-utils.js\";\nimport { mapChatHistory, readAgentVersion } from \"./session-runner-helpers.js\";\nimport { handlePullBranch } from \"./parent-pull-handler.js\";\nimport { ensureClaudeCredentials, removeConveyorCredentials } from \"../harness/pty/credentials.js\";\n\n// ── Configuration ──────────────────────────────────────────────────────────\n\nexport interface SessionRunnerConfig {\n connection: AgentConnectionConfig;\n agentMode?: AgentMode;\n runnerMode?: \"task\" | \"pm\" | \"code-review\";\n isAuto?: boolean;\n workspaceDir: string;\n model?: string;\n lifecycle?: Partial<LifecycleConfig>;\n}\n\nexport interface SessionRunnerCallbacks {\n onStatusChange: (status: AgentRunnerStatus) => void | Promise<void>;\n onEvent: (event: Record<string, unknown>) => void | Promise<void>;\n}\n\n// ── SessionRunner: main lifecycle orchestrator ─────────────────────────────\n\nexport class SessionRunner {\n readonly connection: AgentConnection;\n readonly mode: ModeController;\n readonly lifecycle: Lifecycle;\n\n private readonly config: SessionRunnerConfig;\n private readonly callbacks: SessionRunnerCallbacks;\n private _state: AgentRunnerStatus = \"connecting\";\n private stopped = false;\n private interrupted = false;\n /** Defense-in-depth: set when the agent emits a \"completed\" event.\n * Prevents the core loop from processing any further messages. */\n private completedThisTurn = false;\n /** Absolute deadline (ms epoch) at which the dormant idle wait must time\n * out. Set on the FIRST entry into dormant idle for a given completion\n * cycle and preserved across iterations so inbound critical messages\n * cannot extend the bound past the configured `dormantTimeoutMs`. Reset\n * to null when the agent transitions out of dormant idle (a wake actually\n * promotes it back to a working turn). */\n private dormantDeadline: number | null = null;\n\n private taskContext: ModeTaskContext | null = null;\n private fullContext: TaskContext | null = null;\n private queryBridge: QueryBridge | null = null;\n private inputResolver: ((msg: IncomingMessage | null) => void) | null = null;\n private pendingMessages: IncomingMessage[] = [];\n private prNudgeCount = 0;\n /** Guards overlapping runs of the periodic git flush. */\n private periodicFlushInFlight = false;\n\n constructor(config: SessionRunnerConfig, callbacks: SessionRunnerCallbacks) {\n this.config = config;\n this.callbacks = callbacks;\n\n // Compose components\n this.connection = new AgentConnection(config.connection);\n\n const initialMode =\n config.agentMode ??\n (config.runnerMode === \"pm\" ? (config.isAuto ? \"auto\" : \"discovery\") : \"building\");\n this.mode = new ModeController(initialMode, config.runnerMode, config.isAuto);\n\n const lifecycleConfig = { ...DEFAULT_LIFECYCLE_CONFIG, ...config.lifecycle };\n this.lifecycle = new Lifecycle(lifecycleConfig, {\n onHeartbeat: () => this.connection.sendHeartbeat(),\n onIdleTimeout: () => {\n process.stderr.write(\"[conveyor-agent] Idle timeout reached, stopping agent\\n\");\n this.stopped = true;\n // A prefilled initial query parks inside executeQuery (no\n // inputResolver) — abort it so the wait actually ends.\n this.queryBridge?.stop();\n if (this.inputResolver) {\n const resolver = this.inputResolver;\n this.inputResolver = null;\n resolver(null);\n }\n },\n onDormantTimeout: () => {\n process.stderr.write(\"[conveyor-agent] Dormant idle timeout reached, shutting down\\n\");\n this.stopped = true;\n this.queryBridge?.stop();\n if (this.inputResolver) {\n const resolver = this.inputResolver;\n this.inputResolver = null;\n resolver(null);\n }\n },\n onTokenRefresh: () => void this.refreshGithubToken(),\n onGitFlush: () => void this.periodicGitFlush(),\n });\n }\n\n get state(): AgentRunnerStatus {\n return this._state;\n }\n\n get sessionId(): string {\n return this.connection.sessionId;\n }\n\n get isStopped(): boolean {\n return this.stopped;\n }\n\n // ── Main lifecycle ─────────────────────────────────────────────────\n\n /**\n * Establish the API connection, wire callbacks, and join the session room.\n * Call this before run() when you need to send events (e.g. setup/start\n * command output) before the main agent lifecycle begins.\n */\n async connect(): Promise<void> {\n await this.setState(\"connecting\");\n\n // 1. Connect\n await this.connection.connect();\n await this.setState(\"connected\");\n this.connection.sendEvent({ type: \"connected\", sessionId: this.sessionId });\n\n // 2. Wire callbacks\n this.wireConnectionCallbacks();\n this.lifecycle.startHeartbeat();\n this.lifecycle.startTokenRefresh();\n this.lifecycle.startGitFlush();\n\n // 2.5. Join session room and retrieve pending messages\n const { pendingMessages: serverMessages } = await this.connection.call(\"connectAgent\", {\n sessionId: this.sessionId,\n });\n for (const msg of serverMessages) {\n if (msg.content) {\n this.pendingMessages.push({ content: msg.content, userId: msg.userId });\n }\n }\n\n // 2.6. Fire-and-forget: tell the API our agent version. If a newer\n // @rallycry/conveyor-agent is on NPM, the API will queue a base image\n // rebuild for the project (deduped per-project across concurrent agents).\n // We continue running with the current version regardless.\n const agentVersion = readAgentVersion();\n if (agentVersion) {\n this.connection\n .call(\"notifyAgentVersion\", { sessionId: this.sessionId, agentVersion })\n .catch(() => {\n // Best-effort — don't block agent startup if NPM lookup or rebuild fails\n });\n }\n }\n\n /**\n * Run the main agent lifecycle: fetch context, resolve mode, execute, loop.\n * Requires connect() to have been called first.\n */\n // oxlint-disable-next-line max-lines-per-function, complexity -- lifecycle orchestration is inherently sequential\n async run(): Promise<void> {\n // 3. Fetch context\n await this.setState(\"fetching_context\");\n try {\n const ctx = await this.connection.call(\"getTaskContext\", {\n sessionId: this.sessionId,\n includeHistory: true,\n });\n this.fullContext = this.buildFullContext(ctx);\n this.taskContext = {\n status: ctx.status,\n plan: ctx.plan,\n storyPointId:\n ctx.storyPoints === null || ctx.storyPoints === undefined\n ? null\n : String(ctx.storyPoints),\n model: ctx.model,\n githubPRUrl: ctx.githubPRUrl,\n isParentTask: this.fullContext.isParentTask,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to fetch task context\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n await this.shutdown(\"error\");\n return;\n }\n\n // 3.5. Initial git setup. In claudespace, entrypoint.sh has already done\n // fetch + checkout + merge and sets CONVEYOR_GIT_READY=1 — skip in that\n // case. For GitHub Codespaces / local dev, fall through and do it here.\n if (process.env.CONVEYOR_GIT_READY !== \"1\") {\n if (this.fullContext?.githubBranch) {\n ensureOnTaskBranch(this.config.workspaceDir, this.fullContext.githubBranch);\n }\n if (this.fullContext?.baseBranch) {\n syncWithBaseBranch(this.config.workspaceDir, this.fullContext.baseBranch);\n }\n }\n\n // 3.6. Recover uncommitted work a previous pod snapshotted to the\n // conveyor-wip/<branch> ref before dying (runs for every medium — the\n // parent-HEAD guard makes a stale snapshot a no-op).\n if (this.fullContext?.githubBranch) {\n const restored = restoreWipSnapshot(this.config.workspaceDir, this.fullContext.githubBranch);\n if (restored !== \"none\") {\n process.stderr.write(`[conveyor-agent] WIP snapshot restore: ${restored}\\n`);\n }\n }\n\n // 4. Reconcile mode from server context (overrides env-var defaults)\n this.mode.applyServerMode(this.fullContext?.agentMode, this.fullContext?.isAuto);\n this.mode.resolveInitialMode(this.taskContext);\n\n // 4.1. When canBypassPlanning triggers for an auto task in \"Open\", the server\n // needs to transition the task to InProgress. Fire-and-forget — the agent\n // proceeds to build regardless; the status update is best-effort.\n if (\n this.fullContext?.isAuto &&\n this.taskContext.status === \"Open\" &&\n this.mode.isBuildCapable\n ) {\n void this.connection.triggerIdentification().catch(() => {});\n }\n\n // 4.5. Create query bridge for SDK execution\n this.queryBridge = this.createQueryBridge();\n\n // 4.6. Rehydrate CostTracker from server so maxBudgetUsd is meaningful\n // across agent pod restarts. Fire-and-forget with a 3s cap — failure or\n // slowness must not block startup; the in-process tracker starts at $0\n // and continues to accumulate as queries run.\n await this.seedCostTrackerFromServer();\n\n // 5. Log initialization\n this.logInitialization();\n\n // 6. Execute initial mode\n const staleMessageCount = this.pendingMessages.length;\n const didExecuteInitialQuery = await this.executeInitialMode();\n\n // Clear stale pending messages from connectAgent — they were already\n // included in the initial task context (chat history). Any messages\n // that arrived via live socket events DURING initial mode sit after\n // the stale ones, so we only splice the leading batch.\n // Only splice when the initial mode actually ran a query (auto/building/\n // review/pack) — modes like discovery skip the query, so pending\n // messages must be retained for the core loop to process.\n if (staleMessageCount > 0 && didExecuteInitialQuery) {\n this.pendingMessages.splice(0, staleMessageCount);\n }\n\n // Discovery ExitPlanMode during the (prefilled) initial query: planning is\n // done and the runner falls through to the normal idle wait below. Clear\n // the flag so a later follow-up's completion isn't mistaken for a fresh\n // discovery completion (which would drain pending messages in coreLoop).\n if (this.queryBridge?.isDiscoveryCompleted) {\n process.stderr.write(\n \"[conveyor-agent] Discovery completed during initial query — entering idle\\n\",\n );\n this.queryBridge.isDiscoveryCompleted = false;\n }\n\n // 6.5. Auto-mode nudge: if agent finished without PR, nudge it\n // Skip if a user message arrived during initial execution (it interrupted the query)\n if (!this.stopped && this.pendingMessages.length === 0) {\n await this.maybeSendPRNudge();\n }\n\n // 7. Core loop: idle → message → execute → idle\n if (!this.stopped) {\n process.stderr.write(\n `[conveyor-agent] Listening for messages (mode: ${this.mode.effectiveMode})\\n`,\n );\n }\n while (!this.stopped) {\n if (this._state !== \"idle\") await this.setState(\"idle\");\n await this.coreLoop();\n }\n\n // 8. Shutdown\n await this.shutdown(\"finished\");\n }\n\n /** Convenience wrapper: connect() then run(). */\n async start(): Promise<void> {\n await this.connect();\n await this.run();\n }\n\n // ── Core loop ──────────────────────────────────────────────────────\n\n // oxlint-disable-next-line complexity -- dormant idle paths add branches but are tightly coupled to the loop\n private async coreLoop(): Promise<void> {\n while (!this.stopped) {\n // Defense-in-depth: if the agent already emitted a \"completed\" event,\n // stop the loop. The server-side guard should prevent messages from\n // reaching us, but if one leaks through, this prevents the completion\n // cycle (agent says \"done\" → system message → agent says \"done\" → …).\n if (this.completedThisTurn) {\n const resumed = await this.handleDormantIdle();\n if (!resumed) break;\n continue;\n }\n if (this._state === \"idle\") {\n this.lifecycle.startIdleTimer();\n const msg = await this.waitForMessage();\n this.lifecycle.cancelIdleTimer();\n\n if (!msg) {\n if (this.interrupted && !this.stopped) {\n this.interrupted = false;\n continue;\n }\n break;\n }\n\n await this.setState(\"running\");\n this.interrupted = false;\n await this.callbacks.onEvent({\n type: \"user_message\",\n content: msg.content,\n userId: msg.userId,\n });\n\n // Execute the Claude SDK query with the user's message\n await this.executeQuery(msg.content);\n\n // Discovery ExitPlanMode: agent completed its plan — shut down cleanly.\n // No idle state, no message waiting, no chance of being re-woken.\n if (this.queryBridge?.isDiscoveryCompleted) {\n process.stderr.write(\n \"[conveyor-agent] Discovery completed — entering dormant idle (staying connected)\\n\",\n );\n this.pendingMessages.length = 0;\n if (this._state !== \"idle\") await this.setState(\"idle\");\n const discoveryMsg = await this.waitForMessage();\n if (!discoveryMsg) break;\n process.stderr.write(\n \"[conveyor-agent] Received message while discovery-dormant, resuming\\n\",\n );\n this.queryBridge.isDiscoveryCompleted = false;\n this.completedThisTurn = false;\n this.pendingMessages.unshift(discoveryMsg);\n continue;\n }\n\n if (this.stopped) break;\n if (this.interrupted) {\n this.interrupted = false;\n continue;\n }\n\n // After user message execution, check for auto-mode nudge\n // Skip if a new message arrived during execution (it interrupted the query)\n if (!this.stopped && this.pendingMessages.length === 0) {\n await this.maybeSendPRNudge();\n }\n if (!this.stopped) await this.setState(\"idle\");\n } else if (this._state === \"error\") {\n await this.setState(\"idle\");\n } else {\n break;\n }\n }\n }\n\n /**\n * Handle dormant-after-completed idle. Returns true if a critical message\n * woke us (caller should `continue` the loop), false if we should break\n * (stop signal or dormant timeout fired).\n *\n * The absolute deadline is set on first entry per completion cycle and\n * preserved across re-entries: an inbound critical message cannot extend\n * the bound past `dormantTimeoutMs`. Only a genuine wake (clearing\n * `completedThisTurn`) resets the deadline so the next dormant entry\n * starts a fresh window.\n */\n private async handleDormantIdle(): Promise<boolean> {\n if (this.dormantDeadline === null) {\n this.dormantDeadline = Date.now() + this.lifecycle.config.dormantTimeoutMs;\n process.stderr.write(\n \"[conveyor-agent] Completed — entering dormant idle (staying connected)\\n\",\n );\n }\n this.pendingMessages.length = 0;\n if (this._state !== \"idle\") await this.setState(\"idle\");\n const remainingMs = Math.max(0, this.dormantDeadline - Date.now());\n this.lifecycle.startDormantTimer(remainingMs);\n const dormantMsg = await this.waitForMessage();\n this.lifecycle.cancelDormantTimer();\n if (!dormantMsg) return false;\n const contentPreview =\n dormantMsg.content.length > 80 ? `${dormantMsg.content.slice(0, 80)}...` : dormantMsg.content;\n process.stderr.write(\n `[conveyor-agent] Received message while dormant, resuming: ` +\n `userId=${dormantMsg.userId}, source=${dormantMsg.source || \"unknown\"}, ` +\n `content=\"${contentPreview.replace(/\\n/g, \"\\\\n\")}\"\\n`,\n );\n this.completedThisTurn = false;\n this.dormantDeadline = null;\n this.pendingMessages.unshift(dormantMsg);\n return true;\n }\n\n // ── Initial mode execution ─────────────────────────────────────────\n\n /** Returns true if an initial query was executed, false otherwise. */\n private async executeInitialMode(): Promise<boolean> {\n if (!this.taskContext || !this.fullContext) return false;\n const effectiveMode = this.mode.effectiveMode;\n\n // Pending chat messages already direct the agent (they arrived before it\n // booted) — force submit semantics so they aren't parked behind an\n // unsubmitted prefill: building/review run the initial query as before,\n // discovery falls through to the core loop which processes them.\n const delivery =\n this.pendingMessages.length > 0\n ? \"submit\"\n : (this.queryBridge?.initialPromptDelivery(this.fullContext) ?? \"submit\");\n\n // Submit modes auto-run their initial instructions. Prefill (PTY task\n // chat, manual mode, fresh session) spawns the TUI for ALL modes —\n // including discovery/help, which never auto-run — with the instructions\n // pre-filled and unsubmitted for the human.\n const shouldRun =\n effectiveMode === \"building\" ||\n effectiveMode === \"auto\" ||\n effectiveMode === \"review\" ||\n delivery === \"prefill\";\n\n if (!shouldRun) {\n await this.setState(\"idle\");\n return false;\n }\n\n if (delivery === \"prefill\") {\n // The query parks until the human submits in the TUI. Report\n // waiting_for_input (not running) and bound the wait with the idle\n // timer; the first harness event flips state to running via the\n // onStatusChange hook in createQueryBridge, cancelling the timer.\n await this.setState(\"waiting_for_input\");\n await this.callbacks.onEvent({ type: \"execute_mode\", mode: effectiveMode, delivery });\n // A chat message may have raced the awaits above — let coreLoop process\n // it instead of parking it behind an unsubmitted prefill.\n if (this.pendingMessages.length > 0) {\n if (!this.stopped) await this.setState(\"idle\");\n return false;\n }\n this.lifecycle.startIdleTimer();\n try {\n await this.executeQuery(undefined, delivery);\n } finally {\n this.lifecycle.cancelIdleTimer();\n }\n } else {\n await this.setState(\"running\");\n await this.callbacks.onEvent({ type: \"execute_mode\", mode: effectiveMode });\n await this.executeQuery(undefined, delivery);\n }\n if (!this.stopped) await this.setState(\"idle\");\n return true;\n }\n\n // ── Message waiting ────────────────────────────────────────────────\n\n private waitForMessage(): Promise<IncomingMessage | null> {\n if (this.pendingMessages.length > 0) {\n return Promise.resolve(this.pendingMessages.shift() ?? null);\n }\n return new Promise<IncomingMessage | null>((resolve) => {\n this.inputResolver = resolve;\n });\n }\n\n /** Inject a message (from connection callback or external source) */\n injectMessage(msg: IncomingMessage): void {\n if (this.inputResolver) {\n const resolve = this.inputResolver;\n this.inputResolver = null;\n resolve(msg);\n } else {\n this.pendingMessages.push(msg);\n // Interrupt running query so the new message is processed quickly.\n // waiting_for_input covers a prefilled-but-unsubmitted TUI: the chat\n // message supersedes the prefill (teardown + respawn as follow-up).\n if (this._state === \"running\" || this._state === \"waiting_for_input\") {\n this.queryBridge?.stop();\n }\n }\n }\n\n // ── Query execution with abort handling ────────────────────────────\n\n /** Run queryBridge.execute, swallowing abort errors from stop/softStop. */\n private async executeQuery(\n followUpContent?: string,\n promptDelivery?: \"submit\" | \"prefill\",\n ): Promise<void> {\n if (!this.fullContext || !this.queryBridge) return;\n try {\n await this.queryBridge.execute(this.fullContext, followUpContent, promptDelivery);\n } catch (err) {\n if (this.interrupted || this.stopped) {\n process.stderr.write(\"[conveyor-agent] Query aborted by stop/softStop signal\\n\");\n return;\n }\n throw err;\n }\n }\n\n // ── Stop / soft-stop ───────────────────────────────────────────────\n\n /** Periodic best-effort WIP commit + push during normal agent execution.\n * Covers ungraceful pod termination (OOMKilled, node crash/eviction) where\n * the preStop hook + SIGTERM flush don't get a chance to run. No-ops on a\n * clean tree. Guarded so two ticks can't overlap. Never throws. */\n private async periodicGitFlush(): Promise<void> {\n if (this.periodicFlushInFlight || this.stopped) return;\n this.periodicFlushInFlight = true;\n try {\n const result = await flushPendingChanges(this.config.workspaceDir, {\n wipMessage: \"WIP: periodic auto-commit\",\n refreshToken: async () => {\n try {\n const res = await this.connection.call(\"refreshGithubToken\", {\n sessionId: this.connection.sessionId,\n });\n return res.token;\n } catch {\n return undefined;\n }\n },\n });\n if (result.hadWork) {\n process.stderr.write(\n `[conveyor-agent] Periodic git flush: committed=${result.committed} pushed=${result.pushed}\\n`,\n );\n }\n } catch {\n // best effort — next tick will retry\n } finally {\n this.periodicFlushInFlight = false;\n }\n }\n\n /** Best-effort WIP commit + push on shutdown so in-flight work isn't lost\n * when a claudespace pod is killed. Must be called BEFORE stop() so the\n * connection is still alive for token refresh. Never throws. */\n async flushGitOnShutdown(): Promise<void> {\n try {\n const result = await flushPendingChanges(this.config.workspaceDir, {\n wipMessage: \"WIP: auto-commit on conveyor-agent shutdown\",\n refreshToken: async () => {\n try {\n const res = await this.connection.call(\"refreshGithubToken\", {\n sessionId: this.connection.sessionId,\n });\n return res.token;\n } catch {\n return undefined;\n }\n },\n });\n if (result.hadWork) {\n process.stderr.write(\n `[conveyor-agent] Shutdown git flush: committed=${result.committed} pushed=${result.pushed}\\n`,\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[conveyor-agent] Shutdown git flush failed: ${msg}\\n`);\n }\n }\n\n stop(): void {\n this.stopped = true;\n this.queryBridge?.stop();\n this.lifecycle.destroy();\n this.connection.disconnect();\n if (this.inputResolver) {\n const resolver = this.inputResolver;\n this.inputResolver = null;\n resolver(null);\n }\n }\n\n softStop(): void {\n this.interrupted = true;\n this.queryBridge?.stop();\n // Only null-resolve if no flushed messages are already pending — a message\n // arriving via injectMessage() before the soft stop signal means the agent\n // should process it instead of discarding with a null resolution.\n if (this.inputResolver && this.pendingMessages.length === 0) {\n const resolver = this.inputResolver;\n this.inputResolver = null;\n resolver(null);\n }\n }\n\n // ── Auto-mode PR nudge ──────────────────────────────────────────────\n\n private static readonly MAX_PR_NUDGES = 3;\n\n private needsPRNudge(): boolean {\n if (!this.mode.isAuto || this.stopped) return false;\n if (this.queryBridge?.wasRateLimited) return false;\n if (this.prNudgeCount > SessionRunner.MAX_PR_NUDGES) return false;\n if (!this.taskContext) return false;\n return this.taskContext.status === \"InProgress\" && !this.taskContext.githubPRUrl;\n }\n\n private async refreshTaskContext(): Promise<void> {\n try {\n const ctx = await this.connection.call(\"getTaskContext\", {\n sessionId: this.sessionId,\n includeHistory: false,\n });\n this.taskContext = {\n status: ctx.status,\n plan: ctx.plan,\n storyPointId:\n ctx.storyPoints === null || ctx.storyPoints === undefined\n ? null\n : String(ctx.storyPoints),\n model: ctx.model,\n githubPRUrl: ctx.githubPRUrl,\n };\n // Keep fullContext in sync for PR nudge execution\n if (this.fullContext) {\n this.fullContext.status = ctx.status;\n this.fullContext.plan = ctx.plan;\n this.fullContext.githubPRUrl = ctx.githubPRUrl;\n this.fullContext.model = ctx.model;\n }\n } catch {\n // Continue with stale context\n }\n }\n\n private async maybeSendPRNudge(): Promise<void> {\n await this.refreshTaskContext();\n if (!this.needsPRNudge()) return;\n\n while (!this.stopped && !this.interrupted && this.needsPRNudge()) {\n this.prNudgeCount++;\n\n if (this.prNudgeCount > SessionRunner.MAX_PR_NUDGES) {\n this.connection.postChatMessage(\n `Auto-mode agent failed to open a PR after ${SessionRunner.MAX_PR_NUDGES} nudges. Shutting down.`,\n );\n this.stop();\n return;\n }\n\n const isFirst = this.prNudgeCount === 1;\n const chatMsg = isFirst\n ? \"Auto-nudge: Task is still In Progress with no PR. Prompting agent to continue...\"\n : `Auto-nudge (attempt ${this.prNudgeCount}/${SessionRunner.MAX_PR_NUDGES}): Task still has no PR. Prompting agent again...`;\n\n const prompt = isFirst\n ? \"You are in Auto mode and your task is still In Progress with no pull request. You MUST create a pull request before finishing. Use the create_pull_request tool now to open a PR for your changes. If you are blocked, explain what is preventing you from creating a PR.\"\n : `This is reminder ${this.prNudgeCount} of ${SessionRunner.MAX_PR_NUDGES}. You MUST open a pull request using create_pull_request NOW or explain what is blocking you. Do NOT go idle — either create the PR or describe the specific blocker.`;\n\n this.connection.postChatMessage(chatMsg);\n await this.setState(\"running\");\n await this.callbacks.onEvent({ type: \"pr_nudge\", prompt });\n\n // Execute the nudge prompt through the query bridge\n if (this.interrupted || this.stopped) return;\n await this.executeQuery(prompt);\n if (this.interrupted || this.stopped) return;\n\n // Re-fetch to check if PR was created\n await this.refreshTaskContext();\n }\n }\n\n // ── Context & bridge construction ────────────────────────────────\n\n // oxlint-disable-next-line complexity\n private buildFullContext(ctx: TaskContextDTO): TaskContext {\n const chatHistory = mapChatHistory(ctx.chatHistory);\n\n return {\n taskId: ctx.id,\n projectId: ctx.projectId ?? \"\",\n title: ctx.title,\n description: ctx.description,\n plan: ctx.plan,\n status: ctx.status,\n chatHistory,\n agentId: ctx.agentId ?? null,\n _runnerSessionId: this.sessionId,\n agentInstructions: ctx.agentInstructions ?? \"\",\n model: ctx.model,\n githubBranch: ctx.githubBranch ?? \"\",\n baseBranch: ctx.baseBranch ?? \"\",\n projectName: ctx.projectName ?? null,\n projectDescription: ctx.projectDescription ?? null,\n githubPRUrl: ctx.githubPRUrl,\n claudeSessionId: ctx.claudeSessionId ?? null,\n lastSeenMessageId: ctx.lastSeenMessageId ?? null,\n isParentTask: !!ctx.parentTaskId,\n storyPoints: ctx.storyPoints ?? undefined,\n projectAgents: ctx.projectAgents ?? undefined,\n projectTags: ctx.projectTags ?? undefined,\n taskTagIds: ctx.taskTagIds ?? undefined,\n projectObjectives: ctx.projectObjectives ?? undefined,\n incidents: ctx.incidents ?? undefined,\n recentRelatedTasks: ctx.recentRelatedTasks ?? undefined,\n agentSettings: ctx.agentSettings ?? null,\n agentMode: ctx.agentMode ?? undefined,\n isAuto: ctx.isAuto,\n };\n }\n\n private createQueryBridge(): QueryBridge {\n const runnerConfig: AgentRunnerConfig = {\n conveyorApiUrl: this.config.connection.apiUrl,\n taskToken: this.config.connection.taskToken,\n taskId: this.fullContext?.taskId ?? \"\",\n model: this.fullContext?.model ?? \"claude-sonnet-4-20250514\",\n instructions: this.fullContext?.agentInstructions ?? \"\",\n workspaceDir: this.config.workspaceDir,\n mode: this.config.runnerMode,\n isAuto: this.config.isAuto,\n };\n\n const bridge = new QueryBridge(\n this.connection,\n this.mode,\n runnerConfig,\n {\n onStatusChange: (status) => {\n // A prefilled initial query reports running when the human submits\n // in the TUI (first harness event) — leave waiting_for_input and\n // stop the prefill-wait idle timer so a long working turn isn't\n // killed by it.\n if (status === \"running\" && this._state === \"waiting_for_input\") {\n this._state = \"running\";\n this.lifecycle.cancelIdleTimer();\n }\n return this.callbacks.onStatusChange(status as AgentRunnerStatus);\n },\n onEvent: (event) => {\n // Track completion for the agent-side guard — once the agent emits\n // \"completed\", the core loop will stop accepting further messages.\n if ((event as Record<string, unknown>).type === \"completed\") {\n this.completedThisTurn = true;\n // Immediately refresh the server's heartbeat timestamp so\n // lastHeartbeatAt can't drift stale while the agent sits dormant\n // waiting for a critical wake-up (e.g. review_trigger). The\n // periodic 30s timer would otherwise leave up to a ~29s gap\n // between the `completed` event and the next heartbeat.\n void this.connection.sendHeartbeat();\n }\n return this.callbacks.onEvent(event);\n },\n },\n this.config.workspaceDir,\n );\n\n bridge.isParentTask = this.fullContext?.isParentTask ?? false;\n bridge.onSoftStop = () => {\n process.stderr.write(\"[conveyor-agent] Soft stop requested (discovery ExitPlanMode)\\n\");\n this.softStop();\n };\n\n bridge.onModeTransition = (newMode: AgentMode) => {\n const oldMode = this.mode.effectiveMode;\n process.stderr.write(`[conveyor-agent] Mode transition: ${oldMode} → ${newMode}\\n`);\n this.connection.sendEvent({ type: \"mode_transition\", from: oldMode, to: newMode });\n this.mode.pendingModeRestart = true;\n this.connection.emitModeChanged(newMode);\n this.softStop();\n };\n\n return bridge;\n }\n\n // ── Private helpers ────────────────────────────────────────────────\n\n private wireConnectionCallbacks(): void {\n this.connection.onMessage((msg) => this.injectMessage(msg));\n this.connection.onStop(() => this.stop());\n this.connection.onSoftStop(() => this.softStop());\n this.connection.onModeChange((data) => {\n const action = this.mode.handleModeChange(data.agentMode);\n if (action.type === \"start_auto\") {\n this.connection.emitModeChanged(this.mode.effectiveMode);\n this.softStop();\n } else if (action.type === \"restart_query\") {\n // Server-initiated mode transition (e.g., CI-triggered review).\n // Clear claudeSessionId to prevent SDK resume across model changes\n // (reviewer agent may use a different model than the task agent).\n if (this.fullContext && action.newMode === \"review\") {\n this.fullContext.claudeSessionId = null;\n }\n // On building transition, re-fetch context to pick up the newly created\n // branch (branch creation is deferred until building mode).\n // Also refresh for \"auto\" post-exit (defense-in-depth if \"auto\" leaks through).\n if (\n this.fullContext &&\n (action.newMode === \"building\" ||\n (action.newMode === \"auto\" && this.mode.hasExitedPlanMode))\n ) {\n void this.refreshBranchForBuilding();\n }\n // Exit dormant idle so the review_trigger message that follows\n // is processed in the normal idle path (which handles interrupted\n // correctly without draining pendingMessages).\n this.completedThisTurn = false;\n this.connection.emitModeChanged(action.newMode);\n this.softStop();\n }\n });\n this.connection.onApiKeyUpdate((data) => {\n if (data.isSubscription) {\n process.env.CLAUDE_CODE_OAUTH_TOKEN = data.apiKey;\n delete process.env.ANTHROPIC_API_KEY;\n // The interactive TUI reads credentials from disk, not the env var —\n // refresh the synthesized file so the next PTY spawn (and any on-401\n // re-read by a live CLI) picks up the rotated subscription token.\n void ensureClaudeCredentials();\n } else {\n process.env.ANTHROPIC_API_KEY = data.apiKey;\n delete process.env.CLAUDE_CODE_OAUTH_TOKEN;\n // Drop our synthesized subscription credentials so a stale token\n // can't keep authenticating future TUI spawns over the API key.\n void removeConveyorCredentials();\n }\n });\n this.connection.onPullBranch(({ branch }) => {\n handlePullBranch(this.config.workspaceDir, branch);\n });\n }\n\n /**\n * Rehydrate CostTracker from server. Caps at 3s so a slow API call never\n * blocks agent startup — on timeout/error we fall through with a $0 tracker\n * (the existing behavior before this rehydration path was added).\n */\n private async seedCostTrackerFromServer(): Promise<void> {\n if (!this.queryBridge) return;\n const TIMEOUT_MS = 3000;\n try {\n const timeout = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), TIMEOUT_MS);\n });\n const fetched = await Promise.race([this.connection.getCumulativeSpending(), timeout]);\n if (fetched) {\n this.queryBridge.seedCostTracker(fetched.totalCostUsd, fetched.modelUsage);\n process.stderr.write(\n `[conveyor-agent] CostTracker seeded: $${fetched.totalCostUsd.toFixed(4)} across ${fetched.modelUsage.length} model(s)\\n`,\n );\n } else {\n process.stderr.write(\n \"[conveyor-agent] CostTracker seed timed out after 3s — starting at $0\\n\",\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[conveyor-agent] CostTracker seed failed: ${msg} — starting at $0\\n`);\n }\n }\n\n /** Proactively refresh the GitHub token before the 1-hour expiry. */\n private async refreshGithubToken(): Promise<void> {\n try {\n const res = await this.connection.call(\"refreshGithubToken\", {\n sessionId: this.connection.sessionId,\n });\n updateRemoteToken(this.config.workspaceDir, res.token);\n process.env.GITHUB_TOKEN = res.token;\n process.env.GH_TOKEN = res.token;\n process.stderr.write(\"[conveyor-agent] Proactively refreshed GitHub token\\n\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`[conveyor-agent] Warning: proactive token refresh failed: ${msg}\\n`);\n }\n }\n\n /** Re-fetch task context to pick up a newly created branch and check it out. */\n private async refreshBranchForBuilding(): Promise<void> {\n try {\n const ctx = await this.connection.call(\"getTaskContext\", {\n sessionId: this.sessionId,\n includeHistory: false,\n });\n if (ctx?.githubBranch && this.fullContext) {\n this.fullContext.githubBranch = ctx.githubBranch;\n ensureOnTaskBranch(this.config.workspaceDir, ctx.githubBranch);\n }\n } catch {\n process.stderr.write(\n \"[conveyor-agent] Warning: failed to refresh branch for building transition\\n\",\n );\n }\n }\n\n private async setState(status: AgentRunnerStatus): Promise<void> {\n this._state = status;\n await this.connection.emitStatus(status);\n await this.callbacks.onStatusChange(status);\n }\n\n private async shutdown(finalState: AgentRunnerStatus): Promise<void> {\n process.stderr.write(`[conveyor-agent] Shutdown: reason=${finalState}\\n`);\n this.connection.sendEvent({ type: \"shutdown\", reason: finalState });\n this.lifecycle.destroy();\n await this.setState(finalState);\n this.connection.disconnect();\n this._finalState = finalState;\n }\n\n private _finalState: AgentRunnerStatus | null = null;\n\n /** The final status after run() completes. Use to determine exit code. */\n get finalState(): AgentRunnerStatus | null {\n return this._finalState;\n }\n\n private buildTaskContextSnapshot(): Record<string, unknown> {\n return {\n isParentTask: this.fullContext?.isParentTask ?? false,\n status: this.taskContext?.status,\n taskTitle: this.fullContext?.title,\n hasExistingPR: !!this.fullContext?.githubPRUrl,\n hasExistingSession: !!this.fullContext?.claudeSessionId,\n chatHistoryLength: this.fullContext?.chatHistory?.length ?? 0,\n tagIds: this.fullContext?.taskTagIds ?? [],\n };\n }\n\n private buildInitializationContext(): Record<string, unknown> {\n return {\n mode: this.mode.effectiveMode,\n runnerMode: this.config.runnerMode ?? \"task\",\n sessionId: this.sessionId,\n ...this.buildTaskContextSnapshot(),\n model: this.taskContext?.model,\n isAuto: this.config.isAuto ?? false,\n subscriptionKeyLabel: process.env.CONVEYOR_SUBSCRIPTION_KEY_LABEL ?? null,\n };\n }\n\n private logInitialization(): void {\n const context = this.buildInitializationContext();\n process.stderr.write(`[conveyor-agent] Initialized: ${JSON.stringify(context)}\\n`);\n this.connection.sendEvent({ type: \"session_manifest\", ...context });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport type {\n AgentSessionServiceMethods,\n SocketResponse,\n TagAuditRunnerRequest,\n TaskAuditRunnerRequest,\n} from \"@project/shared\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"ProjectConnection\");\n\n// ── Configuration ──────────────────────────────────────────────────────────\n\nexport interface ProjectConnectionConfig {\n apiUrl: string;\n projectToken: string;\n projectId: string;\n}\n\n// ── Incoming event types ───────────────────────────────────────────────────\n\nexport interface TaskAssignment {\n taskId: string;\n taskToken: string;\n sessionId?: string;\n apiUrl: string;\n mode: string;\n branch: string;\n devBranch: string;\n useWorktree?: boolean;\n isAuto?: boolean;\n useSandbox?: boolean;\n agentMode?: string;\n pty?: boolean;\n /**\n * Decrypted Claude Code subscription token (`CLAUDE_CODE_OAUTH_TOKEN`) for the\n * assigning user, resolved server-side. Forwarded into the forked child's env\n * so the `claude` CLI is authenticated without a login prompt. Absent when the\n * user has no key configured — the child then falls back to the runner\n * machine's own `~/.claude` login.\n */\n claudeCodeOauthToken?: string;\n}\n\nexport interface IncomingChatMessage {\n content: string;\n userId: string;\n chatId?: string;\n projectId: string;\n /** When set, only the runner whose session matches should react. Other\n * runners on the same project room must ignore the message. */\n targetSessionId?: string | null;\n timestamp: string;\n}\n\nexport interface SwitchBranchRequest {\n branch: string;\n syncAfter?: boolean;\n}\n\n// ── Connection class ───────────────────────────────────────────────────────\n\nconst EVENT_BATCH_MS = 500;\n\nexport class ProjectConnection {\n private socket: Socket | null = null;\n private readonly config: ProjectConnectionConfig;\n private eventBuffer: Array<{ event: Record<string, unknown> }> = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectCallbacks: Array<() => void> = [];\n\n constructor(config: ProjectConnectionConfig) {\n this.config = config;\n }\n\n get projectId(): string {\n return this.config.projectId;\n }\n\n get connected(): boolean {\n return this.socket?.connected ?? false;\n }\n\n // ── Typed service method call ──────────────────────────────────────────\n\n call<M extends keyof AgentSessionServiceMethods>(\n method: M,\n payload: AgentSessionServiceMethods[M][\"payload\"],\n ): Promise<AgentSessionServiceMethods[M][\"response\"]> {\n const socket = this.requireSocket();\n return new Promise((resolve, reject) => {\n socket.emit(\n `agentSessionService:${String(method)}`,\n payload,\n (response: SocketResponse<AgentSessionServiceMethods[M][\"response\"]>) => {\n if (response.success && response.data !== undefined) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? `Service call failed: ${String(method)}`));\n }\n },\n );\n });\n }\n\n // ── Connection lifecycle ───────────────────────────────────────────────\n\n connect(): Promise<void> {\n if (!this.config.apiUrl) {\n return Promise.reject(new Error(\"Cannot connect: apiUrl is empty\"));\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n logger.info(\"Connecting\", { apiUrl: this.config.apiUrl, projectId: this.config.projectId });\n\n this.socket = io(this.config.apiUrl, {\n auth: {\n projectToken: this.config.projectToken,\n runnerMode: \"project\",\n },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: { \"ngrok-skip-browser-warning\": \"true\" },\n });\n\n this.socket.on(\"connect\", () => {\n // Always re-subscribe to project room (handles both first connect and reconnect)\n this.socket?.emit(\"projectService:subscribe\", { entryId: this.config.projectId });\n if (!settled) {\n settled = true;\n resolve();\n }\n logger.info(\"Connected to API\");\n });\n\n this.socket.on(\"connect_error\", (error: Error) => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(\n new Error(`Failed to connect after ${maxInitialAttempts} attempts: ${error.message}`),\n );\n }\n });\n\n this.socket.on(\"disconnect\", (reason: string) => {\n logger.warn(\"Disconnected from API\", { reason });\n });\n\n this.socket.io.on(\"reconnect\", () => {\n logger.info(\"Reconnected to API\");\n for (const cb of this.reconnectCallbacks) cb();\n });\n });\n }\n\n disconnect(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n\n onReconnect(callback: () => void): void {\n this.reconnectCallbacks.push(callback);\n }\n\n // ── Event listeners ────────────────────────────────────────────────────\n\n onTaskAssignment(callback: (assignment: TaskAssignment) => void): void {\n this.requireSocket().on(\"projectRunner:assignTask\", callback);\n }\n\n onStopTask(callback: (data: { taskId: string }) => void): void {\n this.requireSocket().on(\"projectRunner:stopTask\", callback);\n }\n\n onShutdown(callback: () => void): void {\n this.requireSocket().on(\"projectRunner:shutdown\", callback);\n }\n\n onDisconnect(callback: () => void): void {\n this.requireSocket().on(\"projectRunner:disconnect\", callback);\n }\n\n onChatMessage(callback: (msg: IncomingChatMessage) => void): void {\n this.requireSocket().on(\"projectRunner:incomingChatMessage\", callback);\n }\n\n onSwitchBranch(\n callback: (\n data: SwitchBranchRequest,\n cb: (res: { ok: boolean; error?: string }) => void,\n ) => void,\n ): void {\n this.requireSocket().on(\"projectRunner:switchBranch\", callback);\n }\n\n onSyncEnvironment(callback: (cb: (res: { ok: boolean; error?: string }) => void) => void): void {\n this.requireSocket().on(\"projectRunner:syncEnvironment\", callback);\n }\n\n onRestartStartCommand(\n callback: (cb: (res: { ok: boolean; error?: string }) => void) => void,\n ): void {\n this.requireSocket().on(\"projectRunner:restartStartCommand\", callback);\n }\n\n onAuditTags(callback: (request: TagAuditRunnerRequest) => void): void {\n this.requireSocket().on(\"projectRunner:auditTags\", callback);\n }\n\n onAuditTasks(callback: (request: TaskAuditRunnerRequest) => void): void {\n this.requireSocket().on(\"projectRunner:auditTasks\", callback);\n }\n\n // ── Outgoing helpers ───────────────────────────────────────────────────\n\n sendHeartbeat(): void {\n void this.call(\"projectRunnerHeartbeat\", { projectId: this.config.projectId }).catch(() => {});\n }\n\n sendEvent(event: Record<string, unknown>): void {\n this.eventBuffer.push({ event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => this.flushEvents(), EVENT_BATCH_MS);\n }\n }\n\n emitStatus(status: \"busy\" | \"idle\"): void {\n void this.call(\"reportProjectAgentStatus\", {\n projectId: this.config.projectId,\n status,\n }).catch(() => {});\n }\n\n emitTaskStarted(taskId: string): void {\n this.sendEvent({ type: \"task_started\", taskId });\n }\n\n emitTaskStopped(taskId: string, reason: string): void {\n this.sendEvent({ type: \"task_stopped\", taskId, reason });\n }\n\n // ── Private helpers ────────────────────────────────────────────────────\n\n private flushEvents(): void {\n this.flushTimer = null;\n if (this.eventBuffer.length === 0) return;\n const batch = this.eventBuffer;\n this.eventBuffer = [];\n for (const { event } of batch) {\n void this.call(\"reportProjectAgentEvent\", {\n projectId: this.config.projectId,\n event,\n }).catch(() => {});\n }\n }\n\n private requireSocket(): Socket {\n if (!this.socket) throw new Error(\"Not connected\");\n return this.socket;\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"CommitWatcher\");\n\nexport interface CommitWatcherConfig {\n projectDir: string;\n pollIntervalMs: number;\n debounceMs: number;\n}\n\nexport interface NewCommitsData {\n branch: string;\n previousSha: string;\n newCommitSha: string;\n commitCount: number;\n latestMessage: string;\n latestAuthor: string;\n}\n\nexport interface CommitWatcherCallbacks {\n onNewCommits: (data: NewCommitsData) => Promise<void>;\n}\n\nexport class CommitWatcher {\n private interval: ReturnType<typeof setInterval> | null = null;\n private lastKnownRemoteSha: string | null = null;\n private branch: string | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private isSyncing = false;\n\n constructor(\n private config: CommitWatcherConfig,\n private callbacks: CommitWatcherCallbacks,\n ) {}\n\n start(branch: string): void {\n this.stop();\n this.branch = branch;\n this.lastKnownRemoteSha = this.getLocalHeadSha();\n this.interval = setInterval(() => void this.poll(), this.config.pollIntervalMs);\n logger.info(\"Commit watcher started\", {\n branch,\n baseSha: this.lastKnownRemoteSha?.slice(0, 8),\n });\n }\n\n stop(): void {\n if (this.interval) clearInterval(this.interval);\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.interval = null;\n this.debounceTimer = null;\n this.branch = null;\n this.lastKnownRemoteSha = null;\n this.isSyncing = false;\n }\n\n private getLocalHeadSha(): string {\n return execSync(\"git rev-parse HEAD\", {\n cwd: this.config.projectDir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n }\n\n private poll(): void {\n if (!this.branch || this.isSyncing) return;\n\n try {\n execSync(`git fetch origin ${this.branch} --quiet`, {\n cwd: this.config.projectDir,\n stdio: \"ignore\",\n timeout: 30_000,\n });\n\n const remoteSha = execSync(`git rev-parse origin/${this.branch}`, {\n cwd: this.config.projectDir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n\n if (remoteSha !== this.lastKnownRemoteSha) {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(\n () => void this.handleNewCommits(remoteSha),\n this.config.debounceMs,\n );\n }\n } catch {\n // Network error, branch deleted, etc. — silently retry next interval\n }\n }\n\n private async handleNewCommits(remoteSha: string): Promise<void> {\n if (!this.branch) return;\n const previousSha = this.lastKnownRemoteSha ?? \"HEAD\";\n\n let commitCount = 1;\n let latestMessage = \"\";\n let latestAuthor = \"\";\n try {\n const countOutput = execSync(`git rev-list --count ${previousSha}..origin/${this.branch}`, {\n cwd: this.config.projectDir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n commitCount = parseInt(countOutput, 10) || 1;\n\n const logOutput = execSync(`git log -1 --format=\"%s|||%an\" origin/${this.branch}`, {\n cwd: this.config.projectDir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim();\n const parts = logOutput.split(\"|||\");\n latestMessage = parts[0] ?? \"\";\n latestAuthor = parts[1] ?? \"\";\n } catch {\n // best effort — counts and messages are informational\n }\n\n this.lastKnownRemoteSha = remoteSha;\n this.isSyncing = true;\n\n logger.info(\"New commits detected\", {\n branch: this.branch,\n commitCount,\n sha: remoteSha.slice(0, 8),\n });\n\n try {\n await this.callbacks.onNewCommits({\n branch: this.branch,\n previousSha,\n newCommitSha: remoteSha,\n commitCount,\n latestMessage,\n latestAuthor,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.error(\"Error handling new commits\", { error: msg });\n } finally {\n this.isSyncing = false;\n }\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { hasUncommittedChanges } from \"./git-utils.js\";\n\nconst WORKTREE_DIR = \".worktrees\";\n\nexport function ensureWorktree(projectDir: string, taskId: string, branch?: string): string {\n if (projectDir.includes(`/${WORKTREE_DIR}/`)) {\n return projectDir;\n }\n\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n\n if (existsSync(worktreePath)) {\n if (branch) {\n if (hasUncommittedChanges(worktreePath)) {\n return worktreePath;\n }\n try {\n execSync(`git checkout --detach origin/${branch}`, {\n cwd: worktreePath,\n stdio: \"ignore\",\n });\n } catch {\n /* branch doesn't exist on remote yet */\n }\n }\n return worktreePath;\n }\n\n const ref = branch ? `origin/${branch}` : \"HEAD\";\n execSync(`git worktree add --detach \"${worktreePath}\" ${ref}`, {\n cwd: projectDir,\n stdio: \"ignore\",\n });\n\n return worktreePath;\n}\n\n/**\n * Detach any task worktree that has `branch` checked out, releasing the branch lock\n * so the main project directory can check it out. Only touches worktrees inside\n * `.worktrees/` — never the main project directory.\n */\nexport function detachWorktreeBranch(projectDir: string, branch: string): void {\n try {\n const output = execSync(\"git worktree list --porcelain\", {\n cwd: projectDir,\n encoding: \"utf-8\",\n });\n const entries = output.split(\"\\n\\n\");\n for (const entry of entries) {\n const lines = entry.trim().split(\"\\n\");\n const worktreeLine = lines.find((l) => l.startsWith(\"worktree \"));\n const branchLine = lines.find((l) => l.startsWith(\"branch \"));\n if (!worktreeLine || branchLine !== `branch refs/heads/${branch}`) continue;\n\n const worktreePath = worktreeLine.replace(\"worktree \", \"\");\n if (!worktreePath.includes(`/${WORKTREE_DIR}/`)) continue;\n\n try {\n execSync(\"git checkout --detach\", { cwd: worktreePath, stdio: \"ignore\" });\n } catch {\n /* best effort */\n }\n }\n } catch {\n /* best effort */\n }\n}\n\n/**\n * Force-remove is intentional: this runs after task completion or explicit stop.\n * Any uncommitted changes at this point are scratch artifacts, not valuable work.\n */\nexport function removeWorktree(projectDir: string, taskId: string): void {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n if (!existsSync(worktreePath)) return;\n try {\n execSync(`git worktree remove \"${worktreePath}\" --force`, {\n cwd: projectDir,\n stdio: \"ignore\",\n });\n } catch {\n /* best effort */\n }\n}\n","import { spawn, execSync, type ChildProcess } from \"node:child_process\";\n\nexport function runSetupCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Setup command exited with code ${code}`));\n }\n });\n\n child.on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\nconst AUTH_TOKEN_TIMEOUT_MS = 30_000;\n\nexport function runAuthTokenCommand(cmd: string, userEmail: string, cwd: string): string | null {\n try {\n const output = execSync(`${cmd} ${JSON.stringify(userEmail)}`, {\n cwd,\n timeout: AUTH_TOKEN_TIMEOUT_MS,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n env: { ...process.env },\n });\n const token = output.toString().trim();\n return token || null;\n } catch {\n return null;\n }\n}\n\nexport function runStartCommand(\n cmd: string,\n cwd: string,\n onOutput: (stream: \"stdout\" | \"stderr\", data: string) => void,\n): ChildProcess {\n const child = spawn(\"sh\", [\"-c\", cmd], {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n env: { ...process.env },\n });\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stdout\", chunk.toString());\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n onOutput(\"stderr\", chunk.toString());\n });\n\n child.unref();\n return child;\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { ProjectConnection } from \"../connection/project-connection.js\";\nimport { textResult } from \"./helpers.js\";\nimport { buildProjectActionTools } from \"./project-action-tools.js\";\nimport { buildProjectSuggestionDependencyTools } from \"./project-suggestion-dependency-tools.js\";\n\n/**\n * Returns the requesting user's id for the in-flight chat turn, or undefined\n * when no chat is being processed (e.g. tag/task audits, idle ticks). Wired\n * from `runChatQuery` so mutation handlers attribute work to the asking user\n * and run ACL checks against THEM, not the runner's project token.\n */\nexport type GetRequestingUserId = () => string | undefined;\n\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : \"Unknown error\";\n}\n\n// ── Read-only Task Discovery ──────────────────────────────────────────\n\nconst DESCRIPTION_PREVIEW_CHARS = 300;\n\n/** List/search results omit `plan` and truncate `description` — `get_project_task` returns the full record. */\nfunction summarizeTask(task: unknown): unknown {\n if (typeof task !== \"object\" || task === null) return task;\n const { plan, description, ...rest } = task as Record<string, unknown>;\n const summary: Record<string, unknown> = { ...rest };\n summary.description =\n typeof description === \"string\" && description.length > DESCRIPTION_PREVIEW_CHARS\n ? `${description.slice(0, DESCRIPTION_PREVIEW_CHARS)}… [truncated — use get_project_task for the full description]`\n : (description ?? null);\n summary.hasPlan = typeof plan === \"string\" && plan.length > 0;\n return summary;\n}\n\nfunction summarizeTasks(tasks: unknown): unknown {\n return Array.isArray(tasks) ? tasks.map(summarizeTask) : tasks;\n}\n\nfunction buildListTasksTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"list_tasks\",\n \"List tasks in the project. Optionally filter by status or assignment (a specific assignee, or unassigned tasks). Returns summaries — plan omitted, description truncated; use get_project_task for full details.\",\n {\n status: z.string().optional().describe(\"Filter by task status\"),\n assigneeId: z.string().optional().describe(\"Filter by assigned user ID\"),\n unassigned: z\n .boolean()\n .optional()\n .describe(\"Only return tasks with no assignee (mutually exclusive with assigneeId)\"),\n limit: z.number().optional().describe(\"Max number of tasks to return (default 50)\"),\n },\n async (params) => {\n try {\n const tasks = await connection.call(\"listProjectTasks\", { projectId, ...params });\n return textResult(JSON.stringify(summarizeTasks(tasks), null, 2));\n } catch (error) {\n return textResult(`Failed to list tasks: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildGetProjectTaskTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"get_project_task\",\n \"Get detailed information about a task in this project (chat messages, child tasks, session). Project-runner scope.\",\n { task_id: z.string().describe(\"The task ID to look up\") },\n async ({ task_id }) => {\n try {\n const task = await connection.call(\"getProjectTask\", { projectId, taskId: task_id });\n return textResult(JSON.stringify(task, null, 2));\n } catch (error) {\n return textResult(`Failed to get task: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildSearchTasksTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"search_tasks\",\n \"Search tasks by tags, text query, status filters, or assignment. Returns summaries — plan omitted, description truncated; use get_project_task for full details.\",\n {\n tagNames: z.array(z.string()).optional().describe(\"Filter by tag names\"),\n searchQuery: z.string().optional().describe(\"Text search in title/description\"),\n statusFilters: z.array(z.string()).optional().describe(\"Filter by statuses\"),\n assigneeId: z.string().optional().describe(\"Filter by assigned user ID\"),\n unassigned: z\n .boolean()\n .optional()\n .describe(\"Only return tasks with no assignee (mutually exclusive with assigneeId)\"),\n limit: z.number().optional().describe(\"Max results (default 20)\"),\n },\n async (params) => {\n try {\n const tasks = await connection.call(\"searchProjectTasks\", { projectId, ...params });\n return textResult(JSON.stringify(summarizeTasks(tasks), null, 2));\n } catch (error) {\n return textResult(`Failed to search tasks: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildListSubtasksTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"list_subtasks\",\n \"List the immediate child tasks under a parent task. Use to coordinate subtask work — see status, ordering, and PR state.\",\n { task_id: z.string().describe(\"Parent task ID\") },\n async ({ task_id }) => {\n try {\n const subtasks = await connection.call(\"listProjectSubtasks\", {\n projectId,\n taskId: task_id,\n });\n return textResult(JSON.stringify(subtasks, null, 2));\n } catch (error) {\n return textResult(`Failed to list subtasks: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildListTagsTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"list_tags\",\n \"List all tags available in the project.\",\n {},\n async () => {\n try {\n const tags = await connection.call(\"listProjectTags\", { projectId });\n return textResult(JSON.stringify(tags, null, 2));\n } catch (error) {\n return textResult(`Failed to list tags: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildListProjectMembersTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"list_project_members\",\n \"List project members with user ID, name, email, and access level. Use to resolve a person's name or email to a user ID for task assignment or review.\",\n {},\n async () => {\n try {\n const members = await connection.call(\"listProjectMembers\", { projectId });\n return textResult(JSON.stringify(members, null, 2));\n } catch (error) {\n return textResult(`Failed to list project members: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildGetProjectSummaryTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"get_project_summary\",\n \"Get a summary of the project including task counts by status and active builds.\",\n {},\n async () => {\n try {\n const summary = await connection.call(\"getProjectSummary\", { projectId });\n return textResult(JSON.stringify(summary, null, 2));\n } catch (error) {\n return textResult(`Failed to get project summary: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\n// ── Chat Tools ─────────────────────────────────────────────────────────\n\nfunction buildPostToChatTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"post_to_chat\",\n \"Post an out-of-band message into a chat. Omit task_id to post into the project chat; pass task_id to post into a specific task's chat. Normal replies already appear in chat automatically.\",\n {\n message: z.string().describe(\"The message content to post\"),\n task_id: z\n .string()\n .optional()\n .describe(\"Task ID to post into a specific task's chat. Omit for the project chat.\"),\n },\n async ({ message, task_id }) => {\n try {\n const requestingUserId = getRequestingUserId();\n if (task_id) {\n await connection.call(\"postToProjectTaskChat\", {\n projectId,\n taskId: task_id,\n content: message,\n ...(requestingUserId ? { requestingUserId } : {}),\n });\n return textResult(JSON.stringify({ posted: true, target: `task:${task_id}` }));\n }\n await connection.call(\"postProjectAgentMessage\", { projectId, content: message });\n return textResult(JSON.stringify({ posted: true, target: \"project\" }));\n } catch (error) {\n return textResult(`Failed to post message: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildReadChatHistoryTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"read_chat_history\",\n \"Read recent messages from a chat. Omit chat_id to read the project chat; pass a chat_id to read a specific chat.\",\n {\n chat_id: z.string().optional().describe(\"Chat ID to read. Omit for the project chat.\"),\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 50)\"),\n },\n async ({ chat_id, limit }) => {\n try {\n const messages = await connection.call(\"getProjectChatHistory\", {\n projectId,\n ...(chat_id !== undefined && { chatId: chat_id }),\n ...(limit !== undefined && { limit }),\n });\n return textResult(JSON.stringify(messages, null, 2));\n } catch (error) {\n return textResult(`Failed to read chat history: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildReadTaskChatTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"read_task_chat\",\n \"Read recent human/user chat messages for a specific task in this project. For agent execution logs use get_task_logs.\",\n {\n task_id: z.string().describe(\"The task ID whose chat to read\"),\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n },\n async ({ task_id, limit }) => {\n try {\n const messages = await connection.call(\"getProjectTaskChat\", {\n projectId,\n taskId: task_id,\n ...(limit !== undefined && { limit }),\n });\n return textResult(JSON.stringify(messages, null, 2));\n } catch (error) {\n return textResult(`Failed to read task chat: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\nfunction buildGetTaskLogsTool(connection: ProjectConnection) {\n const projectId = connection.projectId;\n return defineTool(\n \"get_task_logs\",\n \"Read CLI execution logs for a task — agent reasoning, tool calls, and setup/dev-server output. For human chat use read_task_chat.\",\n {\n task_id: z.string().describe(\"Task ID to read logs from\"),\n source: z\n .enum([\"agent\", \"application\"])\n .optional()\n .describe(\"Filter by log source. Omit for all logs.\"),\n limit: z\n .number()\n .optional()\n .describe(\"Max number of log entries to return (default 50, max 500).\"),\n },\n async ({ task_id, source, limit }) => {\n try {\n const logs = await connection.call(\"getProjectTaskCli\", {\n projectId,\n taskId: task_id,\n ...(source !== undefined && { source }),\n ...(limit !== undefined && { limit }),\n });\n return textResult(JSON.stringify(logs, null, 2));\n } catch (error) {\n return textResult(`Failed to fetch task logs: ${errorMessage(error)}`);\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n}\n\n// ── Aggregator ─────────────────────────────────────────────────────────\n\nexport function buildProjectTools(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId = () => undefined,\n) {\n return [\n buildListTasksTool(connection),\n buildGetProjectTaskTool(connection),\n buildSearchTasksTool(connection),\n buildListSubtasksTool(connection),\n buildListTagsTool(connection),\n buildListProjectMembersTool(connection),\n buildGetProjectSummaryTool(connection),\n buildPostToChatTool(connection, getRequestingUserId),\n buildReadChatHistoryTool(connection),\n buildReadTaskChatTool(connection),\n buildGetTaskLogsTool(connection),\n ...buildProjectActionTools(connection, getRequestingUserId),\n ...buildProjectSuggestionDependencyTools(connection, getRequestingUserId),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { ProjectConnection } from \"../connection/project-connection.js\";\nimport { textResult } from \"./helpers.js\";\nimport { errorMessage, type GetRequestingUserId } from \"./project-tools.js\";\n\nconst SP_DESCRIPTION = \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n\nexport function withRequestingUser<T extends Record<string, unknown>>(\n payload: T,\n getRequestingUserId: GetRequestingUserId,\n): T & { requestingUserId?: string } {\n const requestingUserId = getRequestingUserId();\n return requestingUserId ? { ...payload, requestingUserId } : payload;\n}\n\n// ── Task Mutation Tools ───────────────────────────────────────────────\n\nfunction buildCreateTaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"create_task\",\n \"Create a new task in the project.\",\n {\n title: z.string().describe(\"Task title\"),\n description: z.string().optional().describe(\"Task description\"),\n plan: z.string().optional().describe(\"Implementation plan in markdown\"),\n status: z.string().optional().describe(\"Initial status (default: Planning)\"),\n },\n async (params) => {\n try {\n const result = await connection.call(\n \"createProjectTask\",\n withRequestingUser({ projectId, ...params }, getRequestingUserId),\n );\n return textResult(`Task created: ${result.slug} (ID: ${result.id})`);\n } catch (error) {\n return textResult(`Failed to create task: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildUpdateProjectTaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"update_project_task\",\n \"Update an existing task's title, description, plan, status, or assignee. Project-runner scope.\",\n {\n task_id: z.string().describe(\"The task ID to update\"),\n title: z.string().optional().describe(\"New title\"),\n description: z.string().optional().describe(\"New description\"),\n plan: z.string().optional().describe(\"New plan in markdown\"),\n status: z.string().optional().describe(\"New status\"),\n assignedUserId: z\n .string()\n .nullable()\n .optional()\n .describe(\"Assign to user ID, or null to unassign\"),\n },\n async ({ task_id, ...fields }) => {\n try {\n await connection.call(\n \"updateProjectTask\",\n withRequestingUser({ projectId, taskId: task_id, ...fields }, getRequestingUserId),\n );\n return textResult(\"Task updated successfully.\");\n } catch (error) {\n return textResult(`Failed to update task: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildUpdateTaskPlanTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"update_task_plan\",\n \"Save a plan or description to a task. Convenience wrapper around update_project_task for the common Plan-mode case.\",\n {\n task_id: z.string().describe(\"The task ID to update\"),\n plan: z.string().optional().describe(\"The task plan in markdown\"),\n description: z.string().optional().describe(\"Updated task description\"),\n },\n async ({ task_id, plan, description }) => {\n try {\n await connection.call(\n \"updateProjectTask\",\n withRequestingUser(\n {\n projectId,\n taskId: task_id,\n ...(plan !== undefined && { plan }),\n ...(description !== undefined && { description }),\n },\n getRequestingUserId,\n ),\n );\n return textResult(\"Task updated successfully.\");\n } catch (error) {\n return textResult(`Failed to update task: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildForceUpdateStatusTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"force_update_task_status\",\n \"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.\",\n {\n task_id: z.string().describe(\"The task ID to update\"),\n status: z\n .enum([\"Planning\", \"Open\", \"InProgress\", \"ReviewPR\", \"ReviewDev\", \"ReviewLive\", \"Complete\"])\n .describe(\"The new status for the task\"),\n },\n async ({ task_id, status }) => {\n try {\n await connection.call(\n \"updateProjectTask\",\n withRequestingUser({ projectId, taskId: task_id, status }, getRequestingUserId),\n );\n return textResult(`Task status updated to ${status}.`);\n } catch (error) {\n return textResult(`Failed to update status: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Reviewer Tools ────────────────────────────────────────────────────\n\nfunction formatReviewerList(reviewers: Array<{ userId: string; name: string | null }>): string {\n if (reviewers.length === 0) return \"none\";\n return reviewers.map((r) => `${r.name ?? \"unknown\"} (${r.userId})`).join(\", \");\n}\n\nfunction buildAddReviewerTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"add_reviewer\",\n \"Add a project member as a reviewer on a task. Idempotent — adding an existing reviewer is a no-op.\",\n {\n task_id: z.string().describe(\"The task ID or slug\"),\n user_id: z\n .string()\n .describe(\"User ID of the reviewer (use list_project_members to resolve a name or email)\"),\n },\n async ({ task_id, user_id }) => {\n try {\n const result = await connection.call(\n \"addProjectTaskReviewer\",\n withRequestingUser({ projectId, taskId: task_id, userId: user_id }, getRequestingUserId),\n );\n return textResult(\n `Reviewer added to task ${result.taskId}. Reviewers: ${formatReviewerList(result.reviewers)}`,\n );\n } catch (error) {\n return textResult(`Failed to add reviewer: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildRemoveReviewerTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"remove_reviewer\",\n \"Remove a reviewer from a task. Idempotent — removing a non-reviewer is a no-op.\",\n {\n task_id: z.string().describe(\"The task ID or slug\"),\n user_id: z.string().describe(\"User ID of the reviewer to remove\"),\n },\n async ({ task_id, user_id }) => {\n try {\n const result = await connection.call(\n \"removeProjectTaskReviewer\",\n withRequestingUser({ projectId, taskId: task_id, userId: user_id }, getRequestingUserId),\n );\n return textResult(\n `Reviewer removed from task ${result.taskId}. Reviewers: ${formatReviewerList(result.reviewers)}`,\n );\n } catch (error) {\n return textResult(`Failed to remove reviewer: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Subtask Tools ─────────────────────────────────────────────────────\n\nfunction buildCreateSubtaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"create_subtask\",\n \"Create a subtask under a parent task in this project. Use for breaking parent tasks into smaller pieces during planning.\",\n {\n parent_task_id: z.string().describe(\"The parent task ID\"),\n title: z.string().describe(\"Subtask title\"),\n description: z.string().optional().describe(\"Brief description\"),\n plan: z.string().optional().describe(\"Implementation plan in markdown\"),\n ordinal: z.number().optional().describe(\"Step/order number (0-based)\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async ({ parent_task_id, title, description, plan, ordinal, storyPointValue }) => {\n try {\n const result = await connection.call(\n \"createProjectSubtask\",\n withRequestingUser(\n {\n projectId,\n parentTaskId: parent_task_id,\n title,\n ...(description !== undefined && { description }),\n ...(plan !== undefined && { plan }),\n ...(ordinal !== undefined && { ordinal }),\n ...(storyPointValue !== undefined && { storyPointValue }),\n },\n getRequestingUserId,\n ),\n );\n return textResult(`Subtask created: ${result.slug} (ID: ${result.id})`);\n } catch (error) {\n return textResult(`Failed to create subtask: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildUpdateSubtaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"update_subtask\",\n \"Update an existing subtask's fields (title, description, plan, status, ordinal, storyPointValue).\",\n {\n subtask_id: z.string().describe(\"The subtask ID to update\"),\n title: z.string().optional(),\n description: z.string().optional(),\n plan: z.string().optional(),\n status: z.string().optional(),\n ordinal: z.number().optional(),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async ({ subtask_id, ...fields }) => {\n try {\n await connection.call(\n \"updateProjectSubtask\",\n withRequestingUser({ projectId, subtaskId: subtask_id, ...fields }, getRequestingUserId),\n );\n return textResult(\"Subtask updated.\");\n } catch (error) {\n return textResult(`Failed: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildDeleteSubtaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"delete_subtask\",\n \"Delete a subtask by id. Use when a subtask was created in error or is no longer needed.\",\n { subtask_id: z.string().describe(\"The subtask ID to delete\") },\n async ({ subtask_id }) => {\n try {\n await connection.call(\n \"deleteProjectSubtask\",\n withRequestingUser({ projectId, subtaskId: subtask_id }, getRequestingUserId),\n );\n return textResult(\"Subtask deleted.\");\n } catch (error) {\n return textResult(`Failed: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Macro Tools (build/PR) ────────────────────────────────────────────\n\nfunction buildStartTaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"start_task\",\n \"Start a cloud build (codespace) for a task. Preconditions: task has a story point value and an agent assigned.\",\n { task_id: z.string().describe(\"The task ID to start a build for\") },\n async ({ task_id }) => {\n try {\n const result = await connection.call(\n \"startProjectBuild\",\n withRequestingUser({ projectId, taskId: task_id }, getRequestingUserId),\n );\n return textResult(\n `Cloud build started for task ${result.taskId} (status: ${result.status})`,\n );\n } catch (error) {\n return textResult(`Failed to start task: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildStopTaskTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"stop_task\",\n \"Send a stop signal to a running task's cloud build. Not a force-kill — the agent may take a moment to wind down.\",\n { task_id: z.string().describe(\"The task ID whose build should be stopped\") },\n async ({ task_id }) => {\n try {\n await connection.call(\n \"stopProjectBuild\",\n withRequestingUser({ projectId, taskId: task_id }, getRequestingUserId),\n );\n return textResult(`Stop signal sent for task ${task_id}.`);\n } catch (error) {\n return textResult(`Failed to stop task: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildMergePRTool(connection: ProjectConnection, getRequestingUserId: GetRequestingUserId) {\n const projectId = connection.projectId;\n return defineTool(\n \"approve_and_merge_pr\",\n \"Approve and merge a task's PR. Preconditions: task in ReviewPR with an open PR. Returns { merged }: false means automerge queued — wait for status to flip to ReviewDev.\",\n { task_id: z.string().describe(\"The task ID whose PR should be approved and merged\") },\n async ({ task_id }) => {\n try {\n const result = await connection.call(\n \"approveProjectMergePR\",\n withRequestingUser({ projectId, childTaskId: task_id }, getRequestingUserId),\n );\n if (result.merged) {\n return textResult(\n `PR #${result.prNumber} approved and merged for task ${result.childTaskId}.`,\n );\n }\n return textResult(\n `PR #${result.prNumber} merge queued for task ${result.childTaskId}. The PR will auto-merge when checks pass — wait for status to flip to ReviewDev.`,\n );\n } catch (error) {\n return textResult(`Failed to merge PR: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Aggregator ─────────────────────────────────────────────────────────\n\nexport function buildProjectActionTools(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId = () => undefined,\n) {\n return [\n buildCreateTaskTool(connection, getRequestingUserId),\n buildUpdateProjectTaskTool(connection, getRequestingUserId),\n buildUpdateTaskPlanTool(connection, getRequestingUserId),\n buildForceUpdateStatusTool(connection, getRequestingUserId),\n buildAddReviewerTool(connection, getRequestingUserId),\n buildRemoveReviewerTool(connection, getRequestingUserId),\n buildCreateSubtaskTool(connection, getRequestingUserId),\n buildUpdateSubtaskTool(connection, getRequestingUserId),\n buildDeleteSubtaskTool(connection, getRequestingUserId),\n buildStartTaskTool(connection, getRequestingUserId),\n buildStopTaskTool(connection, getRequestingUserId),\n buildMergePRTool(connection, getRequestingUserId),\n ];\n}\n","import { z } from \"zod\";\nimport { defineTool } from \"../harness/index.js\";\nimport type { ProjectConnection } from \"../connection/project-connection.js\";\nimport { textResult } from \"./helpers.js\";\nimport { errorMessage, type GetRequestingUserId } from \"./project-tools.js\";\nimport { withRequestingUser } from \"./project-action-tools.js\";\n\n// Suggestion + dependency tools for the project runner. Split from\n// project-action-tools.ts to stay within file size limits.\n\n// ── Suggestion Tools ──────────────────────────────────────────────────\n\nfunction buildCreateSuggestionTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"create_suggestion\",\n \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.\",\n {\n title: z.string().describe(\"Short title for the suggestion\"),\n description: z\n .string()\n .optional()\n .describe(\"1-2 sentence description of what should change and why.\"),\n tag_names: z.array(z.string()).optional().describe(\"Tag names to categorize the suggestion\"),\n },\n async ({ title, description, tag_names }) => {\n try {\n const result = await connection.call(\n \"createProjectSuggestion\",\n withRequestingUser(\n {\n projectId,\n title,\n ...(description !== undefined && { description }),\n ...(tag_names !== undefined && { tagNames: tag_names }),\n },\n getRequestingUserId,\n ),\n );\n if (result.merged) {\n return textResult(\n `Your suggestion was merged into an existing one (ID: ${result.mergedIntoId ?? result.id}). Your upvote has been recorded.`,\n );\n }\n return textResult(`Suggestion created (ID: ${result.id}).`);\n } catch (error) {\n return textResult(`Failed to create suggestion: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildVoteSuggestionTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"vote_suggestion\",\n \"Vote +1 or -1 on a project suggestion.\",\n {\n suggestion_id: z.string().describe(\"The suggestion ID to vote on\"),\n value: z\n .number()\n .refine((v) => v === 1 || v === -1, { message: \"Value must be 1 or -1\" })\n .describe(\"+1 to upvote, -1 to downvote\"),\n },\n async ({ suggestion_id, value }) => {\n try {\n const result = await connection.call(\n \"voteProjectSuggestion\",\n withRequestingUser(\n {\n projectId,\n suggestionId: suggestion_id,\n value: value as 1 | -1,\n },\n getRequestingUserId,\n ),\n );\n return textResult(`Vote recorded. Current score: ${result.score}`);\n } catch (error) {\n return textResult(`Failed to vote: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Dependency Tools ──────────────────────────────────────────────────\n\nfunction buildAddDependencyTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"add_dependency\",\n \"Add a blocking dependency — a task cannot start until the named task is merged to dev.\",\n {\n task_id: z.string().describe(\"The task that should be blocked\"),\n depends_on_slug_or_id: z.string().describe(\"Slug or ID of the task this task depends on\"),\n },\n async ({ task_id, depends_on_slug_or_id }) => {\n try {\n await connection.call(\n \"addProjectTaskDependency\",\n withRequestingUser(\n {\n projectId,\n taskId: task_id,\n dependsOnSlugOrId: depends_on_slug_or_id,\n },\n getRequestingUserId,\n ),\n );\n return textResult(\n `Dependency added: task ${task_id} now depends on \"${depends_on_slug_or_id}\"`,\n );\n } catch (error) {\n return textResult(`Failed to add dependency: ${errorMessage(error)}`);\n }\n },\n );\n}\n\nfunction buildRemoveDependencyTool(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId,\n) {\n const projectId = connection.projectId;\n return defineTool(\n \"remove_dependency\",\n \"Remove a previously added dependency from a task.\",\n {\n task_id: z.string().describe(\"The task to update\"),\n depends_on_slug_or_id: z.string().describe(\"Slug or ID of the task to remove as dependency\"),\n },\n async ({ task_id, depends_on_slug_or_id }) => {\n try {\n await connection.call(\n \"removeProjectTaskDependency\",\n withRequestingUser(\n {\n projectId,\n taskId: task_id,\n dependsOnSlugOrId: depends_on_slug_or_id,\n },\n getRequestingUserId,\n ),\n );\n return textResult(\"Dependency removed\");\n } catch (error) {\n return textResult(`Failed to remove dependency: ${errorMessage(error)}`);\n }\n },\n );\n}\n\n// ── Aggregator ─────────────────────────────────────────────────────────\n\nexport function buildProjectSuggestionDependencyTools(\n connection: ProjectConnection,\n getRequestingUserId: GetRequestingUserId = () => undefined,\n) {\n return [\n buildCreateSuggestionTool(connection, getRequestingUserId),\n buildVoteSuggestionTool(connection, getRequestingUserId),\n buildAddDependencyTool(connection, getRequestingUserId),\n buildRemoveDependencyTool(connection, getRequestingUserId),\n ];\n}\n","import {\n createHarness,\n type HarnessAssistantEvent,\n type HarnessQueryOptions,\n} from \"../harness/index.js\";\nimport type { ProjectConnection, IncomingChatMessage } from \"../connection/project-connection.js\";\nimport { buildProjectTools } from \"../tools/project-tools.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"ProjectChat\");\n\nconst FALLBACK_MODEL = \"claude-sonnet-4-20250514\";\n\ninterface AgentContext {\n projectName: string;\n projectDescription: string | null;\n agentInstructions: string;\n model: string;\n agentSettings: Record<string, unknown> | null;\n}\n\ninterface ChatHistoryMessage {\n role: string;\n content: string;\n userId: string | null;\n userName: string | null;\n createdAt: string;\n}\n\n// ── Prompt builders ──────────────────────────────────────────────────────\n\nfunction buildSystemPrompt(projectDir: string, agentCtx: AgentContext | null): string {\n const parts: string[] = [];\n\n if (agentCtx?.agentInstructions) {\n parts.push(agentCtx.agentInstructions);\n }\n\n const projectName = agentCtx?.projectName ?? \"this project\";\n parts.push(`\\nYou are the project management assistant for ${projectName}.`);\n if (agentCtx?.projectDescription) {\n parts.push(`Project description: ${agentCtx.projectDescription}`);\n }\n\n parts.push(\n `You are running locally on the developer's machine with full access to the codebase at: ${projectDir}`,\n ``,\n `Your role is to help team members:`,\n `- Discuss project direction and priorities`,\n `- Answer questions about the codebase, architecture, and implementation`,\n `- Help plan new work and break it into tasks`,\n `- Review code and suggest improvements`,\n ``,\n `Keep responses concise and helpful. When referencing code, cite specific files and line numbers.`,\n );\n\n return parts.join(\"\\n\");\n}\n\nfunction buildPrompt(message: IncomingChatMessage, chatHistory: ChatHistoryMessage[]): string {\n const parts: string[] = [];\n\n if (chatHistory.length > 0) {\n parts.push(\"Recent conversation history:\");\n for (const msg of chatHistory.slice(-20)) {\n const prefix = msg.role === \"assistant\" ? \"Agent\" : (msg.userName ?? \"User\");\n parts.push(`[${prefix}]: ${msg.content}`);\n }\n parts.push(\"\");\n }\n\n parts.push(`Latest message from the user:\\n${message.content}`);\n return parts.join(\"\\n\");\n}\n\n// ── Context fetching ─────────────────────────────────────────────────────\n\nasync function fetchContext(\n connection: ProjectConnection,\n chatId?: string,\n): Promise<{ agentCtx: AgentContext | null; chatHistory: ChatHistoryMessage[] }> {\n let agentCtx: AgentContext | null = null;\n try {\n agentCtx = await connection.call(\"getProjectAgentContext\", {\n projectId: connection.projectId,\n });\n } catch {\n logger.warn(\"Could not fetch agent context, using defaults\");\n }\n\n let chatHistory: ChatHistoryMessage[] = [];\n try {\n chatHistory = await connection.call(\"getProjectChatHistory\", {\n projectId: connection.projectId,\n limit: 30,\n chatId,\n });\n } catch {\n logger.warn(\"Could not fetch chat history, proceeding without it\");\n }\n\n return { agentCtx, chatHistory };\n}\n\n// ── Query options ────────────────────────────────────────────────────────\n\nfunction buildChatQueryOptions(\n agentCtx: AgentContext | null,\n projectDir: string,\n connection: ProjectConnection,\n getRequestingUserId: () => string | undefined,\n): { options: HarnessQueryOptions; harness: ReturnType<typeof createHarness> } {\n const model = agentCtx?.model || FALLBACK_MODEL;\n const settings = agentCtx?.agentSettings ?? {};\n\n const harness = createHarness();\n const mcpServer = harness.createMcpServer({\n name: \"conveyor\",\n tools: buildProjectTools(connection, getRequestingUserId),\n });\n\n return {\n options: {\n model,\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: buildSystemPrompt(projectDir, agentCtx),\n },\n cwd: projectDir,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: { conveyor: mcpServer },\n maxTurns: (settings.maxTurns as number | undefined) ?? 30,\n maxBudgetUsd: (settings.maxBudgetUsd as number | undefined) ?? 50,\n effort: settings.effort as \"low\" | \"medium\" | \"high\" | \"max\" | undefined,\n thinking: settings.thinking as\n | { type: \"adaptive\" }\n | { type: \"enabled\"; budgetTokens: number }\n | { type: \"disabled\" }\n | undefined,\n },\n harness,\n };\n}\n\n// ── Event processing ─────────────────────────────────────────────────────\n\ninterface ToolCallSummary {\n tool: string;\n input?: string;\n timestamp: string;\n}\n\nfunction processContentBlock(\n block: { type: string; text?: string; name?: string; input?: unknown },\n responseParts: string[],\n turnToolCalls: ToolCallSummary[],\n): void {\n if (block.type === \"text\" && block.text) {\n responseParts.push(block.text);\n } else if (block.type === \"tool_use\" && block.name) {\n const inputStr = typeof block.input === \"string\" ? block.input : JSON.stringify(block.input);\n turnToolCalls.push({\n tool: block.name,\n input: inputStr.slice(0, 10_000),\n timestamp: new Date().toISOString(),\n });\n }\n}\n\nfunction processEvent(\n event: { type: string },\n connection: ProjectConnection,\n responseParts: string[],\n turnToolCalls: ToolCallSummary[],\n isTyping: { value: boolean },\n): boolean {\n if (event.type === \"assistant\") {\n if (!isTyping.value) {\n setTimeout(() => connection.sendEvent({ type: \"agent_typing_start\" }), 200);\n isTyping.value = true;\n }\n\n const assistantEvent = event as HarnessAssistantEvent;\n for (const block of assistantEvent.message.content) {\n processContentBlock(block, responseParts, turnToolCalls);\n }\n\n if (turnToolCalls.length > 0) {\n connection.sendEvent({ type: \"activity_block\", events: [...turnToolCalls] });\n turnToolCalls.length = 0;\n }\n return false;\n }\n if (event.type === \"result\") {\n if (isTyping.value) {\n connection.sendEvent({ type: \"agent_typing_stop\" });\n isTyping.value = false;\n }\n emitResultCost(event, connection);\n return true;\n }\n return false;\n}\n\nfunction emitResultCost(event: { type: string }, connection: ProjectConnection): void {\n const resultEvent = event as {\n type: string;\n total_cost_usd?: number;\n modelUsage?: Record<string, unknown>;\n };\n if (resultEvent.total_cost_usd !== undefined && resultEvent.total_cost_usd > 0) {\n connection.sendEvent({ type: \"cost_update\", costUsd: resultEvent.total_cost_usd });\n }\n}\n\n// ── Main handler ─────────────────────────────────────────────────────────\n\nasync function runChatQuery(\n message: IncomingChatMessage,\n connection: ProjectConnection,\n projectDir: string,\n sessionId?: string,\n): Promise<string | undefined> {\n const { agentCtx, chatHistory } = await fetchContext(connection, message.chatId);\n // Closure-bound: mutation tools read this to attribute work to the asking\n // user. The server runs ACL checks against THIS userId, not the runner's\n // project token, so a Read-level user can't ask the agent to do\n // Moderate-level mutations.\n const requestingUserId = message.userId;\n const { options, harness } = buildChatQueryOptions(\n agentCtx,\n projectDir,\n connection,\n () => requestingUserId,\n );\n const prompt = buildPrompt(message, chatHistory);\n\n connection.emitStatus(\"busy\");\n const events = harness.executeQuery({\n prompt,\n options,\n ...(sessionId ? { resume: sessionId } : {}),\n });\n\n const responseParts: string[] = [];\n const turnToolCalls: ToolCallSummary[] = [];\n const isTyping = { value: false };\n let resultSessionId: string | undefined;\n\n for await (const event of events) {\n if (event.type === \"result\") {\n const resultEvent = event as { type: string; sessionId?: string };\n resultSessionId = resultEvent.sessionId;\n }\n const done = processEvent(event, connection, responseParts, turnToolCalls, isTyping);\n if (done) break;\n }\n\n if (isTyping.value) {\n connection.sendEvent({ type: \"agent_typing_stop\" });\n }\n\n const responseText = responseParts.join(\"\\n\\n\").trim();\n if (responseText) {\n await connection.call(\"postProjectAgentMessage\", {\n projectId: connection.projectId,\n content: responseText,\n chatId: message.chatId,\n });\n }\n\n return resultSessionId;\n}\n\nexport async function handleProjectChatMessage(\n message: IncomingChatMessage,\n connection: ProjectConnection,\n projectDir: string,\n sessionId?: string,\n): Promise<string | undefined> {\n connection.emitStatus(\"busy\");\n\n try {\n return await runChatQuery(message, connection, projectDir, sessionId);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\"Failed to handle message\", { error: msg });\n try {\n await connection.call(\"postProjectAgentMessage\", {\n projectId: connection.projectId,\n content: \"I encountered an error processing your message. Please try again.\",\n chatId: message.chatId,\n });\n } catch {\n // best effort\n }\n return undefined;\n } finally {\n connection.emitStatus(\"idle\");\n }\n}\n","/** Extract error message from unknown error value. */\nexport function parseErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { fork, type ChildProcess } from \"node:child_process\";\nimport { execSync } from \"node:child_process\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ProjectConnection, TaskAssignment } from \"../connection/project-connection.js\";\nimport { syncWithBaseBranch } from \"./git-utils.js\";\nimport { removeWorktree } from \"./worktree.js\";\nimport { setupWorkDir } from \"./project-runner-git.js\";\nimport { parseErrorMessage } from \"./project-runner-helpers.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"ProjectRunner\");\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport const STOP_TIMEOUT_MS = 30_000;\nconst MAX_CONCURRENT = Math.max(1, parseInt(process.env.CONVEYOR_MAX_CONCURRENT ?? \"10\", 10) || 10);\n\nexport interface ActiveAgent {\n process: ChildProcess;\n worktreePath: string;\n mode: string;\n usesWorktree: boolean;\n}\n\n/**\n * Resolve the Claude auth env for a forked child. Prefer the Conveyor-resolved\n * subscription token: when present, drop any inherited ANTHROPIC_API_KEY (in\n * `childEnv`) so the `claude` CLI authenticates via the subscription rather than\n * API-usage billing — matching the runtime `onApiKeyUpdate` precedence — and\n * return it as an override. When absent, leave `childEnv` untouched so the child\n * falls back to the runner machine's own `~/.claude` login.\n *\n * PTY-harness caveat: the interactive TUI ignores CLAUDE_CODE_OAUTH_TOKEN, so\n * the env var alone only authenticates headless (SDK) paths. In cloud\n * environments the child's PtySession materializes the token as\n * `.credentials.json` before spawning (see harness/pty/credentials.ts). For a\n * LOCAL project runner that write is deliberately skipped — we never touch a\n * developer's real ~/.claude — so local children's TUIs bill to the machine's\n * own login rather than the per-task token.\n */\nfunction applyChildClaudeAuth(\n childEnv: NodeJS.ProcessEnv,\n token: string | undefined,\n): Record<string, string> {\n if (!token) return {};\n delete childEnv.ANTHROPIC_API_KEY;\n return { CLAUDE_CODE_OAUTH_TOKEN: token };\n}\n\nexport function spawnChildAgent(assignment: TaskAssignment, workDir: string): ChildProcess {\n const {\n taskToken,\n apiUrl,\n taskId,\n sessionId,\n mode,\n isAuto,\n useSandbox,\n agentMode,\n pty,\n claudeCodeOauthToken,\n } = assignment;\n const cliPath = path.resolve(__dirname, \"cli.js\");\n\n const childEnv = { ...process.env };\n delete childEnv.CONVEYOR_PROJECT_TOKEN;\n delete childEnv.CONVEYOR_PROJECT_ID;\n delete childEnv.CONVEYOR_SETUP_COMMAND;\n delete childEnv.CONVEYOR_START_COMMAND;\n\n const claudeAuthEnv = applyChildClaudeAuth(childEnv, claudeCodeOauthToken);\n\n const effectiveAgentMode = agentMode ?? (isAuto ? \"auto\" : \"\");\n // Prefer the assignment's apiUrl, but fall back to the parent's CONVEYOR_API_URL.\n // The assignment's apiUrl comes from NEXT_PUBLIC_SERVER on the API server, which\n // may be empty or differ from the URL the project runner actually connected to.\n const effectiveApiUrl = apiUrl || process.env.CONVEYOR_API_URL || \"\";\n if (!effectiveApiUrl) {\n logger.error(\"No API URL available for child agent\", { taskId: taskId.slice(0, 8) });\n }\n\n const child = fork(cliPath, [], {\n env: {\n ...childEnv,\n CONVEYOR_API_URL: effectiveApiUrl,\n CONVEYOR_TASK_TOKEN: taskToken,\n CONVEYOR_TASK_ID: taskId,\n ...(sessionId ? { CONVEYOR_SESSION_ID: sessionId } : {}),\n CONVEYOR_MODE: mode,\n CONVEYOR_WORKSPACE: workDir,\n CONVEYOR_USE_WORKTREE: \"false\",\n CONVEYOR_AGENT_MODE: effectiveAgentMode,\n CONVEYOR_IS_AUTO: isAuto ? \"true\" : \"false\",\n CONVEYOR_USE_SANDBOX: useSandbox === true ? \"true\" : \"false\",\n ...(pty ? { CONVEYOR_HARNESS: \"pty\" } : {}),\n ...claudeAuthEnv,\n },\n cwd: workDir,\n stdio: [\"pipe\", \"pipe\", \"pipe\", \"ipc\"],\n });\n\n child.stdin?.on(\"error\", () => {});\n child.stdout?.on(\"error\", () => {});\n child.stderr?.on(\"error\", () => {});\n\n const shortId = taskId.slice(0, 8);\n child.stdout?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trimEnd().split(\"\\n\")) {\n logger.info(line, { taskId: shortId });\n }\n });\n child.stderr?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trimEnd().split(\"\\n\")) {\n // Child loggers write to stderr by default — not necessarily errors\n logger.info(line, { taskId: shortId });\n }\n });\n\n return child;\n}\n\nexport async function killAgent(agent: ActiveAgent, taskId: string): Promise<void> {\n const shortId = taskId.slice(0, 8);\n\n // Already dead — nothing to kill\n if (agent.process.exitCode !== null) {\n logger.info(\"Agent process already exited\", { taskId: shortId });\n return;\n }\n\n logger.info(\"Killing agent process\", { taskId: shortId });\n agent.process.kill(\"SIGTERM\");\n\n await new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n if (agent.process.exitCode === null) {\n logger.warn(\"Agent did not exit after SIGTERM, sending SIGKILL\", { taskId: shortId });\n agent.process.kill(\"SIGKILL\");\n }\n resolve();\n }, STOP_TIMEOUT_MS);\n\n agent.process.on(\"exit\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\nexport async function handleAssignment(\n assignment: TaskAssignment,\n activeAgents: Map<string, ActiveAgent>,\n projectDir: string,\n connection: ProjectConnection,\n): Promise<void> {\n const { taskId, mode } = assignment;\n const shortId = taskId.slice(0, 8);\n const agentKey = mode === \"code-review\" ? `${taskId}:code-review` : taskId;\n\n const existing = activeAgents.get(agentKey);\n if (existing) {\n if (existing.process.exitCode === null) {\n // Process alive but socket may be dead — kill and re-spawn\n logger.info(\"Re-assignment received, killing existing agent\", { taskId: shortId });\n await killAgent(existing, taskId);\n } else {\n // Process already dead — clean up stale entry and re-spawn below\n logger.info(\"Stale agent entry (process already exited), cleaning up\", { taskId: shortId });\n }\n activeAgents.delete(agentKey);\n }\n\n if (activeAgents.size >= MAX_CONCURRENT) {\n logger.warn(\"Max concurrent agents reached\", { maxConcurrent: MAX_CONCURRENT });\n connection.emitTaskStopped(taskId, \"max_concurrent_reached\");\n return;\n }\n\n try {\n try {\n execSync(\"git fetch origin\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n logger.warn(\"Git fetch failed\", { taskId: shortId });\n }\n\n const { workDir, usesWorktree } = setupWorkDir(projectDir, assignment);\n\n if (assignment.devBranch) {\n syncWithBaseBranch(workDir, assignment.devBranch);\n }\n\n const child = spawnChildAgent(assignment, workDir);\n\n activeAgents.set(agentKey, {\n process: child,\n worktreePath: workDir,\n mode,\n usesWorktree,\n });\n connection.emitTaskStarted(taskId);\n logger.info(\"Started task\", { taskId: shortId, mode, workDir });\n\n child.on(\"exit\", (code) => {\n activeAgents.delete(agentKey);\n const reason = code === 0 ? \"completed\" : `exited with code ${code}`;\n connection.emitTaskStopped(taskId, reason);\n logger.info(\"Task exited\", { taskId: shortId, reason });\n if (code === 0 && usesWorktree) {\n try {\n removeWorktree(projectDir, taskId);\n } catch {\n // best effort\n }\n }\n });\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Failed to start task\", { taskId: shortId, error: msg });\n connection.emitTaskStopped(taskId, `start_failed: ${msg}`);\n }\n}\n\nexport function handleStopTask(\n taskId: string,\n activeAgents: Map<string, ActiveAgent>,\n projectDir: string,\n): void {\n const agentKey = activeAgents.has(taskId) ? taskId : `${taskId}:code-review`;\n const agent = activeAgents.get(agentKey);\n if (!agent) return;\n\n logger.info(\"Stopping task\", { taskId: taskId.slice(0, 8) });\n\n void killAgent(agent, taskId).then(() => {\n if (agent.usesWorktree) {\n try {\n removeWorktree(projectDir, taskId);\n } catch {\n // best effort\n }\n }\n });\n}\n","import { execSync } from \"node:child_process\";\nimport type { ProjectConnection } from \"../connection/project-connection.js\";\nimport type { TaskAssignment } from \"../connection/project-connection.js\";\nimport type { CommitWatcher } from \"./commit-watcher.js\";\nimport { ensureWorktree, detachWorktreeBranch } from \"./worktree.js\";\nimport { hasUncommittedChanges, getCurrentBranch as gitGetCurrentBranch } from \"./git-utils.js\";\nimport { smartSync, handleSyncEnvironment, type StartCommandState } from \"./project-runner-sync.js\";\nimport { parseErrorMessage } from \"./project-runner-helpers.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"ProjectRunner\");\n\n// ── Worktree / branch setup ─────────────────────────────────────────────\n\nexport function setupWorkDir(\n projectDir: string,\n assignment: TaskAssignment,\n): { workDir: string; usesWorktree: boolean } {\n const { taskId, branch, devBranch, useWorktree } = assignment;\n const shortId = taskId.slice(0, 8);\n const shouldWorktree = useWorktree === true;\n\n let workDir: string;\n if (shouldWorktree) {\n workDir = ensureWorktree(projectDir, taskId, devBranch);\n } else {\n workDir = projectDir;\n }\n\n if (branch && branch !== devBranch) {\n if (hasUncommittedChanges(workDir)) {\n logger.warn(\"Uncommitted changes, skipping checkout\", { taskId: shortId, branch });\n } else {\n try {\n execSync(`git checkout ${branch}`, { cwd: workDir, stdio: \"ignore\" });\n } catch {\n try {\n execSync(`git checkout -b ${branch}`, { cwd: workDir, stdio: \"ignore\" });\n } catch {\n logger.warn(\"Could not checkout branch\", { taskId: shortId, branch });\n }\n }\n }\n }\n\n return { workDir, usesWorktree: shouldWorktree };\n}\n\nexport function checkoutWorkspaceBranch(projectDir: string): void {\n const workspaceBranch = process.env.CONVEYOR_WORKSPACE_BRANCH;\n if (!workspaceBranch) return;\n\n const currentBranch = gitGetCurrentBranch(projectDir);\n if (currentBranch === workspaceBranch) return;\n\n if (hasUncommittedChanges(projectDir)) {\n logger.warn(\"Uncommitted changes, skipping workspace branch checkout\");\n return;\n }\n\n try {\n execSync(`git fetch origin ${workspaceBranch}`, { cwd: projectDir, stdio: \"pipe\" });\n execSync(`git checkout ${workspaceBranch}`, { cwd: projectDir, stdio: \"pipe\" });\n logger.info(\"Checked out workspace branch\", { workspaceBranch });\n } catch {\n logger.warn(\"Failed to checkout workspace branch\", { workspaceBranch });\n }\n}\n\n// ── Branch switching ────────────────────────────────────────────────────\n\nexport async function handleSwitchBranch(\n projectDir: string,\n branchSwitchCommand: string | undefined,\n startCmd: StartCommandState,\n connection: ProjectConnection,\n commitWatcher: CommitWatcher,\n data: { branch: string; syncAfter?: boolean },\n callback: (res: { ok: boolean; error?: string }) => void,\n): Promise<void> {\n try {\n try {\n execSync(\"git fetch origin\", { cwd: projectDir, stdio: \"pipe\" });\n } catch {\n logger.warn(\"Git fetch failed during branch switch\");\n }\n\n detachWorktreeBranch(projectDir, data.branch);\n\n try {\n execSync(`git checkout ${data.branch}`, { cwd: projectDir, stdio: \"pipe\" });\n } catch (err) {\n const msg = parseErrorMessage(err);\n callback({ ok: false, error: `Failed to checkout branch: ${msg}` });\n return;\n }\n\n try {\n execSync(`git pull origin ${data.branch}`, { cwd: projectDir, stdio: \"pipe\" });\n } catch {\n logger.warn(\"Git pull failed during branch switch\");\n }\n\n if (data.syncAfter !== false) {\n await handleSyncEnvironment(projectDir, branchSwitchCommand, startCmd, connection);\n }\n\n commitWatcher.start(data.branch);\n callback({ ok: true });\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Branch switch failed\", { error: msg });\n callback({ ok: false, error: msg });\n }\n}\n\n// ── Commit watching ─────────────────────────────────────────────────────\n\nexport async function handleNewCommits(\n projectDir: string,\n branchSwitchCommand: string | undefined,\n startCmd: StartCommandState,\n connection: ProjectConnection,\n setupComplete: boolean,\n data: {\n branch: string;\n previousSha: string;\n newCommitSha: string;\n commitCount: number;\n latestMessage: string;\n latestAuthor: string;\n },\n): Promise<void> {\n await connection.call(\"reportNewCommitsDetected\", {\n projectId: connection.projectId,\n branch: data.branch,\n commits: [\n {\n sha: data.newCommitSha,\n message: data.latestMessage,\n author: data.latestAuthor,\n },\n ],\n });\n\n const stepsRun = await smartSync(\n projectDir,\n branchSwitchCommand,\n startCmd,\n connection,\n data.previousSha,\n data.newCommitSha,\n data.branch,\n );\n\n await connection.call(\"reportEnvironmentReady\", {\n projectId: connection.projectId,\n branch: data.branch,\n setupComplete,\n startCommandRunning: startCmd.running,\n });\n\n logger.info(\"Commit sync complete\", { steps: stepsRun.join(\", \") });\n}\n","import type { ChildProcess } from \"node:child_process\";\nimport { execSync } from \"node:child_process\";\nimport type { ProjectConnection } from \"../connection/project-connection.js\";\nimport { runSetupCommand, runStartCommand } from \"../setup/commands.js\";\nimport { hasUncommittedChanges } from \"./git-utils.js\";\nimport { parseErrorMessage } from \"./project-runner-helpers.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\n\nconst logger = createServiceLogger(\"ProjectRunner\");\n\nconst START_CMD_KILL_TIMEOUT_MS = 5_000;\n\nexport interface StartCommandState {\n child: ChildProcess | null;\n running: boolean;\n}\n\n// ── Setup / start command lifecycle ─────────────────────────────────────\n\nexport async function executeSetupCommand(\n projectDir: string,\n connection: ProjectConnection,\n): Promise<void> {\n const cmd = process.env.CONVEYOR_SETUP_COMMAND;\n if (!cmd) return;\n\n logger.info(\"Running setup command\", { command: cmd });\n try {\n await runSetupCommand(cmd, projectDir, (stream, data) => {\n connection.sendEvent({ type: \"setup_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n });\n logger.info(\"Setup command completed\");\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Setup command failed\", { error: msg });\n connection.sendEvent({ type: \"setup_error\", message: msg });\n throw error;\n }\n}\n\nexport function executeStartCommand(\n projectDir: string,\n state: StartCommandState,\n connection: ProjectConnection,\n): void {\n const cmd = process.env.CONVEYOR_START_COMMAND;\n if (!cmd) return;\n\n logger.info(\"Running start command\", { command: cmd });\n const child = runStartCommand(cmd, projectDir, (stream, data) => {\n connection.sendEvent({ type: \"start_command_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n });\n\n state.child = child;\n state.running = true;\n\n child.on(\"exit\", (code, signal) => {\n state.running = false;\n state.child = null;\n logger.info(\"Start command exited\", { code, signal });\n connection.sendEvent({ type: \"start_command_exited\", code, signal });\n });\n\n child.on(\"error\", (err) => {\n state.running = false;\n state.child = null;\n logger.error(\"Start command error\", { error: err.message });\n });\n}\n\nexport async function killStartCommand(state: StartCommandState): Promise<void> {\n const child = state.child;\n if (!child || !state.running) return;\n\n try {\n if (child.pid) process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill(\"SIGTERM\");\n }\n\n await new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n if (state.running && child.pid) {\n try {\n process.kill(-child.pid, \"SIGKILL\");\n } catch {\n child.kill(\"SIGKILL\");\n }\n }\n resolve();\n }, START_CMD_KILL_TIMEOUT_MS);\n\n child.on(\"exit\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n\n state.child = null;\n state.running = false;\n}\n\nexport async function restartStartCommand(\n projectDir: string,\n state: StartCommandState,\n connection: ProjectConnection,\n): Promise<void> {\n await killStartCommand(state);\n executeStartCommand(projectDir, state, connection);\n}\n\n// ── Environment sync ────────────────────────────────────────────────────\n\nexport async function handleSyncEnvironment(\n projectDir: string,\n branchSwitchCommand: string | undefined,\n state: StartCommandState,\n connection: ProjectConnection,\n callback?: (res: { ok: boolean; error?: string }) => void,\n): Promise<void> {\n try {\n await killStartCommand(state);\n\n const cmd = branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;\n if (cmd) {\n try {\n await runSetupCommand(cmd, projectDir, (stream, data) => {\n connection.sendEvent({ type: \"sync_output\", stream, data });\n });\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Branch switch sync command failed\", { error: msg });\n }\n }\n\n executeStartCommand(projectDir, state, connection);\n callback?.({ ok: true });\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Environment sync failed\", { error: msg });\n callback?.({ ok: false, error: msg });\n }\n}\n\n// ── Dependency sync (commit-watch) ──────────────────────────────────────\n\nexport function getChangedFiles(projectDir: string, previousSha: string, newSha: string): string[] {\n try {\n return execSync(`git diff --name-only ${previousSha}..${newSha}`, {\n cwd: projectDir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n .toString()\n .trim()\n .split(\"\\n\")\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\nfunction runIndividualSyncSteps(\n projectDir: string,\n needsInstall: boolean,\n needsPrisma: boolean,\n stepsRun: string[],\n): void {\n if (needsInstall) {\n try {\n execSync(\"bun install\", { cwd: projectDir, timeout: 120_000, stdio: \"pipe\" });\n stepsRun.push(\"install\");\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"bun install failed\", { error: msg });\n }\n }\n if (needsPrisma) {\n try {\n execSync(\"bunx prisma generate\", { cwd: projectDir, timeout: 60_000, stdio: \"pipe\" });\n execSync(\"bunx prisma db push --accept-data-loss\", {\n cwd: projectDir,\n timeout: 60_000,\n stdio: \"pipe\",\n });\n stepsRun.push(\"prisma\");\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Prisma sync failed\", { error: msg });\n }\n }\n}\n\nexport async function syncDependencies(\n projectDir: string,\n branchSwitchCommand: string | undefined,\n connection: ProjectConnection,\n changedFiles: string[],\n stepsRun: string[],\n): Promise<void> {\n const needsInstall = changedFiles.some(\n (f) =>\n f === \"package.json\" ||\n f === \"bun.lockb\" ||\n f.endsWith(\"/package.json\") ||\n f.endsWith(\"/bun.lockb\"),\n );\n const needsPrisma = changedFiles.some(\n (f) => f.includes(\"prisma/schema.prisma\") || f.includes(\"prisma/migrations/\"),\n );\n\n const cmd = branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;\n if (cmd && (needsInstall || needsPrisma)) {\n try {\n await runSetupCommand(cmd, projectDir, (stream, data) => {\n connection.sendEvent({ type: \"sync_output\", stream, data });\n });\n stepsRun.push(\"branchSwitchCommand\");\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Branch switch command failed\", { error: msg });\n }\n } else if (!cmd) {\n runIndividualSyncSteps(projectDir, needsInstall, needsPrisma, stepsRun);\n }\n}\n\nexport async function smartSync(\n projectDir: string,\n branchSwitchCommand: string | undefined,\n state: StartCommandState,\n connection: ProjectConnection,\n previousSha: string,\n newSha: string,\n branch: string,\n): Promise<string[]> {\n if (hasUncommittedChanges(projectDir)) {\n connection.sendEvent({\n type: \"commit_watch_warning\",\n message: \"Working tree has uncommitted changes. Auto-pull skipped.\",\n });\n return [\"skipped:dirty_tree\"];\n }\n\n await killStartCommand(state);\n\n try {\n execSync(`git pull origin ${branch}`, {\n cwd: projectDir,\n stdio: \"pipe\",\n timeout: 60_000,\n });\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.error(\"Git pull failed during commit sync\", { error: msg });\n executeStartCommand(projectDir, state, connection);\n return [\"error:pull\"];\n }\n\n const stepsRun = [\"pull\"];\n const changedFiles = getChangedFiles(projectDir, previousSha, newSha);\n await syncDependencies(projectDir, branchSwitchCommand, connection, changedFiles, stepsRun);\n\n executeStartCommand(projectDir, state, connection);\n stepsRun.push(\"startCommand\");\n return stepsRun;\n}\n","import { ProjectConnection } from \"../connection/project-connection.js\";\nimport { getCurrentBranch as gitGetCurrentBranch, flushPendingChanges } from \"./git-utils.js\";\nimport { handleProjectChatMessage } from \"./project-chat-handler.js\";\nimport { CommitWatcher } from \"./commit-watcher.js\";\nimport { createServiceLogger } from \"../utils/logger.js\";\nimport { parseErrorMessage } from \"./project-runner-helpers.js\";\n\n// Child process management\nimport {\n type ActiveAgent,\n STOP_TIMEOUT_MS,\n handleAssignment,\n handleStopTask,\n} from \"./project-runner-children.js\";\n\n// Environment sync\nimport {\n type StartCommandState,\n executeSetupCommand,\n executeStartCommand,\n killStartCommand,\n restartStartCommand,\n handleSyncEnvironment,\n} from \"./project-runner-sync.js\";\n\n// Git operations\nimport {\n checkoutWorkspaceBranch,\n handleSwitchBranch,\n handleNewCommits,\n} from \"./project-runner-git.js\";\n\nconst logger = createServiceLogger(\"ProjectRunner\");\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\n\nexport interface ProjectRunnerConfig {\n conveyorApiUrl: string;\n projectToken: string;\n projectId: string;\n projectDir: string;\n}\n\n// ── ProjectRunner class ──────────────────────────────────────────────────\n\nexport class ProjectRunner {\n private connection: ProjectConnection;\n private projectDir: string;\n private activeAgents = new Map<string, ActiveAgent>();\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private stopping = false;\n private resolveLifecycle: (() => void) | null = null;\n private chatSessionIds = new Map<string, string>();\n /** ProjectCodespaceSession id assigned at register time. Used to filter\n * targeted incoming chat messages so we only react to ones addressed\n * to this specific runner. */\n private projectSessionId: string | null = null;\n\n private startCmd: StartCommandState = { child: null, running: false };\n private setupComplete = false;\n private branchSwitchCommand: string | undefined;\n private commitWatcher: CommitWatcher;\n\n constructor(config: ProjectRunnerConfig) {\n this.projectDir = config.projectDir;\n this.connection = new ProjectConnection({\n apiUrl: config.conveyorApiUrl,\n projectToken: config.projectToken,\n projectId: config.projectId,\n });\n this.commitWatcher = new CommitWatcher(\n {\n projectDir: this.projectDir,\n pollIntervalMs: Number(process.env.CONVEYOR_COMMIT_POLL_INTERVAL) || 10_000,\n debounceMs: 3_000,\n },\n {\n onNewCommits: async (data) => {\n await handleNewCommits(\n this.projectDir,\n this.branchSwitchCommand,\n this.startCmd,\n this.connection,\n this.setupComplete,\n data,\n );\n },\n },\n );\n }\n\n // ── Public lifecycle ───────────────────────────────────────────────────\n\n async start(): Promise<void> {\n checkoutWorkspaceBranch(this.projectDir);\n await this.connection.connect();\n\n // Register with the API\n const registration = await this.connection.call(\"registerProjectAgent\", {\n projectId: this.connection.projectId,\n capabilities: [\"task\", \"pm\", \"code-review\", \"audit\"],\n });\n this.projectSessionId = registration.sessionId;\n this.branchSwitchCommand =\n registration.branchSwitchCommand ?? process.env.CONVEYOR_BRANCH_SWITCH_COMMAND;\n\n logger.info(\"Registered as project agent\", { agentName: registration.agentName });\n\n // Run setup command (blocking), then start command (background)\n try {\n await executeSetupCommand(this.projectDir, this.connection);\n executeStartCommand(this.projectDir, this.startCmd, this.connection);\n this.setupComplete = true;\n this.connection.sendEvent({\n type: \"setup_complete\",\n startCommandRunning: this.startCmd.running,\n });\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Environment setup failed\", { error: msg });\n this.setupComplete = false;\n }\n\n // Wire event handlers\n this.wireEventHandlers();\n\n // Re-register on reconnect so the server broadcasts connected status to UI\n this.connection.onReconnect(() => void this.handleReconnect());\n\n // Start heartbeat\n this.heartbeatTimer = setInterval(() => {\n this.connection.sendHeartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n\n // Start commit watcher\n const currentBranch = this.getCurrentBranch();\n if (currentBranch) {\n this.commitWatcher.start(currentBranch);\n }\n\n logger.info(\"Connected, waiting for task assignments\");\n\n await new Promise<void>((resolve) => {\n this.resolveLifecycle = resolve;\n });\n }\n\n /** Best-effort WIP commit + push of every tracked working tree on shutdown.\n * Iterates the main project dir plus any active agent worktrees so nothing\n * pending is lost when the pod is killed. Never throws. */\n async flushGitOnShutdown(): Promise<void> {\n const dirs = new Set<string>([this.projectDir]);\n for (const agent of this.activeAgents.values()) {\n if (agent.worktreePath) dirs.add(agent.worktreePath);\n }\n\n for (const dir of dirs) {\n try {\n const result = await flushPendingChanges(dir, {\n wipMessage: \"WIP: auto-commit on conveyor-agent shutdown\",\n });\n if (result.hadWork) {\n logger.info(\"Shutdown git flush\", {\n dir,\n committed: result.committed,\n pushed: result.pushed,\n });\n }\n } catch (err) {\n const msg = parseErrorMessage(err);\n logger.warn(\"Shutdown git flush failed\", { dir, error: msg });\n }\n }\n }\n\n async stop(): Promise<void> {\n if (this.stopping) return;\n this.stopping = true;\n logger.info(\"Shutting down\");\n\n this.commitWatcher.stop();\n await killStartCommand(this.startCmd);\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n const stopPromises = [...this.activeAgents.keys()].map(\n (key) =>\n new Promise<void>((resolve) => {\n const agent = this.activeAgents.get(key);\n if (!agent) {\n resolve();\n return;\n }\n agent.process.on(\"exit\", () => resolve());\n handleStopTask(key, this.activeAgents, this.projectDir);\n }),\n );\n\n await Promise.race([\n Promise.all(stopPromises),\n new Promise<void>((resolve) => {\n setTimeout(resolve, STOP_TIMEOUT_MS + 5_000);\n }),\n ]);\n\n // Flush any pending WIP work to origin now that child agents have exited\n // and worktrees are at rest. Best-effort: never blocks shutdown on failure.\n await this.flushGitOnShutdown();\n\n // Disconnect from API\n try {\n await this.connection.call(\"disconnectProjectRunner\", {\n projectId: this.connection.projectId,\n });\n } catch {\n // best effort\n }\n this.connection.disconnect();\n logger.info(\"Shutdown complete\");\n\n if (this.resolveLifecycle) {\n this.resolveLifecycle();\n this.resolveLifecycle = null;\n }\n }\n\n // ── Event wiring ───────────────────────────────────────────────────────\n\n private wireEventHandlers(): void {\n this.connection.onTaskAssignment(\n (assignment) =>\n void handleAssignment(assignment, this.activeAgents, this.projectDir, this.connection),\n );\n this.connection.onStopTask((data) =>\n handleStopTask(data.taskId, this.activeAgents, this.projectDir),\n );\n this.connection.onShutdown(() => void this.stop());\n // The UI \"Disconnect\" action emits `projectRunner:disconnect`; treat it as a\n // shutdown signal so the local runner stops cleanly and the process exits.\n this.connection.onDisconnect(() => void this.stop());\n\n this.connection.onChatMessage((msg) => {\n // Targeted routing: when targetSessionId is set, only the addressed\n // runner reacts. Older API revisions omit the field — treat that as\n // \"broadcast to all runners\" for backwards compat.\n if (\n msg.targetSessionId &&\n this.projectSessionId &&\n msg.targetSessionId !== this.projectSessionId\n ) {\n return;\n }\n const chatId = msg.chatId ?? \"default\";\n const existingSessionId = this.chatSessionIds.get(chatId);\n void handleProjectChatMessage(msg, this.connection, this.projectDir, existingSessionId).then(\n (newSessionId) => {\n if (newSessionId) this.chatSessionIds.set(chatId, newSessionId);\n },\n );\n });\n\n this.connection.onAuditTags((request) => void this.handleAuditTags(request));\n this.connection.onAuditTasks((request) => void this.handleAuditTasks(request));\n\n this.connection.onSwitchBranch(\n (data, cb) =>\n void handleSwitchBranch(\n this.projectDir,\n this.branchSwitchCommand,\n this.startCmd,\n this.connection,\n this.commitWatcher,\n data,\n cb,\n ),\n );\n this.connection.onSyncEnvironment(\n (cb) =>\n void handleSyncEnvironment(\n this.projectDir,\n this.branchSwitchCommand,\n this.startCmd,\n this.connection,\n cb,\n ),\n );\n this.connection.onRestartStartCommand((cb) => {\n void restartStartCommand(this.projectDir, this.startCmd, this.connection)\n .then(() => cb({ ok: true }))\n .catch((err) =>\n cb({ ok: false, error: err instanceof Error ? err.message : \"Restart failed\" }),\n );\n });\n }\n\n private async handleReconnect(): Promise<void> {\n try {\n const registration = await this.connection.call(\"registerProjectAgent\", {\n projectId: this.connection.projectId,\n capabilities: [\"task\", \"pm\", \"code-review\", \"audit\"],\n });\n this.projectSessionId = registration.sessionId;\n this.connection.emitStatus(this.activeAgents.size > 0 ? \"busy\" : \"idle\");\n logger.info(\"Re-registered after reconnect\");\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Failed to re-register after reconnect\", { error: msg });\n }\n }\n\n // ── Tag audit ──────────────────────────────────────────────────────────\n\n private async handleAuditTags(\n request: import(\"@project/shared\").TagAuditRunnerRequest,\n ): Promise<void> {\n this.connection.emitStatus(\"busy\");\n try {\n const { handleTagAudit } = await import(\"./tag-audit-handler.js\");\n await handleTagAudit(request, this.connection, this.projectDir);\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Tag audit failed\", { error: msg, requestId: request.requestId });\n try {\n await this.connection.call(\"reportTagAuditResult\", {\n projectId: this.connection.projectId,\n requestId: request.requestId,\n recommendations: [],\n summary: `Audit failed: ${msg}`,\n complete: true,\n });\n } catch {\n // best effort\n }\n } finally {\n this.connection.emitStatus(\"idle\");\n }\n }\n\n // ── Task audit ─────────────────────────────────────────────────────────\n\n private async handleAuditTasks(\n request: import(\"@project/shared\").TaskAuditRunnerRequest,\n ): Promise<void> {\n this.connection.emitStatus(\"busy\");\n try {\n const { handleTaskAudit } = await import(\"./task-audit-handler.js\");\n await handleTaskAudit(request, this.connection, this.projectDir);\n } catch (error) {\n const msg = parseErrorMessage(error);\n logger.error(\"Task audit failed\", { error: msg, requestId: request.requestId });\n for (const task of request.tasks) {\n try {\n await this.connection.call(\"reportTaskAuditResult\", {\n projectId: this.connection.projectId,\n requestId: request.requestId,\n taskId: task.taskId,\n summary: \"\",\n turnGrades: [],\n planningAccuracy: null,\n buildingAccuracy: null,\n humanAccuracy: null,\n planningCorrect: 0,\n planningNeutral: 0,\n planningBlunder: 0,\n buildingCorrect: 0,\n buildingNeutral: 0,\n buildingBlunder: 0,\n humanCorrect: 0,\n humanNeutral: 0,\n humanBlunder: 0,\n suggestionIds: [],\n auditCostUsd: null,\n model: null,\n error: `Audit failed: ${msg}`,\n });\n } catch {\n // best effort\n }\n }\n // Signal batch completion so UI gets unblocked even on total failure\n await this.connection\n .call(\"reportTaskAuditBatchComplete\", {\n projectId: this.connection.projectId,\n requestId: request.requestId,\n })\n .catch(() => {});\n } finally {\n this.connection.emitStatus(\"idle\");\n }\n }\n\n private getCurrentBranch(): string | null {\n return gitGetCurrentBranch(this.projectDir);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { SessionPreviewPort } from \"@project/shared\";\n\nexport interface ConveyorConfig {\n setupCommand?: string;\n startCommand?: string;\n previewPort?: number;\n}\n\nexport interface ForwardPortsResult {\n ports: number[];\n attributes: Record<string, { label?: string; visibility?: \"public\" | \"private\" }>;\n}\n\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\n/** Ports bound by sidecars (postgres/redis/elasticsearch) — never expose. */\nconst DEVCONTAINER_PORT_DENY_LIST = new Set([5432, 6379, 9200]);\n\nexport async function loadForwardPorts(workspaceDir: string): Promise<ForwardPortsResult> {\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as {\n forwardPorts?: number[];\n portsAttributes?: Record<string, { label?: string; visibility?: string }>;\n };\n const ports = (parsed.forwardPorts ?? []).filter(\n (p) => typeof p === \"number\" && !DEVCONTAINER_PORT_DENY_LIST.has(p),\n );\n const attributes: ForwardPortsResult[\"attributes\"] = {};\n for (const [key, value] of Object.entries(parsed.portsAttributes ?? {})) {\n if (!value || typeof value !== \"object\") continue;\n const entry: { label?: string; visibility?: \"public\" | \"private\" } = {};\n if (typeof value.label === \"string\") entry.label = value.label;\n if (value.visibility === \"public\" || value.visibility === \"private\") {\n entry.visibility = value.visibility;\n }\n attributes[key] = entry;\n }\n return { ports, attributes };\n } catch {\n return { ports: [], attributes: {} };\n }\n}\n\n/** Merge forwardPorts + portsAttributes into a SessionPreviewPort[] the API\n * can persist directly onto CodespaceSession.previewPorts. Deny-listed\n * ports are filtered (defense-in-depth; authoritative filter lives API-side). */\nexport function buildSessionPreviewPorts(result: ForwardPortsResult): SessionPreviewPort[] {\n return result.ports\n .filter((port) => !DEVCONTAINER_PORT_DENY_LIST.has(port))\n .map((port) => {\n const attr = result.attributes[String(port)];\n const entry: SessionPreviewPort = { port };\n if (attr?.label) entry.label = attr.label;\n if (attr?.visibility) entry.visibility = attr.visibility;\n return entry;\n });\n}\n\n/** Load config from env vars (project-level settings injected via bootstrap). */\nexport function loadConveyorConfig(): ConveyorConfig | null {\n const envSetup = process.env.CONVEYOR_SETUP_COMMAND;\n const envStart = process.env.CONVEYOR_START_COMMAND;\n const envPort = process.env.CONVEYOR_PREVIEW_PORT;\n if (envSetup || envStart) {\n return {\n setupCommand: envSetup,\n startCommand: envStart,\n previewPort: envPort ? Number(envPort) : undefined,\n };\n }\n return null;\n}\n","import { execSync } from \"node:child_process\";\n\n/** Fetch full git history if the repo was cloned with --depth=1. */\nexport function unshallowRepo(workspaceDir: string): void {\n try {\n execSync(\"git fetch --unshallow\", {\n cwd: workspaceDir,\n timeout: 60_000,\n stdio: \"ignore\",\n });\n } catch {\n // Already unshallowed or not a shallow clone\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6CA,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB,CAAC,KAAO,KAAQ,GAAM;AAE9C,SAAS,iBAAiB,SAAsC;AAC9D,UAAQ,OAAO,MAAM,KAAK,UAAU,OAAO,IAAI,IAAI;AACrD;AAEA,eAAe,uBACb,QACA,cACA,gBACA,WACiC;AACjC,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAC5D,MAAI;AACF,UAAM,UAAkC,CAAC;AACzC,QAAI,eAAgB,SAAQ,mBAAmB,IAAI;AACnD,UAAM,WAAW,MAAM,MAAM,GAAG,MAAM,4BAA4B,YAAY,IAAI;AAAA,MAChF;AAAA,MACA,QAAQ,WAAW;AAAA,IACrB,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACtD,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ,SAAS;AAAA,QACjB,WAAW,UAAU,MAAM,GAAG,GAAG;AAAA,QACjC,QAAQ,SAAS,WAAW,OAAO,SAAS,WAAW,MAAM,kBAAkB;AAAA,MACjF;AAAA,IACF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,EAAE,IAAI,MAAM,KAAK;AAAA,EAC1B,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,SAAS,WAAW,OAAO,UAAU,YAAY;AACvD,WAAO,EAAE,IAAI,OAAO,WAAW,QAAQ,MAAM,GAAG,GAAG,GAAG,OAAO;AAAA,EAC/D,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAEA,eAAe,MAAM,IAA2B;AAC9C,QAAM,IAAI,QAAc,CAACA,aAAY;AACnC,eAAWA,UAAS,EAAE;AAAA,EACxB,CAAC;AACH;AA0BA,SAAS,aACP,QACA,UACA,QACA,QACuB;AACvB,QAAM,MAA6B,EAAE,IAAI,OAAO,QAAQ,SAAS;AACjE,MAAI,WAAW,QAAW;AAAA,EAE1B,OAAO;AACL,QAAI,SAAS;AAAA,EACf;AACA,MAAI,OAAQ,KAAI,SAAS;AACzB,SAAO;AACT;AAEA,SAAS,YAAY,QAAgB,kBAAgD;AACnF,MAAI,WAAW,aAAa,WAAW,gBAAiB,QAAO;AAC/D,SAAO,qBAAqB,QAAQ,WAAW;AACjD;AAOA,eAAsB,eACpB,MACwD;AACxD,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,SAAS,KAAK,iBAAiB;AACrC,QAAM,cAAc,OAAO,SAAS;AACpC,QAAM,oBAAoB,QAAQ,KAAK,cAAc;AACrD,QAAM,eAAe,QAAQ,QAAQ,IAAI,mBAAmB;AAE5D,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,UAAM,SAAS,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AACA,QAAI,OAAO,MAAM,OAAO,MAAM;AAC5B,aAAO,EAAE,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,QAAQ;AAAA,IAC5D;AACA,iBAAa,OAAO,UAAU;AAC9B,iBAAa,OAAO;AACpB,iBAAa,OAAO;AAEpB,UAAM,iBAAwC;AAAA,MAC5C,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ,KAAK;AAAA,MACb,cAAc,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,eAAe,QAAW;AAAA,IAE9B,OAAO;AACL,qBAAe,SAAS;AAAA,IAC1B;AACA,QAAI,WAAY,gBAAe,SAAS;AACxC,qBAAiB,cAAc;AAE/B,QAAI,CAAC,YAAY,YAAY,KAAK,gBAAgB,KAAK,WAAW,aAAa;AAC7E,aAAO,aAAa,YAAY,SAAS,YAAY,UAAU;AAAA,IACjE;AACA,UAAM,MAAM,OAAO,UAAU,CAAC,CAAC;AAAA,EACjC;AAEA,SAAO,aAAa,YAAY,aAAa,YAAY,UAAU;AACrE;AAGO,SAAS,oBAAoB,QAA+B;AACjE,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,WAAW,CAAC,CAAC,GAAG;AAC/D,YAAQ,IAAI,GAAG,IAAI;AAAA,EACrB;AACA,MAAI,OAAO,SAAS,WAAW;AAC7B,QAAI,OAAO,aAAc,SAAQ,IAAI,yBAAyB,OAAO;AACrE,QAAI,OAAO,UAAW,SAAQ,IAAI,sBAAsB,OAAO;AAC/D,QAAI,OAAO,gBAAiB,SAAQ,IAAI,4BAA4B,OAAO;AAC3E;AAAA,EACF;AACA,MAAI,OAAO,OAAQ,SAAQ,IAAI,mBAAmB,OAAO;AACzD,MAAI,OAAO,UAAW,SAAQ,IAAI,sBAAsB,OAAO;AAC/D,MAAI,OAAO,UAAW,SAAQ,IAAI,sBAAsB,OAAO;AAC/D,MAAI,OAAO,cAAc,OAAW,SAAQ,IAAI,sBAAsB,OAAO;AAC7E,MAAI,OAAO,WAAW,OAAW,SAAQ,IAAI,mBAAmB,OAAO;AACvE,MAAI,OAAO,WAAY,SAAQ,IAAI,gBAAgB,OAAO;AAC1D,MAAI,OAAO,WAAY,SAAQ,IAAI,uBAAuB,OAAO;AACnE;;;ACrNA,SAAS,UAAuB;AAuChC,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AAElB,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EACnB,SAAwB;AAAA,EACf;AAAA,EACT,cAA0E,CAAC;AAAA,EAC3E,aAAmD;AAAA,EACnD,oBAAmC;AAAA,EACnC,qBAAoC;AAAA,EACpC,oBAAoB;AAAA;AAAA,EAGpB,yBAAyB,oBAAI,IAAuD;AAAA;AAAA,EAGpF,iBAAoF,CAAC;AAAA,EAC7F,OAAwB,kBAAkB;AAAA,EAC1C,OAAwB,6BAA6B;AAAA,EACrD,OAAwB,sBAAsB;AAAA;AAAA,EAGtC,gBAAmC,CAAC;AAAA,EACpC,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,mBAAkC,CAAC;AAAA;AAAA,EAGnC,kBAA2D;AAAA,EAC3D,eAAoC;AAAA,EACpC,mBAAwC;AAAA,EACxC,qBAA2D;AAAA,EAC3D,uBAAkE;AAAA,EAClE,qBAAkE;AAAA,EAClE,oBAA+C,CAAC;AAAA;AAAA,EAGhD,mBAAoD;AAAA,EACpD,oBAAmE;AAAA,EAE3E,YAAY,QAA+B;AACzC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,QAAQ,aAAa;AAAA,EACnC;AAAA;AAAA,EAIA,KACE,QACA,SACoD;AACpD,QAAI,CAAC,KAAK,QAAQ;AAChB,aAAO,QAAQ;AAAA,QACb,IAAI,MAAM,0BAA0B,OAAO,MAAM,CAAC,cAAc,KAAK,OAAO,SAAS,GAAG;AAAA,MAC1F;AAAA,IACF;AACA,UAAM,SAAS,KAAK;AACpB,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,aAAO;AAAA,QACL,uBAAuB,OAAO,MAAM,CAAC;AAAA,QACrC;AAAA,QACA,CAAC,aAAwE;AACvE,cAAI,SAAS,WAAW,SAAS,SAAS,QAAW;AACnD,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,wBAAwB,OAAO,MAAM,CAAC,EAAE,CAAC;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAKA,UAAyB;AACvB,QAAI,CAAC,KAAK,OAAO,QAAQ;AACvB,aAAO,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC;AAAA,IACpE;AAEA,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,cAAQ,OAAO;AAAA,QACb,kCAAkC,KAAK,OAAO,MAAM,WAAW,KAAK,OAAO,cAAc,MAAM,cAAc,KAAK,OAAO,SAAS;AAAA;AAAA,MACpI;AAEA,WAAK,SAAS,GAAG,KAAK,OAAO,QAAQ;AAAA,QACnC,MAAM;AAAA,UACJ,WAAW,KAAK,OAAO;AAAA,UACvB,YAAY,KAAK,OAAO,cAAc;AAAA,QACxC;AAAA,QACA,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc,EAAE,8BAA8B,OAAO;AAAA,MACvD,CAAC;AAOD,WAAK,OAAO,GAAG,mBAAmB,CAAC,QAAyB;AAE1D,cAAM,WAA4B;AAAA,UAChC,SAAS,IAAI;AAAA,UACb,QAAQ,IAAI;AAAA,UACZ,GAAI,IAAI,UAAU,EAAE,QAAQ,IAAI,OAAO;AAAA,UACvC,GAAI,IAAI,SAAS,EAAE,OAAO,IAAI,MAAM;AAAA,QACtC;AACA,YAAI,KAAK,gBAAiB,MAAK,gBAAgB,QAAQ;AAAA,YAClD,MAAK,cAAc,KAAK,QAAQ;AAAA,MACvC,CAAC;AAED,WAAK,OAAO,GAAG,gBAAgB,MAAM;AACnC,YAAI,KAAK,aAAc,MAAK,aAAa;AAAA,YACpC,MAAK,YAAY;AAAA,MACxB,CAAC;AAED,WAAK,OAAO,GAAG,oBAAoB,MAAM;AACvC,YAAI,KAAK,iBAAkB,MAAK,iBAAiB;AAAA,YAC5C,MAAK,gBAAgB;AAAA,MAC5B,CAAC;AAED,WAAK,OAAO,GAAG,sBAAsB,CAAC,SAAsB;AAC1D,YAAI,KAAK,mBAAoB,MAAK,mBAAmB,IAAI;AAAA,YACpD,MAAK,iBAAiB,KAAK,IAAI;AAAA,MACtC,CAAC;AAED,WAAK,OAAO;AAAA,QACV;AAAA,QACA,CAAC,SAAiE;AAChE,gBAAM,WAAW,KAAK,uBAAuB,IAAI,KAAK,SAAS;AAC/D,cAAI,SAAU,UAAS,KAAK,OAAO;AAAA,QACrC;AAAA,MACF;AAEA,WAAK,OAAO,GAAG,4BAA4B,CAAC,SAA2B;AACrE,YAAI,KAAK,qBAAsB,MAAK,qBAAqB,IAAI;AAAA,MAC/D,CAAC;AAED,WAAK,OAAO,GAAG,sBAAsB,CAAC,SAA6B;AACjE,YAAI,KAAK,mBAAoB,MAAK,mBAAmB,IAAI;AAAA,YACpD,MAAK,kBAAkB,KAAK,IAAI;AAAA,MACvC,CAAC;AAMD,WAAK,OAAO,GAAG,aAAa,CAAC,SAA+C;AAC1E,YAAI,KAAK,aAAa,KAAK,cAAc,KAAK,OAAO,UAAW;AAChE,aAAK,mBAAmB,KAAK,IAAI;AAAA,MACnC,CAAC;AAED,WAAK,OAAO,GAAG,cAAc,CAAC,SAA6D;AACzF,YAAI,KAAK,aAAa,KAAK,cAAc,KAAK,OAAO,UAAW;AAChE,aAAK,oBAAoB,KAAK,MAAM,KAAK,IAAI;AAAA,MAC/C,CAAC;AAGD,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,gBAAQ,OAAO,MAAM,qCAAqC;AAC1D,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,iBAAiB,CAAC,QAAe;AAC9C;AACA,gBAAQ,OAAO;AAAA,UACb,8CAA8C,QAAQ,IAAI,kBAAkB,MAAM,IAAI,OAAO;AAAA;AAAA,QAC/F;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV;AAAA,YACE,IAAI;AAAA,cACF,wBAAwB,KAAK,OAAO,MAAM,UAAU,kBAAkB,cAAc,IAAI,OAAO;AAAA,YACjG;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,cAAc,CAAC,WAAmB;AAC/C,gBAAQ,OAAO,MAAM,kCAAkC,MAAM;AAAA,CAAI;AAKjE,YAAI,WAAW,0BAA0B,WAAW,+BAA+B;AACjF,eAAK,KAAK,8BAA8B,EACrC,KAAK,CAAC,cAAc;AACnB,gBAAI,aAAa,KAAK,QAAQ;AAG5B,mBAAK,OAAO,QAAQ;AAAA,YACtB;AAAA,UACF,CAAC,EACA,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QACnB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,iBAAiB,MAAM;AACpC,gBAAQ,OAAO,MAAM,kEAAkE;AACvF,aAAK,KAAK,8BAA8B,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC1D,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,aAAa,MAAM;AACnC,gBAAQ,OAAO,MAAM,gCAAgC;AAErD,aAAK,KAAK,mBAAmB;AAAA,MAC/B,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,qBAAqB,MAAM;AAAA,MAE7C,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AAEjB,SAAK,KAAK,YAAY;AACtB,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,GAAG,aAAa,KAAK;AACjC,WAAK,OAAO,mBAAmB;AAC/B,WAAK,OAAO,WAAW;AACvB,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAwB,0BAA0B;AAAA,EAClD,OAAwB,yBAAyB;AAAA,EACjD,OAAwB,2BAA2B;AAAA,EAE3C,iBAAiB;AAAA,EAEzB,MAAc,qBAAoC;AAChD,QAAI,KAAK,eAAgB;AACzB,SAAK,iBAAiB;AACtB,QAAI;AACF,UAAI,UAAU;AACd,aAAO,KAAK,QAAQ;AAClB;AACA,YAAI;AACF,gBAAM,EAAE,gBAAgB,IAAI,MAAM,KAAK,KAAK,gBAAgB;AAAA,YAC1D,WAAW,KAAK,OAAO;AAAA,UACzB,CAAC;AACD,eAAK,qBAAqB,eAAe;AACzC,kBAAQ,OAAO;AAAA,YACb,mEAAmE,OAAO;AAAA;AAAA,UAC5E;AAIA,cAAI,KAAK,qBAAqB,KAAK,sBAAsB,KAAK,oBAAoB;AAChF,kBAAM,SAAS,KAAK;AACpB,iBAAK,KAAK,KAAK,qBAAqB;AAAA,cAClC,WAAW,KAAK,OAAO;AAAA,cACvB;AAAA,YACF,CAAC,EACE,KAAK,MAAM;AACV,mBAAK,qBAAqB;AAAA,YAC5B,CAAC,EACA,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACnB;AAEA,eAAK,UAAU;AAAA,YACb,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,UAAU;AAAA,UACZ,CAAC;AACD;AAAA,QACF,SAAS,KAAK;AACZ,gBAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE9D,gBAAM,UAAU,KAAK;AAAA,YACnB,iBAAgB,0BAA0B,KAAK,KAAK,IAAI,UAAU,GAAG,CAAC;AAAA,YACtE,iBAAgB;AAAA,UAClB;AACA,kBAAQ,OAAO;AAAA,YACb,iDAAiD,OAAO,MAAM,MAAM,uBAAkB,UAAU,GAAI;AAAA;AAAA,UACtG;AAKA,cAAI,KAAK,mBAAmB,MAAM,GAAG;AACnC,iBAAK,KAAK,8BAA8B,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UAC1D;AAKA,cAAI,UAAU,iBAAgB,6BAA6B,GAAG;AAC5D,iBAAK,UAAU;AAAA,cACb,MAAM;AAAA,cACN,QAAQ;AAAA,cACR;AAAA,YACF,CAAC;AAAA,UACH;AAEA,gBAAM,IAAI,QAAc,CAACA,aAAY;AACnC,uBAAWA,UAAS,OAAO;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,mBAAmB,SAA0B;AACnD,WAAO,8BAA8B,KAAK,OAAO;AAAA,EACnD;AAAA,EAEQ,qBAAqB,UAA4D;AACvF,eAAW,OAAO,UAAU;AAC1B,UAAI,CAAC,IAAI,QAAS;AAClB,UAAI,KAAK,iBAAiB;AACxB,aAAK,gBAAgB,EAAE,SAAS,IAAI,SAAS,QAAQ,IAAI,OAAO,CAAC;AAAA,MACnE,OAAO;AACL,aAAK,cAAc,KAAK,EAAE,SAAS,IAAI,SAAS,QAAQ,IAAI,OAAO,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,UAAU,UAAgD;AACxD,SAAK,kBAAkB;AACvB,eAAW,OAAO,KAAK,cAAe,UAAS,GAAG;AAClD,SAAK,gBAAgB,CAAC;AAAA,EACxB;AAAA,EAEA,OAAO,UAA4B;AACjC,SAAK,eAAe;AACpB,QAAI,KAAK,WAAW;AAClB,eAAS;AACT,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,WAAW,UAA4B;AACrC,SAAK,mBAAmB;AACxB,QAAI,KAAK,eAAe;AACtB,eAAS;AACT,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,aAAa,UAA6C;AACxD,SAAK,qBAAqB;AAC1B,eAAW,QAAQ,KAAK,iBAAkB,UAAS,IAAI;AACvD,SAAK,mBAAmB,CAAC;AAAA,EAC3B;AAAA,EAEA,eAAe,UAAkD;AAC/D,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEA,aAAa,UAAoD;AAC/D,SAAK,qBAAqB;AAC1B,eAAW,QAAQ,KAAK,kBAAmB,UAAS,IAAI;AACxD,SAAK,oBAAoB,CAAC;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAc,MAAc,MAA6C;AACvE,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,KAAK,KAAK,aAAa;AAAA,MAC1B,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,MACA,GAAI,OAAO,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IACrD,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA;AAAA,EAGA,WAAW,SAA6C;AACtD,SAAK,mBAAmB;AACxB,WAAO,MAAM;AACX,UAAI,KAAK,qBAAqB,QAAS,MAAK,mBAAmB;AAAA,IACjE;AAAA,EACF;AAAA;AAAA,EAGA,YAAY,SAA2D;AACrE,SAAK,oBAAoB;AACzB,WAAO,MAAM;AACX,UAAI,KAAK,sBAAsB,QAAS,MAAK,oBAAoB;AAAA,IACnE;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,WAAW,QAA+B;AAC9C,SAAK,oBAAoB;AAIzB,UAAM,KAAK,YAAY;AACvB,UAAM,iBAAiB,CAAC,QAAQ,qBAAqB,WAAW;AAChE,QAAI,eAAe,SAAS,MAAM,GAAG;AAEnC,UAAI;AACF,cAAM,KAAK,KAAK,qBAAqB;AAAA,UACnC,WAAW,KAAK,OAAO;AAAA,UACvB;AAAA,QACF,CAAC;AACD,aAAK,qBAAqB;AAAA,MAC5B,QAAQ;AAAA,MAGR;AAAA,IACF,OAAO;AACL,WAAK,KAAK,KAAK,qBAAqB;AAAA,QAClC,WAAW,KAAK,OAAO;AAAA,QACvB;AAAA,MACF,CAAC,EACE,KAAK,MAAM;AACV,aAAK,qBAAqB;AAAA,MAC5B,CAAC,EACA,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,gBAAgB,SAAuB;AACrC,QAAI,CAAC,KAAK,OAAQ;AAClB,QAAI,KAAK,oBAAoB,OAAO,EAAG;AACvC,SAAK,KAAK,KAAK,oBAAoB;AAAA,MACjC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,qBAAqB,SAAgC;AACzD,QAAI,CAAC,KAAK,OAAQ;AAClB,QAAI,KAAK,oBAAoB,OAAO,EAAG;AACvC,QAAI;AACF,YAAM,KAAK,KAAK,oBAAoB;AAAA,QAClC,WAAW,KAAK,OAAO;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,cAAQ,OAAO;AAAA,QACb,iDAAiD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA;AAAA,MACnG;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBAAoB,SAA0B;AACpD,UAAM,IAAI,KAAK,uBAAuB,OAAO;AAC7C,QAAI,CAAC,EAAE,UAAW,QAAO;AACzB,YAAQ,OAAO;AAAA,MACb,gDAAgD,EAAE,qBAAqB;AAAA;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,uBACE,SAC2E;AAC3E,UAAM,MAAM,KAAK,IAAI;AACrB,SAAK,iBAAiB,KAAK,eAAe;AAAA,MACxC,CAAC,MAAM,MAAM,EAAE,YAAY,iBAAgB;AAAA,IAC7C;AACA,UAAM,QAAQ,IAAI;AAAA,MAChB,QACG,YAAY,EACZ,QAAQ,YAAY,EAAE,EACtB,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,IAChC;AACA,QAAI,MAAM,SAAS,EAAG,QAAO,EAAE,WAAW,MAAM;AAChD,eAAW,UAAU,KAAK,gBAAgB;AACxC,UAAI,eAAe;AACnB,iBAAW,KAAK,MAAO,KAAI,OAAO,MAAM,IAAI,CAAC,EAAG;AAChD,YAAM,SAAQ,oBAAI,IAAI,CAAC,GAAG,OAAO,GAAG,OAAO,KAAK,CAAC,GAAE;AACnD,UAAI,QAAQ,KAAK,eAAe,QAAQ,iBAAgB,4BAA4B;AAClF,eAAO,EAAE,WAAW,MAAM,uBAAuB,OAAO,QAAQ;AAAA,MAClE;AAAA,IACF;AACA,UAAM,MAAM,iBAAgB;AAC5B,UAAM,UAAU,QAAQ,SAAS,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI,WAAM;AACrE,SAAK,eAAe,KAAK,EAAE,OAAO,WAAW,KAAK,QAAQ,CAAC;AAC3D,QAAI,KAAK,eAAe,SAAS,EAAG,MAAK,eAAe,MAAM;AAC9D,WAAO,EAAE,WAAW,MAAM;AAAA,EAC5B;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,YAA4D;AAAA,MAChE,SAAS;AAAA,MACT,kBAAkB;AAAA,MAClB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,MAAM;AAAA,IACR;AACA,UAAM,kBAAkB,UAAU,KAAK,qBAAqB,MAAM,KAAK;AACvE,SAAK,KAAK,KAAK,aAAa;AAAA,MAC1B,WAAW,KAAK,OAAO;AAAA,MACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ;AAAA,IACV,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA,EAEA,gBAAgB,WAAoC;AAClD,SAAK,UAAU,EAAE,MAAM,gBAAgB,UAAU,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,iBAAiB,QAGsB;AAC3C,QAAI,CAAC,KAAK,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO,uBAAuB;AACpE,QAAI;AACF,YAAM,KAAK,KAAK,oBAAoB,EAAE,WAAW,KAAK,OAAO,WAAW,GAAG,OAAO,CAAC;AACnF,aAAO,EAAE,IAAI,KAAK;AAAA,IACpB,SAAS,KAAK;AACZ,aAAO,EAAE,IAAI,OAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,eAAe,cAA4B;AACzC,SAAK,KAAK,KAAK,kBAAkB,EAAE,WAAW,KAAK,OAAO,WAAW,aAAa,CAAC,EAAE;AAAA,MACnF,MAAM;AAAA,MAAC;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAIA,kBAAwB;AACtB,SAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAAA,EAC/C;AAAA,EAEA,iBAAuB;AACrB,SAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,EAC9C;AAAA;AAAA,EAIA,cAAc,QAML;AACP,QAAI,CAAC,KAAK,OAAQ;AAElB,SAAK,KAAK,KAAK,iBAAiB;AAAA,MAC9B,WAAW,KAAK,OAAO;AAAA,MACvB,aAAa,OAAO,YAAY,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,eAAe,IAAI,CAAC,KAAK;AAAA,MACjF,cAAc,OAAO,YAAY,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,gBAAgB,IAAI,CAAC,KAAK;AAAA,MACnF,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO,aAAa,CAAC,GAAG,SAAS;AAAA,IAC1C,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA,EAEA,mBAAmB,UAAwB;AACzC,SAAK,UAAU,EAAE,MAAM,qBAAqB,SAAS,CAAC;AAAA,EACxD;AAAA,EAEA,aAAa,QAAsB;AACjC,SAAK,WAAW,MAAM;AAAA,EACxB;AAAA,EAEA,qBAAqB,SAAiB,UAAyB;AAC7D,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,KAAK,KAAK,0BAA0B;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA;AAAA,EAIA,MAAM,gBAAgB,WAA6D;AACjF,UAAM,eAAe,UAClB;AAAA,MACC,CAAC,MACC,KAAK,EAAE,MAAM;AAAA,EAAO,EAAE,QAAQ,GAAG,EAAE,QAAQ,SAAS,OAAO,EAAE,QAAQ,IAAI,CAAC,MAAM,KAAK,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,IAAI,EAAE;AAAA,IACrI,EACC,KAAK,MAAM;AAEd,UAAM,YAAY,OAAO,WAAW;AAMpC,UAAM,mBAAmB,IAAI,QAAgC,CAACA,aAAY;AACxE,WAAK,uBAAuB,IAAI,WAAWA,QAAO;AAAA,IACpD,CAAC;AAED,UAAM,aAAa,KAAK,KAAK,mBAAmB;AAAA,MAC9C,WAAW,KAAK,OAAO;AAAA,MACvB,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO;AAE5B,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK,CAAC,YAAY,gBAAgB,CAAC;AAAA,IAC1D,UAAE;AACA,WAAK,uBAAuB,OAAO,SAAS;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA,EAIA,oBAIG;AACD,WAAO,KAAK,KAAK,qBAAqB,EAAE,WAAW,KAAK,OAAO,UAAU,CAAC;AAAA,EAC5E;AAAA,EAEA,wBAA0D;AACxD,WAAO,KAAK,KAAK,yBAAyB,EAAE,WAAW,KAAK,OAAO,UAAU,CAAC;AAAA,EAChF;AAAA,EAEA,wBAGG;AACD,WAAO,KAAK,KAAK,yBAAyB,EAAE,WAAW,KAAK,OAAO,UAAU,CAAC;AAAA,EAChF;AAAA,EAEA,MAAM,mBAAqC;AACzC,UAAM,SAAS,MAAM,KAAK,qBAAqB;AAC/C,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,yBAAyB;AAAA,EACjC,MAAM,gCAAkD;AACtD,UAAM,SAAS,MAAM,KAAK,qBAAqB;AAC/C,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAc,uBAGX;AACD,UAAM,gBAAgB,QAAQ,IAAI,kBAAkB,QAAQ,IAAI;AAChE,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,CAAC,iBAAiB,CAAC,OAAQ,QAAO,EAAE,iBAAiB,OAAO,oBAAoB,MAAM;AAC1F,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,KAAK,yBAAyB,KAAQ;AAC9C,aAAO,EAAE,iBAAiB,OAAO,oBAAoB,MAAM;AAAA,IAC7D;AACA,SAAK,yBAAyB;AAC9B,UAAM,iBAAiB,QAAQ,IAAI;AACnC,UAAM,SAAS,MAAM,eAAe;AAAA,MAClC;AAAA,MACA,cAAc;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,IAIF,CAAC;AACD,QAAI,CAAC,OAAO,GAAI,QAAO,EAAE,iBAAiB,OAAO,oBAAoB,MAAM;AAC3E,UAAM,oBAAoB,QAAQ,IAAI;AACtC,wBAAoB,OAAO,MAAM;AACjC,UAAM,qBACJ,OAAO,OAAO,SAAS,aACvB,QAAQ,OAAO,OAAO,SAAS,KAC/B,OAAO,OAAO,cAAc;AAC9B,QAAI,sBAAsB,OAAO,OAAO,WAAW;AACjD,WAAK,OAAO,YAAY,OAAO,OAAO;AAEtC,UAAI,KAAK,QAAQ;AACf,cAAM,OAAO,KAAK,OAAO;AACzB,YAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,eAAK,YAAY,OAAO,OAAO;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AACA,UAAM,kBAAkB,QAAQ,OAAO,OAAO,SAAS,uBAAuB;AAC9E,WAAO,EAAE,iBAAiB,mBAAmB;AAAA,EAC/C;AAAA;AAAA,EAIA,UAAU,OAAuD;AAC/D,QAAI,CAAC,KAAK,OAAQ;AAGlB,QAAI,KAAK,YAAY,UAAU,kBAAkB;AAC/C,WAAK,YAAY,MAAM;AACvB,WAAK;AACL,UAAI,KAAK,sBAAsB,KAAK,KAAK,oBAAoB,QAAQ,GAAG;AACtE,gBAAQ,OAAO;AAAA,UACb,wDAAmD,KAAK,iBAAiB,mBAAmB,gBAAgB;AAAA;AAAA,QAC9G;AAAA,MACF;AAAA,IACF;AACA,SAAK,YAAY,KAAK,EAAE,MAAM,CAAC;AAC/B,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,WAAW,MAAM,KAAK,KAAK,YAAY,GAAG,cAAc;AAAA,IAC5E;AAAA,EACF;AAAA,EAEA,MAAM,cAA6B;AACjC,QAAI,KAAK,YAAY;AACnB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,QAAI,CAAC,KAAK,UAAU,KAAK,YAAY,WAAW,EAAG;AACnD,UAAM,SAAS,KAAK,YAAY,IAAI,CAAC,UAAU,MAAM,KAAK;AAC1D,SAAK,cAAc,CAAC;AAEpB,UAAM,KAAK,KAAK,kBAAkB,EAAE,WAAW,KAAK,OAAO,WAAW,OAAO,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAChG;AACF;;;ACnwBO,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EACA,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB;AAAA,EACA;AAAA,EAER,YACE,aACA,aAA4C,QAC5C,SAAS,OACT;AACA,SAAK,QAAQ;AACb,SAAK,cAAc;AACnB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAIA,IAAI,OAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,oBAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,kBAAkB,KAAc;AAClC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,IAAI,qBAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,mBAAmB,KAAc;AACnC,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA,EAGA,IAAI,gBAA2B;AAC7B,QAAI,KAAK,MAAO,QAAO,KAAK;AAC5B,QAAI,KAAK,gBAAgB,MAAM;AAC7B,aAAO,KAAK,UAAU,SAAS;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,aAAsB;AACxB,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,aAAa,MAAM,EAAE,SAAS,CAAC,EAAG,QAAO;AAC9C,WAAO,MAAM,UAAU,CAAC,KAAK;AAAA,EAC/B;AAAA,EAEA,IAAI,iBAA0B;AAC5B,WAAO,KAAK,kBAAkB,UAAU,CAAC,KAAK;AAAA,EAChD;AAAA,EAEA,IAAI,iBAA0B;AAC5B,UAAM,IAAI,KAAK;AACf,WAAO,MAAM,cAAc,MAAM,YAAa,MAAM,UAAU,KAAK;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,WAAyC,QAAmC;AAC1F,QAAI,WAAW;AACb,WAAK,QAAQ;AACb,WAAK,UAAU,cAAc,UAAU,CAAC,CAAC;AAAA,IAC3C,WAAW,WAAW,QAAW;AAC/B,WAAK,UAAU;AACf,UAAI,UAAU,KAAK,gBAAgB,QAAQ,CAAC,KAAK,OAAO;AACtD,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,KAAK,UAAU,aAAa;AAC9C,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,mBAAmB,SAAqC;AAEtD,QAAI,KAAK,gBAAgB,eAAe;AACtC,WAAK,QAAQ;AACb,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,KAAK,UAAU,UAAU,KAAK,kBAAkB,OAAO,GAAG;AAC5D,WAAK,qBAAqB,OAAO;AACjC,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,kBAAkB,SAAmC;AACnD,QAAI,KAAK,UAAU,OAAQ,QAAO;AAClC,QAAI,QAAQ,WAAW,WAAY,QAAO;AAC1C,QAAI,QAAQ,MAAM,KAAK,KAAK,QAAQ,aAAc,QAAO;AACzD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAKA,iBAAiB,SAAgC;AAC/C,QAAI,YAAY,KAAK,MAAO,QAAO,EAAE,MAAM,OAAO;AAGlD,QAAI,KAAK,gBAAgB,UAAU,YAAY,UAAU;AACvD,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,iBAAiB,SAAS,SAAS;AAAA,IACpD;AAGA,QAAI,KAAK,gBAAgB,UAAU,YAAY,YAAY;AACzD,WAAK,QAAQ;AACb,WAAK,UAAU;AACf,WAAK,qBAAqB;AAC1B,aAAO,EAAE,MAAM,iBAAiB,SAAS,WAAW;AAAA,IACtD;AAGA,QAAI,KAAK,gBAAgB,UAAU,YAAY,QAAQ;AACrD,WAAK,QAAQ;AACb,WAAK,UAAU;AACf,WAAK,qBAAqB;AAC1B,aAAO,EAAE,MAAM,iBAAiB,SAAS,OAAO;AAAA,IAClD;AAIA,QAAI,KAAK,UAAU,UAAU,KAAK,sBAAsB,YAAY,YAAY;AAC9E,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,OAAO;AAAA,IACxB;AAEA,QAAI,KAAK,gBAAgB,KAAM,QAAO,EAAE,MAAM,OAAO;AAErD,SAAK,QAAQ;AACb,SAAK,yBAAyB,OAAO;AAErC,QAAI,KAAK,gBAAgB;AACvB,aAAO,EAAE,MAAM,aAAa;AAAA,IAC9B;AACA,WAAO,EAAE,MAAM,OAAO;AAAA,EACxB;AAAA;AAAA,EAGA,mBAAmB,SAAsC;AACvD,QAAI,KAAK,mBAAoB,QAAO,EAAE,MAAM,OAAO;AACnD,SAAK,qBAAqB,OAAO;AACjC,SAAK,sBAAsB;AAC3B,WAAO,EAAE,MAAM,iBAAiB,SAAS,KAAK,MAAM;AAAA,EACtD;AAAA;AAAA,EAGA,aAAa,SAAmC;AAC9C,WAAO,CAAC,CAAC,QAAQ;AAAA,EACnB;AAAA;AAAA,EAIQ,qBAAqB,SAAgC;AAC3D,SAAK,qBAAqB;AAC1B,SAAK,QAAQ,QAAQ,eAAe,WAAW;AAAA,EACjD;AAAA,EAEQ,yBAAyB,SAA0B;AACzD,QAAI,YAAY,YAAY;AAC1B,WAAK,qBAAqB;AAAA,IAC5B;AAAA,EAGF;AACF;;;ACtLO,IAAM,2BAA4C;AAAA,EACvD,eAAe,KAAK,KAAK;AAAA,EACzB,kBAAkB,KAAK,KAAK;AAAA,EAC5B,qBAAqB;AAAA,EACrB,wBAAwB,KAAK,KAAK;AAAA,EAClC,oBAAoB,IAAI,KAAK;AAC/B;AAIO,IAAM,YAAN,MAAgB;AAAA,EACZ;AAAA,EACQ;AAAA,EAET,iBAAwD;AAAA,EACxD,oBAA2D;AAAA,EAC3D,YAAkD;AAAA,EAClD,oBAA2D;AAAA,EAC3D,eAAqD;AAAA,EACrD,gBAAuD;AAAA,EAE/D,YAAY,QAAyB,WAA+B;AAClE,SAAK,SAAS;AACd,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA,EAIA,iBAAuB;AACrB,SAAK,cAAc;AACnB,SAAK,iBAAiB,YAAY,MAAM;AACtC,WAAK,UAAU,YAAY;AAAA,IAC7B,GAAG,KAAK,OAAO,mBAAmB;AAAA,EACpC;AAAA,EAEA,gBAAsB;AACpB,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAIA,oBAA0B;AACxB,SAAK,iBAAiB;AAEtB,SAAK,UAAU,eAAe;AAC9B,SAAK,oBAAoB,YAAY,MAAM;AACzC,WAAK,UAAU,eAAe;AAAA,IAChC,GAAG,KAAK,OAAO,sBAAsB;AAAA,EACvC;AAAA,EAEA,mBAAyB;AACvB,QAAI,KAAK,mBAAmB;AAC1B,oBAAc,KAAK,iBAAiB;AACpC,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAIA,gBAAsB;AACpB,SAAK,aAAa;AAClB,QAAI,KAAK,OAAO,sBAAsB,EAAG;AACzC,SAAK,gBAAgB,YAAY,MAAM;AACrC,WAAK,UAAU,WAAW;AAAA,IAC5B,GAAG,KAAK,OAAO,kBAAkB;AAAA,EACnC;AAAA,EAEA,eAAqB;AACnB,QAAI,KAAK,eAAe;AACtB,oBAAc,KAAK,aAAa;AAChC,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA;AAAA,EAIA,iBAAuB;AACrB,SAAK,gBAAgB;AACrB,SAAK,YAAY,WAAW,MAAM;AAChC,WAAK,UAAU,cAAc;AAAA,IAC/B,GAAG,KAAK,OAAO,aAAa;AAAA,EAC9B;AAAA,EAEA,kBAAwB;AACtB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,kBAAkB,YAA2B;AAC3C,SAAK,mBAAmB;AACxB,UAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,KAAK,OAAO,gBAAgB;AACpE,SAAK,eAAe,WAAW,MAAM;AACnC,WAAK,UAAU,iBAAiB;AAAA,IAClC,GAAG,KAAK;AAAA,EACV;AAAA,EAEA,qBAA2B;AACzB,QAAI,KAAK,cAAc;AACrB,mBAAa,KAAK,YAAY;AAC9B,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAIA,UAAgB;AACd,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAIQ,kBAAwB;AAC9B,QAAI,KAAK,WAAW;AAClB,mBAAa,KAAK,SAAS;AAC3B,WAAK,YAAY;AAAA,IACnB;AACA,QAAI,KAAK,mBAAmB;AAC1B,oBAAc,KAAK,iBAAiB;AACpC,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AACF;;;ACxKA,SAAS,gBAAgB;AAIlB,SAAS,mBAAmB,KAAa,YAA6B;AAC3E,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;AACF,aAAS,oBAAoB,UAAU,IAAI,EAAE,KAAK,OAAO,UAAU,SAAS,IAAO,CAAC;AAAA,EACtF,QAAQ;AACN,YAAQ,OAAO;AAAA,MACb,8CAA8C,UAAU;AAAA;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,aAAS,oBAAoB,UAAU,cAAc,EAAE,KAAK,OAAO,UAAU,SAAS,IAAO,CAAC;AAAA,EAChG,QAAQ;AACN,YAAQ,OAAO;AAAA,MACb,0CAA0C,UAAU;AAAA;AAAA,IACtD;AACA,QAAI;AACF,eAAS,qBAAqB,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACxD,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,MAAM,8CAA8C,UAAU;AAAA,CAAI;AACjF,SAAO;AACT;AAIO,SAAS,mBAAmB,KAAa,YAA6B;AAC3E,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,UAAU,iBAAiB,GAAG;AACpC,MAAI,YAAY,WAAY,QAAO;AAEnC,MAAI;AACF,aAAS,oBAAoB,UAAU,IAAI,EAAE,KAAK,OAAO,UAAU,SAAS,IAAO,CAAC;AAAA,EACtF,QAAQ;AACN,YAAQ,OAAO,MAAM,8CAA8C,UAAU;AAAA,CAAW;AACxF,WAAO;AAAA,EACT;AAMA,MAAI;AACF,aAAS,mBAAmB,UAAU,WAAW,UAAU,IAAI;AAAA,MAC7D;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH,QAAQ;AACN,YAAQ,OAAO,MAAM,0CAA0C,UAAU;AAAA,CAAW;AACpF,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,MAAM,4CAA4C,UAAU;AAAA,CAAI;AAC/E,SAAO;AACT;AAGO,SAAS,sBAAsB,KAAsB;AAC1D,QAAM,SAAS,SAAS,0BAA0B;AAAA,IAChD;AAAA,IACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,EACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,SAAO,OAAO,SAAS;AACzB;AAGO,SAAS,iBAAiB,KAA4B;AAC3D,MAAI;AACF,UAAM,SAAS,SAAS,6BAA6B;AAAA,MACnD;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,WAAO,UAAU;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,mBAAmB,KAAsB;AACvD,MAAI;AACF,UAAM,gBAAgB,iBAAiB,GAAG;AAC1C,QAAI,CAAC,cAAe,QAAO;AAE3B,QAAI;AACF,eAAS,wBAAwB,aAAa,IAAI;AAAA,QAChD;AAAA,QACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,MACpC,CAAC;AAAA,IACH,QAAQ;AACN,UAAI;AACF,iBAAS,sBAAsB,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC;AAC3E,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,QAAQ,SAAS,0CAA0C,aAAa,IAAI;AAAA,MAChF;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,WAAO,SAAS,OAAO,EAAE,IAAI;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,eAAe,KAAa,SAAgC;AAC1E,MAAI;AACF,aAAS,cAAc,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC;AAEnE,QAAI,CAAC,sBAAsB,GAAG,EAAG,QAAO;AAExC,aAAS,iBAAiB,KAAK,UAAU,OAAO,CAAC,IAAI;AAAA,MACnD;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC;AAED,WAAO,SAAS,sBAAsB,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC,EAC/E,SAAS,EACT,KAAK;AAAA,EACV,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,KAAa,QAAyB;AACrD,MAAI;AACF,aAAS,mBAAmB,MAAM,IAAI;AAAA,MACpC;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,SAAS;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,QAAI;AACF,eAAS,sCAAsC,MAAM,IAAI;AAAA,QACvD;AAAA,QACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,QAChC,SAAS;AAAA,MACX,CAAC;AACD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,YAAY,KAAsB;AACzC,MAAI;AACF,aAAS,sBAAsB,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,MAAM,GAAG,SAAS,IAAO,CAAC;AAC1F,WAAO;AAAA,EACT,SAAS,KAAc;AACrB,QAAK,IAA6B,OAAQ,QAAO;AACjD,UAAM,SAAU,IAA4B,QAAQ,SAAS,KAAK;AAClE,UAAM,SAAU,IAA4B,QAAQ,SAAS,KAAK;AAClE,UAAM,MAAM,UAAU,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtE,WAAO,8CAA8C,KAAK,GAAG;AAAA,EAC/D;AACF;AAGO,SAAS,kBAAkB,KAAa,OAAqB;AAClE,MAAI;AACF,UAAM,MAAM,SAAS,6BAA6B,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC,EAC3F,SAAS,EACT,KAAK;AACR,UAAM,QAAQ,IAAI,MAAM,gCAAgC;AACxD,QAAI,OAAO;AACT,YAAM,OAAO,MAAM,CAAC,EAAE,QAAQ,UAAU,EAAE;AAC1C;AAAA,QACE,qDAAqD,KAAK,eAAe,IAAI;AAAA,QAC7E,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAaO,SAAS,gBAAgB,QAAwB;AACtD,SAAO,gBAAgB,MAAM;AAC/B;AAGA,IAAM,eAAe,oBAAI,IAAY;AAQrC,SAAS,kBAAkB,KAAa,SAAgC;AACtE,MAAI;AACF,aAAS,cAAc,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC;AACnE,UAAM,MAAM,SAAS,oBAAoB,KAAK,UAAU,OAAO,CAAC,IAAI;AAAA,MAClE;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,QAAI;AACF,eAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvE,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,eAAe,KAAa,SAAiB,QAAQ,OAAgB;AAC5E,MAAI;AACF,aAAS,YAAY,QAAQ,aAAa,EAAE,UAAU,KAAK,UAAU,OAAO,CAAC,IAAI;AAAA,MAC/E;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,SAAS;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,mBACb,KACA,cACe;AACf,MAAI,CAAC,aAAc;AACnB,MAAI;AACF,UAAM,QAAQ,MAAM,aAAa;AACjC,QAAI,OAAO;AACT,wBAAkB,KAAK,KAAK;AAC5B,cAAQ,IAAI,eAAe;AAC3B,cAAQ,IAAI,WAAW;AAAA,IACzB;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAOO,SAAS,mBACd,KACA,QACyC;AACzC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,MAAM,gBAAgB,MAAM;AAClC,MAAI;AACF,aAAS,gCAAgC,GAAG,wBAAwB,GAAG,IAAI;AAAA,MACzE;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH,QAAQ;AAEN,WAAO;AAAA,EACT;AAEA,eAAa,IAAI,GAAG;AACpB,MAAI;AACF,UAAM,MAAM,SAAS,qCAAqC,GAAG,IAAI;AAAA,MAC/D;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AAER,UAAM,SAAS,SAAS,kBAAkB,GAAG,MAAM;AAAA,MACjD;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,UAAM,OAAO,SAAS,sBAAsB,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,QAAQ,EAAE,CAAC,EACrF,SAAS,EACT,KAAK;AACR,QAAI,WAAW,KAAM,QAAO;AAC5B,aAAS,mBAAmB,GAAG,IAAI,EAAE,KAAK,OAAO,CAAC,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC7E,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,oBACpB,KACA,MACoE;AACpE,MAAI,YAAY;AAChB,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,MAAI;AACF,UAAM,SAAS,iBAAiB,GAAG;AACnC,QAAI,CAAC,OAAQ,QAAO,EAAE,WAAW,QAAQ,QAAQ;AAEjD,UAAM,QAAQ,sBAAsB,GAAG;AACvC,UAAM,WAAW,mBAAmB,GAAG;AAEvC,QAAI,CAAC,SAAS,CAAC,UAAU;AACvB,YAAM,gBAAgB,KAAK,QAAQ,MAAM,YAAY;AACrD,aAAO,EAAE,WAAW,QAAQ,QAAQ;AAAA,IACtC;AAEA,cAAU;AACV,UAAM,mBAAmB,KAAK,MAAM,YAAY;AAGhD,QAAI,UAAU;AACZ,eAAS,MAAM,aAAa,KAAK,MAAM,YAAY;AAAA,IACrD;AAEA,QAAI,OAAO;AACT,YAAM,UAAU,MAAM,cAAc;AACpC,YAAM,MAAM,kBAAkB,KAAK,OAAO;AAC1C,UAAI,KAAK;AACP,oBAAY,eAAe,KAAK,GAAG,GAAG,eAAe,gBAAgB,MAAM,CAAC,IAAI,IAAI;AACpF,YAAI,UAAW,cAAa,IAAI,GAAG;AAAA,MACrC;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO,EAAE,WAAW,QAAQ,QAAQ;AACtC;AAIA,eAAe,gBACb,KACA,QACA,cACe;AACf,MAAI,CAAC,aAAa,IAAI,GAAG,EAAG;AAC5B,QAAM,mBAAmB,KAAK,YAAY;AAC1C,MAAI,eAAe,KAAK,eAAe,gBAAgB,MAAM,CAAC,EAAE,GAAG;AACjE,iBAAa,OAAO,GAAG;AAAA,EACzB;AACF;AAIA,eAAsB,aACpB,KACA,cACkB;AAClB,MAAI;AACF,UAAM,gBAAgB,iBAAiB,GAAG;AAC1C,QAAI,CAAC,cAAe,QAAO;AAG3B,QAAI,cAAc;AAChB,UAAI;AACF,cAAM,QAAQ,MAAM,aAAa;AACjC,YAAI,OAAO;AACT,4BAAkB,KAAK,KAAK;AAC5B,kBAAQ,IAAI,eAAe;AAC3B,kBAAQ,IAAI,WAAW;AAAA,QACzB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,aAAa,EAAG,QAAO;AAExC,QAAI,gBAAgB,YAAY,GAAG,GAAG;AACpC,YAAM,QAAQ,MAAM,aAAa;AACjC,UAAI,OAAO;AACT,0BAAkB,KAAK,KAAK;AAC5B,gBAAQ,IAAI,eAAe;AAC3B,gBAAQ,IAAI,WAAW;AACvB,eAAO,QAAQ,KAAK,aAAa;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACxaA,SAAS,aAAa,UAAU,oBAAoB;AACpD,SAAS,YAAY;AAGd,IAAM,WAAN,MAAe;AAAA,EACZ,mBAAmB,oBAAI,IAAoB;AAAA,EAC3C,iBAAgC;AAAA,EAChC;AAAA,EACA;AAAA,EAER,YAAY,cAAsB,YAA6B;AAC7D,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,mBAAmB,cAA4B;AAC7C,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,cAAwB;AAC9B,WAAO,CAAC,KAAK,KAAK,cAAc,WAAW,OAAO,CAAC;AAAA,EACrD;AAAA,EAEA,oBAA0B;AACxB,SAAK,iBAAiB,MAAM;AAC5B,SAAK,iBAAiB;AACtB,eAAW,YAAY,KAAK,YAAY,GAAG;AACzC,UAAI;AACF,mBAAW,QAAQ,YAAY,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,GAAG;AACzE,cAAI;AACF,kBAAM,WAAW,KAAK,UAAU,IAAI;AACpC,kBAAMC,QAAO,SAAS,QAAQ;AAC9B,iBAAK,iBAAiB,IAAI,UAAUA,MAAK,OAAO;AAAA,UAClD,QAAQ;AACN;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAA6D;AACnE,QAAI,SAAiD;AACrD,eAAW,YAAY,KAAK,YAAY,GAAG;AACzC,UAAI;AACJ,UAAI;AACF,gBAAQ,YAAY,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AAAA,MAC/D,QAAQ;AACN;AAAA,MACF;AAEA,iBAAW,QAAQ,OAAO;AACxB,cAAM,WAAW,KAAK,UAAU,IAAI;AACpC,YAAI;AACF,gBAAMA,QAAO,SAAS,QAAQ;AAC9B,gBAAM,YAAY,KAAK,iBAAiB,IAAI,QAAQ;AACpD,gBAAM,QAAQ,cAAc,UAAaA,MAAK,UAAU;AACxD,cAAI,UAAU,CAAC,UAAUA,MAAK,UAAU,OAAO,QAAQ;AACrD,qBAAS,EAAE,MAAM,UAAU,OAAOA,MAAK,QAAQ;AAAA,UACjD;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAA8B;AAClC,UAAM,qBAAqB,KAAK,mBAAmB;AACnD,UAAM,SAAS,KAAK,kBAAkB,KAAK,mBAAmB,GAAG,QAAQ;AACzE,QAAI,CAAC,OAAQ;AAIb,QAAI,oBAAoB;AACtB,WAAK,iBAAiB;AAAA,IACxB;AAEA,UAAM,WAAW,OAAO,MAAM,GAAG,EAAE,IAAI,KAAK;AAE5C,QAAI;AACJ,QAAI;AACF,gBAAU,aAAa,QAAQ,OAAO,EAAE,KAAK;AAAA,IAC/C,SAAS,KAAK;AACZ,YAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,WAAK,WAAW;AAAA,QACd,sDAAsD,QAAQ,MAAM,MAAM;AAAA,MAC5E;AACA;AAAA,IACF;AAEA,QAAI,CAAC,QAAS;AAEd,UAAM,SAAS,MAAM,KAAK,WAAW,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACvE,QAAI,CAAC,OAAO,IAAI;AACd,WAAK,WAAW;AAAA,QACd,0CAA0C,QAAQ,oCAAoC,OAAO,SAAS,eAAe;AAAA,MACvH;AACA;AAAA,IACF;AAEA,UAAM,OAAO,qBAAqB,6BAA6B;AAC/D,UAAM,SAAS,qBAAqB,qCAAqC;AACzE,SAAK,WAAW,gBAAgB,GAAG,IAAI,KAAK,QAAQ,IAAI,MAAM,EAAE;AAAA,EAClE;AACF;;;AC3GA,SAAS,kBAAkB;AAC3B,SAAS,YAAY,gBAAAC,eAAc,oBAAoB;;;ACkNvD,SAAS,SAAS;AAgXlB,SAAS,KAAK,UAAU;AA8zCxB,SAAS,KAAK,UAAU;AApvDxB,IAAI,sBAAsB,KAAK,OAAO;AACtC,IAAI,yBAAyB,IAAI,OAAO;AACxC,IAAI,uBAAuB,IAAI,OAAO;AAwBtC,IAAI,oBAAoB,KAAK;AA6C7B,IAAI,uBAAuB,EAAE,OAAO;AAAA,EAClC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,KAAK,CAAC,UAAU,QAAQ,UAAU,CAAC;AAAA,EAC7C,eAAe,EAAE,OAAO,EAAE,SAAS;AACrC,CAAC;AACD,IAAI,sBAAsB,EAAE,OAAO;AAAA,EACjC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AACD,IAAI,wBAAwB,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,MAAM,EAAE,KAAK,CAAC,WAAW,YAAY,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,SAAS;AAC9E,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AACtD,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACxD,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;AAC7D,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,2BAA2B,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,uBAAuB,EAAE,OAAO;AAAA,EAClC,WAAW,EAAE,OAAO;AAAA,EACpB,cAAc,EAAE,OAAO;AACzB,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG;AAAA,EACzD,QAAQ,EAAE,KAAK,CAAC,SAAS,aAAa,CAAC,EAAE,SAAS;AACpD,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AACnD,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,OAAO;AACtB,CAAC;AAED,IAAI,iCAAiC,oBAAoB,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACzF,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,mBAAmB;AAC/D,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO;AAAA,EACjB,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACtC,CAAC;AACD,IAAI,gCAAgC,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO;AAAA,EACjB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAC7C,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,cAAc,EAAE,OAAO;AACzB,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC;AAC9D,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC1C,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,SAAS,EAAE,OAAO,EAAE,YAAY;AAAA,EAChC,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,WAAW,EAAE,OAAO;AAAA,EACpB,cAAc,EAAE,OAAO;AAAA,EACvB,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;AAClC,CAAC;AACD,IAAI,2BAA2B,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAC9B,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,kCAAkC,EAAE,OAAO;AAAA,EAC7C,WAAW,EAAE,OAAO;AAAA,EACpB,cAAc,EAAE,OAAO;AACzB,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACtD,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AACnD,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAClC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AACxD,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,qCAAqC,EAAE,OAAO;AAAA,EAChD,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,wBAAwB,EAAE,OAAO;AAAA,EACnC,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO,EAAE,YAAY;AAAA,EACpC,cAAc,EAAE,OAAO,EAAE,YAAY;AAAA,EACrC,sBAAsB,EAAE,OAAO,EAAE,YAAY;AAAA,EAC7C,0BAA0B,EAAE,OAAO,EAAE,YAAY;AAAA,EACjD,SAAS,EAAE,OAAO,EAAE,YAAY;AAClC,CAAC;AACD,IAAI,sCAAsC,EAAE,OAAO;AAAA,EACjD,cAAc,EAAE,OAAO,EAAE,YAAY;AAAA,EACrC,YAAY,EAAE,MAAM,qBAAqB;AAC3C,CAAC;AACD,IAAI,gCAAgC,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AACD,IAAI,oCAAoC,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACtD,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACrC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACvC,cAAc,EAAE,OAAO,EAAE,SAAS;AACpC,CAAC;AACD,IAAI,yBAAyB,EAAE,OAAO;AAAA,EACpC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,gCAAgC,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAC9C,CAAC;AACD,IAAI,0BAA0B,EAAE,OAAO;AAAA,EACrC,WAAW,EAAE,OAAO;AAAA,EACpB,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC/B,kBAAkB,EAAE,OAAO,EAAE,SAAS;AACxC,CAAC;AACD,IAAI,kCAAkC,EAAE,OAAO;AAAA,EAC7C,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AACxD,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,mBAAmB,EAAE,OAAO;AAC9B,CAAC;AACD,IAAI,gCAAgC,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO;AAAA,EACpB,mBAAmB,EAAE,OAAO;AAC9B,CAAC;AACD,IAAI,gCAAgC,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,cAAc,EAAE,OAAO;AAAA,EACvB,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC9C,CAAC;AACD,IAAI,qCAAqC,EAAE,OAAO;AAAA,EAChD,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,sCAAsC,EAAE,OAAO;AAAA,EACjD,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,QAAQ;AAAA,EACpB,SAAS,EAAE,OAAO;AACpB,CAAC;AACD,IAAI,oCAAoC,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AACxB,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AACxB,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AACxB,CAAC;AACD,IAAI,oCAAoC,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AAAA,EACtB,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAC3B,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AAAA,EACtB,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,mCAAmC,EAAE,OAAO;AAAA,EAC9C,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,QAAQ,EAAE,OAAO;AAAA,EACjB,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,uCAAuC,EAAE,OAAO;AAAA,EAClD,QAAQ,EAAE,OAAO;AAAA,EACjB,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,wCAAwC,EAAE,OAAO;AAAA,EACnD,QAAQ,EAAE,OAAO;AAAA,EACjB,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AACD,IAAI,+CAA+C,EAAE,OAAO;AAAA,EAC1D,WAAW,EAAE,OAAO;AAAA,EACpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACtC,CAAC;AACD,IAAI,mCAAmC,EAAE,OAAO;AAAA,EAC9C,QAAQ,EAAE,OAAO;AAAA,EACjB,WAAW,EAAE,OAAO;AAAA,EACpB,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAC1C,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO;AAAA,EACtB,SAAS,EAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AACD,IAAI,sBAAsB,EAAE,OAAO;AAAA,EACjC,UAAU,EAAE,OAAO;AAAA,EACnB,QAAQ,EAAE,OAAO;AAAA,EACjB,SAAS,EAAE,MAAM,yBAAyB;AAAA,EAC1C,aAAa,EAAE,QAAQ,EAAE,SAAS;AACpC,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC3B,WAAW,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC;AAC/C,CAAC;AACD,IAAI,mBAAmB,EAAE,OAAO;AAAA,EAC9B,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;AACvB,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,MAAM,gBAAgB,EAAE,IAAI,GAAG;AAC3C,CAAC;AACD,IAAI,kCAAkC,EAAE,OAAO;AAAA,EAC7C,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,mCAAmC,EAAE,OAAO;AAAA,EAC9C,OAAO,EAAE,OAAO;AAClB,CAAC;AACD,IAAI,sBAAsB,MAAM;AAChC,IAAI,oBAAoB;AACxB,IAAI,yBAAyB,EAAE,OAAO;AAAA,EACpC,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,IAAI,mBAAmB;AAAA,EACxC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,iBAAiB,EAAE,SAAS;AAAA,EAClE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,iBAAiB,EAAE,SAAS;AACpE,CAAC;AACD,IAAI,wBAAwB,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,IAAI,mBAAmB;AAC1C,CAAC;AACD,IAAI,yBAAyB,EAAE,OAAO;AAAA,EACpC,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,iBAAiB;AAAA,EACvD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,iBAAiB;AACzD,CAAC;AACD,IAAI,yBAAyB,EAAE,OAAO;AAAA,EACpC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,yBAAyB,EAAE,OAAO;AAAA,EACpC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACpC,OAAO,EAAE,OAAO,EAAE,IAAI;AACxB,CAAC;AACD,IAAI,2BAA2B,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,iCAAiC,EAAE,OAAO;AAAA,EAC5C,QAAQ,EAAE,OAAO;AAAA,EACjB,QAAQ,EAAE,OAAO;AACnB,CAAC;AACD,IAAI,+BAA+B,EAAE,OAAO;AAAA,EAC1C,SAAS,EAAE,QAAQ;AACrB,CAAC;AACD,IAAI,0BAA0B,EAAE,OAAO;AAAA,EACrC,cAAc,EAAE,QAAQ;AAC1B,CAAC;AACD,IAAI,6BAA6B,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,4BAA4B,EAAE,OAAO;AAAA,EACvC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AACtB,CAAC;AACD,IAAI,8BAA8B,EAAE,OAAO;AAAA,EACzC,SAAS,EAAE,QAAQ;AACrB,CAAC;AACD,IAAI,qCAAqC,EAAE,OAAO;AAAA,EAChD,YAAY,EAAE,QAAQ;AAAA;AAAA,EAEtB,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO;AAAA,EACpB,mBAAmB,EAAE,OAAO;AAAA,EAC5B,OAAO,EAAE,OAAO;AAAA,EAChB,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC1D,qBAAqB,EAAE,OAAO,EAAE,SAAS;AAC3C,CAAC;AAID,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AACpC,CAAC;AACD,IAAI,sCAAsC,GAAG,OAAO;AAAA,EAClD,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,wCAAwC,GAAG,OAAO;AAAA,EACpD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,KAAK,CAAC,QAAQ,MAAM,CAAC;AAAA,EAChC,cAAc,GAAG,OAAO,EAAE,QAAQ;AAAA,EAClC,cAAc,GAAG,OAAO,EAAE,QAAQ;AAAA,EAClC,cAAc,GAAG,OAAO,EAAE,QAAQ;AACpC,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,sCAAsC,GAAG,OAAO;AAAA,EAClD,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,4CAA4C,GAAG,OAAO;AAAA,EACxD,WAAW,GAAG,OAAO;AAAA,EACrB,MAAM,GAAG,OAAO;AAClB,CAAC;AACD,IAAI,wCAAwC,GAAG,OAAO;AAAA,EACpD,WAAW,GAAG,OAAO;AAAA,EACrB,YAAY,GAAG,OAAO;AACxB,CAAC;AACD,IAAI,qCAAqC,GAAG,OAAO;AAAA,EACjD,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACzD,QAAQ,GAAG,OAAO,EAAE,SAAS;AAC/B,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AAAA,EACrB,SAAS,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,QAAQ,GAAG,OAAO,EAAE,SAAS;AAC/B,CAAC;AACD,IAAI,gCAAgC,GAAG,OAAO;AAAA,EAC5C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO,EAAE,SAAS;AAAA,EAC7B,YAAY,GAAG,OAAO,EAAE,SAAS;AAAA,EACjC,YAAY,GAAG,QAAQ,EAAE,SAAS;AAAA,EAClC,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC3D,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,aAAa;AAAA,EAChD,SAAS;AACX,CAAC;AACD,IAAI,8BAA8B,GAAG,OAAO;AAAA,EAC1C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AACpB,CAAC;AACD,IAAI,kCAAkC,GAAG,OAAO;AAAA,EAC9C,WAAW,GAAG,OAAO;AAAA,EACrB,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,SAAS;AAAA,EAC9C,YAAY,GAAG,OAAO,EAAE,SAAS;AAAA,EACjC,YAAY,GAAG,QAAQ,EAAE,SAAS;AAAA,EAClC,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC3D,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,aAAa;AAAA,EAChD,SAAS;AACX,CAAC;AACD,IAAI,+BAA+B,GAAG,OAAO;AAAA,EAC3C,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,iCAAiC,GAAG,OAAO;AAAA,EAC7C,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,iCAAiC,GAAG,OAAO;AAAA,EAC7C,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,QAAQ,GAAG,OAAO,EAAE,SAAS;AAAA,EAC7B,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,iCAAiC,GAAG,OAAO;AAAA,EAC7C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,EAC5B,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,QAAQ,GAAG,OAAO,EAAE,SAAS;AAAA,EAC7B,gBAAgB,GAAG,OAAO,EAAE,QAAQ;AAAA,EACpC,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,GAAG,QAAQ,CAAC;AAC5C,CAAC;AACD,IAAI,sCAAsC,GAAG,OAAO;AAAA,EAClD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,UAAU,GAAG,OAAO;AAAA,IAClB,MAAM,GAAG,OAAO;AAAA,IAChB,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,GAAG,OAAO;AAAA,EACvB,CAAC;AACH,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,GAAG,QAAQ,CAAC,CAAC;AAAA,EAC9D,SAAS,GAAG,OAAO;AAAA,EACnB,UAAU,GAAG,QAAQ;AACvB,CAAC;AACD,IAAI,wCAAwC,GAAG,OAAO;AAAA,EACpD,WAAW,GAAG,OAAO;AAAA,EACrB,SAAS,GAAG;AAAA,IACV,GAAG,OAAO;AAAA,MACR,KAAK,GAAG,OAAO;AAAA,MACf,SAAS,GAAG,OAAO;AAAA,MACnB,QAAQ,GAAG,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EACA,QAAQ,GAAG,OAAO;AACpB,CAAC;AACD,IAAI,sCAAsC,GAAG,OAAO;AAAA,EAClD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,eAAe,GAAG,QAAQ;AAAA,EAC1B,qBAAqB,GAAG,QAAQ;AAClC,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AAAA,EACrB,MAAM,GAAG,OAAO;AAAA,EAChB,UAAU,GAAG,OAAO;AAAA,EACpB,SAAS,GAAG,OAAO,EAAE,SAAS;AAChC,CAAC;AACD,IAAI,yCAAyC,GAAG,OAAO;AAAA,EACrD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,SAAS,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,cAAc,GAAG,OAAO,EAAE,SAAS;AACrC,CAAC;AACD,IAAI,0CAA0C,GAAG,OAAO;AAAA,EACtD,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACzD,QAAQ,GAAG,OAAO,EAAE,SAAS;AAC/B,CAAC;AACD,IAAI,qCAAqC,GAAG,OAAO;AAAA,EACjD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,SAAS,GAAG,OAAO;AAAA,EACnB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,iCAAiC,GAAG,OAAO;AAAA,EAC7C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACzD,QAAQ,GAAG,OAAO,EAAE,SAAS;AAC/B,CAAC;AACD,IAAI,iCAAiC,GAAG,OAAO;AAAA,EAC7C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,gCAAgC,GAAG,OAAO;AAAA,EAC5C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,qCAAqC,GAAG,OAAO;AAAA,EACjD,WAAW,GAAG,OAAO;AAAA,EACrB,aAAa,GAAG,OAAO;AAAA,EACvB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,mCAAmC,GAAG,OAAO;AAAA,EAC/C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AACpB,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,cAAc,GAAG,OAAO;AAAA,EACxB,OAAO,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,SAAS,GAAG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAClD,iBAAiB,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACvD,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,EAC5B,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,QAAQ,GAAG,OAAO,EAAE,SAAS;AAAA,EAC7B,SAAS,GAAG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAClD,iBAAiB,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACvD,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,kCAAkC,GAAG,OAAO;AAAA,EAC9C,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC3D,CAAC;AACD,IAAI,wCAAwC,GAAG,OAAO;AAAA,EACpD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,mBAAmB,GAAG,OAAO;AAAA,EAC7B,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,2CAA2C,GAAG,OAAO;AAAA,EACvD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,mBAAmB,GAAG,OAAO;AAAA,EAC7B,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,qCAAqC,GAAG,OAAO;AAAA,EACjD,WAAW,GAAG,OAAO;AAAA,EACrB,cAAc,GAAG,OAAO;AAAA,EACxB,OAAO,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC;AAAA,EAC/C,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,0CAA0C,GAAG,OAAO;AAAA,EACtD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AACpB,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AACpB,CAAC;AACD,IAAI,oCAAoC,GAAG,OAAO;AAAA,EAChD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,QAAQ,GAAG,OAAO;AAAA;AAAA,EAElB,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA;AAAA,EAEjD,UAAU,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAClD,CAAC;AACD,IAAI,wCAAwC,GAAG,OAAO;AAAA,EACpD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,OAAO,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,MAAM,GAAG,OAAO;AAAA,EAChB,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,MAAM,GAAG,OAAO,EAAE,SAAS;AAAA,EAC3B,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,kCAAkC,GAAG,OAAO;AAAA,EAC9C,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,sCAAsC,GAAG,OAAO;AAAA,EAClD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,QAAQ,GAAG,OAAO;AAAA,EAClB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,yCAAyC,GAAG,OAAO;AAAA,EACrD,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,QAAQ,GAAG,OAAO;AAAA,EAClB,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AAsjCD,IAAI,8BAA8B,GAAG,OAAO;AAAA,EAC1C,WAAW,GAAG,OAAO;AAAA,EACrB,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC;AACtC,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,UAAU,GAAG,OAAO;AAAA,IAClB,MAAM,GAAG,OAAO;AAAA,IAChB,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,GAAG,OAAO;AAAA,EACvB,CAAC;AACH,CAAC;AACD,IAAI,uCAAuC,GAAG,OAAO;AAAA,EACnD,WAAW,GAAG,OAAO;AAAA,EACrB,OAAO,GAAG,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,aAAa,GAAG,OAAO,EAAE,SAAS;AAAA,EAClC,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,kBAAkB,GAAG,OAAO,EAAE,SAAS;AACzC,CAAC;AACD,IAAI,4CAA4C,GAAG,OAAO;AAAA,EACxD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AACvB,CAAC;AACD,IAAI,qCAAqC,GAAG,OAAO;AAAA,EACjD,WAAW,GAAG,OAAO;AAAA,EACrB,WAAW,GAAG,OAAO;AAAA,EACrB,QAAQ,GAAG,OAAO;AAAA,EAClB,SAAS,GAAG,OAAO;AAAA,EACnB,YAAY,GAAG;AAAA,IACb,GAAG,OAAO;AAAA,MACR,WAAW,GAAG,OAAO;AAAA,MACrB,OAAO,GAAG,KAAK,CAAC,YAAY,YAAY,OAAO,CAAC;AAAA,MAChD,OAAO,GAAG,KAAK,CAAC,WAAW,WAAW,SAAS,CAAC;AAAA,MAChD,WAAW,GAAG,OAAO;AAAA,MACrB,WAAW,GAAG,OAAO;AAAA,MACrB,cAAc,GAAG,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EACA,kBAAkB,GAAG,OAAO,EAAE,SAAS;AAAA,EACvC,kBAAkB,GAAG,OAAO,EAAE,SAAS;AAAA,EACvC,eAAe,GAAG,OAAO,EAAE,SAAS;AAAA,EACpC,iBAAiB,GAAG,OAAO;AAAA,EAC3B,iBAAiB,GAAG,OAAO;AAAA,EAC3B,iBAAiB,GAAG,OAAO;AAAA,EAC3B,iBAAiB,GAAG,OAAO;AAAA,EAC3B,iBAAiB,GAAG,OAAO;AAAA,EAC3B,iBAAiB,GAAG,OAAO;AAAA,EAC3B,cAAc,GAAG,OAAO;AAAA,EACxB,cAAc,GAAG,OAAO;AAAA,EACxB,cAAc,GAAG,OAAO;AAAA,EACxB,kBAAkB,GAAG;AAAA,IACnB,GAAG,OAAO;AAAA,MACR,cAAc,GAAG,OAAO;AAAA,MACxB,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC;AAAA,MACvC,WAAW,GAAG,OAAO;AAAA,IACvB,CAAC;AAAA,EACH,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACvB,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAAA,EACnC,cAAc,GAAG,OAAO,EAAE,SAAS;AAAA,EACnC,OAAO,GAAG,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,GAAG,OAAO,EAAE,SAAS;AAC9B,CAAC;AAmBD,IAAI,0BAA0B;AAC9B,IAAI,wBAAwB;AAC5B,IAAI,iCAAiC,KAAK,IAAI,yBAAyB,qBAAqB,IAAI;;;ACr9DhG,SAAS,0BAA0B,SAAgC;AACjE,WAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,QAAI,QAAQ,CAAC,EAAE,SAAS,YAAa,QAAO;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,eAAoE;AAC/F,QAAM,QAAkB,CAAC,IAAI,mBAAmB;AAChD,aAAW,MAAM,eAAe;AAC9B,UAAM,OAAO,GAAG,OAAO,SAAS,GAAG,IAAI,KAAK;AAC5C,UAAM,KACJ,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,SAC1C,KACA,mBAAmB,GAAG,WAAW;AACvC,UAAM,KAAK,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG;AAAA,EAChD;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,aAAgE;AACzF,QAAM,QAAkB,CAAC,IAAI,sBAAsB;AACnD,aAAW,MAAM,aAAa;AAC5B,UAAM,OAAO,GAAG,cAAc,WAAM,GAAG,WAAW,KAAK;AACvD,UAAM,KAAK,WAAW,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,EACvD;AACA,SAAO;AACT;AAEO,SAAS,4BACd,SACA,QACA,UACQ;AACR,QAAM,QAAkB;AAAA,IACtB,mEAAmE,QAAQ,KAAK;AAAA,IAChF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gDAAgD,QAAQ,UAAU;AAAA,IAClE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACzD,UAAM,KAAK,GAAG,kBAAkB,QAAQ,WAAW,CAAC;AAAA,EACtD;AAEA,MAAI,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,GAAG;AAC7D,UAAM,KAAK,GAAG,oBAAoB,QAAQ,aAAa,CAAC;AAAA,EAC1D;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,IAAI,4BAA4B,OAAO,GAAG,UAAU,KAAK;AAAA,EACtE;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,UAAM,KAAK,IAAI,yBAAyB,QAAQ,iBAAiB;AAAA,EACnE;AACA,MAAI,OAAO,cAAc;AACvB,UAAM,KAAK,IAAI,8BAA8B,OAAO,YAAY;AAAA,EAClE;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,4BACd,SACA,UACU;AACV,QAAM,QAAkB,CAAC;AAAA,gBAAmB;AAE5C,MAAI,aAAa,SAAS;AACxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,aAAa,iBAAiB;AACvC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,6FAA6F,QAAQ,UAAU;AAAA,MAC/G;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,eAAe,0BAA0B,QAAQ,WAAW;AAClE,UAAM,cAAc,QAAQ,YACzB,MAAM,eAAe,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAClC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA;AAAA,MACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,MACnE;AAAA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AClJO,SAAS,eAAe,OAAmC;AAChE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,GAAG,KAAK,MAAM,QAAQ,IAAI,CAAC;AAC3D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAYO,SAAS,eAAe,MAAgC;AAC7D,QAAM,UAAU,KAAK,WAAW,KAAK,eAAe,KAAK,QAAQ,CAAC,KAAK;AACvE,MAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,WAAO;AAAA,MACL,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO;AAAA,MACvD;AAAA,MACA,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,KAAK,SAAS;AACjB,WAAO,CAAC,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,OAAO,KAAK,WAAW,EAAE;AAAA,EAC1F;AACA,MAAI,KAAK,WAAW,KAAK,oBAAoB,UAAU;AACrD,WAAO;AAAA,MACL,oBAAoB,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,gCAA2B,KAAK,MAAM;AAAA,IACrG;AAAA,EACF;AACA,SAAO,CAAC,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,IAAI;AACrE;AAEO,SAAS,eAAe,MAAgC;AAC7D,MAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,WAAO,CAAC;AAAA,MAAS,KAAK,QAAQ,KAAK,KAAK,QAAQ,KAAK,OAAO,KAAK,SAAS,KAAK;AAAA,EACjF;AACA,MAAI,KAAK,WAAW,KAAK,oBAAoB,UAAU;AACrD,UAAM,OAAO,eAAe,KAAK,QAAQ;AACzC,WAAO;AAAA,MACL,sBAAsB,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,KAAK,IAAI,KAAK,EAAE,gCAA2B,KAAK,MAAM;AAAA,IACvH;AAAA,EACF;AACA,MAAI,CAAC,KAAK,SAAS;AACjB,WAAO,CAAC,OAAO,KAAK,QAAQ,OAAO,KAAK,QAAQ,MAAM,KAAK,WAAW,EAAE;AAAA,EAC1E;AACA,SAAO,CAAC;AACV;AAEO,SAAS,kBACd,aACA,OACU;AACV,QAAM,WAAW,YAAY,MAAM,EAAE,SAAS,sBAAsB;AACpE,QAAM,QAAQ,CAAC;AAAA,uBAA0B;AACzC,aAAW,OAAO,UAAU;AAC1B,UAAM,SAAS,IAAI,YAAY,IAAI;AACnC,UAAM,KAAK,IAAI,MAAM,MAAM,IAAI,OAAO,EAAE;AACxC,QAAI,IAAI,OAAO,QAAQ;AACrB,iBAAW,QAAQ,IAAI,OAAO;AAC5B,cAAM,KAAK,GAAG,eAAe,IAAI,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,eAAe,UAA0D;AACvF,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,yBAA4B;AACvC,aAAW,OAAO,UAAU;AAC1B,UAAM,OAAO,IAAI,YAAY,WAAW,WAAW;AACnD,UAAM,KAAK,MAAM,IAAI,OAAO,IAAI,IAAI,IAAI;AAAA,EAC1C;AACA,SAAO;AACT;AAEO,SAAS,wBACd,mBACU;AACV,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,sBAAyB;AACpC,QAAM;AAAA,IACJ;AAAA;AAAA,EACF;AACA,aAAW,OAAO,mBAAmB;AACnC,UAAM,OACJ,IAAI,mBAAmB,IAAI,iBACvB,KAAK,IAAI,eAAe,IAAI,IAAI,cAAc,MAC9C;AACN,UAAM,KAAK,OAAO,IAAI,IAAI,KAAK,IAAI,oCAA+B,IAAI,IAAI,KAAK;AAAA,EACjF;AACA,SAAO;AACT;AAEO,SAAS,wBACd,YACU;AACV,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,sBAAyB;AACpC,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,GAAG,IAAI,UAAU,MAAM,GAAG,EAAE,CAAC,CAAC,OAAO,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;AAC5E,UAAM,KAAK,OAAO,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,cAAc,OAAO,IAAI,cAAc,EAAE,EAAE;AAAA,EAC3F;AACA,SAAO;AACT;AAEO,SAAS,yBACd,OACU;AACV,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,oCAAuC;AAClD,QAAM;AAAA,IACJ;AAAA;AAAA,EACF;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,KAAK,SAAS,SAAS,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI,CAAC,MAAM;AAC3E,UAAM,KAAK,KAAK,cAAc,eAAU,KAAK,WAAW,KAAK;AAC7D,UAAM,KAAK,OAAO,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,EAAE;AAAA,EAC9C;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,WAA4D;AAC1F,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK;AAAA,oBAAuB;AAClC,QAAM;AAAA,IACJ;AAAA;AAAA,EACF;AACA,aAAW,OAAO,WAAW;AAC3B,UAAM,WAAW,IAAI,WAAW,KAAK,IAAI,QAAQ,MAAM;AACvD,UAAM,SAAS,IAAI,SAAS,KAAK,IAAI,MAAM,MAAM;AACjD,UAAM,KAAK,OAAO,IAAI,KAAK,GAAG,QAAQ,GAAG,MAAM,EAAE;AACjD,QAAI,IAAI,YAAa,OAAM,KAAK,IAAI,WAAW;AAC/C,QAAI,IAAI,OAAQ,OAAM,KAAK,WAAW,IAAI,MAAM,EAAE;AAAA,EACpD;AACA,SAAO;AACT;;;AClJA,SAAS,UAAU,SAAS,YAAY;AAiBxC,IAAM,gBAAwC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAE;AAGpF,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,aAAa,UAA2B;AAC/C,QAAM,MAAM,SAAS,MAAM,SAAS,YAAY,GAAG,CAAC,EAAE,YAAY;AAClE,SAAO,kBAAkB,IAAI,GAAG;AAClC;AAKA,IAAM,mBAAmB,oBAAI,IAAkD;AAC/E,IAAM,qBAAqB,oBAAI,IAAkD;AACjF,IAAI,gBAAgB;AACpB,IAAI,kBAAkB;AA0BtB,SAAS,sBAAsB,QAAgB,OAAkB,YAAiC;AAChG,QAAM,gBAAgB,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC,IAAI,MAAY;AAEjF,QAAM,YAAY,eAAe,SAAS,OAAO;AAEjD,SAAO,gBAAgB,YAAY;AACrC;AAEA,eAAe,gBAAgB,UAAkB,UAA0C;AACzF,MAAI;AACF,QAAI,aAAa,QAAQ,EAAG,QAAO;AACnC,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,QAAQ;AAC9B,gBAAU,GAAG;AAAA,IACf,QAAQ;AACN,aAAO;AAAA,IACT;AACA,UAAM,SAAS,iBAAiB,IAAI,QAAQ;AAC5C,QAAI,UAAU,OAAO,YAAY,SAAS;AACxC,mBAAa,OAAO;AAAA,IACtB,OAAO;AACL,mBAAa,MAAM,SAAS,UAAU,OAAO;AAC7C;AACA,uBAAiB,IAAI,UAAU,EAAE,SAAS,SAAS,WAAW,CAAC;AAAA,IACjE;AACA,QAAI,WAAW,SAAS,UAAU;AAChC,YAAM,UAAU,WAAW,SAAS;AACpC,aAAO,WAAW,MAAM,GAAG,QAAQ,IAAI;AAAA,kBAAqB,OAAO;AAAA,IACrE;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,kBAAkB,YAA4C;AAC3E,MAAI;AACF,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,UAAU;AAChC,gBAAU,GAAG;AAAA,IACf,QAAQ;AACN,aAAO;AAAA,IACT;AACA,UAAM,SAAS,mBAAmB,IAAI,UAAU;AAChD,QAAI,UAAU,OAAO,YAAY,SAAS;AACxC,aAAO,OAAO;AAAA,IAChB;AACA,UAAM,UAAU,MAAM,QAAQ,UAAU;AACxC;AACA,UAAM,UAAU,UAAU,QAAQ,KAAK,IAAI,CAAC;AAC5C,uBAAmB,IAAI,YAAY,EAAE,SAAS,QAAQ,CAAC;AACvD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,aACb,OACA,QACwB;AACxB,QAAM,SAAwB;AAAA,IAC5B,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAEA,MAAI,OAAO,aAAa,EAAG,QAAO;AAElC,MAAI,MAAM,SAAS,OAAO;AAExB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,UAAU;AAC3B,UAAM,UAAU,MAAM,kBAAkB,MAAM,IAAI;AAClD,QAAI,SAAS;AACX,aAAO,UAAU;AACjB,aAAO,YAAY,QAAQ;AAC3B,aAAO,aAAa,QAAQ;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAIA,QAAM,WAAW,KAAK,MAAM,OAAO,YAAY,GAAG,KAAK,OAAO;AAC9D,QAAM,UAAU,MAAM,gBAAgB,MAAM,MAAM,QAAQ;AAC1D,MAAI,SAAS;AACX,WAAO,UAAU;AACjB,WAAO,YAAY,QAAQ;AAC3B,WAAO,aAAa,QAAQ;AAAA,EAC9B;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAA8B;AACjD,QAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,KAAK,MAAM;AAClD,QAAM,SAAS,QAAQ,MAAM,IAAI,GAAG,KAAK,KAAK,MAAM,IAAI;AAExD,MAAI,MAAM,YAAY,MAAM;AAC1B,WAAO,KAAK,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG,KAAK;AAAA,EAC/C;AAEA,MAAI,MAAM,SAAS,UAAU;AAC3B,WAAO,GAAG,MAAM;AAAA,EAAK,MAAM,OAAO;AAAA,EACpC;AAGA,SAAO,GAAG,MAAM;AAAA;AAAA,EAAa,MAAM,OAAO;AAAA;AAC5C;AAEA,SAAS,mBAAmB,UAAwC;AAClE,QAAM,QAAkB,CAAC;AAAA,eAAkB;AAE3C,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,QAAQ,WAAW,EAAG;AAC9B,UAAM,OAAO,IAAI,cAAc,WAAM,IAAI,WAAW,KAAK;AACzD,UAAM,KAAK;AAAA,YAAe,IAAI,OAAO,IAAI,IAAI,EAAE;AAE/C,UAAM,iBAAiB,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI;AACnE,UAAM,iBAAiB,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI;AAEnE,eAAW,SAAS,gBAAgB;AAClC,YAAM,KAAK;AAAA,EAAK,YAAY,KAAK,CAAC,EAAE;AAAA,IACtC;AAEA,QAAI,eAAe,SAAS,GAAG;AAC7B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,2EAA2E;AACtF,iBAAW,SAAS,gBAAgB;AAClC,cAAM,KAAK,YAAY,KAAK,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,kBACpB,aACA,YACA,OACA,OACA,YACoF;AACpF,MAAI,CAAC,aAAa,UAAU,CAAC,WAAW,QAAQ;AAC9C,WAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,EAAE;AAAA,EACnE;AAEA,QAAM,eAAe,IAAI,IAAI,UAAU;AACvC,QAAM,eAAe,YAAY,OAAO,CAAC,MAAM,aAAa,IAAI,EAAE,EAAE,CAAC;AAErE,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,EAAE;AAAA,EACnE;AAGA,QAAM,aACJ,CAAC;AACH,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,MAAM,aAAa,CAAC;AAC1B,QAAI,CAAC,IAAI,cAAc,OAAQ;AAC/B,UAAM,SAAS,CAAC,GAAG,IAAI,YAAY,EAAE;AAAA,MACnC,CAAC,GAAG,OAAO,cAAc,EAAE,IAAI,KAAK,OAAO,cAAc,EAAE,IAAI,KAAK;AAAA,IACtE;AACA,eAAW,SAAS,QAAQ;AAC1B,iBAAW,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,EAAE;AAAA,EACnE;AAEA,QAAM,cAAc,sBAAsB,OAAO,OAAO,UAAU;AAClE,QAAM,SAAS,EAAE,WAAW,YAAY;AACxC,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,QAAM,WAAiC,aAAa,IAAI,CAAC,OAAO;AAAA,IAC9D,SAAS,EAAE;AAAA,IACX,aAAa,EAAE;AAAA,IACf,SAAS,CAAC;AAAA,EACZ,EAAE;AAEF,aAAW,EAAE,UAAU,MAAM,KAAK,YAAY;AAC5C,UAAM,SAAS,MAAM,aAAa,OAAO,MAAM;AAC/C,aAAS,QAAQ,EAAE,QAAQ,KAAK,MAAM;AACtC,QAAI,OAAO,YAAY,MAAM;AAC3B;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,iBAAiB,mBAAmB,QAAQ;AAAA,IAC5C,OAAO,EAAE,UAAU,QAAQ;AAAA,EAC7B;AACF;;;ACrSA,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,yBACJ;AAOK,SAAS,sBAAsB,MAAsB;AAC1D,MAAI,KAAK,UAAU,cAAe,QAAO;AACzC,QAAM,OAAO,KAAK,MAAM,GAAG,eAAe;AAC1C,QAAM,OAAO,KAAK,MAAM,KAAK,SAAS,eAAe;AACrD,SAAO,GAAG,IAAI,GAAG,sBAAsB,GAAG,IAAI;AAChD;;;ACdA,IAAM,oBAAoB;AAE1B,SAAS,oBAAoB,MAAc,UAA0B;AACnE,MAAI,KAAK,UAAU,SAAU,QAAO;AACpC,SAAO,KAAK,MAAM,GAAG,QAAQ,IAAI;AACnC;AAIA,SAAS,0BAA0B,KAA2B;AAC5D,QAAM,OAAO,IAAI,cAAc,WAAM,IAAI,WAAW,KAAK;AACzD,QAAM,QAAQ,CAAC,YAAY,IAAI,IAAI,IAAI,IAAI,EAAE;AAC7C,aAAW,QAAQ,IAAI,gBAAgB,CAAC,GAAG;AACzC,UAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAChD,UAAM,KAAK,cAAS,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,EAAE;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B,SAAsB,YAAmC;AAC1F,QAAM,SAAS,eAAe;AAC9B,QAAM,QAAkB,CAAC;AACzB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,MAAI,CAAC,UAAU,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACpE,UAAM,KAAK,IAAI,8BAA8B;AAC7C,eAAW,MAAM,QAAQ,aAAa;AACpC,YAAM,OAAO,GAAG,cACZ,WAAM,oBAAoB,GAAG,aAAa,iBAAiB,CAAC,KAC5D;AACJ,YAAM,KAAK,WAAW,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,IACvD;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACzD,UAAM,cAAc,IAAI,IAAI,QAAQ,cAAc,CAAC,CAAC;AACpD,UAAM,WAAW,QAAQ,YAAY,OAAO,CAAC,MAAM,YAAY,IAAI,EAAE,EAAE,CAAC;AACxE,UAAM,aAAa,QAAQ,YAAY,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;AAE3E,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,KAAK,IAAI,gBAAgB;AAC/B,iBAAW,OAAO,SAAU,OAAM,KAAK,GAAG,0BAA0B,GAAG,CAAC;AAAA,IAC1E;AAGA,QAAI,CAAC,UAAU,WAAW,SAAS,GAAG;AACpC,YAAM,KAAK,IAAI,yBAAyB;AACxC,iBAAW,OAAO,WAAY,OAAM,KAAK,GAAG,0BAA0B,GAAG,CAAC;AAAA,IAC5E;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,8BAAwC;AAC/C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,0BAAoC;AAC3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAuB,YAAiC;AACpF,QAAM,QAAQ;AAAA,IACZ;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,4BAA4B;AAAA,IAC/B,GAAG,wBAAwB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,SAAS,eACT;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAS,OAAM,KAAK,GAAG,0BAA0B,SAAS,UAAU,CAAC;AACzE,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,gBAAgB,SAAuB,YAAiC;AAC/E,QAAM,QAAQ;AAAA,IACZ;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,wBAAwB;AAAA,IAC3B;AAAA,IACA,GAAI,SAAS,eACT;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IACA,CAAC;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAS,OAAM,KAAK,GAAG,0BAA0B,SAAS,UAAU,CAAC;AACzE,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,gBACd,WACA,SACA,YACe;AACf,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,qBAAqB,SAAS,UAAU;AAAA,IACjD,KAAK,YAAY;AACf,YAAM,QAAQ;AAAA,QACZ;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,SAAS,eACT;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF,IACA;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,sCAAsC,SAAS,cAAc,KAAK;AAAA,QACpE;AAAA,MACN;AACA,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IACA,KAAK;AACH,aAAO,kBAAkB,OAAO;AAAA,IAClC,KAAK;AACH,aAAO,gBAAgB,SAAS,UAAU;AAAA,IAC5C;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,kBAAkB,SAA+B;AACxD,QAAM,QAAQ;AAAA,IACZ;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS,cAAc;AACzB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,MACA,qBAAqB,SAAS,cAAc,KAAK;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AClUA,SAAS,uBAAuB,IAA+D;AAC7F,QAAM,OAAO,GAAG,OAAO,SAAS,GAAG,IAAI,KAAK;AAC5C,QAAM,KACJ,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,SAC1C,KACA,mBAAmB,GAAG,WAAW;AACvC,SAAO,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,EAAE;AACzC;AAEA,SAAS,gBAAgB,SAAgC;AACvD,QAAM,QAAQ;AAAA,IACZ,gEAAgE,QAAQ,KAAK;AAAA,IAC7E;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ,cAAc;AACxB,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,GAAG;AAC7D,UAAM,KAAK;AAAA,gBAAmB;AAC9B,eAAW,MAAM,QAAQ,eAAe;AACtC,YAAM,KAAK,uBAAuB,EAAE,CAAC;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,SAAsB,cAAgC;AACjF,SAAO;AAAA,IACL,yDAAyD,QAAQ,KAAK;AAAA,IACtE,sDAAsD,YAAY;AAAA,IAClE;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,eAAe,kCAAkC,QAAQ,YAAY,OAAO;AAAA,IACpF;AAAA;AAAA,IACA,wCAAwC,YAAY;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,OAAO,OAAO;AAClB;AAEA,SAAS,uBAAuB,SAAgC;AAC9D,SAAO;AAAA,IACL,kDAAkD,QAAQ,KAAK;AAAA,IAC/D;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA,cAAc,QAAQ,YAAY;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA,iGAAiG,QAAQ,YAAY;AAAA,IACrH;AAAA,IACA,oCAAoC,QAAQ,UAAU;AAAA,IACtD,6FAA6F,QAAQ,YAAY;AAAA,EACnH;AACF;AAEA,SAAS,sBAAsB,mBAA+C;AAC5E,QAAM,QAAQ;AAAA,IACZ;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,eAAe,kBAAkB,gBAAgB;AACvD,QAAI,cAAc;AAChB,YAAM,KAAK,IAAI,YAAY;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,kBACd,MACA,SACA,QACA,UACA,WACA,SACQ;AACR,QAAM,OAAO,SAAS;AACtB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,eAAe,QAAQ,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,QAAQ;AAE1D,MAAI,cAAc;AAChB,WAAO,4BAA4B,SAAS,QAAQ,QAAQ;AAAA,EAC9D;AAEA,QAAM,QAAQ,aACV,oBAAoB,SAAS,OAAO,YAAY,IAChD,OACE,gBAAgB,OAAO,IACvB,uBAAuB,OAAO;AAEpC,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,UAAM,KAAK;AAAA;AAAA,EAA0B,QAAQ,iBAAiB,EAAE;AAAA,EAClE;AACA,MAAI,OAAO,cAAc;AACvB,UAAM,KAAK;AAAA;AAAA,EAA+B,OAAO,YAAY,EAAE;AAAA,EACjE;AACA,QAAM;AAAA,IACJ;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,CAAC,QAAQ,YAAY;AACvB,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,eAAe;AAC1B,UAAM,KAAK,sBAAsB,QAAQ,iBAAiB,CAAC;AAAA,EAC7D;AAEA,QAAM,aAAa,gBAAgB,WAAW,SAAS,IAAI;AAC3D,MAAI,YAAY;AACd,UAAM,KAAK,UAAU;AAAA,EACvB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACtKA,SAASC,2BAA0B,SAAgC;AACjE,WAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,QAAI,QAAQ,CAAC,EAAE,SAAS,YAAa,QAAO;AAAA,EAC9C;AACA,SAAO;AACT;AAaA,SAAS,oBACP,SACA,mBACe;AACf,MAAI,CAAC,kBAAmB,QAAO;AAC/B,QAAM,MAAM,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,iBAAiB;AAC/D,SAAO,QAAQ,KAAK,UAAU,QAAQ,MAAM,MAAM,CAAC;AACrD;AAEA,SAAS,uBACP,SACA,mBAAmB,OAC8B;AAGjD,MAAI,QAAQ,mBAAmB;AAC7B,UAAM,cAAc,oBAAoB,QAAQ,aAAa,QAAQ,iBAAiB;AACtF,UAAMC,sBAAqB,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACpE,WAAOA,sBAAqB,sBAAsB;AAAA,EACpD;AAKA,QAAM,eAAeD,2BAA0B,QAAQ,WAAW;AAClE,MAAI,iBAAiB,GAAI,QAAO;AAKhC,QAAM,eAAe,CAAC,CAAC,QAAQ,eAAe;AAC9C,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,qBAAqB,QAAQ,YAAY,MAAM,eAAe,CAAC;AACrE,QAAM,qBAAqB,mBAAmB,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAC3E,SAAO,qBAAqB,sBAAsB;AACpD;AAEA,SAAS,qBACP,SACA,cACA,QACA,WACU;AACV,QAAM,QAAkB,CAAC;AACzB,QAAM,cAAc,QAAQ,YAAY,MAAM,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAC/F,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,IACrE;AAAA,EACF,OAAO;AACL,UAAM,KAAK,oEAAoE;AAAA,EACjF;AAGA,MAAI,cAAc,cAAc,cAAc,UAAU;AACtD,UAAM;AAAA,MACJ;AAAA;AAAA,MACA,2BAA2B,QAAQ,YAAY;AAAA,MAC/C;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ;AACV,YAAM;AAAA,QACJ;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,QAAQ;AACjB,QAAI,QAAQ,MAAM,KAAK,GAAG;AACxB,YAAM;AAAA,QACJ;AAAA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBACP,MACA,SACA,WACA,QACe;AACf,QAAM,WAAW,uBAAuB,OAAO;AAK/C,QAAM,eAAe,CAAC,CAAC,QAAQ,qBAAqB,CAAC,CAAC,QAAQ;AAC9D,MAAI,CAAC,gBAAgB,aAAa,QAAS,QAAO;AAElD,QAAM,QAAkB,CAAC;AACzB,QAAM,eAAeA,2BAA0B,QAAQ,WAAW;AAElE,MAAI,SAAS,MAAM;AACjB,UAAM,KAAK,GAAG,qBAAqB,SAAS,cAAc,QAAQ,SAAS,CAAC;AAAA,EAC9E,WAAW,aAAa,qBAAqB;AAC3C,UAAM,eACJ,QAAQ,oBACJ,oBAAoB,QAAQ,aAAa,QAAQ,iBAAiB,IAClE,QAAQ,YAAY,MAAM,eAAe,CAAC,GAC9C,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AACjC,UAAM;AAAA,MACJ;AAAA,MACA,2BAA2B,QAAQ,YAAY;AAAA,MAC/C;AAAA;AAAA,MACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,MACnE;AAAA;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,aAAa;AACvB,YAAM;AAAA,QACJ,6BAA6B,QAAQ,WAAW;AAAA,MAClD;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,MACA,2BAA2B,QAAQ,YAAY;AAAA,MAC/C;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAc,UAAU,cAAc,cAAc,QAAQ;AAC9D,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,aAAa;AACvB,YAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,IACxF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,sBACb,SACA,YACwB;AACxB,MAAI,CAAC,QAAQ,aAAa,UAAU,CAAC,QAAQ,YAAY,OAAQ,QAAO;AACxE,QAAM,EAAE,gBAAgB,IAAI,MAAM;AAAA,IAChC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ,eAAe;AAAA,IACvB;AAAA,EACF;AACA,SAAO,mBAAmB;AAC5B;AAGA,eAAe,cAAc,SAAsB,YAA4C;AAC7F,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,WAAW,QAAQ,KAAK,EAAE;AACrC,MAAI,QAAQ,aAAa;AACvB,UAAM,WAAW,QAAQ,qBAAqB;AAAA,EAAK,QAAQ,kBAAkB,KAAK;AAClF,UAAM,KAAK;AAAA,cAAiB,QAAQ,WAAW,GAAG,QAAQ,EAAE;AAAA,EAC9D;AACA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAAqB,QAAQ,WAAW,EAAE;AAAA,EACvD;AACA,MAAI,QAAQ,MAAM;AAChB,UAAM,KAAK;AAAA;AAAA,EAAc,sBAAsB,QAAQ,IAAI,CAAC,EAAE;AAAA,EAChE;AAEA,MAAI,QAAQ,SAAS,QAAQ,MAAM,SAAS,GAAG;AAC7C,UAAM,KAAK;AAAA,kBAAqB;AAChC,eAAW,QAAQ,QAAQ,OAAO;AAChC,YAAM,KAAK,GAAG,eAAe,IAAI,CAAC;AAAA,IACpC;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,GAAG;AACnD,UAAM,KAAK,GAAG,eAAe,QAAQ,QAAQ,CAAC;AAAA,EAChD;AAEA,MAAI,QAAQ,qBAAqB,QAAQ,kBAAkB,SAAS,GAAG;AACrE,UAAM,KAAK,GAAG,wBAAwB,QAAQ,iBAAiB,CAAC;AAAA,EAClE;AAEA,QAAM,aAAa,MAAM,sBAAsB,SAAS,UAAU;AAClE,MAAI,WAAY,OAAM,KAAK,UAAU;AAIrC,MAAI,eAAe,QAAQ;AACzB,QAAI,QAAQ,qBAAqB,QAAQ,kBAAkB,SAAS,GAAG;AACrE,YAAM,KAAK,GAAG,wBAAwB,QAAQ,iBAAiB,CAAC;AAAA,IAClE;AACA,QAAI,QAAQ,sBAAsB,QAAQ,mBAAmB,SAAS,GAAG;AACvE,YAAM,KAAK,GAAG,yBAAyB,QAAQ,kBAAkB,CAAC;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa,QAAQ,UAAU,SAAS,GAAG;AACrD,UAAM,KAAK,GAAG,gBAAgB,QAAQ,SAAS,CAAC;AAAA,EAClD;AAEA,MAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,UAAM,YAAY,eAAe,SAAS,0BAA0B;AACpE,UAAM,KAAK,GAAG,kBAAkB,QAAQ,aAAa,SAAS,CAAC;AAAA,EACjE;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,MACA,YACA,SACA,WACU;AAGV,MAAI,QAAQ,cAAc,YAAY;AACpC,WAAO;AAAA,MACL;AAAA,MACA,2BAA2B,QAAQ,YAAY;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc,MAAM;AACtB,QAAI,QAAQ,MAAM,KAAK,GAAG;AACxB,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,cAAc;AAChC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM;AACR,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,2BAA2B,QAAQ,YAAY;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,YAAY;AACd,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,0BACP,SACA,MACA,WACA,QACU;AACV,QAAM,eAAeA,2BAA0B,QAAQ,WAAW;AAClE,QAAM,cAAc,QAAQ,YAAY,MAAM,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAC/F,MAAI,MAAM;AACR,UAAME,SAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,IACrE;AACA,QAAI,WAAW,cAAc,cAAc,cAAc,WAAW;AAClE,MAAAA,OAAM;AAAA,QACJ;AAAA;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,QAAQ;AACjB,MAAAA,OAAM;AAAA,QACJ;AAAA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,MAAAA,OAAM;AAAA,QACJ;AAAA;AAAA,MACF;AAAA,IACF;AACA,WAAOA;AAAA,EACT;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,2BAA2B,QAAQ,YAAY;AAAA,IAC/C;AAAA,IACA;AAAA;AAAA,IACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,IACnE;AAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ,aAAa;AACvB,UAAM;AAAA,MACJ,6BAA6B,QAAQ,WAAW;AAAA,IAClD;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,8BACP,SACA,MACA,WACA,QACU;AACV,MAAI,QAAQ,cAAc,UAAU,QAAQ,WAAW,YAAY;AACjE,QAAI,QAAQ,MAAM,KAAK,GAAG;AACxB,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,EAAE,cAAc,cAAc,cAAc,YAAY,cAAc,SAAS;AACzF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAIA,QAAM,aAAa,cAAc,UAAU,cAAc,cAAc;AACvE,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,2BAA2B,QAAQ,YAAY;AAAA,IAC/C;AAAA,EACF;AACA,MAAI,YAAY;AACd,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,EACxF;AACA,SAAO;AACT;AAEA,SAAS,kBACP,MACA,SACA,UACA,WACA,QACU;AACV,QAAM,QAAkB,CAAC;AAAA,gBAAmB;AAE5C,QAAM,OAAO,SAAS;AAEtB,MAAI,aAAa,SAAS;AACxB,UAAM,KAAK,GAAG,uBAAuB,MAAM,cAAc,QAAQ,SAAS,SAAS,CAAC;AACpF,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,iBAAiB;AAChC,UAAM,KAAK,GAAG,8BAA8B,SAAS,MAAM,WAAW,MAAM,CAAC;AAC7E,WAAO;AAAA,EACT;AAEA,QAAM,KAAK,GAAG,0BAA0B,SAAS,MAAM,WAAW,MAAM,CAAC;AACzE,SAAO;AACT;AAEA,eAAsB,mBACpB,MACA,SACA,QACA,WACiB;AACjB,QAAM,eAAe,SAAS,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ;AAE5D,MAAI,CAAC,cAAc;AACjB,UAAM,kBAAkB,yBAAyB,MAAM,SAAS,WAAW,MAAM;AACjF,QAAI,gBAAiB,QAAO;AAAA,EAC9B;AAEA,QAAM,OAAO,SAAS;AACtB,MAAI,WAAW,uBAAuB,SAAS,IAAI;AAKnD,MACE,QACA,cAAc,cACd,UACA,CAAC,QAAQ,mBACT,CAAC,QAAQ,eACT,aAAa,iBACb;AACA,eAAW;AAAA,EACb;AACA,QAAM,OAAO,MAAM,cAAc,SAAS,IAAI;AAC9C,QAAM,eAAe,eACjB,4BAA4B,SAAS,QAAQ,IAC7C,kBAAkB,MAAM,SAAS,UAAU,WAAW,MAAM;AAChE,SAAO,CAAC,GAAG,MAAM,GAAG,YAAY,EAAE,KAAK,IAAI;AAC7C;;;ACrgBA,SAAS,KAAAC,UAAS;AASX,SAAS,sBAAsB,YAA6B;AACjE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACvF,SAASA,GACN,OAAO,EACP,SAAS,EACT,SAAS,wEAAwE;AAAA,IACtF;AAAA,IACA,OAAO,EAAE,OAAO,QAAQ,MAAM;AAC5B,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,KAAK,mBAAmB;AAAA,UACxD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MACrD,QAAQ;AACN,eAAO;AAAA,UACL,KAAK,UAAU;AAAA,YACb,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,wBAAwB,YAA6B;AACnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,MAAM,MAAM,WAAW,KAAK,kBAAkB;AAAA,UAClD,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,eAAO,WAAW,IAAI,QAAQ,oBAAoB;AAAA,MACpD,QAAQ;AACN,eAAO,WAAW,+BAA+B;AAAA,MACnD;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,iBAAiB,YAA6B;AAC5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,YAAYA,GAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,IAC1E;AAAA,IACA,OAAO,EAAE,WAAW,MAAM;AACxB,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,WAAW;AAAA,UAC5C,WAAW,WAAW;AAAA,UACtB,cAAc;AAAA,QAChB,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACjF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,0BAA0B,YAA6B;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GACN,OAAO,EACP,SAAS,EACT,SAAS,2DAA2D;AAAA,MACvE,QAAQA,GACL,KAAK,CAAC,SAAS,aAAa,CAAC,EAC7B,SAAS,EACT,SAAS,0CAA0C;AAAA,MACtD,OAAOA,GACJ,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM,MAAM;AACpC,UAAI;AACF,cAAM,iBAAiB,KAAK,IAAI,SAAS,IAAI,GAAG;AAChD,cAAM,SAAS,MAAM,WAAW,KAAK,iBAAiB;AAAA,UACpD,WAAW,WAAW;AAAA,UACtB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AACD,cAAM,YAAa,OAChB,IAAI,CAAC,UAAU;AACd,gBAAM,OAAO,MAAM;AACnB,gBAAM,OAAO,MAAM;AACnB,iBAAO,IAAI,IAAI,MAAM,IAAI,KAAK,eAAe,KAAgC,CAAC;AAAA,QAChF,CAAC,EACA,KAAK,IAAI;AACZ,eAAO,WAAW,aAAa,oBAAoB;AAAA,MACrD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,uBAAuB,YAA6B;AAClE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,QAAQ,MAAM,WAAW,KAAK,gBAAgB;AAAA,UAClD,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,cAAM,WAAW,MAAM,IAAI,CAAC,SAAS;AACnC,gBAAM,EAAE,SAAS,IAAI,GAAG,KAAK,IAAI;AACjC,iBAAO;AAAA,QACT,CAAC;AACD,cAAM,UAA0B;AAAA,UAC9B,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE;AAAA,QACnE;AACA,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,WAAW,KAAK,oBAAoB,YAAY,gBAAgB,KAAK,QAAQ,GAAG;AACvF,oBAAQ,KAAK,WAAW,KAAK,SAAS,KAAK,QAAQ,CAAC;AAAA,UACtD;AAAA,QACF;AACA,eAAO,EAAE,QAAQ;AAAA,MACnB,QAAQ;AACN,eAAO,WAAW,4BAA4B;AAAA,MAChD;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,uBAAuB,YAA6B;AAClE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,QAAQA,GAAE,OAAO,EAAE,SAAS,yBAAyB,EAAE;AAAA,IACzD,OAAO,EAAE,OAAO,MAAM;AACpB,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,eAAe;AAAA,UAChD,WAAW,WAAW;AAAA,UACtB;AAAA,QACF,CAAC;AACD,cAAM,EAAE,SAAS,YAAY,GAAG,SAAS,IAAI;AAC7C,cAAM,UAA0B;AAAA,UAC9B,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE;AAAA,QACnE;AACA,YAAI,cAAc,KAAK,oBAAoB,YAAY,gBAAgB,KAAK,QAAQ,GAAG;AACrF,kBAAQ,KAAK,WAAW,YAAY,KAAK,QAAQ,CAAC;AAAA,QACpD,WAAW,YAAY;AACrB,kBAAQ,CAAC,IAAI,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,QAC5E;AACA,eAAO,EAAE,QAAQ;AAAA,MACnB,SAAS,OAAO;AACd,eAAO;AAAA,UACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAGO,SAAS,sBAAsB,YAA6B;AACjE,SAAO;AAAA,IACL,sBAAsB,UAAU;AAAA,IAChC,wBAAwB,UAAU;AAAA,IAClC,iBAAiB,UAAU;AAAA,IAC3B,0BAA0B,UAAU;AAAA,IACpC,uBAAuB,UAAU;AAAA,IACjC,uBAAuB,UAAU;AAAA,EACnC;AACF;;;ACxMA,SAAS,KAAAC,UAAS;AAKX,SAAS,yBAAyB,YAA6B;AACpE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,mBAAmB;AAAA,UACpD,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,wBAAwB,YAA6B;AACnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQC,GACL,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,IACxF;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM,MAAM;AAC3B,UAAI;AACF,cAAM,cAAc,MAAM,WAAW,KAAK,kBAAkB;AAAA,UAC1D,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,QACF,CAAC;AACD,YAAI,YAAY,WAAW,GAAG;AAC5B,iBAAO,WAAW,uBAAuB;AAAA,QAC3C;AACA,eAAO,WAAW,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,MACxD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACxF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;;;AC1DA,SAAS,KAAAC,UAAS;AAYX,SAAS,oBAAoB,YAA6B;AAC/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASC,GAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,MAC9D,SAASA,GACN,OAAO,EACP,SAAS,EACT,SAAS,oEAAoE;AAAA,IAClF;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM;AAC9B,UAAI;AACF,YAAI,SAAS;AACX,gBAAM,WAAW,KAAK,wBAAwB;AAAA,YAC5C,WAAW,WAAW;AAAA,YACtB,aAAa;AAAA,YACb;AAAA,UACF,CAAC;AACD,iBAAO,WAAW,KAAK,UAAU,EAAE,QAAQ,MAAM,QAAQ,SAAS,OAAO,GAAG,CAAC,CAAC;AAAA,QAChF;AACA,cAAM,QAAQ,WAAW,uBAAuB,OAAO;AACvD,YAAI,MAAM,WAAW;AACnB,iBAAO;AAAA,YACL,KAAK,UAAU;AAAA,cACb,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,uBAAuB,MAAM;AAAA,cAC7B,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,WAAW,KAAK,cAAc,EAAE,QAAQ,CAAC;AAC/C,eAAO,WAAW,KAAK,UAAU,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,MACpD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACrF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,+BAA+B,YAA6B;AAC1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQA,GACL,KAAK,CAAC,cAAc,YAAY,aAAa,UAAU,CAAC,EACxD,SAAS,6BAA6B;AAAA,MACzC,SAASA,GACN,OAAO,EACP,SAAS,EACT,SAAS,2DAA2D;AAAA,IACzE;AAAA,IACA,OAAO,EAAE,QAAQ,QAAQ,MAAM;AAC7B,UAAI;AACF,YAAI,SAAS;AACX,gBAAM,WAAW,KAAK,qBAAqB;AAAA,YACzC,WAAW,WAAW;AAAA,YACtB,aAAa;AAAA,YACb;AAAA,UACF,CAAC;AACD,iBAAO,WAAW,cAAc,OAAO,sBAAsB,MAAM,GAAG;AAAA,QACxE;AACA,cAAM,WAAW,KAAK,oBAAoB;AAAA,UACxC,WAAW,WAAW;AAAA,UACtB;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AACD,eAAO,WAAW,0BAA0B,MAAM,GAAG;AAAA,MACvD,SAAS,OAAO;AACd,eAAO;AAAA,UACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,2BAA2B,YAA6B,QAA2B;AACjG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOA,GAAE,OAAO,EAAE,SAAS,cAAc;AAAA,MACzC,MAAMA,GAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MAC/D,QAAQA,GACL,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,YAAYA,GACT,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,eAAeA,GACZ,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,IACJ;AAAA,IACA,OAAO,EAAE,OAAO,MAAM,QAAQ,YAAY,cAAc,MAAM;AAC5D,UAAI;AACF,cAAM,MAAM,OAAO;AAEnB,YAAI,sBAAsB,GAAG,GAAG;AAC9B,gBAAM,UACJ,iBAAiB,GAAG,KAAK;AAAA;AAAA;AAC3B,gBAAM,aAAa,eAAe,KAAK,OAAO;AAC9C,cAAI,YAAY;AACd,uBAAW,UAAU;AAAA,cACnB,MAAM;AAAA,cACN,SAAS,2BAA2B,WAAW,MAAM,GAAG,CAAC,CAAC;AAAA,YAC5D,CAAC;AAAA,UACH,OAAO;AACL,mBAAO;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,YAAI,mBAAmB,GAAG,GAAG;AAC3B,gBAAM,cAAc,MAAM,aAAa,KAAK,YAAY;AACtD,gBAAI;AACF,oBAAMC,UAAS,MAAM,WAAW,KAAK,sBAAsB;AAAA,gBACzD,WAAW,WAAW;AAAA,cACxB,CAAC;AACD,qBAAOA,QAAO;AAAA,YAChB,QAAQ;AACN,qBAAO;AAAA,YACT;AAAA,UACF,CAAC;AACD,cAAI,aAAa;AACf,uBAAW,UAAU;AAAA,cACnB,MAAM;AAAA,cACN,SAAS;AAAA,YACX,CAAC;AAAA,UACH,OAAO;AACL,mBAAO;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,WAAW,KAAK,qBAAqB;AAAA,UACxD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AACD,mBAAW,UAAU;AAAA,UACnB,MAAM;AAAA,UACN,KAAK,OAAO;AAAA,UACZ,QAAQ,OAAO;AAAA,QACjB,CAAC;AACD,eAAO,WAAW,iBAAiB,OAAO,QAAQ,aAAa,OAAO,KAAK,EAAE;AAAA,MAC/E,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,eAAO;AAAA,UACL,kCAAkC,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,uBAAuB,YAA6B;AAClE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,uBAAuBD,GAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,IAC1F;AAAA,IACA,OAAO,EAAE,sBAAsB,MAAM;AACnC,UAAI;AACF,cAAM,WAAW,KAAK,iBAAiB;AAAA,UACrC,WAAW,WAAW;AAAA,UACtB,mBAAmB;AAAA,QACrB,CAAC;AACD,eAAO,WAAW,+CAA+C,qBAAqB,GAAG;AAAA,MAC3F,SAAS,OAAO;AACd,eAAO;AAAA,UACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BAA0B,YAA6B;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,uBAAuBA,GAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,IAC7F;AAAA,IACA,OAAO,EAAE,sBAAsB,MAAM;AACnC,UAAI;AACF,cAAM,WAAW,KAAK,oBAAoB;AAAA,UACxC,WAAW,WAAW;AAAA,UACtB,mBAAmB;AAAA,QACrB,CAAC;AACD,eAAO,WAAW,oBAAoB;AAAA,MACxC,SAAS,OAAO;AACd,eAAO;AAAA,UACL,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,4BAA4B,YAA6B;AACvE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOA,GAAE,OAAO,EAAE,SAAS,sBAAsB;AAAA,MACjD,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MACrF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,MACnE,mBAAmBA,GAChB,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E;AAAA,IACA,OAAO,EAAE,OAAO,aAAa,MAAM,kBAAkB,MAAM;AACzD,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,KAAK,sBAAsB;AAAA,UACzD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB;AAAA,QACnB,CAAC;AACD,eAAO;AAAA,UACL,4BAA4B,KAAK,YAAY,OAAO,IAAI;AAAA,QAC1D;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC9F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BAA0B,YAA6B;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOA,GAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,MAC3D,aAAaA,GACV,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,WAAWA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,IAC7F;AAAA,IACA,OAAO,EAAE,OAAO,aAAa,UAAU,MAAM;AAC3C,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,KAAK,oBAAoB;AAAA,UACvD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AACD,YAAI,OAAO,QAAQ;AACjB,iBAAO;AAAA,YACL,wDAAwD,OAAO,gBAAgB,OAAO,EAAE;AAAA,UAC1F;AAAA,QACF;AACA,eAAO,WAAW,2BAA2B,OAAO,EAAE,IAAI;AAAA,MAC5D,SAAS,OAAO;AACd,eAAO;AAAA,UACL,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,wBAAwB,YAA6B;AACnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,eAAeA,GAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,MACjE,OAAOA,GACJ,OAAO,EACP,OAAO,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,EAAE,SAAS,wBAAwB,CAAC,EACvE,SAAS,8BAA8B;AAAA,IAC5C;AAAA,IACA,OAAO,EAAE,eAAe,MAAM,MAAM;AAClC,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,KAAK,kBAAkB;AAAA,UACrD,WAAW,WAAW;AAAA,UACtB,cAAc;AAAA,UACd;AAAA,QACF,CAAC;AACD,eAAO,WAAW,iCAAiC,OAAO,KAAK,EAAE;AAAA,MACnE,SAAS,OAAO;AACd,eAAO;AAAA,UACL,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,mBAAmB,YAA6B,QAA2B;AACzF,SAAO;AAAA,IACL,oBAAoB,UAAU;AAAA,IAC9B,2BAA2B,YAAY,MAAM;AAAA,IAC7C,uBAAuB,UAAU;AAAA,IACjC,0BAA0B,UAAU;AAAA,IACpC,4BAA4B,UAAU;AAAA,IACtC,0BAA0B,UAAU;AAAA,IACpC,wBAAwB,UAAU;AAAA,EACpC;AACF;;;ACtVA,SAAS,YAAAE,WAAU,QAAAC,aAAY;AAC/B,SAAS,UAAU,SAAS,YAAY,QAAAC,aAAY;AACpD,SAAS,KAAAC,UAAS;AAOlB,IAAM,oBAA4C;AAAA,EAChD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,SAAS,0BAA0B,YAA6B,QAA2B;AAChG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAMC,GACH,OAAO,EACP,SAAS,2EAAsE;AAAA,MAClF,OAAOA,GACJ,OAAO,EACP,SAAS,EACT,SAAS,iEAAiE;AAAA,IAC/E;AAAA,IACA,OAAO,EAAE,MAAAC,OAAM,MAAM,MAAM;AACzB,UAAI;AACF,cAAM,WAAW,WAAWA,KAAI,IAAIA,QAAOC,MAAK,OAAO,cAAcD,KAAI;AACzE,cAAM,WAAW,kBAAkB,QAAQ,QAAQ,EAAE,YAAY,CAAC;AAClE,YAAI,CAAC,UAAU;AACb,iBAAO;AAAA,YACL,0BAA0B,QAAQ,QAAQ,KAAK,QAAQ,iBAAiB,OAAO,KAAK,iBAAiB,EAAE,KAAK,IAAI,CAAC;AAAA,UACnH;AAAA,QACF;AAEA,cAAM,OAAO,MAAME,MAAK,QAAQ,EAAE,MAAM,MAAM,IAAI;AAClD,YAAI,CAAC,MAAM,OAAO,GAAG;AACnB,iBAAO,WAAW,mBAAmB,QAAQ,EAAE;AAAA,QACjD;AACA,YAAI,KAAK,OAAO,qBAAqB;AACnC,iBAAO;AAAA,YACL,WAAW,KAAK,IAAI,6BAAwB,mBAAmB;AAAA,UACjE;AAAA,QACF;AAEA,cAAM,WAAW,SAAS,QAAQ;AAClC,cAAM,EAAE,QAAQ,UAAU,IAAI,MAAM,WAAW,KAAK,qBAAqB;AAAA,UACvE,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,UACA,UAAU,KAAK;AAAA,QACjB,CAAC;AAED,cAAM,OAAO,MAAMC,UAAS,QAAQ;AACpC,cAAM,MAAM,MAAM,MAAM,WAAW;AAAA,UACjC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,SAAS;AAAA,UACpC;AAAA,QACF,CAAC;AACD,YAAI,CAAC,IAAI,IAAI;AACX,iBAAO;AAAA,YACL,kCAAkC,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC;AAAA,UAClF;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,WAAW,KAAK,qBAAqB;AAAA,UACxD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,QACF,CAAC;AAED,eAAO;AAAA,UACL,YAAY,QAAQ,KAAK,KAAK,IAAI,yCAAyC,QAAQ,kBAAkB,KAAK,MAAM,EAAE,cAAc,OAAO,MAAM;AAAA,QAC/I;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACtFA,SAAS,KAAAC,UAAS;AAKX,SAAS,yBAAyB,YAA6B;AACpE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,QAAQ,MAAM,WAAW,KAAK,mBAAmB;AAAA,UACrD,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,YAAI,MAAM,WAAW,EAAG,QAAO,WAAW,yCAAyC;AACnF,cAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,MAAM;AACnC,gBAAM,UAAU,KAAK,UAAU,QAAQ;AACvC,iBAAO,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,KAAK,KAAK;AAAA,QAC3C,CAAC;AACD,eAAO,WAAW,MAAM,KAAK,IAAI,CAAC;AAAA,MACpC,QAAQ;AACN,eAAO,WAAW,8BAA8B;AAAA,MAClD;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,wBAAwB,YAA6B;AACnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOC,GACJ,MAAMA,GAAE,OAAO,EAAE,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,iCAAiC,EAAE,CAAC,CAAC,EACxF,IAAI,CAAC,EACL,SAAS,kCAAkC;AAAA,IAChD;AAAA,IACA,OAAO,EAAE,MAAM,MAAM;AACnB,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,KAAK,kBAAkB;AAAA,UACrD,WAAW,WAAW;AAAA,UACtB;AAAA,QACF,CAAC;AACD,cAAM,QAAQ,CAAC,WAAW,OAAO,OAAO,uBAAuB;AAC/D,YAAI,OAAO,UAAU,EAAG,OAAM,KAAK,WAAW,OAAO,OAAO,gBAAgB;AAC5E,eAAO,WAAW,MAAM,KAAK,GAAG,CAAC;AAAA,MACnC,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,eAAO,WAAW,+BAA+B,GAAG,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;;;AC5BO,SAAS,iBAAiB,YAA6B,QAA2B;AACvF,SAAO;AAAA,IACL,GAAG,sBAAsB,UAAU;AAAA,IACnC,yBAAyB,UAAU;AAAA,IACnC,wBAAwB,UAAU;AAAA,IAClC,yBAAyB,UAAU;AAAA,IACnC,wBAAwB,UAAU;AAAA,IAClC,GAAG,mBAAmB,YAAY,MAAM;AAAA,IACxC,0BAA0B,YAAY,MAAM;AAAA,EAC9C;AACF;;;ACpCA,SAAS,KAAAC,UAAS;AAKlB,IAAM,iBAAiB;AAEhB,SAAS,oBAAoB,YAA6B;AAC/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAMC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MAChE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,IACxE;AAAA,IACA,OAAO,EAAE,MAAM,YAAY,MAAM;AAC/B,UAAI;AACF,cAAM,WAAW,KAAK,oBAAoB;AAAA,UACxC,WAAW,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAO,WAAW,4BAA4B;AAAA,MAChD,QAAQ;AACN,eAAO,WAAW,wBAAwB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,YAA6B;AAC3D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOA,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,MAC1C,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC/D,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,MACtE,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,MACrE,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,IAChE;AAAA,IACA,OAAO,EAAE,OAAO,aAAa,MAAM,SAAS,gBAAgB,MAAM;AAChE,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,KAAK,iBAAiB;AAAA,UACpD,WAAW,WAAW;AAAA,UACtB;AAAA,UACA,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,UAC/C,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,UACjC,GAAI,oBAAoB,UAAa,EAAE,gBAAgB;AAAA,UACvD,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,QACzC,CAAC;AACD,eAAO,WAAW,4BAA4B,OAAO,EAAE,EAAE;AAAA,MAC3D,SAAS,OAAO;AACd,eAAO;AAAA,UACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,YAA6B;AAC3D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MACzD,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,MACjC,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,IAChE;AAAA,IACA,OAAO,EAAE,WAAW,OAAO,aAAa,MAAM,gBAAgB,MAAM;AAClE,UAAI;AACF,cAAM,WAAW,KAAK,iBAAiB;AAAA,UACrC,WAAW,WAAW;AAAA,UACtB;AAAA,UACA,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,UACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,UAC/C,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,UACjC,GAAI,oBAAoB,UAAa,EAAE,gBAAgB;AAAA,QACzD,CAAC;AACD,eAAO,WAAW,kBAAkB;AAAA,MACtC,SAAS,OAAO;AACd,eAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,MACzF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,YAA6B;AAC3D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,WAAWA,GAAE,OAAO,EAAE,SAAS,0BAA0B,EAAE;AAAA,IAC7D,OAAO,EAAE,UAAU,MAAM;AACvB,UAAI;AACF,cAAM,WAAW,KAAK,iBAAiB;AAAA,UACrC,WAAW,WAAW;AAAA,UACtB;AAAA,QACF,CAAC;AACD,eAAO,WAAW,kBAAkB;AAAA,MACtC,SAAS,OAAO;AACd,eAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,MACzF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,YAA6B;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,KAAK,gBAAgB;AAAA,UACrD,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MACrD,QAAQ;AACN,eAAO,WAAW,0BAA0B;AAAA,MAC9C;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,eAAe,YAA6B;AACnD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,aAAaA,GAAE,OAAO,EAAE,SAAS,8CAA8C;AAAA,MACjF;AAAA,MACA,OAAO,EAAE,YAAY,MAAM;AACzB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,KAAK,wBAAwB;AAAA,YAC3D,WAAW,WAAW;AAAA,YACtB;AAAA,UACF,CAAC;AACD,iBAAO,WAAW,uCAAuC,OAAO,WAAW,EAAE;AAAA,QAC/E,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAChG;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,aAAaA,GAAE,OAAO,EAAE,SAAS,iDAAiD;AAAA,MACpF;AAAA,MACA,OAAO,EAAE,YAAY,MAAM;AACzB,YAAI;AACF,gBAAM,WAAW,KAAK,kBAAkB;AAAA,YACtC,WAAW,WAAW;AAAA,YACtB;AAAA,UACF,CAAC;AACD,iBAAO,WAAW,mCAAmC,WAAW,EAAE;AAAA,QACpE,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACzF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,aAAaA,GACV,OAAO,EACP,SAAS,0DAA0D;AAAA,MACxE;AAAA,MACA,OAAO,EAAE,YAAY,MAAM;AACzB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,KAAK,qBAAqB;AAAA,YACxD,WAAW,WAAW;AAAA,YACtB;AAAA,UACF,CAAC;AACD,cAAI,OAAO,QAAQ;AACjB,mBAAO;AAAA,cACL,OAAO,OAAO,QAAQ,iCAAiC,OAAO,WAAW;AAAA,YAC3E;AAAA,UACF;AACA,iBAAO;AAAA,YACL,OAAO,OAAO,QAAQ,0BAA0B,OAAO,WAAW;AAAA,UACpE;AAAA,QACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAC7F;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,aACd,YACA,SACA;AACA,QAAM,QAAQ;AAAA,IACZ,oBAAoB,UAAU;AAAA,IAC9B,uBAAuB,UAAU;AAAA,IACjC,uBAAuB,UAAU;AAAA,IACjC,uBAAuB,UAAU;AAAA,IACjC,sBAAsB,UAAU;AAAA,EAClC;AACA,MAAI,CAAC,SAAS,iBAAkB,QAAO;AACvC,SAAO,CAAC,GAAG,OAAO,GAAG,eAAe,UAAU,CAAC;AACjD;;;ACxNA,SAAS,KAAAC,WAAS;AAKlB,IAAMC,kBAAiB;AAEhB,SAAS,oBAAoB,YAA6B;AAC/D,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAOC,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,QAC1D,iBAAiBA,IAAE,OAAO,EAAE,SAAS,EAAE,SAASD,eAAc;AAAA,QAC9D,UAAUC,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,QAChF,aAAaA,IACV,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,8CAA8C;AAAA,QAC1D,cAAcA,IACX,OAAO,EACP,SAAS,EACT,SAAS,8EAA8E;AAAA,MAC5F;AAAA,MACA,OAAO,EAAE,OAAO,iBAAiB,UAAU,aAAa,aAAa,MAAM;AACzE,YAAI;AACF,gBAAM,WAAW,KAAK,wBAAwB;AAAA,YAC5C,WAAW,WAAW;AAAA,YACtB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAED,gBAAM,gBAAgB,CAAC;AACvB,cAAI,UAAU,OAAW,eAAc,KAAK,aAAa,KAAK,GAAG;AACjE,cAAI,oBAAoB;AACtB,0BAAc,KAAK,mBAAmB,eAAe,EAAE;AACzD,cAAI,aAAa,OAAW,eAAc,KAAK,SAAS,SAAS,MAAM,UAAU;AACjF,cAAI,gBAAgB,OAAW,eAAc,KAAK,eAAe,WAAW,GAAG;AAC/E,cAAI,iBAAiB,OAAW,eAAc,KAAK,cAAc,YAAY,GAAG;AAEhF,iBAAO,WAAW,4BAA4B,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,QAC1E,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAC/F;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACtDA,SAAS,KAAAC,WAAS;AAKX,SAAS,qBAAqB,YAA6B;AAChE,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAASC,IAAE,OAAO,EAAE,SAAS,0DAA0D;AAAA,MACzF;AAAA,MACA,OAAO,EAAE,QAAQ,MAAM;AACrB,cAAM,UAAU;AAAA;AAAA,EAAmD,OAAO;AAC1E,cAAM,WAAW,KAAK,0BAA0B;AAAA,UAC9C,WAAW,WAAW;AAAA,UACtB,UAAU;AAAA,UACV;AAAA,QACF,CAAC;AACD,mBAAW,UAAU;AAAA,UACnB,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AACD,eAAO,WAAW,gCAAgC;AAAA,MACpD;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQA,IACL;AAAA,UACCA,IAAE,OAAO;AAAA,YACP,MAAMA,IAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,YAC/D,MAAMA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,YAClE,UAAUA,IAAE,KAAK,CAAC,YAAY,SAAS,OAAO,CAAC,EAAE,SAAS,gBAAgB;AAAA,YAC1E,aAAaA,IAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,UACpE,CAAC;AAAA,QACH,EACC,SAAS,oCAAoC;AAAA,QAChD,SAASA,IAAE,OAAO,EAAE,SAAS,8CAA8C;AAAA,MAC7E;AAAA,MACA,OAAO,EAAE,QAAQ,QAAQ,MAAM;AAC7B,cAAM,aAAa,OAChB,IAAI,CAAC,UAAU;AACd,gBAAM,MAAM,MAAM,OAAO,IAAI,MAAM,IAAI,KAAK;AAC5C,iBAAO,QAAQ,MAAM,QAAQ,SAAS,MAAM,IAAI,GAAG,GAAG,OAAO,MAAM,WAAW;AAAA,QAChF,CAAC,EACA,KAAK,IAAI;AAEZ,cAAM,UAAU;AAAA;AAAA,EAAmD,OAAO;AAAA;AAAA,EAAO,UAAU;AAC3F,cAAM,WAAW,KAAK,0BAA0B;AAAA,UAC9C,WAAW,WAAW;AAAA,UACtB,UAAU;AAAA,UACV;AAAA,QACF,CAAC;AACD,mBAAW,UAAU;AAAA,UACnB,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAO,WAAW,yDAAoD;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;;;ACpEA,SAAS,KAAAC,WAAS;;;ACAlB,SAAS,KAAAC,WAAS;;;ACKlB,IAAM,cAAc;AACpB,IAAM,iBAAiB;AACvB,IAAM,YAAY;AAIlB,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,iBAAiB,CAAC,WAAW,aAAa,YAAY,aAAa,YAAY,SAAS;AAC9F,IAAM,yBAAyB,CAAC,QAAQ,QAAQ,cAAc,cAAc,aAAa,SAAS;AAIlG,SAAS,iBAAyB;AAChC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKa,WAAW;AAAA,yBACR,cAAc;AAAA,oBACnB,SAAS;AAAA,6BACA,KAAK,UAAU,mBAAmB,CAAC;AAAA,wBACxC,KAAK,UAAU,cAAc,CAAC;AAAA,+BACvB,KAAK,UAAU,sBAAsB,CAAC;AACrE;AAEA,SAAS,gBAAwB;AAC/B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CT;AAEA,SAAS,eAAuB;AAC9B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CT;AAEA,SAAS,qBAA6B;AACpC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CT;AAEA,SAAS,oBAA4B;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BT;AAEA,SAAS,sBAA8B;AACrC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCT;AAEA,SAAS,oBAA4B;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBT;AAEA,SAAS,aAAqB;AAC5B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBT;AAaO,SAAS,0BAAkC;AAChD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,cAAc;AAAA,IACd,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,WAAW;AAAA,EACb,EAAE,KAAK,IAAI;AACb;AASA,eAAsB,gBACpB,WACkF;AAClF,MAAI;AACF,UAAM,SAAS,wBAAwB;AACvC,UAAM,SAAS,MAAM,UAAU,SAAS,MAAM;AAE9C,QAAI,OAAO,SAAS,SAAS;AAC3B,aAAO,EAAE,SAAS,OAAO,OAAO,OAAO,MAAM;AAAA,IAC/C;AAGA,QAAI;AACF,UAAI,SAAS,KAAK,MAAM,OAAO,KAAK;AAGpC,UAAI,OAAO,WAAW,SAAU,UAAS,KAAK,MAAM,MAAM;AAC1D,aAAO;AAAA,QACL,SAAS,OAAO,YAAY;AAAA,QAC5B,SAAS,OAAO;AAAA,MAClB;AAAA,IACF,QAAQ;AAEN,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD;AAAA,EACF;AACF;AAOA,eAAsB,eACpB,WACA,QACA,OAC2B;AAC3B,QAAM,aAAa,KAAK,UAAU,UAAU,CAAC,CAAC;AAC9C,QAAM,WAAW,SAAS;AAE1B,QAAM,SAAS,MAAM,UAAU;AAAA,IAC7B,4FAA4F,UAAU,KAAK,QAAQ;AAAA,EACrH;AAEA,MAAI,OAAO,SAAS,SAAS;AAC3B,UAAM,IAAI,MAAM,2BAA2B,OAAO,KAAK,EAAE;AAAA,EAC3D;AAEA,MAAI;AAEF,QAAI,MAAM,OAAO;AAEjB,QAAI,IAAI,WAAW,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AAC5C,YAAM,KAAK,MAAM,GAAG;AAAA,IACtB;AACA,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAsB,eAAe,WAA0C;AAC7E,QAAM,UAAU;AAAA,IACd;AAAA,EACF;AACF;AAKA,eAAsB,mBAAmB,WAAqD;AAC5F,QAAM,SAAS,MAAM,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAS;AAC3B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,SAAS,EAAE,SAAS,OAAO,QAAQ,OAAO,UAAU,OAAO,cAAc,MAAM;AAAA,IACjF;AAAA,EACF;AAEA,MAAI;AACF,QAAI,MAAM,OAAO;AACjB,QAAI,IAAI,WAAW,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AAC5C,YAAM,KAAK,MAAM,GAAG;AAAA,IACtB;AACA,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,SAAS,EAAE,SAAS,OAAO,QAAQ,OAAO,UAAU,OAAO,cAAc,MAAM;AAAA,IACjF;AAAA,EACF;AACF;;;ADlbA,SAAS,mBAAmB,SAAgD;AAC1E,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAEA,SAAS,sBAAsB,SAAuB;AACpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAMC,IAAE,KAAK,CAAC,QAAQ,MAAM,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC1F,YAAYA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACvF,aAAaA,IACV,OAAO,EACP,SAAS,EACT,SAAS,mEAA8D;AAAA,MAC1E,WAAWA,IACR,QAAQ,EACR,SAAS,EACT,SAAS,qDAAqD;AAAA,MACjE,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,MACtE,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,IAC9F;AAAA,IACA,OAAO,EAAE,MAAM,YAAY,aAAa,WAAW,OAAO,MAAM,MAAM;AACpE,YAAM,cAAc,mBAAmB,OAAO;AAC9C,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,UAAI;AACF,cAAM,SAAS;AAAA,UACb,GAAI,QAAQ,EAAE,KAAK;AAAA,UACnB,GAAI,cAAc,EAAE,WAAW;AAAA,UAC/B,GAAI,eAAe,EAAE,YAAY;AAAA,UACjC,GAAI,aAAa,EAAE,UAAU;AAAA,UAC7B,GAAI,SAAS,EAAE,MAAM;AAAA,QACvB;AACA,cAAM,YAAY,OAAO,KAAK,MAAM,EAAE,SAAS;AAC/C,cAAM,SAAS,MAAM,eAAe,aAAa,YAAY,SAAS,QAAW,KAAK;AAEtF,YAAI,OAAO,WAAW,GAAG;AACvB,iBAAO,WAAW,gDAAgD;AAAA,QACpE;AAEA,eAAO,WAAW,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MACnD,SAAS,OAAO;AACd,eAAO,WAAW,8BAA8B,YAAY,KAAK,CAAC,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,wBAAwB,SAAuB;AACtD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,cAAc,mBAAmB,OAAO;AAC9C,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,UAAI;AACF,cAAM,eAAe,WAAW;AAChC,eAAO,WAAW,2BAA2B;AAAA,MAC/C,SAAS,OAAO;AACd,eAAO,WAAW,8BAA8B,YAAY,KAAK,CAAC,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,SAAuB;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,cAAc,mBAAmB,OAAO;AAC9C,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,UAAI;AACF,cAAM,SAAS,MAAM,mBAAmB,WAAW;AACnD,eAAO,WAAW,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MACnD,SAAS,OAAO;AACd,eAAO,WAAW,mCAAmC,YAAY,KAAK,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEO,SAAS,oBAAoB,SAAuB;AACzD,SAAO;AAAA,IACL,sBAAsB,OAAO;AAAA,IAC7B,wBAAwB,OAAO;AAAA,IAC/B,yBAAyB,OAAO;AAAA,EAClC;AACF;;;AErHA,SAAS,KAAAC,WAAS;AAMlB,SAAS,wBAAwB,SAAuD;AACtF,MAAI,CAAC,QAAQ,kBAAkB,GAAG;AAChC,WAAO;AAAA,EACT;AACA,QAAM,SAAS,QAAQ,oBAAoB;AAC3C,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAASC,aAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAIA,SAAS,2BAA2B,SAAuB;AACzD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAMC,IACH,OAAO,EACP;AAAA,UACC;AAAA,QACF;AAAA,QACF,MAAMA,IAAE,OAAO,EAAE,SAAS,mDAAmD;AAAA,QAC7E,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,6EAAwE;AAAA,MACtF;AAAA,MACA,OAAO,EAAE,MAAM,MAAM,UAAU,MAAM;AACnC,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,eAAe,MAAM,YAAY,cAAc,MAAM,MAAM,SAAS;AAC1E,gBAAM,UAAU,YAAY,gBAAgB,SAAS,MAAM;AAC3D,gBAAM,gBACJ,YAAY,cAAc,MAAM,QAC5B,4FACA;AACN,iBAAO;AAAA,YACL,0BAA0B,IAAI,IAAI,IAAI,GAAG,OAAO;AAAA,iBAAoB,YAAY,GAAG,aAAa;AAAA,UAClG;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,WAAW,oCAAoCD,aAAY,KAAK,CAAC,EAAE;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,cAAcC,IACX,OAAO,EACP,SAAS,2DAA2D;AAAA,MACzE;AAAA,MACA,OAAO,EAAE,aAAa,MAAM;AAC1B,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,YAAY,iBAAiB,YAAY;AAC/C,iBAAO,WAAW,qBAAqB,YAAY,WAAW;AAAA,QAChE,SAAS,OAAO;AACd,iBAAO,WAAW,uCAAuCD,aAAY,KAAK,CAAC,EAAE;AAAA,QAC/E;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA;AAAA,MAED,YAAY;AACV,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,cAAM,cAAc,YAAY,gBAAgB;AAChD,YAAI,YAAY,WAAW,GAAG;AAC5B,iBAAO,WAAW,4BAA4B;AAAA,QAChD;AACA,eAAO,WAAW,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,MACxD;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;AAIA,SAAS,2BAA2B,SAAuB;AACzD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,cAAM,aAAa,QAAQ,8BAA8B;AAEzD,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,cAAI,WAAW,SAAS,GAAG;AACzB,mBAAO;AAAA,cACL;AAAA,EAA8E,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAAA,YACnH;AAAA,UACF;AACA,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,YAAY,YAAY,aAAa;AAC3C,gBAAM,WAAW,UAAU,CAAC;AAC5B,cAAI,YAA6D,CAAC;AAElE,cAAI,UAAU;AACZ,gBAAI;AACF,0BAAY,MAAM,YAAY,kBAAkB,SAAS,WAAW;AAAA,YACtE,QAAQ;AAAA,YAER;AAAA,UACF;AAEA,gBAAM,SAAS;AAAA,YACb,MAAM;AAAA,YACN,QAAQ,YAAY,eAAe,GAAG;AAAA,YACtC,gBAAgB,YAAY,eAAe,GAAG;AAAA,YAC9C;AAAA,YACA,gBAAgB;AAAA,UAClB;AAEA,iBAAO,WAAW,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QACnD,SAAS,OAAO;AACd,iBAAO,WAAW,0CAA0CA,aAAY,KAAK,CAAC,EAAE;AAAA,QAClF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAYC,IAAE,OAAO,EAAE,SAAS,0DAA0D;AAAA,QAC1F,YAAYA,IACT,OAAO,EACP,SAAS,EACT,SAAS,oEAAoE;AAAA,MAClF;AAAA,MACA,OAAO,EAAE,YAAY,WAAW,MAAM;AACpC,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,cAAI;AAEJ,cAAI,YAAY,SAAS,GAAG;AAC1B,kBAAM,YAAY,YAAY,aAAa;AAC3C,kBAAM,QAAQ,UAAU,cAAc,CAAC;AACvC,0BAAc,OAAO;AAAA,UACvB;AAEA,gBAAM,SAAS,MAAM,YAAY,SAAS,YAAY,WAAW;AACjE,iBAAO,WAAW,IAAI,OAAO,IAAI,KAAK,OAAO,KAAK,EAAE;AAAA,QACtD,SAAS,OAAO;AACd,iBAAO,WAAW,6BAA6BD,aAAY,KAAK,CAAC,EAAE;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,0BAA0B,SAAuB;AACxD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,iBAAO,WAAW,gCAAgC;AAAA,QACpD;AAEA,YAAI;AACF,gBAAM,YAAY,OAAO;AACzB,iBAAO,WAAW,2BAA2B;AAAA,QAC/C,SAAS,OAAO;AACd,iBAAO,WAAW,4BAA4BA,aAAY,KAAK,CAAC,EAAE;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,4BAA4B,SAAuB;AAC1D,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,SAAS,MAAM,YAAY,WAAW;AAC5C,iBAAO;AAAA,YACL,SAAS;AAAA,cACP,WAAW,QAAQ,WAAW;AAAA,cAC9B;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,wBAAwB,YAAY,cAAc,CAAC;AAAA,cAC3D;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,WAAW,iCAAiCA,aAAY,KAAK,CAAC,EAAE;AAAA,QACzE;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,KAAKC,IAAE,OAAO,EAAE,SAAS,4DAA4D;AAAA,MACvF;AAAA,MACA,OAAO,EAAE,IAAI,MAAM;AACjB,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,YAAY,SAAS,GAAG;AAC9B,iBAAO,WAAW,iBAAiB,YAAY,cAAc,CAAC,EAAE;AAAA,QAClE,SAAS,OAAO;AACd,iBAAO,WAAW,uBAAuBD,aAAY,KAAK,CAAC,EAAE;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,UAAUC,IACP,OAAO,EACP;AAAA,UACC;AAAA,QACF;AAAA,MACJ;AAAA,MACA,OAAO,EAAE,SAAS,MAAM;AACtB,cAAM,cAAc,wBAAwB,OAAO;AACnD,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,YAAY,MAAM,QAAQ;AAChC,iBAAO,WAAW,YAAY,QAAQ,EAAE;AAAA,QAC1C,SAAS,OAAO;AACd,iBAAO,WAAW,oBAAoB,QAAQ,MAAMD,aAAY,KAAK,CAAC,EAAE;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,uBAAuB,SAAuB;AACrD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOC,IACJ,OAAO,EACP,SAAS,EACT,SAAS,wDAAwD;AAAA,MACpE,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E;AAAA;AAAA,IAEA,OAAO,EAAE,OAAO,MAAM,MAAM;AAC1B,YAAM,cAAc,wBAAwB,OAAO;AACnD,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAM,WAAW,YAAY,mBAAmB,OAAO,KAAK;AAC5D,UAAI,SAAS,WAAW,GAAG;AACzB,cAAM,aAAa,QAAQ,YAAY,KAAK,MAAM;AAClD,eAAO,WAAW,+BAA+B,UAAU,GAAG;AAAA,MAChE;AAEA,YAAM,YAAY,SACf,IAAI,CAAC,MAAM;AACV,cAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,mBAAmB,SAAS,EAAE,QAAQ,MAAM,CAAC;AAChF,cAAM,MAAM,EAAE,MAAM,KAAK,EAAE,GAAG,GAAG,EAAE,OAAO,IAAI,EAAE,IAAI,KAAK,EAAE,MAAM;AACjE,eAAO,IAAI,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,GAAG;AAAA,MAC5D,CAAC,EACA,KAAK,IAAI;AAEZ,aAAO,WAAW,GAAG,SAAS,MAAM;AAAA,EAAyB,SAAS,EAAE;AAAA,IAC1E;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,uBAAuB,SAAuB;AACrD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MAChF,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E;AAAA;AAAA,IAEA,OAAO,EAAE,QAAQ,MAAM,MAAM;AAC3B,YAAM,cAAc,wBAAwB,OAAO;AACnD,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAM,WAAW,YAAY,mBAAmB,QAAQ,KAAK;AAC7D,UAAI,SAAS,WAAW,GAAG;AACzB,cAAM,aAAa,SAAS,cAAc,MAAM,MAAM;AACtD,eAAO,WAAW,+BAA+B,UAAU,GAAG;AAAA,MAChE;AAEA,YAAM,YAAY,SACf,IAAI,CAAC,MAAM;AACV,cAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,mBAAmB,SAAS,EAAE,QAAQ,MAAM,CAAC;AAChF,cAAM,SAAS,EAAE,SAAS,WAAM,EAAE,MAAM,KAAK;AAC7C,cAAM,MAAM,EAAE,WAAW,KAAK,EAAE,QAAQ,QAAQ;AAChD,eAAO,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG;AAAA,MACtD,CAAC,EACA,KAAK,IAAI;AAEZ,aAAO,WAAW,GAAG,SAAS,MAAM;AAAA,EAAyB,SAAS,EAAE;AAAA,IAC1E;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,sBAAsB,SAAuB;AACpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,IACxE;AAAA;AAAA,IAEA,OAAO,EAAE,MAAM,MAAM;AACnB,YAAM,cAAc,wBAAwB,OAAO;AACnD,UAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAM,SAAS,YAAY,cAAc,KAAK;AAC9C,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO,WAAW,mCAAmC;AAAA,MACvD;AAEA,YAAM,YAAY,OACf,IAAI,CAAC,MAAM;AACV,cAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,mBAAmB,SAAS,EAAE,QAAQ,MAAM,CAAC;AAChF,cAAM,QAAQ,EAAE,QAAQ;AAAA,IAAO,EAAE,MAAM,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK;AAChF,eAAO,IAAI,IAAI,KAAK,EAAE,OAAO,GAAG,KAAK;AAAA,MACvC,CAAC,EACA,KAAK,MAAM;AAEd,aAAO,WAAW,GAAG,OAAO,MAAM;AAAA,EAAoB,SAAS,EAAE;AAAA,IACnE;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,wBAAwB,SAAuB;AACtD,SAAO;AAAA,IACL,uBAAuB,OAAO;AAAA,IAC9B,uBAAuB,OAAO;AAAA,IAC9B,sBAAsB,OAAO;AAAA,EAC/B;AACF;AAIO,SAAS,sBAAsB,SAAuB;AAC3D,SAAO;AAAA,IACL,GAAG,2BAA2B,OAAO;AAAA,IACrC,GAAG,2BAA2B,OAAO;AAAA,IACrC,GAAG,0BAA0B,OAAO;AAAA,IACpC,GAAG,4BAA4B,OAAO;AAAA,IACtC,GAAG,wBAAwB,OAAO;AAAA,EACpC;AACF;;;AH1ZA,SAASC,oBAAmB,SAAgD;AAC1E,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAASC,aAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAEA,eAAe,qBACb,SACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMA;AACA,QAAM,aAAa,cAAc,CAAC;AAClC,QAAM,aAAa,cAAc;AAEjC,QAAM,aAAa,mBAAmB,SAAS,YAAY,UAAU;AACrE,MAAI,WAAY,QAAO,WAAW,UAAU;AAE5C,QAAM,QAAQ,eAAe,QAAW;AAAA,IACtC,YAAY,cAAc,CAAC,QAAQ,YAAY;AAAA,IAC/C,YAAY,cAAc,CAAC,QAAQ,kBAAkB;AAAA,IACrD;AAAA,EACF,CAAC;AAED,SAAO,WAAW,uBAAuB,SAAS,UAAU,CAAC;AAC/D;AAEA,SAAS,mBACP,SACA,YACA,YACe;AACf,MAAI,cAAc,QAAQ,YAAY,KAAK,CAAC,WAAY,QAAO;AAC/D,MAAI,cAAc,QAAQ,kBAAkB,KAAK,CAAC;AAChD,WAAO;AACT,MAAI,cAAc,QAAQ,YAAY,KAAK,cAAc,QAAQ,kBAAkB,GAAG;AACpF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,SAAuB,YAA6B;AAClF,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ,YAAY,EAAG,OAAM,KAAK,QAAQ;AAC9C,MAAI,QAAQ,kBAAkB,EAAG,OAAM,KAAK,QAAQ;AACpD,QAAM,UAAU,MAAM,KAAK,KAAK;AAEhC,QAAM,mBACJ,QAAQ,oBAAoB,GAAG,cAAc,MAAM,QAC/C,iHACA;AAEN,SAAO,aACH,yBAAyB,OAAO,kBAAkB,UAAU;AAAA,0CAA6C,gBAAgB,KACzH,yBAAyB,OAAO,yCAAyC,gBAAgB;AAC/F;AAEA,SAAS,yBAAyB,SAAuB;AACvD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAYC,IACT,OAAO,EACP,SAAS,EACT,SAAS,mEAA8D;AAAA,QAC1E,YAAYA,IACT,QAAQ,EACR,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,QACF,YAAYA,IACT,QAAQ,EACR,SAAS,EACT,SAAS,yEAAyE;AAAA,QACrF,YAAYA,IACT,OAAO,EACP,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,MACJ;AAAA,MACA,OAAO,WAAW;AAChB,YAAI;AACF,iBAAO,MAAM,qBAAqB,SAAS,MAAM;AAAA,QACnD,SAAS,OAAO;AACd,iBAAO,WAAW,+BAA+BD,aAAY,KAAK,CAAC,EAAE;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,cAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,mBAAO,WAAW,oBAAoB;AAAA,UACxC;AACA,gBAAM,QAAQ,cAAc;AAC5B,iBAAO,WAAW,wDAAwD;AAAA,QAC5E,SAAS,OAAO;AACd,iBAAO,WAAW,8BAA8BA,aAAY,KAAK,CAAC,EAAE;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAuB;AACnD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAMC,IAAE,OAAO,EAAE,SAAS,yDAAyD;AAAA,QACnF,MAAMA,IAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,QAC1E,WAAWA,IACR,OAAO,EACP,SAAS,EACT,SAAS,6EAAwE;AAAA,MACtF;AAAA,MACA,OAAO,EAAE,MAAM,MAAM,UAAU,MAAM;AACnC,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,SAAS;AACf,gBAAM,eAAe,MAAM,OAAO,cAAc,MAAM,MAAM,SAAS;AACrE,gBAAM,UAAU,YAAY,gBAAgB,SAAS,MAAM;AAC3D,iBAAO;AAAA,YACL,mBAAmB,IAAI,IAAI,IAAI,GAAG,OAAO;AAAA,iBAAoB,YAAY;AAAA,UAC3E;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,WAAW,6BAA6BC,aAAY,KAAK,CAAC,EAAE;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,cAAcC,IAAE,OAAO,EAAE,SAAS,oDAAoD;AAAA,MACxF;AAAA,MACA,OAAO,EAAE,aAAa,MAAM;AAC1B,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,SAAS;AACf,gBAAM,OAAO,iBAAiB,YAAY;AAC1C,iBAAO,WAAW,cAAc,YAAY,WAAW;AAAA,QACzD,SAAS,OAAO;AACd,iBAAO,WAAW,gCAAgCC,aAAY,KAAK,CAAC,EAAE;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA;AAAA,MAED,YAAY;AACV,cAAM,cAAcD,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,cAAM,cAAc,YAAY,gBAAgB;AAChD,YAAI,YAAY,WAAW,GAAG;AAC5B,iBAAO,WAAW,qBAAqB;AAAA,QACzC;AACA,eAAO,WAAW,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,MACxD;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAuB;AACnD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAcA,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAClE,cAAM,SAAS;AAEf,cAAM,aAAa,QAAQ,wBAAwB;AAEnD,YAAI,CAAC,OAAO,SAAS,GAAG;AACtB,cAAI,WAAW,SAAS,GAAG;AACzB,mBAAO;AAAA,cACL;AAAA,EAAuE,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAAA,YAC5G;AAAA,UACF;AACA,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,YAAY,OAAO,aAAa;AACtC,gBAAM,WAAW,UAAU,CAAC;AAC5B,cAAI,YAA6D,CAAC;AAElE,cAAI,UAAU;AACZ,gBAAI;AACF,0BAAY,MAAM,OAAO,kBAAkB,SAAS,WAAW;AAAA,YACjE,QAAQ;AAAA,YAER;AAAA,UACF;AAEA,gBAAM,SAAS;AAAA,YACb,QAAQ,OAAO,eAAe,GAAG;AAAA,YACjC,gBAAgB,OAAO,eAAe,GAAG;AAAA,YACzC;AAAA,YACA,gBAAgB;AAAA,UAClB;AAEA,iBAAO,WAAW,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QACnD,SAAS,OAAO;AACd,iBAAO,WAAW,mCAAmCC,aAAY,KAAK,CAAC,EAAE;AAAA,QAC3E;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAYC,IAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,QACvE,YAAYA,IACT,OAAO,EACP,SAAS,EACT,SAAS,oEAAoE;AAAA,MAClF;AAAA,MACA,OAAO,EAAE,YAAY,WAAW,MAAM;AACpC,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,SAAS;AACf,cAAI;AAEJ,cAAI,OAAO,SAAS,GAAG;AACrB,kBAAM,YAAY,OAAO,aAAa;AACtC,kBAAM,QAAQ,UAAU,cAAc,CAAC;AACvC,0BAAc,OAAO;AAAA,UACvB;AAEA,gBAAM,SAAS,MAAM,OAAO,SAAS,YAAY,WAAW;AAC5D,iBAAO,WAAW,IAAI,OAAO,IAAI,KAAK,OAAO,KAAK,EAAE;AAAA,QACtD,SAAS,OAAO;AACd,iBAAO,WAAW,sBAAsBC,aAAY,KAAK,CAAC,EAAE;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,0BAA0B,SAAuB;AACxD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAMC,IAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,QAC9C,MAAMA,IAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,QAC1D,aAAaA,IACV,MAAMA,IAAE,OAAO,CAAC,EAChB;AAAA,UACC;AAAA,QACF;AAAA,QACF,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,uDAAuD;AAAA,MACrE;AAAA,MACA,OAAO,EAAE,MAAM,MAAM,aAAa,MAAM,MAAM;AAC5C,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,UAAU,MAAM,YAAY,YAAY,MAAM,MAAM,aAAa,KAAK;AAC5E,gBAAM,aAAa,SAAS,GAAG,IAAI,IAAI,IAAI;AAC3C,gBAAM,WAAW,YAAY,KAAK,IAAI;AACtC,iBAAO;AAAA,YACL,UAAU,UAAU,YAAY,IAAI,IAAI,IAAI;AAAA,aAAgB,QAAQ;AAAA,YAAe,OAAO;AAAA;AAAA;AAAA,UAC5F;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,WAAW,wBAAwBC,aAAY,KAAK,CAAC,EAAE;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAASC,IAAE,OAAO,EAAE,SAAS,0CAA0C;AAAA,MACzE;AAAA,MACA,OAAO,EAAE,QAAQ,MAAM;AACrB,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AACF,gBAAM,YAAY,YAAY,OAAO;AACrC,iBAAO,WAAW,SAAS,OAAO,WAAW;AAAA,QAC/C,SAAS,OAAO;AACd,iBAAO,WAAW,2BAA2BC,aAAY,KAAK,CAAC,EAAE;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA;AAAA,MAED,YAAY;AACV,cAAM,cAAcD,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,cAAM,SAAS,YAAY,WAAW;AACtC,YAAI,OAAO,WAAW,GAAG;AACvB,iBAAO,WAAW,gBAAgB;AAAA,QACpC;AAEA,cAAM,QAAQ,OAAO;AAAA,UACnB,CAAC,MACC,GAAG,EAAE,OAAO,MAAM,EAAE,KAAK,QAAQ,EAAE,IAAI,IAAI,EAAE,IAAI,YAAO,EAAE,YAAY,KAAK,IAAI,CAAC;AAAA,QACpF;AACA,eAAO,WAAW,MAAM,KAAK,IAAI,CAAC;AAAA,MACpC;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,SAAuB;AACpD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAASE,IACN,OAAO,EACP,SAAS,EACT,SAAS,oDAAoD;AAAA,QAChE,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QACrE,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,wDAAwD;AAAA,MACtE;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,MAAM,MAAM;AACnC,cAAM,cAAcF,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI;AAEF,cAAI,cAAc;AAClB,cAAI,WAAW,CAAC,aAAa;AAC3B,kBAAM,QAAQ,YAAY,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AACxE,gBAAI,MAAO,eAAc,MAAM;AAAA,UACjC;AAEA,gBAAM,OAAO,MAAM,YAAY,gBAAgB,aAAa,KAAK;AAEjE,cAAI,KAAK,WAAW,GAAG;AACrB,kBAAM,aAAa,cAAc,SAAS,WAAW,MAAM;AAC3D,mBAAO;AAAA,cACL,gBAAgB,UAAU;AAAA,YAC5B;AAAA,UACF;AAGA,gBAAM,YAAY,gBAAgB,IAAI;AACtC,iBAAO,WAAW,SAAS;AAAA,QAC7B,SAAS,OAAO;AACd,iBAAO,WAAW,gCAAgCC,aAAY,KAAK,CAAC,EAAE;AAAA,QACxE;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,gBACP,MACQ;AAER,QAAM,UAAU,oBAAI,IAAyB;AAC7C,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,QAAQ,IAAI,IAAI,KAAK,KAAK,CAAC;AACzC,UAAM,KAAK,GAAG;AACd,YAAQ,IAAI,IAAI,OAAO,KAAK;AAAA,EAC9B;AAEA,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,OAAO,SAAS,KAAK,SAAS;AACxC,UAAM,SAAS,UAAU,KAAK,gBAAW,UAAU,MAAM,QAAQ,UAAU,WAAW,IAAI,KAAK,GAAG;AAClG,UAAM,QAAQ,UAAU,IAAI,CAAC,QAAQ;AACnC,YAAM,OAAO,IAAI,KAAK,IAAI,SAAS,EAAE,mBAAmB,SAAS,EAAE,QAAQ,MAAM,CAAC;AAClF,YAAM,UAAU,OAAO,QAAQ,IAAI,IAAI,EACpC,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,GAAG,GAAG,IAAI,iBAAiB,GAAG,CAAC,EAAE,EACrD,KAAK,IAAI;AACZ,aAAO,MAAM,IAAI,KAAK,OAAO;AAAA,IAC/B,CAAC;AACD,aAAS,KAAK,CAAC,QAAQ,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,EAC7C;AAEA,SAAO,SAAS,KAAK,MAAM;AAC7B;AAEA,SAAS,iBAAiB,OAAwB;AAChD,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,SAAS,MAAM,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,IAAI,KAAK;AAAA,EACtE;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AAChF,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,SAAS,MAAM,MAAM;AAAA,EAC9B;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,OAAO,OAAO,KAAK,KAAgC;AACzD,QAAI,KAAK,UAAU,GAAG;AACpB,YAAM,UAAU,KACb,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,iBAAkB,MAAkC,CAAC,CAAC,CAAC,EAAE,EAC7E,KAAK,IAAI;AACZ,aAAO,IAAI,OAAO;AAAA,IACpB;AACA,WAAO,UAAU,KAAK,MAAM;AAAA,EAC9B;AACA,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,2BAA2B,SAAuB;AACzD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAcD,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,iBAAO,WAAW,yBAAyB;AAAA,QAC7C;AAEA,YAAI;AACF,gBAAM,YAAY,OAAO;AACzB,iBAAO,WAAW,oBAAoB;AAAA,QACxC,SAAS,OAAO;AACd,iBAAO,WAAW,qBAAqBC,aAAY,KAAK,CAAC,EAAE;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAcD,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,iBAAO,WAAW,yBAAyB;AAAA,QAC7C;AAEA,YAAI;AACF,gBAAM,YAAY,SAAS;AAC3B,iBAAO,WAAW,8DAA8D;AAAA,QAClF,SAAS,OAAO;AACd,iBAAO,WAAW,wBAAwBC,aAAY,KAAK,CAAC,EAAE;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,cAAM,cAAcD,oBAAmB,OAAO;AAC9C,YAAI,OAAO,gBAAgB,SAAU,QAAO,WAAW,WAAW;AAElE,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,iBAAO,WAAW,yBAAyB;AAAA,QAC7C;AAEA,YAAI;AACF,gBAAM,YAAY,SAAS;AAC3B,iBAAO,WAAW,8DAA8D;AAAA,QAClF,SAAS,OAAO;AACd,iBAAO,WAAW,wBAAwBC,aAAY,KAAK,CAAC,EAAE;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,SAAuB;AACrD,SAAO;AAAA,IACL,GAAG,yBAAyB,OAAO;AAAA,IACnC,GAAG,qBAAqB,OAAO;AAAA,IAC/B,GAAG,0BAA0B,OAAO;AAAA,IACpC,GAAG,sBAAsB,OAAO;AAAA,IAChC,GAAG,qBAAqB,OAAO;AAAA,IAC/B,GAAG,2BAA2B,OAAO;AAAA,IACrC,GAAG,oBAAoB,OAAO;AAAA,IAC9B,GAAG,sBAAsB,OAAO;AAAA,EAClC;AACF;;;AIthBA,SAAS,iBAAiB,WAAkC,YAA6B;AACvF,MAAI,cAAc,eAAe,cAAc,QAAQ;AACrD,WAAO,CAAC,oBAAoB,UAAU,CAAC;AAAA,EACzC;AACA,SAAO,CAAC;AACV;AAEA,SAAS,aACP,WACA,YACA,QACA,SACA;AACA,MAAI,OAAO,SAAS,OAAQ,QAAO,iBAAiB,WAAW,UAAU;AAEzE,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,SAAS,eAAe,aAAa,YAAY,EAAE,kBAAkB,KAAK,CAAC,IAAI,CAAC;AAAA,IACzF,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,aAAa,YAAY;AAAA,QAC9B,kBAAkB,CAAC,CAAC,SAAS;AAAA,MAC/B,CAAC;AAAA,IACH;AACE,aAAO,OAAO,SAAS,OAAO,aAAa,YAAY,EAAE,kBAAkB,MAAM,CAAC,IAAI,CAAC;AAAA,EAC3F;AACF;AAKO,SAAS,mBACd,YACA,QACA,SACA,WACA,cACyB;AACzB,QAAM,gBAAgB,aAAa,SAAS,aAAa;AAEzD,QAAM,cAAc,iBAAiB,YAAY,MAAM;AACvD,QAAM,YAAY,aAAa,eAAe,YAAY,QAAQ,OAAO;AAEzE,QAAM,iBACJ,kBAAkB,eAAe,kBAAkB,SAC/C,oBAAoB,UAAU,IAC9B,CAAC;AAGP,QAAM,kBAAkB,kBAAkB,WAAW,qBAAqB,UAAU,IAAI,CAAC;AAEzF,QAAM,iBAAiB,CAAC,+BAA+B,UAAU,CAAC;AAGlE,QAAM,aACJ,gBAAgB,kBAAkB,aAAa,gBAAgB,YAAY,IAAI,CAAC;AAElF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAKO,SAAS,wBACd,SACA,YACA,QACA,SACA,WACA,cACA;AACA,SAAO,QAAQ,gBAAgB;AAAA,IAC7B,MAAM;AAAA,IACN,OAAO,mBAAmB,YAAY,QAAQ,SAAS,WAAW,YAAY;AAAA,EAChF,CAAC;AACH;;;ACrFA,IAAM,SAAS,oBAAoB,gBAAgB;AAEnD,SAAS,SAAS,SAAkC,SAAuB;AACzE,MAAI,WAAW,OAAQ,QAA6B,UAAU,YAAY;AACxE,IAAC,QAA6B,MAAM,CAAC,QAAQ;AAC3C,cAAQ,OAAO,MAAM,cAAc,OAAO,KAAK,GAAG;AAAA,CAAI;AAAA,IACxD,CAAC;AAAA,EACH;AACF;AASA,SAAS,kBAAkB,OAAoC;AAC7D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,SAAS,EAAG,QAAO;AAEpD,QAAM,KAAK,QAAQ,OAAO,QAAQ,MAAO;AACzC,SAAO,IAAI,KAAK,EAAE,EAAE,YAAY;AAClC;AAEA,eAAsB,sBACpB,OACA,MACA,eACe;AACf,QAAM,EAAE,QAAQ,IAAI,MAAM;AAC1B,QAAM,gBAA0B,CAAC;AAEjC,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,SAAS,UAAU,MAAM,MAAM;AACvC,oBAAc,KAAK,MAAM,IAAI;AAC7B,WAAK,WAAW,UAAU,EAAE,MAAM,WAAW,SAAS,MAAM,KAAK,CAAC;AAClE,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,WAAW,SAAS,MAAM,KAAK,CAAC;AAAA,IACvE,WAAW,MAAM,SAAS,cAAc,MAAM,MAAM;AAClD,YAAM,WAAW,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK;AAC3F,YAAM,gBAAgB,CAAC,QAAQ,OAAO,EAAE,SAAS,MAAM,KAAK,YAAY,CAAC;AACzE,YAAM,aAAa,gBAAgB,MAAS;AAC5C,YAAM,UAAgC;AAAA,QACpC,MAAM,MAAM;AAAA,QACZ,OAAO,SAAS,MAAM,GAAG,UAAU;AAAA,QACnC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AACA,oBAAc,KAAK,OAAO;AAC1B,WAAK,WAAW,UAAU,EAAE,MAAM,YAAY,MAAM,MAAM,MAAM,OAAO,SAAS,CAAC;AACjF,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,YAAY,MAAM,MAAM,MAAM,OAAO,SAAS,CAAC;AAAA,IACtF;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB;AACjC,IAAM,sBAAsB;AAC5B,IAAM,qBACJ;AAEK,SAASE,aAAY,KAAsB;AAChD,SAAO,mBAAmB,KAAK,GAAG;AACpC;AAEA,SAAS,mBAAmB,KAAsB;AAChD,MAAI,oBAAoB,KAAK,GAAG,EAAG,QAAO;AAC1C,MAAI,kBAAkB,KAAK,GAAG,EAAG,QAAO;AACxC,SAAO;AACT;AAEA,SAAS,oBAAoB,YAM3B;AACA,MAAI,mBAAmB;AACvB,MAAI,gBAAgB;AACpB,MAAI,mBAAmB;AACvB,MAAI,iBAAiB;AACrB,MAAI,qBAAqB;AACzB,aAAW,QAAQ,OAAO,OAAO,UAAU,GAAG;AAC5C,UAAM,IAAI;AAKV,UAAM,QAAQ,EAAE,eAAe;AAC/B,UAAM,YAAY,EAAE,wBAAwB;AAC5C,UAAM,gBAAgB,EAAE,4BAA4B;AACpD,wBAAoB;AACpB,sBAAkB;AAClB,0BAAsB;AACtB,wBAAoB,QAAQ,YAAY;AACxC,UAAM,KAAM,KAAoC,iBAAiB;AACjE,QAAI,KAAK,cAAe,iBAAgB;AAAA,EAC1C;AACA,SAAO,EAAE,kBAAkB,eAAe,kBAAkB,gBAAgB,mBAAmB;AACjG;AAEA,SAAS,kBACP,YACA,MACA,SACA,oBACM;AACN,QAAM,QAAQ,oBAAoB,UAAU;AAC5C,MAAI,EAAE,cAAc,IAAI;AAGxB,QAAM,WAAW,QAAQ,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AACxE,QAAM,YAAa,SAAS,OAAgC,SAAS,uBAAuB;AAC5F,MAAI,aAAa,gBAAgB,KAAK,iBAAiB,KAAS;AAC9D,oBAAgB;AAAA,EAClB;AAEA,MAAI,gBAAgB,GAAG;AAErB,UAAM,uBAAuB,sBACxB,mBAAmB,gBAAgB,MACnC,mBAAmB,2BAA2B,MAC9C,mBAAmB,+BAA+B,KACnD,MAAM;AAEV,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,eAAe;AAAA,MACf;AAAA,MACA,aAAa,MAAM;AAAA,MACnB,sBAAsB,MAAM;AAAA,MAC5B,0BAA0B,MAAM;AAAA,MAChC,iBAAiB,MAAM;AAAA,IACzB,CAAC;AAAA,EACH;AACF;AAEA,SAAS,kBAAkB,MAAiB,SAAsB,iBAA+B;AAC/F,MAAI,kBAAkB,KAAK,QAAQ,WAAW,QAAQ,kBAAkB;AACtE,UAAM,YAAY,KAAK,YAAY;AACnC,SAAK,WAAW,cAAc;AAAA,MAC5B,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ;AAAA,MACnB,cAAc;AAAA,MACd,gBAAgB,KAAK,OAAO,SAAS,QAAQ,CAAC,CAAC,QAAQ,IAAI;AAAA,MAC3D,YAAY,UAAU,SAAS,IAAI,YAAY;AAAA,IACjD,CAAC;AAAA,EACH;AACF;AAEA,SAAS,oBACP,OACA,MACA,SACA,WACA,oBAC8C;AAC9C,QAAM,aAAa,KAAK,IAAI,IAAI;AAChC,QAAM,UAAU,MAAM,UAAU;AAChC,QAAM,YAAY,mBAAmB,OAAO;AAE5C,QAAM,kBAAkB,KAAK,YAAY,aAAa,MAAM,cAAc;AAE1E,QAAM,EAAE,WAAW,IAAI;AACvB,MAAI,cAAc,OAAO,eAAe,UAAU;AAChD,SAAK,YAAY;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,OAAK,WAAW,UAAU,EAAE,MAAM,aAAa,SAAS,SAAS,iBAAiB,WAAW,CAAC;AAE9F,MAAI,cAAc,OAAO,eAAe,UAAU;AAChD,sBAAkB,YAAuC,MAAM,SAAS,kBAAkB;AAAA,EAC5F;AAEA,oBAAkB,MAAM,SAAS,eAAe;AAEhD,SAAO,EAAE,cAAc,iBAAiB,UAAU;AACpD;AAEA,SAAS,kBACP,OACA,MACqE;AACrE,QAAM,WACJ,MAAM,OAAO,SAAS,IAAI,MAAM,OAAO,KAAK,IAAI,IAAI,kBAAkB,MAAM,OAAO;AAGrF,QAAM,iBAAiB,SAAS,SAAS,uCAAuC;AAEhF,MAAI,gBAAgB;AAElB,WAAO,EAAE,WAAW,OAAO,cAAc,KAAK;AAAA,EAChD;AAGA,MAAIA,aAAY,QAAQ,GAAG;AACzB,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,SAAS,SAAS,CAAC;AAC9D,WAAO,EAAE,WAAW,OAAO,WAAW,KAAK;AAAA,EAC7C;AAEA,QAAM,YAAY,mBAAmB,QAAQ;AAC7C,OAAK,WAAW,UAAU,EAAE,MAAM,SAAS,SAAS,SAAS,CAAC;AAC9D,SAAO,EAAE,UAAU;AACrB;AAEA,SAAS,kBACP,OACA,MACA,SACA,WACA,oBAOA;AACA,QAAM,gBACJ,MAAM,YAAY,YACb,MAAoC,SACpC,MAAkC,OAAO,KAAK,IAAI;AAEzD,MAAI,MAAM,YAAY,WAAW;AAC/B,UAAMC,UAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,EAAE,GAAGA,SAAQ,cAAc;AAAA,EACpC;AAEA,QAAM,SAAS,kBAAkB,OAAkC,IAAI;AACvE,SAAO,EAAE,cAAc,GAAG,GAAG,QAAQ,cAAc;AACrD;AAEA,eAAsB,gBACpB,OACA,MACA,SACA,WACA,oBAMC;AACD,QAAM,SAAS,kBAAkB,OAAO,MAAM,SAAS,WAAW,kBAAkB;AACpF,QAAM,aAAa,KAAK,IAAI,IAAI;AAEhC,MAAI,MAAM,YAAY,WAAW;AAC/B,UAAM,eAAe;AACrB,UAAM,UAAU,aAAa,UAAU;AACvC,UAAM,KAAK,UAAU,QAAQ;AAAA,MAC3B,MAAM;AAAA,MACN;AAAA,MACA,SAAS,OAAO;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH,WAAW,CAAC,OAAO,cAAc;AAE/B,UAAM,aAAa;AACnB,UAAM,WACJ,WAAW,OAAO,SAAS,IACvB,WAAW,OAAO,KAAK,IAAI,IAC3B,kBAAkB,WAAW,OAAO;AAC1C,UAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,SAAS,SAAS,CAAC;AAAA,EACnE;AAEA,SAAO;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,eAAe,OAAO;AAAA,IACtB,cAAc,OAAO;AAAA,IACrB,WAAW,OAAO;AAAA,EACpB;AACF;AAEO,SAAS,qBACd,OACA,MACoB;AACpB,QAAM,EAAE,gBAAgB,IAAI;AAC5B,SAAO,KAAK,6BAA6B,EAAE,gBAAgB,CAAC;AAC5D,QAAM,SAAS,gBAAgB;AAI/B,QAAM,cAAc,gBAAgB,gBAAgB,WAAW,aAAa,IAAM;AAClF,MAAI,gBAAgB,UAAa,gBAAgB,eAAe;AAC9D,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,eAAe,gBAAgB;AAAA,MAC/B;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,YAAY;AACzB,UAAM,WAAW,kBAAkB,gBAAgB,QAAQ;AAC3D,UAAM,kBAAkB,YAAY;AACpC,UAAM,UAAU,8BAA8B,gBAAgB,iBAAiB,SAAS,gBAAgB,eAAe;AACvH,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,QAAQ,CAAC;AACpD,aAAS,KAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,QAAQ,CAAC,GAAG,mBAAmB;AAChF,WAAO;AAAA,EACT,WAAW,WAAW,mBAAmB;AACvC,UAAM,mBAAmB,gBAAgB,cACrC,GAAG,KAAK,MAAM,gBAAgB,cAAc,GAAG,CAAC,MAChD;AACJ,UAAM,UAAU,uBAAuB,gBAAgB,uBAAuB,gBAAgB,iBAAiB,SAAS;AACxH,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,QAAQ,CAAC;AACvD,aAAS,KAAK,UAAU,QAAQ,EAAE,MAAM,YAAY,QAAQ,CAAC,GAAG,kBAAkB;AAAA,EACpF;AACA,SAAO;AACT;AAEA,eAAsB,kBACpB,OACA,MACA,SACA,iBACkB;AAClB,MAAI,MAAM,YAAY,OAAQ,QAAO;AACrC,MAAI,MAAM,cAAc,CAAC,iBAAiB;AACxC,SAAK,WAAW,eAAe,MAAM,UAAU;AAC/C,YAAQ,kBAAkB,MAAM;AAAA,EAClC;AACA,QAAM,KAAK,UAAU,QAAQ;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS,6BAA6B,MAAM,KAAK;AAAA,EACnD,CAAC;AACD,SAAO,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC;AAEO,SAAS,sBACd,aACA,MACM;AACN,MAAI,YAAY,YAAY,oBAAoB;AAC9C;AAAA,MACE,KAAK,UAAU,QAAQ;AAAA,QACrB,MAAM;AAAA,QACN,SAAS,YAAY,iBAAiB;AAAA,QACtC,WAAW,YAAY,iBAAiB;AAAA,MAC1C,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF,WAAW,YAAY,YAAY,gBAAgB;AACjD;AAAA,MACE,KAAK,UAAU,QAAQ;AAAA,QACrB,MAAM;AAAA,QACN,WAAW,YAAY;AAAA,QACvB,aAAa,YAAY;AAAA,MAC3B,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF,WAAW,YAAY,YAAY,iBAAiB;AAClD;AAAA,MACE,KAAK,UAAU,QAAQ;AAAA,QACrB,MAAM;AAAA,QACN,WAAW,YAAY;AAAA,QACvB,aAAa,YAAY;AAAA,QACzB,UAAU,YAAY,OAAO,aAAa;AAAA,QAC1C,YAAY,YAAY,OAAO,eAAe;AAAA,MAChD,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,wBAAwB,OAAgB,MAAuB;AAC7E,QAAM,MAAM;AACZ;AAAA,IACE,KAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,UAAU,IAAI,aAAa;AAAA,MAC3B,gBAAgB,IAAI,wBAAwB;AAAA,IAC9C,CAAC;AAAA,IACD;AAAA,EACF;AACF;AAEA,eAAsB,oBACpB,OACA,MACA,eACgC;AAChC,QAAM,sBAAsB,OAAO,MAAM,aAAa;AACtD,QAAM,WAAY,MAAM,QAAkC;AAC1D,SAAO,YAAY;AACrB;AAEA,eAAsB,iBACpB,OACA,MACA,SACA,WACA,UACA,oBAOC;AACD,MAAI,gBAAgB;AACpB,MAAI,UAAU;AACZ,SAAK,WAAW,eAAe;AAC/B,oBAAgB;AAAA,EAClB;AACA,QAAM,aAAa,MAAM,gBAAgB,OAAO,MAAM,SAAS,WAAW,kBAAkB;AAC5F,SAAO;AAAA,IACL,WAAW,WAAW;AAAA,IACtB,eAAe,WAAW;AAAA,IAC1B,cAAc,WAAW;AAAA,IACzB,WAAW,WAAW;AAAA,IACtB;AAAA,EACF;AACF;;;AChZA,SAAS,mBAAmB,MAAiB,UAAyB;AACpE,MAAI,SAAU,MAAK,WAAW,eAAe;AAC/C;AAGA,SAAS,sBAAsB,MAAiB,eAA6C;AAC3F,MAAI,cAAc,WAAW,GAAG;AAE9B,SAAK,mBAAmB,SAAS;AACjC;AAAA,EACF;AAEA,QAAM,gBAAgB,oBAAI,IAAsB;AAChD,aAAW,SAAS,KAAK,oBAAoB;AAC3C,UAAM,OAAO,cAAc,IAAI,MAAM,IAAI,KAAK,CAAC;AAC/C,SAAK,KAAK,MAAM,MAAM;AACtB,kBAAc,IAAI,MAAM,MAAM,IAAI;AAAA,EACpC;AACA,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,cAAc,IAAI,KAAK,IAAI;AACxC,QAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,WAAK,SAAS,KAAK,MAAM;AAAA,IAC3B;AAAA,EACF;AACA,OAAK,WAAW,UAAU,EAAE,MAAM,YAAY,WAAW,CAAC,GAAG,aAAa,EAAE,CAAC;AAC7E,gBAAc,SAAS;AACvB,OAAK,mBAAmB,SAAS;AACnC;AAEA,eAAe,kBACb,OAKA,MACA,SACA,OACe;AACf,MAAI,MAAM,YAAY,QAAQ;AAC5B,UAAM,SAAS,MAAM,kBAAkB,OAAO,MAAM,SAAS,MAAM,eAAe;AAClF,QAAI,OAAQ,OAAM,kBAAkB;AAAA,EACtC,OAAO;AACL;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,qBACb,OACA,MACA,OACe;AACf,MAAI,CAAC,MAAM,UAAU;AACnB,eAAW,MAAM,KAAK,WAAW,gBAAgB,GAAG,GAAG;AACvD,UAAM,WAAW;AAAA,EACnB;AACA,QAAM,QAAQ,MAAM,oBAAoB,OAAO,MAAM,MAAM,aAAa;AACxE,MAAI,MAAO,OAAM,qBAAqB;AAKtC,MAAI,CAAC,MAAM,aAAa;AACtB,UAAM,WAAW,MAAM,QAAQ,QAC5B,OAAO,CAAC,MAAwB,EAAE,SAAS,MAAM,EACjD,IAAI,CAAC,MAAwC,EAAuB,IAAI,EACxE,KAAK,GAAG;AACX,QAAI,kBAAkB,KAAK,QAAQ,GAAG;AACpC,YAAM,cAAc;AAAA,IACtB;AAAA,EACF;AACF;AAEA,eAAe,kBACb,OACA,MACA,SACA,WACA,OACe;AACf,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACA,MAAI,KAAK,cAAe,OAAM,WAAW;AACzC,QAAM,YAAY,KAAK;AAGvB,MAAI,CAAC,KAAK,UAAW,OAAM,cAAc;AACzC,QAAM,gBAAgB,KAAK;AAC3B,MAAI,KAAK,aAAc,OAAM,eAAe;AAC5C,MAAI,KAAK,UAAW,OAAM,YAAY;AACxC;AAEA,eAAsB,cACpB,QACA,SACA,MAQC;AACD,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,iBAAiB,KAAK,IAAI;AAC9B,QAAM,4BAA4B;AAElC,QAAM,QAAwB;AAAA,IAC5B,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,cAAc;AAAA,IACd,WAAW;AAAA,IACX,oBAAoB;AAAA,IACpB,eAAe,CAAC;AAAA,EAClB;AAEA,mBAAiB,SAAS,QAAQ;AAChC,QAAI,KAAK,UAAU,EAAG;AAItB,0BAAsB,MAAM,MAAM,aAAa;AAG/C,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,kBAAkB,2BAA2B;AACrD,WAAK,WAAW,WAAW,SAAS;AACpC,uBAAiB;AAAA,IACnB;AAEA,QAAI,KAAK,oBAAoB;AAC3B,yBAAmB,MAAM,MAAM,QAAQ;AACvC,aAAO,EAAE,WAAW,OAAO,aAAa,KAAK;AAAA,IAC/C;AAEA,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,cAAM,kBAAkB,OAAiC,MAAM,SAAS,KAAK;AAC7E;AAAA,MACF,KAAK;AACH,cAAM,qBAAqB,OAAgC,MAAM,KAAK;AACtE;AAAA,MACF,KAAK;AACH,cAAM,kBAAkB,OAA6B,MAAM,SAAS,WAAW,KAAK;AACpF;AAAA,MACF,KAAK,oBAAoB;AACvB,cAAM,WAAW,qBAAqB,OAAgC,IAAI;AAC1E,YAAI,SAAU,OAAM,oBAAoB;AACxC;AAAA,MACF;AAAA,MACA,KAAK;AACH,gCAAwB,OAAO,IAAI;AACnC;AAAA,IACJ;AAAA,EACF;AAEA,wBAAsB,MAAM,MAAM,aAAa;AAC/C,qBAAmB,MAAM,MAAM,QAAQ;AAEvC,SAAO;AAAA,IACL,WAAW,MAAM,aAAa,MAAM;AAAA,IACpC,eAAe,MAAM;AAAA,IACrB,mBAAmB,MAAM;AAAA,IACzB,GAAI,MAAM,gBAAgB,EAAE,cAAc,MAAM,aAAa;AAAA,IAC7D,GAAI,MAAM,aAAa,EAAE,WAAW,MAAM,UAAU;AAAA,EACtD;AACF;;;ACpNO,SAAS,oBAAoB,WAIvB;AACX,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAC,UAAU,MAAM,KAAK,EAAG,SAAQ,KAAK,kCAAkC;AAC5E,MAAI,CAAC,UAAU,aAAc,SAAQ,KAAK,2CAA2C;AACrF,MAAI,CAAC,UAAU,SAAS,UAAU,UAAU;AAC1C,YAAQ,KAAK,oCAAoC;AACnD,SAAO;AACT;;;ACZA,IAAM,qBAAqB,oBAAI,IAAI,CAAC,SAAS,QAAQ,WAAW,CAAC;AAEjE,IAAM,uBAAuD;AAAA,EAC3D;AAAA,IACE,MAAM;AAAA,IACN,IAAI;AAAA,EACN;AAAA,EACA,EAAE,MAAM,qBAAqB,IAAI,mCAAmC;AAAA,EACpE,EAAE,MAAM,oBAAoB,IAAI,yBAAyB;AAAA,EACzD;AAAA,IACE,MAAM;AAAA,IACN,IAAI;AAAA,EACN;AAAA,EACA,EAAE,MAAM,WAAW,IAAI,gBAAgB;AAAA,EACvC,EAAE,MAAM,wBAAwB,IAAI,qCAAqC;AAAA,EACzE,EAAE,MAAM,gBAAgB,IAAI,wBAAwB;AAAA,EACpD,EAAE,MAAM,4BAA4B,IAAI,yCAAyC;AAAA,EACjF,EAAE,MAAM,4BAA4B,IAAI,kBAAkB;AAAA,EAC1D,EAAE,MAAM,iCAAiC,IAAI,wCAAwC;AAAA,EACrF,EAAE,MAAM,aAAa,IAAI,qCAAqC;AAChE;AAEA,SAAS,mBAAmB,KAA4B;AACtD,aAAW,EAAE,MAAM,GAAG,KAAK,sBAAsB;AAC/C,QAAI,GAAG,KAAK,GAAG,EAAG,QAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAMA,SAAS,WAAW,OAAyC;AAC3D,QAAM,WAAW,OAAO,MAAM,aAAa,MAAM,QAAQ,EAAE;AAC3D,SAAO,SAAS,SAAS,gBAAgB;AAC3C;AAEA,SAAS,0BAA0B,UAAkB,OAA4C;AAC/F,MAAI,mBAAmB,IAAI,QAAQ,GAAG;AACpC,QAAI,WAAW,KAAK,GAAG;AACrB,aAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,IAClD;AACA,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAClD;AAEA,SAAS,yBAAyB,UAAkB,OAA4C;AAC9F,MAAI,aAAa,QAAQ;AACvB,UAAM,MAAM,OAAO,MAAM,WAAW,EAAE;AACtC,UAAM,UAAU,mBAAmB,GAAG;AACtC,QAAI,SAAS;AACX,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS,kCAAkC,OAAO;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAClD;AAEA,SAAS,uBAAuB,UAAkB,OAA4C;AAE5F,SAAO,yBAAyB,UAAU,KAAK;AACjD;AAEA,SAAS,qBACP,UACA,OACA,mBACA,cACY;AACZ,MAAI,mBAAmB;AACrB,WAAO,eACH,uBAAuB,UAAU,KAAK,IACtC,yBAAyB,UAAU,KAAK;AAAA,EAC9C;AAEA,SAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAClD;AAEA,SAAS,oBACP,MACA,OACA,cACmB;AACnB,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,MAAI,MAAM,qBAAqB,MAAM;AACnC,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,QACP;AAAA,QACA,GAAG,aAAa,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACA,OAAK,WAAW;AAAA,IACd,0HAAgH,aAAa,KAAK,IAAI,CAAC;AAAA,EACzI;AACA,SAAO;AACT;AAEA,eAAe,mBACb,MACA,OACqB;AACrB,MAAI,KAAK,mBAAmB;AAC1B,WAAO,EAAE,UAAU,SAAkB,cAAc,MAAM;AAAA,EAC3D;AAEA,MAAI;AAIF,UAAM,KAAK,aAAa;AAExB,UAAM,YAAY,MAAM,KAAK,WAAW,kBAAkB;AAC1D,UAAM,eAAe,oBAAoB,SAAS;AAGlD,QAAI,KAAK,cAAc;AACrB,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,WAAW,KAAK,gBAAgB;AAAA,UAC1D,WAAW,KAAK,WAAW;AAAA,QAC7B,CAAC;AACD,cAAM,uBAAuB,SAAS;AAAA,UACpC,CAAC,MAA+C,CAAC,EAAE,MAAM,KAAK;AAAA,QAChE;AACA,YAAI,qBAAqB,SAAS,GAAG;AACnC,gBAAM,QAAQ,qBAAqB,IAAI,CAAC,MAAyB,EAAE,KAAK,EAAE,KAAK,IAAI;AACnF,uBAAa;AAAA,YACX,0DAAqD,KAAK;AAAA,UAC5D;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,OAAO,oBAAoB,MAAM,OAAO,YAAY;AAC1D,QAAI,KAAM,QAAO;AAEjB,QAAI,KAAK,cAAc,aAAa;AAClC,WAAK,oBAAoB;AACzB,WAAK,qBAAqB;AAM1B,UAAI;AACF,cAAM,KAAK,WAAW,sBAAsB;AAAA,MAC9C,SAAS,YAAY;AACnB,aAAK,WAAW;AAAA,UACd,gDAAgD,sBAAsB,QAAQ,WAAW,UAAU,eAAe;AAAA,QACpH;AAAA,MACF;AACA,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,MACF;AAGA,WAAK,YAAY;AACjB,aAAO,EAAE,UAAU,SAAkB,cAAc,MAAM;AAAA,IAC3D;AAKA,QAAI;AACF,YAAM,KAAK,WAAW,sBAAsB;AAAA,IAC9C,SAAS,YAAY;AACnB,WAAK,WAAW;AAAA,QACd,gDAAgD,sBAAsB,QAAQ,WAAW,UAAU,eAAe;AAAA,MACpH;AAAA,IACF;AAEA,SAAK,oBAAoB;AAEzB,UAAM,UAAU,KAAK,eAAe,WAAW;AAC/C,SAAK,WAAW,UAAU,EAAE,MAAM,mBAAmB,MAAM,QAAQ,IAAI,QAAQ,CAAC;AAChF,SAAK,WAAW,gBAAgB,OAAO;AAEvC,WAAO,EAAE,UAAU,SAAkB,cAAc,MAAM;AAAA,EAC3D,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IACrF;AAAA,EACF;AACF;AAEA,eAAe,sBACb,MACA,OACqB;AACrB,QAAM,sBAAsB,IAAI,KAAK;AACrC,QAAM,YAAY,MAAM;AAOxB,OAAK,WAAW,WAAW,mBAAmB;AAC9C,OAAK,WAAW,UAAU;AAAA,IACxB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,CAAC;AAED,QAAM,gBAAgB,KAAK,WAAW,gBAAgB,SAAS;AAC/D,QAAM,iBAAiB,IAAI,QAAc,CAACC,aAAY;AACpD,eAAW,MAAMA,SAAQ,IAAI,GAAG,mBAAmB;AAAA,EACrD,CAAC;AAED,QAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,eAAe,cAAc,CAAC;AAClE,OAAK,WAAW,WAAW,SAAS;AAEpC,MAAI,CAAC,WAAW,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACjD,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SACE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,SAAS,cAAc,EAAE,WAAW,MAAM,WAAW,QAAQ,EAAE;AACpF;AAEA,IAAM,oBAAoB,oBAAI,IAAI,CAAC,QAAQ,QAAQ,MAAM,CAAC;AAE1D,SAAS,iBACP,SACA,UACA,OACwB;AACxB,MAAI,CAAC,kBAAkB,IAAI,QAAQ,EAAG,QAAO;AAE7C,MAAI,aAAa,QAAQ;AACvB,UAAM,WAAW,OAAO,MAAM,aAAa,EAAE;AAC7C,QAAI,SAAU,QAAO,QAAQ,eAAe,QAAQ;AAAA,EACtD;AAEA,MAAI,aAAa,UAAU,aAAa,QAAQ;AAC9C,UAAM,UAAU,OAAO,MAAM,WAAW,EAAE;AAC1C,QAAI,QAAS,QAAO,QAAQ,aAAa,OAAO;AAAA,EAClD;AAEA,SAAO;AACT;AAEA,IAAM,2BAA2B;AACjC,IAAM,8BAA8B;AAEpC,SAAS,uBAAuB,MAAiB,oBAAkC;AACjF,MAAI,uBAAuB,0BAA0B;AACnD,SAAK,WAAW;AAAA,MACd,2DAAiD,KAAK,SAAS;AAAA,IAGjE;AAAA,EACF;AACA,MAAI,sBAAsB,6BAA6B;AACrD,SAAK,WAAW;AAAA,MACd,6BAA6B,2BAA2B;AAAA,IAE1D;AACA,SAAK,YAAY;AAAA,EACnB;AACF;AAEA,SAAS,kBACP,MACA,UACA,OACY;AACZ,UAAQ,KAAK,WAAW;AAAA,IACtB,KAAK;AACH,aAAO,0BAA0B,UAAU,KAAK;AAAA,IAClD,KAAK;AACH,aAAO,yBAAyB,UAAU,KAAK;AAAA,IACjD,KAAK;AACH,aAAO,uBAAuB,UAAU,KAAK;AAAA,IAC/C,KAAK;AACH,aAAO,qBAAqB,UAAU,OAAO,KAAK,mBAAmB,KAAK,YAAY;AAAA,IACxF;AACE,aAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,EACpD;AACF;AAEO,SAAS,gBACd,MAC2E;AAC3E,MAAI,qBAAqB;AAEzB,SAAO,OAAO,UAAU,UAAU;AAChC,QACE,aAAa,mBACZ,KAAK,cAAc,UAAU,KAAK,cAAc,gBACjD,CAAC,KAAK,mBACN;AACA,aAAO,MAAM,mBAAmB,MAAM,KAAK;AAAA,IAC7C;AAIA,QAAI,aAAa,kBAAkB,KAAK,cAAc,eAAe,KAAK,mBAAmB;AAC3F,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SACE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,aAAa,mBAAmB;AAClC,aAAO,MAAM,sBAAsB,MAAM,KAAK;AAAA,IAChD;AAEA,UAAM,SAAS,kBAAkB,MAAM,UAAU,KAAK;AAItD,QAAI,OAAO,aAAa,WAAW,KAAK,sBAAsB,CAAC,KAAK,mBAAmB;AACrF,YAAM,SAAS,iBAAiB,KAAK,oBAAoB,UAAU,KAAK;AACxE,UAAI,QAAQ;AACV,aAAK,WAAW,gBAAgB,OAAO,OAAO;AAAA,MAChD;AAAA,IACF;AAEA,QAAI,OAAO,aAAa,QAAQ;AAC9B;AACA,6BAAuB,MAAM,kBAAkB;AAAA,IACjD,OAAO;AACL,2BAAqB;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AACF;;;ACnVA,IAAM,WAAW;AAEjB,IAAM,YAAY;AAElB,IAAM,gBACJ;AAEF,IAAM,oBAAoB;AAI1B,IAAM,SAAS;AAKf,IAAM,gBACJ;AAEF,IAAM,mBAAmB;AAGzB,IAAM,oBAAoB;AAK1B,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;AAI5B,IAAM,qBAAqB;AAOpB,SAAS,OAAO,OAA6B;AAClD,MAAI,CAAC,MAAO,QAAO,EAAE,QAAQ,OAAO,UAAU,EAAE;AAEhD,MAAI,QAAQ;AACZ,MAAI,SAAS;AAEb,WAAS,OAAO,QAAQ,oBAAoB,MAAM;AAChD;AACA,WAAO;AAAA,EACT,CAAC;AAED,WAAS,OAAO,QAAQ,WAAW,CAAC,QAAQ,WAAmB;AAC7D;AACA,WAAO,GAAG,MAAM,GAAG,QAAQ;AAAA,EAC7B,CAAC;AAED,WAAS,OAAO,QAAQ,eAAe,MAAM;AAC3C;AACA,WAAO;AAAA,EACT,CAAC;AAED,WAAS,OAAO,QAAQ,mBAAmB,MAAM;AAC/C;AACA,WAAO;AAAA,EACT,CAAC;AAED,WAAS,OAAO,QAAQ,QAAQ,MAAM;AACpC;AACA,WAAO;AAAA,EACT,CAAC;AAED,WAAS,OAAO;AAAA,IAAQ;AAAA,IAAoB,CAAC,SAC3C,KAAK,QAAQ,qBAAqB,CAAC,UAAU;AAI3C,UAAI,eAAe,KAAK,KAAK,EAAG,QAAO;AACvC;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,WAAS,OAAO,QAAQ,eAAe,CAAC,QAAQ,QAAgB,MAAc,WAAmB;AAC/F;AACA,WAAO,GAAG,MAAM,GAAG,QAAQ;AAAA,EAC7B,CAAC;AAED,WAAS,OAAO,QAAQ,kBAAkB,CAAC,QAAQ,WAAmB;AACpE;AACA,WAAO,GAAG,MAAM,GAAG,QAAQ;AAAA,EAC7B,CAAC;AAED,WAAS,OAAO,QAAQ,mBAAmB,CAAC,QAAQ,QAAgB,SAAiB;AACnF;AACA,WAAO,GAAG,MAAM,GAAG,IAAI,IAAI,QAAQ;AAAA,EACrC,CAAC;AAED,SAAO,EAAE,QAAQ,UAAU,MAAM;AACnC;;;A3BjFA,IAAMC,UAAS,oBAAoB,eAAe;AAClD,IAAMC,uBAAsB;AAC5B,IAAMC,mBAAkB,CAAC,KAAQ,MAAS,MAAS,GAAO;AAmC1D,SAAS,WAAW,MAA+C;AACjE,SAAO;AAAA,IACL,aAAa;AAAA,MACX;AAAA,QACE,OAAO;AAAA,UACL,OAAO,UAAwD;AAC7D,gBAAI,KAAK,UAAU,EAAG,QAAO,MAAM,QAAQ,QAAQ,EAAE,UAAU,MAAM,CAAC;AACtE,gBAAI,MAAM,oBAAoB,eAAe;AAC3C,oBAAM,MACJ,OAAO,MAAM,kBAAkB,WAC3B,MAAM,gBACN,KAAK,UAAU,MAAM,aAAa;AACxC,oBAAM,EAAE,QAAQ,UAAU,UAAU,cAAc,IAAI,OAAO,GAAG;AAChE,oBAAM,SAAS,SAAS,MAAM,GAAG,GAAG;AACpC,mBAAK,WAAW,UAAU;AAAA,gBACxB,MAAM;AAAA,gBACN,MAAM,MAAM;AAAA,gBACZ;AAAA,gBACA,SAAS;AAAA,gBACT,GAAI,gBAAgB,IAAI,EAAE,cAAc,IAAI,CAAC;AAAA,cAC/C,CAAC;AACD,mBAAK,mBAAmB,KAAK,EAAE,MAAM,MAAM,WAAW,OAAO,CAAC;AAG9D,kBAAI,MAAM,cAAc,sCAAsC;AAC5D,oBAAI;AACF,wBAAM,QAAQ,MAAM,KAAK,WAAW,kBAAkB;AACtD,wBAAM,UAAU,oBAAoB,KAAK;AACzC,sBAAI,QAAQ,SAAS,GAAG;AACtB,yBAAK,WAAW;AAAA,sBACd,wDAAwD,QAAQ,KAAK,IAAI,CAAC;AAAA,oBAC5E;AAAA,kBACF;AAAA,gBACF,QAAQ;AAAA,gBAER;AAAA,cACF;AAAA,YACF;AACA,mBAAO,MAAM,QAAQ,QAAQ,EAAE,UAAU,KAAK,CAAC;AAAA,UACjD;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAOA,SAAS,oBAAoB,YAA4B;AACvD,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK;AAEjE,SAAO,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,EAAE,CAAC;AACrH;AAYO,SAAS,kBACd,QACA,WACA,YACQ;AACR,SAAO,cAAc,YAAY,eAAe,gBAAgB,GAAG,MAAM,YAAY;AACvF;AAOA,SAAS,kBAAkB,aAAqB,KAAsB;AACpE,MAAI;AACF,WAAO,WAAW,sBAAsB,KAAK,WAAW,CAAC;AAAA,EAC3D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,uBACd,QACA,KACA,SACS;AACT,QAAM,MAAM,kBAAkB,QAAQ,QAAQ,WAAW,QAAQ,UAAU;AAC3E,SAAO,kBAAkB,oBAAoB,GAAG,GAAG,GAAG;AACxD;AAQO,SAAS,sBAAsBC,OAAuB;AAC3D,MAAI;AACF,QAAI,CAAC,WAAWA,KAAI,EAAG,QAAO;AAC9B,UAAM,UAAUC,cAAaD,OAAM,MAAM;AACzC,QAAI,QAAQ,WAAW,EAAG,QAAO;AAGjC,QAAI,UAAU,QAAQ;AACtB,QAAI,CAAC,QAAQ,SAAS,IAAI,GAAG;AAE3B,gBAAU,QAAQ,YAAY,IAAI,IAAI;AAAA,IACxC;AAGA,WAAO,UAAU,GAAG;AAClB,YAAM,cAAc,QAAQ,YAAY,MAAM,UAAU,CAAC;AACzD,YAAM,OAAO,QAAQ,MAAM,cAAc,GAAG,UAAU,CAAC,EAAE,KAAK;AAC9D,UAAI,KAAK,SAAS,GAAG;AACnB,YAAI;AACF,eAAK,MAAM,IAAI;AAEf;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,gBAAU,cAAc;AAAA,IAC1B;AAEA,QAAI,YAAY,QAAQ,OAAQ,QAAO;AACvC,iBAAaA,OAAM,OAAO,WAAW,QAAQ,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AACvE,IAAAH,QAAO,KAAK,0CAA0C;AAAA,MACpD,MAAAG;AAAA,MACA,cAAc,QAAQ,SAAS;AAAA,IACjC,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAwBO,SAAS,sBAAsB,QAAoD;AACxF,MAAI,OAAO,gBAAgB,MAAO,QAAO;AACzC,OAAK,OAAO,cAAc,YAAY,OAAQ,QAAO;AACrD,MAAI,OAAO,cAAc,OAAO,mBAAoB,QAAO;AAC3D,MAAI,OAAO,UAAU,OAAO,cAAc,OAAQ,QAAO;AACzD,SAAO;AACT;AAEA,SAAS,eAAe,MAAiB,mBAAqC;AAC5E,SAAO,SAAS,eAAe,SAAS,UAAW,SAAS,UAAU,CAAC;AACzE;AAEA,SAAS,qBACP,UACA,MACA,mBACsB;AACtB,QAAM,iBAAiB,eAAe,MAAM,iBAAiB,IACzD,CAAC,aAAa,YAAY,cAAc,IACxC,CAAC;AACL,QAAM,aAAa,SAAS,mBAAmB,CAAC;AAChD,QAAM,WAAW,CAAC,GAAG,YAAY,GAAG,cAAc;AAClD,SAAO,SAAS,SAAS,IAAI,WAAW;AAC1C;AAEA,SAAS,kBAAkB,MAAiB,SAA2C;AACrF,QAAM,WAAW,QAAQ,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AACxE,QAAM,OAAO,KAAK;AAMlB,QAAM,aAAa,eAAe,MAAM,KAAK,iBAAiB;AAC9D,QAAM,kBAAkB;AAExB,QAAM,mBAAmB;AAAA,IACvB,KAAK,OAAO;AAAA,IACZ;AAAA,IACA,EAAE,GAAG,KAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,IACtC,KAAK;AAAA,IACL;AAAA,EACF;AACA,QAAM,iBAAkB,SAAS,kBAAkB,CAAC,QAAQ,SAAS;AAMrE,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS,KAAK,OAAO;AAAA,IACpC,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ,oBAAoB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,KAAK,KAAK,OAAO;AAAA,IACjB,gBAAgB,kBAAkB,SAAS;AAAA,IAC3C,iCAAiC,CAAC;AAAA,IAClC,YAAY,gBAAgB,IAAI;AAAA,IAChC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,IACjE,YAAY;AAAA,MACV,UAAU,wBAAwB,KAAK,SAAS,KAAK,YAAY,KAAK,QAAQ,SAAS,IAAI;AAAA,IAC7F;AAAA,IACA,SAAS,QAAQ,aAAa,EAAE,SAAS,KAAK,IAAI,EAAE,SAAS,MAAM;AAAA,IACnE,OAAO,WAAW,IAAI;AAAA,IACtB,UAAU,SAAS;AAAA,IACnB,QAAQ,SAAS;AAAA,IACjB,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,cAAc,SAAS,gBAAgB;AAAA,IACvC,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,iBAAiB,qBAAqB,UAAU,MAAM,KAAK,iBAAiB;AAAA,IAC5E,yBAAyB,SAAS;AAAA,IAClC,QAAQ,CAAC,SAAiB;AACxB,MAAAH,QAAO,KAAK,sBAAsB,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AACF;AAMA,SAAS,sBACP,YACA,SACA,aAAa,OACe;AAC5B,MAAI,WAAY,QAAO;AAEvB,QAAM,cAAc,QAAQ,SAAS,CAAC,GAAG;AAAA,IACvC,CAAC,MAAM,EAAE,WAAW,EAAE,oBAAoB;AAAA,EAC5C;AACA,QAAM,aAAwE,CAAC;AAC/E,aAAW,OAAO,QAAQ,aAAa;AACrC,eAAW,KAAK,IAAI,SAAS,CAAC,GAAG;AAC/B,UAAI,EAAE,WAAW,EAAE,oBAAoB,UAAU;AAC/C,mBAAW,KAAK,EAAE,UAAU,EAAE,UAAU,UAAU,EAAE,UAAU,SAAS,EAAE,QAAQ,CAAC;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,KAAK,WAAW,WAAW,EAAG,QAAO;AAE/D,QAAM,SAA4B,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AACrE,aAAW,QAAQ,YAAY;AAC7B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,YAAY,KAAK;AAAA,QACjB,MAAM,KAAK,WAAW;AAAA,MACxB;AAAA,IACF,CAAC;AACD,WAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,KAAK,KAAK,QAAQ,KAAK,CAAC;AAAA,EAC7F;AACA,aAAW,QAAQ,YAAY;AAC7B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,UAAU,YAAY,KAAK,UAA4B,MAAM,KAAK,QAAQ;AAAA,IAC5F,CAAC;AACD,WAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,gBAAgB,KAAK,QAAQ,KAAK,KAAK,QAAQ,KAAK,CAAC;AAAA,EACzF;AACA,SAAO;AACT;AAIA,eAAe,oBACb,MACA,SACA,iBACqC;AACrC,QAAM,WAAW,KAAK,OAAO,SAAS;AACtC,QAAM,eACJ,OAAO,oBAAoB,WACvB,kBACA,gBACG,OAAO,CAAC,MAAuD,EAAE,SAAS,MAAM,EAChF,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AAElB,QAAM,iBACJ,OAAO,oBAAoB,WACvB,CAAC,IACD,gBAAgB;AAAA,IACd,CAAC,MAAwD,EAAE,SAAS;AAAA,EACtE;AAEN,QAAM,aAAa,WACf,GAAG,MAAM,mBAAmB,KAAK,OAAO,MAAM,SAAS,KAAK,QAAQ,KAAK,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAA8B,YAAY,KAC7H;AAEJ,MAAI,UAAU;AACZ,UAAM,SAAS,sBAAsB,YAAY,OAAO;AACxD,QAAI,eAAe,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;AACtD,aAAO,KAAK,GAAG,cAAc;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AACA,MAAI,eAAe,SAAS,GAAG;AAC7B,WAAO,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,GAAG,GAAG,cAAc;AAAA,EAC/D;AACA,SAAO;AACT;AAKA,gBAAgB,mBACd,OACA,SACoC;AACpC,MAAI,QAAQ;AACZ,mBAAiB,SAAS,OAAO;AAC/B,QAAI,CAAC,SAAS,MAAM,SAAS,UAAU;AACrC,cAAQ;AACR,YAAM,QAAQ;AAAA,IAChB;AACA,UAAM;AAAA,EACR;AACF;AAQA,IAAM,sBAAsB;AAQ5B,gBAAuB,kBACrB,OACA,MACoC;AACpC,MAAI,SAAS;AAIb,QAAM,QAAQ,WAAW,MAAM;AAC7B,aAAS;AACT,SAAK,WAAW,WAAW,mBAAmB;AAC9C,SAAK,KAAK,UAAU,eAAe,mBAAmB;AAAA,EACxD,GAAG,mBAAmB;AACtB,MAAI;AACF,qBAAiB,SAAS,OAAO;AAC/B,mBAAa,KAAK;AAClB,UAAI,QAAQ;AACV,iBAAS;AACT,aAAK,WAAW,WAAW,SAAS;AACpC,cAAM,KAAK,UAAU,eAAe,SAAS;AAAA,MAC/C;AACA,YAAM;AAAA,IACR;AAAA,EACF,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAEA,eAAsB,YACpB,MACA,SACA,iBACA,wBACe;AACf,MAAI,KAAK,UAAU,EAAG;AAEtB,QAAM,OAAO,KAAK;AAClB,QAAM,kBAAkB,SAAS,eAAe,SAAS;AACzD,QAAM,gBAAgB,mBAAoB,SAAS,UAAU,CAAC,KAAK;AACnE,MAAI,eAAe;AACjB,SAAK,kBAAkB;AAAA,EACzB;AAYA,QAAM,cAAc;AAAA,IAClB,kBAAkB,QAAQ,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EAC1D;AACA,QAAM,qBAAqB,kBAAkB,aAAa,KAAK,OAAO,YAAY;AAClF,MAAI,oBAAoB;AAGtB,0BAAsB,sBAAsB,KAAK,OAAO,cAAc,WAAW,CAAC;AAAA,EACpF;AACA,QAAM,iBACJ,0BACA,sBAAsB;AAAA,IACpB,aAAa,KAAK;AAAA,IAClB,YAAY,KAAK,OAAO;AAAA,IACxB,QAAQ,KAAK;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,CAAC;AAAA,IACd;AAAA,EACF,CAAC;AACH,QAAM,UAAU;AAAA,IACd,GAAG,kBAAkB,MAAM,OAAO;AAAA,IAClC;AAAA,IACA,GAAI,qBAAqB,CAAC,IAAI,EAAE,WAAW,YAAY;AAAA,EACzD;AACA,QAAM,SAAS,qBAAqB,cAAc;AAElD,MAAI,iBAAiB;AACnB,UAAM,SAAS,MAAM,oBAAoB,MAAM,SAAS,eAAe;AACvE,UAAM,aAAa,KAAK,QAAQ,aAAa;AAAA,MAC3C,QAAQ,OAAO,WAAW,WAAW,SAAS,KAAK,kBAAkB,MAAM;AAAA,MAC3E,SAAS,EAAE,GAAG,QAAQ;AAAA,MACtB;AAAA,IACF,CAAC;AACD,UAAM,YAAY,MAAM,SAAS,SAAS,UAAU;AAAA,EACtD,WAAW,mBAAmB,mBAAmB,WAAW;AAG1D;AAAA,EACF,OAAO;AACL,UAAM,gBAAgB,MAAM,SAAS,SAAS,QAAQ,cAAc;AAAA,EACtE;AAEA,MAAI,eAAe;AACjB,UAAM,KAAK,aAAa;AAAA,EAC1B;AACF;AAGA,eAAe,YACb,MACA,SACA,SACA,YACe;AAIf,MAAI,KAAK,gBAAgB,SAAS,QAAQ,mBAAmB,WAAW;AACtE,iBAAa,kBAAkB,YAAY,IAAI;AAAA,EACjD;AACA,OAAK,cAAc;AACnB,MAAI;AACF,UAAM,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,EACvD,UAAE;AACA,SAAK,cAAc;AAAA,EACrB;AACF;AAGA,eAAe,gBACb,MACA,SACA,SACA,QACA,gBACe;AACf,QAAM,gBAAgB,MAAM;AAAA,IAC1B,KAAK,OAAO;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,QAAM,SAAS,sBAAsB,eAAe,OAAO;AAC3D,MAAI,aAAa,KAAK,QAAQ,aAAa;AAAA,IACzC,QAAQ,KAAK,kBAAkB,MAAM;AAAA,IACrC,SAAS,EAAE,GAAG,QAAQ;AAAA,IACtB;AAAA,EACF,CAAC;AACD,MAAI,mBAAmB,WAAW;AAKhC,iBAAa,mBAAmB,YAAY,YAAY;AACtD,WAAK,WAAW,WAAW,SAAS;AACpC,YAAM,KAAK,UAAU,eAAe,SAAS;AAAA,IAC/C,CAAC;AAAA,EACH;AACA,QAAM,YAAY,MAAM,SAAS,SAAS,UAAU;AACtD;AAIA,eAAe,gBACb,MACA,SACA,SACA,mBAC6C;AAC7C,MAAI,mBAAmB;AACrB,SAAK,WAAW;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,KAAK,OAAO,MAAM,SAAS,KAAK,QAAQ,KAAK,SAAS;AAAA,IAC/E;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,QAAQ,aAAa;AAAA,IAC/B,QAAQ,KAAK,kBAAkB,WAAW;AAAA;AAAA;AAAA;AAAA,IAI1C,SAAS,EAAE,GAAG,SAAS,WAAW,OAAU;AAAA,IAC5C,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,eAAe,gBACb,SACA,MACA,SACe;AACf,OAAK,WAAW,gBAAgB,yDAAyD;AAEzF,QAAM,YAAY,MAAM,KAAK,WAAW,iBAAiB;AACzD,MAAI,CAAC,WAAW;AACd,SAAK,WAAW,gBAAgB,uDAAuD;AACvF,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AACD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,kBAAkB;AAC1B,OAAK,WAAW,eAAe,EAAE;AAEjC,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,KAAK,OAAO,MAAM,SAAS,KAAK,QAAQ,KAAK,SAAS;AAAA,IAC/E;AAAA,EACF;AACA,QAAM,aAAa,KAAK,QAAQ,aAAa;AAAA,IAC3C,QAAQ,KAAK,kBAAkB,WAAW;AAAA,IAC1C,SAAS,EAAE,GAAG,SAAS,WAAW,OAAU;AAAA,IAC5C,QAAQ;AAAA,EACV,CAAC;AACD,SAAO,aAAa,YAAY,SAAS,MAAM,OAAO;AACxD;AAEA,eAAe,mBACb,SACA,MACA,SACe;AACf,UAAQ,kBAAkB;AAC1B,OAAK,WAAW,eAAe,EAAE;AACjC,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,KAAK,OAAO,MAAM,SAAS,KAAK,QAAQ,KAAK,SAAS;AAAA,IAC/E;AAAA,EACF;AACA,QAAM,aAAa,KAAK,QAAQ,aAAa;AAAA,IAC3C,QAAQ,KAAK,kBAAkB,WAAW;AAAA,IAC1C,SAAS,EAAE,GAAG,SAAS,WAAW,OAAU;AAAA,IAC5C,QAAQ;AAAA,EACV,CAAC;AACD,SAAO,aAAa,YAAY,SAAS,MAAM,OAAO;AACxD;AAEA,eAAe,kBAAkB,MAAiB,SAAgC;AAChF,QAAM,IAAI,QAAc,CAACK,aAAY;AACnC,UAAM,QAAQ,WAAWA,UAAS,OAAO;AACzC,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,KAAK,UAAU,GAAG;AACpB,qBAAa,KAAK;AAClB,sBAAc,YAAY;AAC1B,QAAAA,SAAQ;AAAA,MACV;AAAA,IACF,GAAG,GAAI;AACP,eAAW,MAAM,cAAc,YAAY,GAAG,UAAU,GAAG;AAAA,EAC7D,CAAC;AACH;AAEA,SAAS,uBAAuB,OAAgB,SAA+B;AAC7E,MAAI,EAAE,iBAAiB,OAAQ,QAAO;AACtC,MAAI,MAAM,QAAQ,SAAS,uCAAuC,EAAG,QAAO;AAC5E,SAAO,CAAC,CAAC,QAAQ,mBAAmB,MAAM,QAAQ,SAAS,gBAAgB;AAC7E;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,iBAAiB,OAAyB;AACjD,QAAM,UAAU,gBAAgB,KAAK;AACrC,SAAO,kBAAkB,KAAK,OAAO,KAAKJ,qBAAoB,KAAK,OAAO;AAC5E;AAEA,SAAS,mBAAmB,OAAyB;AACnD,SAAOA,qBAAoB,KAAK,gBAAgB,KAAK,CAAC;AACxD;AAEA,eAAe,gBAAgB,MAAiB,SAAiB,SAAgC;AAC/F,QAAM,WAAW,KAAK,MAAM,UAAU,GAAM;AAC5C,OAAK,WAAW;AAAA,IACd,sCAAsC,QAAQ,UAAU,WAAW,IAAI,MAAM,EAAE,gBAAgB,UAAU,CAAC,IAAIC,iBAAgB,MAAM;AAAA,EACtI;AACA,OAAK,WAAW,UAAU;AAAA,IACxB,MAAM;AAAA,IACN,SAAS,0BAA0B,QAAQ,MAAM,UAAU,CAAC,IAAIA,iBAAgB,MAAM;AAAA,EACxF,CAAC;AACD,OAAK,WAAW,WAAW,mBAAmB;AAC9C,QAAM,KAAK,UAAU,eAAe,mBAAmB;AAEvD,QAAM,kBAAkB,MAAM,OAAO;AAErC,OAAK,WAAW,WAAW,SAAS;AACpC,QAAM,KAAK,UAAU,eAAe,SAAS;AAC/C;AAEA,SAAS,qBAAqB,MAAiB,mBAAiC;AAC9E,OAAK,iBAAiB;AACtB,OAAK,WAAW,mBAAmB,iBAAiB;AACpD,OAAK,WAAW;AAAA,IACd,2EAA2E,IAAI,KAAK,iBAAiB,EAAE,eAAe,CAAC;AAAA,EACzH;AACF;AAIA,SAAS,iBACP,OACA,SACA,MACA,SACA,gBAC8B;AAC9B,MAAI,uBAAuB,OAAO,OAAO,KAAK,QAAQ,iBAAiB;AACrE,WAAO,mBAAmB,SAAS,MAAM,OAAO;AAAA,EAClD;AACA,MAAII,aAAY,gBAAgB,KAAK,CAAC,GAAG;AACvC,WAAO,gBAAgB,SAAS,MAAM,OAAO;AAAA,EAC/C;AACA,MAAI,CAAC,iBAAiB,KAAK,EAAG,OAAM;AACpC,SAAO,EAAE,QAAQ,YAAY,mBAAmB,mBAAmB,KAAK,KAAK,eAAe;AAC9F;AAOA,SAAS,oBACP,QACA,SACA,MACA,SACe;AACf,MAAI,OAAO,eAAe,KAAK,UAAU,EAAG,QAAO,EAAE,QAAQ,SAAS;AAEtE,MAAI,OAAO,mBAAmB;AAC5B,yBAAqB,MAAM,OAAO,iBAAiB;AACnD,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B;AAGA,MAAI,OAAO,gBAAgB,QAAQ,iBAAiB;AAClD,WAAO,EAAE,QAAQ,kBAAkB,SAAS,mBAAmB,SAAS,MAAM,OAAO,EAAE;AAAA,EACzF;AAGA,MAAI,OAAO,WAAW;AACpB,WAAO,EAAE,QAAQ,kBAAkB,SAAS,gBAAgB,SAAS,MAAM,OAAO,EAAE;AAAA,EACtF;AAEA,MAAI,CAAC,OAAO,UAAW,QAAO,EAAE,QAAQ,SAAS;AACjD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,mBAAmBL,qBAAoB,KAAK,OAAO,iBAAiB,EAAE;AAAA,EACxE;AACF;AAEA,eAAe,aACb,cACA,SACA,MACA,SACe;AACf,MAAI,oBAAoB;AAExB,WAAS,UAAU,GAAG,WAAWC,iBAAgB,QAAQ,WAAW;AAClE,QAAI,KAAK,UAAU,EAAG;AAEtB,UAAM,aACJ,YAAY,IACR,eACA,MAAM,gBAAgB,MAAM,SAAS,SAAS,iBAAiB;AAErE,QAAI;AACF,YAAM,SAAS,MAAM,cAAc,YAAY,SAAS,IAAI;AAC5D,YAAM,UAAU,oBAAoB,QAAQ,SAAS,MAAM,OAAO;AAClE,UAAI,QAAQ,WAAW,SAAU;AACjC,UAAI,QAAQ,WAAW,iBAAkB,QAAO,QAAQ;AACxD,0BAAoB,QAAQ;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,OAAO,SAAS,MAAM,SAAS,iBAAiB;AACjF,UAAI,mBAAmB,QAAS,QAAO;AACvC,UAAI,QAAQ,WAAW,SAAU;AACjC,0BAAoB,QAAQ;AAAA,IAC9B;AAEA,QAAI,WAAWA,iBAAgB,QAAQ;AACrC,WAAK,WAAW;AAAA,QACd,6BAA6BA,iBAAgB,MAAM;AAAA,MAErD;AACA;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,SAASA,iBAAgB,OAAO,CAAC;AAAA,EAC/D;AACF;;;A4B5yBO,IAAM,cAAN,MAAkB;AAAA,EACf,oBAAoB;AAAA,EACpB,aAAa,oBAAI,IAA6B;AAAA,EAC9C,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,KAAK,cAAsB,YAAqC;AAC9D,QAAI,KAAK,OAAQ;AACjB,QAAI,KAAK,oBAAoB,KAAK,KAAK,WAAW,OAAO,EAAG;AAC5D,SAAK,oBAAoB;AACzB,eAAW,SAAS,YAAY;AAC9B,WAAK,WAAW,IAAI,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC;AAAA,IAC/C;AACA,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,aAAa,cAA8B;AACzC,SAAK,qBAAqB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,cACE,OAUM;AACN,eAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,YAAM,WAAW,KAAK,WAAW,IAAI,KAAK,KAAK;AAAA,QAC7C;AAAA,QACA,aAAa;AAAA,QACb,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,0BAA0B;AAAA,QAC1B,SAAS;AAAA,MACX;AACA,eAAS,eAAe,KAAK,eAAe;AAC5C,eAAS,gBAAgB,KAAK,gBAAgB;AAC9C,eAAS,wBAAwB,KAAK,wBAAwB;AAC9D,eAAS,4BAA4B,KAAK,4BAA4B;AACtE,eAAS,WAAW,KAAK,WAAW;AACpC,WAAK,WAAW,IAAI,OAAO,QAAQ;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,IAAI,eAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,iBAAoC;AACtC,WAAO,CAAC,GAAG,KAAK,WAAW,OAAO,CAAC;AAAA,EACrC;AACF;;;ACzDA,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAC7B,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAC/B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAE3B,SAAS,cAAc,UAA0B;AAE/C,MAAI,aAAa,SAAS,QAAQ,SAAS,EAAE;AAE7C,eAAa,WAAW,QAAQ,QAAQ,GAAG;AAC3C,SAAO;AACT;AAEO,IAAM,qBAAN,MAAyB;AAAA,EACtB,iBAAiB,oBAAI,IAAoB;AAAA,EACzC,eAAe,oBAAI,IAAoB;AAAA,EACvC,aAAa;AAAA,EACb,sBAAsC;AAAA,EAC7B;AAAA,EAEjB,YAAY,cAAuB;AACjC,SAAK,uBAAuB,eAAe,MAAM;AAAA,EACnD;AAAA;AAAA,EAGA,eAAe,UAA0C;AACvD,UAAM,aAAa,cAAc,QAAQ;AACzC,UAAM,SAAS,KAAK,eAAe,IAAI,UAAU,KAAK,KAAK;AAC3D,SAAK,eAAe,IAAI,YAAY,KAAK;AACzC,SAAK;AAGL,WAAO,KAAK,sBAAsB,YAAY,KAAK,KAAK,KAAK,sBAAsB;AAAA,EACrF;AAAA;AAAA,EAGA,aAAa,SAAyC;AACpD,UAAM,SAAS,KAAK,aAAa,IAAI,OAAO,KAAK,KAAK;AACtD,SAAK,aAAa,IAAI,SAAS,KAAK;AAEpC,WAAO,KAAK,wBAAwB,SAAS,KAAK;AAAA,EACpD;AAAA,EAEQ,gBAAgB,MAAsB;AAC5C,WAAO,KAAK,KAAK,OAAO,KAAK,oBAAoB;AAAA,EACnD;AAAA,EAEQ,sBAAsB,UAAkB,OAAuC;AACrF,UAAM,KAAK,KAAK,gBAAgB,oBAAoB;AACpD,UAAM,KAAK,KAAK,gBAAgB,oBAAoB;AAEpD,QAAI,SAAS,MAAM,KAAK,sBAAsB,GAAG;AAC/C,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,kDAAwC,QAAQ,KAAK,KAAK;AAAA,MAG9D;AAAA,IACF;AAEA,QAAI,SAAS,MAAM,KAAK,sBAAsB,GAAG;AAC/C,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,kCAAkC,QAAQ,KAAK,KAAK;AAAA,MAGxD;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,SAAiB,OAAuC;AACtF,UAAM,KAAK,KAAK,gBAAgB,sBAAsB;AACtD,UAAM,KAAK,KAAK,gBAAgB,sBAAsB;AAGtD,UAAM,iBAAiB,QAAQ,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,QAAQ;AAE5E,QAAI,SAAS,MAAM,KAAK,sBAAsB,GAAG;AAC/C,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,0DAAgD,cAAc,KAAK,KAAK;AAAA,MAG5E;AAAA,IACF;AAEA,QAAI,SAAS,MAAM,KAAK,sBAAsB,GAAG;AAC/C,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,0CAA0C,cAAc,KAAK,KAAK;AAAA,MAEtE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAgD;AACtD,UAAM,cAAc,KAAK,eAAe;AACxC,UAAM,QAAQ,KAAK,aAAa,IAAI,cAAc,KAAK,aAAa;AAEpE,UAAM,aAAa,KAAK,gBAAgB,kBAAkB;AAC1D,QACE,KAAK,cAAc,cACnB,QAAQ,sBACR,KAAK,sBAAsB,GAC3B;AACA,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,0CAAgC,KAAK,MAAM,QAAQ,GAAG,CAAC,aAAa,KAAK,UAAU;AAAA,MAEvF;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,gBAAgB,kBAAkB;AAC1D,QACE,KAAK,cAAc,cACnB,QAAQ,sBACR,KAAK,sBAAsB,GAC3B;AACA,WAAK,sBAAsB;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SACE,qBAAqB,KAAK,MAAM,QAAQ,GAAG,CAAC,aAAa,KAAK,UAAU;AAAA,MAE5E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AC1IA,IAAMK,UAAS,oBAAoB,aAAa;AAazC,SAAS,qBAAkC;AAChD,SAAO,QAAQ,IAAI,qBAAqB,QAAQ,QAAQ;AAC1D;AAMA,SAAS,eAAe,YAAwC;AAC9D,SAAO;AAAA,IACL,YAAY,CAAC,MAAM,SAAS,WAAW,cAAc,MAAM,IAAI;AAAA,IAC/D,SAAS,CAAC,YAAY,WAAW,WAAW,OAAO;AAAA,IACnD,UAAU,CAAC,YAAY,WAAW,YAAY,OAAO;AAAA,EACvD;AACF;AAEO,IAAM,cAAN,MAAkB;AAAA,EAoBvB,YACmB,YACA,MACA,cACA,WACjB,cACA;AALiB;AACA;AACA;AACA;AAGjB,UAAM,cAAc,mBAAmB;AACvC,SAAK,cAAc;AACnB,SAAK,UAAU;AAAA,MACb;AAAA,MACA,gBAAgB,QAAQ,eAAe,UAAU,IAAI;AAAA,IACvD;AACA,SAAK,cAAc,IAAI,YAAY;AACnC,SAAK,WAAW,IAAI,SAAS,cAAc,UAAU;AAAA,EACvD;AAAA,EAdmB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAvBF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa,oBAAI,IAAoB;AAAA,EAC9C,cAAyD;AAAA,EAChD,qBAAyD,CAAC;AAAA,EACnE,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,mBAA2C;AAAA;AAAA,EAGnD;AAAA;AAAA,EAGA;AAAA,EAmBA,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,uBAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,qBAAqB,KAAc;AACrC,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEA,IAAI,eAAwB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,aAAa,KAAc;AAC7B,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,IAAI,iBAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAa;AACX,SAAK,WAAW;AAChB,SAAK,kBAAkB,MAAM;AAAA,EAC/B;AAAA,EAEA,SAAe;AACb,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA,EAGA,gBAAgB,cAAsB,YAAqC;AACzE,SAAK,YAAY,KAAK,cAAc,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,sBAAsB,SAA4C;AAChE,WAAO,sBAAsB;AAAA,MAC3B,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK,aAAa;AAAA,MAC9B,QAAQ,KAAK,KAAK;AAAA,MAClB,WAAW,KAAK,KAAK;AAAA,MACrB,YAAY;AAAA,MACZ,oBAAoB,uBAAuB,QAAQ,QAAQ,KAAK,aAAa,cAAc;AAAA,QACzF,WAAW,KAAK,KAAK;AAAA,QACrB,YAAY,KAAK,aAAa;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QACJ,SACA,iBACA,gBACe;AACf,SAAK,WAAW;AAChB,SAAK,kBAAkB;AACvB,SAAK,mBAAmB,IAAI,gBAAgB;AAC5C,UAAM,OAAO,KAAK,UAAU;AAC5B,QAAI;AACF,YAAM,YAAY,MAAM,SAAS,iBAAiB,cAAc;AAAA,IAClE,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM,UAAU,KAAK,YAAY,SAAS,KAAK,GAAG;AAClD,UAAI,SAAS;AACX,QAAAA,QAAO,KAAK,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,MACrD,OAAO;AACL,QAAAA,QAAO,MAAM,0BAA0B,EAAE,OAAO,IAAI,CAAC;AACrD,aAAK,WAAW,UAAU,EAAE,MAAM,SAAS,SAAS,IAAI,CAAC;AAAA,MAC3D;AAAA,IACF,UAAE;AACA,WAAK,KAAK,qBAAqB;AAC/B,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA,EAIQ,YAAuB;AAE7B,UAAM,SAAS;AACf,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,UAAU,CAAC;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,oBACE,OAAO,KAAK,kBAAkB,eAC7B,OAAO,KAAK,kBAAkB,UAAU,CAAC,OAAO,KAAK,oBAClD,IAAI,mBAAmB,OAAO,aAAa,IAC3C;AAAA,MACN,YAAY,KAAK;AAAA,MACjB,oBAAoB,KAAK;AAAA;AAAA,MAGzB,IAAI,YAAY;AACd,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA,IAAI,SAAS;AACX,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA,IAAI,eAAe;AACjB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,IAAI,oBAAoB;AACtB,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA,IAAI,kBAAkB,KAAc;AAClC,eAAO,KAAK,oBAAoB;AAAA,MAClC;AAAA,MACA,IAAI,qBAAqB;AACvB,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA,IAAI,mBAAmB,KAAc;AACnC,eAAO,KAAK,qBAAqB;AAAA,MACnC;AAAA,MACA,IAAI,qBAAqB;AACvB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,IAAI,mBAAmB,KAAc;AACnC,eAAO,sBAAsB;AAAA,MAC/B;AAAA,MACA,IAAI,iBAAiB;AACnB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,IAAI,eAAe,KAAc;AAC/B,eAAO,kBAAkB;AAAA,MAC3B;AAAA,MACA,IAAI,cAAc;AAChB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,IAAI,YAAY,KAAgD;AAC9D,eAAO,cAAc;AAAA,MACvB;AAAA,MACA,IAAI,kBAAkB;AACpB,eAAO,OAAO;AAAA,MAChB;AAAA,MAEA,WAAW,MAAM,OAAO;AAAA,MACxB,aAAa,MAAM,OAAO,KAAK;AAAA,MAC/B,iBAAiB,MAAM;AACrB,YAAI,OAAO,WAAY,QAAO,WAAW;AAAA,MAC3C;AAAA,MACA,mBAAmB,CAAC,WAAW,OAAO,kBAAkB,MAAM;AAAA,MAC9D,mBAAmB,MAAM,OAAO,SAAS,kBAAkB;AAAA,MAC3D,cAAc,MAAM,OAAO,SAAS,aAAa;AAAA,MACjD,kBAAkB,OAAO;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAIA,OAAe,kBACb,QACmD;AACnD,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,EAAE,MAAM,QAAiB,SAAS,OAAO;AAAA,MAClD,oBAAoB;AAAA,IACtB;AAAA,EACF;AACF;;;ACjRA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,SAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;AAGvB,SAAS,eACd,UACe;AACf,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,SAAO,SAAS,IAAI,CAAC,OAAO;AAAA,IAC1B,IAAI,EAAE;AAAA,IACN,MAAO,EAAE,QAAQ;AAAA,IACjB,SAAS,EAAE,WAAW;AAAA,IACtB,QAAQ,EAAE;AAAA,IACV,UAAU,EAAE,MAAM,QAAQ;AAAA,IAC1B,WAAW,EAAE;AAAA,IACb,GAAI,EAAE,SAAS,EAAE,MAAM,SAAS,IAC5B;AAAA,MACE,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO;AAAA,QACzB,QAAQ,EAAE;AAAA,QACV,UAAU,EAAE;AAAA,QACZ,UAAU,EAAE;AAAA,QACZ,UAAU,EAAE;AAAA,QACZ,aAAa,EAAE,eAAe;AAAA,QAC9B,SAAS,EAAE;AAAA,QACX,iBAAiB,EAAE;AAAA,MACrB,EAAE;AAAA,IACJ,IACA,CAAC;AAAA,EACP,EAAE;AACJ;AAGO,SAAS,mBAAkC;AAChD,MAAI;AACF,UAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAEnD,eAAW,OAAO,CAAC,mBAAmB,oBAAoB,GAAG;AAC3D,UAAI;AACF,cAAM,MAAM,KAAK,MAAMD,cAAaC,MAAK,MAAM,GAAG,GAAG,OAAO,CAAC;AAC7D,YAAI,IAAI,QAAS,QAAO,IAAI;AAAA,MAC9B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;ACjDA,SAAS,YAAAC,iBAAgB;AAYlB,SAAS,iBAAiB,SAAiB,QAAsB;AACtE,MAAI,CAAC,OAAQ;AAEb,QAAM,UAAU,iBAAiB,OAAO;AACxC,MAAI,YAAY,QAAQ;AACtB,YAAQ,OAAO;AAAA,MACb,8DAAyD,WAAW,YAAY,OAAO,MAAM;AAAA;AAAA,IAC/F;AACA;AAAA,EACF;AAEA,MAAI,sBAAsB,OAAO,GAAG;AAClC,YAAQ,OAAO;AAAA,MACb,sEAAiE,MAAM;AAAA;AAAA,IACzE;AACA;AAAA,EACF;AAEA,MAAI;AACF,IAAAC,UAAS,oBAAoB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,UAAU,SAAS,IAAO,CAAC;AAAA,EAC3F,QAAQ;AACN,YAAQ,OAAO,MAAM,kDAAkD,MAAM;AAAA,CAAI;AACjF;AAAA,EACF;AAEA,MAAI;AACF,IAAAA,UAAS,6BAA6B,MAAM,IAAI;AAAA,MAC9C,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AACD,YAAQ,OAAO,MAAM,+CAA+C,MAAM;AAAA,CAAI;AAAA,EAChF,QAAQ;AACN,YAAQ,OAAO;AAAA,MACb,yDAAyD,MAAM;AAAA;AAAA,IACjE;AAAA,EACF;AACF;;;ACRO,IAAM,gBAAN,MAAM,eAAc;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA,EACT,SAA4B;AAAA,EAC5B,UAAU;AAAA,EACV,cAAc;AAAA;AAAA;AAAA,EAGd,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,kBAAiC;AAAA,EAEjC,cAAsC;AAAA,EACtC,cAAkC;AAAA,EAClC,cAAkC;AAAA,EAClC,gBAAgE;AAAA,EAChE,kBAAqC,CAAC;AAAA,EACtC,eAAe;AAAA;AAAA,EAEf,wBAAwB;AAAA,EAEhC,YAAY,QAA6B,WAAmC;AAC1E,SAAK,SAAS;AACd,SAAK,YAAY;AAGjB,SAAK,aAAa,IAAI,gBAAgB,OAAO,UAAU;AAEvD,UAAM,cACJ,OAAO,cACN,OAAO,eAAe,OAAQ,OAAO,SAAS,SAAS,cAAe;AACzE,SAAK,OAAO,IAAI,eAAe,aAAa,OAAO,YAAY,OAAO,MAAM;AAE5E,UAAM,kBAAkB,EAAE,GAAG,0BAA0B,GAAG,OAAO,UAAU;AAC3E,SAAK,YAAY,IAAI,UAAU,iBAAiB;AAAA,MAC9C,aAAa,MAAM,KAAK,WAAW,cAAc;AAAA,MACjD,eAAe,MAAM;AACnB,gBAAQ,OAAO,MAAM,yDAAyD;AAC9E,aAAK,UAAU;AAGf,aAAK,aAAa,KAAK;AACvB,YAAI,KAAK,eAAe;AACtB,gBAAM,WAAW,KAAK;AACtB,eAAK,gBAAgB;AACrB,mBAAS,IAAI;AAAA,QACf;AAAA,MACF;AAAA,MACA,kBAAkB,MAAM;AACtB,gBAAQ,OAAO,MAAM,gEAAgE;AACrF,aAAK,UAAU;AACf,aAAK,aAAa,KAAK;AACvB,YAAI,KAAK,eAAe;AACtB,gBAAM,WAAW,KAAK;AACtB,eAAK,gBAAgB;AACrB,mBAAS,IAAI;AAAA,QACf;AAAA,MACF;AAAA,MACA,gBAAgB,MAAM,KAAK,KAAK,mBAAmB;AAAA,MACnD,YAAY,MAAM,KAAK,KAAK,iBAAiB;AAAA,IAC/C,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,QAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAyB;AAC7B,UAAM,KAAK,SAAS,YAAY;AAGhC,UAAM,KAAK,WAAW,QAAQ;AAC9B,UAAM,KAAK,SAAS,WAAW;AAC/B,SAAK,WAAW,UAAU,EAAE,MAAM,aAAa,WAAW,KAAK,UAAU,CAAC;AAG1E,SAAK,wBAAwB;AAC7B,SAAK,UAAU,eAAe;AAC9B,SAAK,UAAU,kBAAkB;AACjC,SAAK,UAAU,cAAc;AAG7B,UAAM,EAAE,iBAAiB,eAAe,IAAI,MAAM,KAAK,WAAW,KAAK,gBAAgB;AAAA,MACrF,WAAW,KAAK;AAAA,IAClB,CAAC;AACD,eAAW,OAAO,gBAAgB;AAChC,UAAI,IAAI,SAAS;AACf,aAAK,gBAAgB,KAAK,EAAE,SAAS,IAAI,SAAS,QAAQ,IAAI,OAAO,CAAC;AAAA,MACxE;AAAA,IACF;AAMA,UAAM,eAAe,iBAAiB;AACtC,QAAI,cAAc;AAChB,WAAK,WACF,KAAK,sBAAsB,EAAE,WAAW,KAAK,WAAW,aAAa,CAAC,EACtE,MAAM,MAAM;AAAA,MAEb,CAAC;AAAA,IACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAqB;AAEzB,UAAM,KAAK,SAAS,kBAAkB;AACtC,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,WAAW,KAAK,kBAAkB;AAAA,QACvD,WAAW,KAAK;AAAA,QAChB,gBAAgB;AAAA,MAClB,CAAC;AACD,WAAK,cAAc,KAAK,iBAAiB,GAAG;AAC5C,WAAK,cAAc;AAAA,QACjB,QAAQ,IAAI;AAAA,QACZ,MAAM,IAAI;AAAA,QACV,cACE,IAAI,gBAAgB,QAAQ,IAAI,gBAAgB,SAC5C,OACA,OAAO,IAAI,WAAW;AAAA,QAC5B,OAAO,IAAI;AAAA,QACX,aAAa,IAAI;AAAA,QACjB,cAAc,KAAK,YAAY;AAAA,MACjC;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,WAAW,UAAU,EAAE,MAAM,SAAS,QAAQ,CAAC;AACpD,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,QAAQ,CAAC;AACvD,YAAM,KAAK,SAAS,OAAO;AAC3B;AAAA,IACF;AAKA,QAAI,QAAQ,IAAI,uBAAuB,KAAK;AAC1C,UAAI,KAAK,aAAa,cAAc;AAClC,2BAAmB,KAAK,OAAO,cAAc,KAAK,YAAY,YAAY;AAAA,MAC5E;AACA,UAAI,KAAK,aAAa,YAAY;AAChC,2BAAmB,KAAK,OAAO,cAAc,KAAK,YAAY,UAAU;AAAA,MAC1E;AAAA,IACF;AAKA,QAAI,KAAK,aAAa,cAAc;AAClC,YAAM,WAAW,mBAAmB,KAAK,OAAO,cAAc,KAAK,YAAY,YAAY;AAC3F,UAAI,aAAa,QAAQ;AACvB,gBAAQ,OAAO,MAAM,0CAA0C,QAAQ;AAAA,CAAI;AAAA,MAC7E;AAAA,IACF;AAGA,SAAK,KAAK,gBAAgB,KAAK,aAAa,WAAW,KAAK,aAAa,MAAM;AAC/E,SAAK,KAAK,mBAAmB,KAAK,WAAW;AAK7C,QACE,KAAK,aAAa,UAClB,KAAK,YAAY,WAAW,UAC5B,KAAK,KAAK,gBACV;AACA,WAAK,KAAK,WAAW,sBAAsB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC7D;AAGA,SAAK,cAAc,KAAK,kBAAkB;AAM1C,UAAM,KAAK,0BAA0B;AAGrC,SAAK,kBAAkB;AAGvB,UAAM,oBAAoB,KAAK,gBAAgB;AAC/C,UAAM,yBAAyB,MAAM,KAAK,mBAAmB;AAS7D,QAAI,oBAAoB,KAAK,wBAAwB;AACnD,WAAK,gBAAgB,OAAO,GAAG,iBAAiB;AAAA,IAClD;AAMA,QAAI,KAAK,aAAa,sBAAsB;AAC1C,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AACA,WAAK,YAAY,uBAAuB;AAAA,IAC1C;AAIA,QAAI,CAAC,KAAK,WAAW,KAAK,gBAAgB,WAAW,GAAG;AACtD,YAAM,KAAK,iBAAiB;AAAA,IAC9B;AAGA,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,OAAO;AAAA,QACb,kDAAkD,KAAK,KAAK,aAAa;AAAA;AAAA,MAC3E;AAAA,IACF;AACA,WAAO,CAAC,KAAK,SAAS;AACpB,UAAI,KAAK,WAAW,OAAQ,OAAM,KAAK,SAAS,MAAM;AACtD,YAAM,KAAK,SAAS;AAAA,IACtB;AAGA,UAAM,KAAK,SAAS,UAAU;AAAA,EAChC;AAAA;AAAA,EAGA,MAAM,QAAuB;AAC3B,UAAM,KAAK,QAAQ;AACnB,UAAM,KAAK,IAAI;AAAA,EACjB;AAAA;AAAA;AAAA,EAKA,MAAc,WAA0B;AACtC,WAAO,CAAC,KAAK,SAAS;AAKpB,UAAI,KAAK,mBAAmB;AAC1B,cAAM,UAAU,MAAM,KAAK,kBAAkB;AAC7C,YAAI,CAAC,QAAS;AACd;AAAA,MACF;AACA,UAAI,KAAK,WAAW,QAAQ;AAC1B,aAAK,UAAU,eAAe;AAC9B,cAAM,MAAM,MAAM,KAAK,eAAe;AACtC,aAAK,UAAU,gBAAgB;AAE/B,YAAI,CAAC,KAAK;AACR,cAAI,KAAK,eAAe,CAAC,KAAK,SAAS;AACrC,iBAAK,cAAc;AACnB;AAAA,UACF;AACA;AAAA,QACF;AAEA,cAAM,KAAK,SAAS,SAAS;AAC7B,aAAK,cAAc;AACnB,cAAM,KAAK,UAAU,QAAQ;AAAA,UAC3B,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,QAAQ,IAAI;AAAA,QACd,CAAC;AAGD,cAAM,KAAK,aAAa,IAAI,OAAO;AAInC,YAAI,KAAK,aAAa,sBAAsB;AAC1C,kBAAQ,OAAO;AAAA,YACb;AAAA,UACF;AACA,eAAK,gBAAgB,SAAS;AAC9B,cAAI,KAAK,WAAW,OAAQ,OAAM,KAAK,SAAS,MAAM;AACtD,gBAAM,eAAe,MAAM,KAAK,eAAe;AAC/C,cAAI,CAAC,aAAc;AACnB,kBAAQ,OAAO;AAAA,YACb;AAAA,UACF;AACA,eAAK,YAAY,uBAAuB;AACxC,eAAK,oBAAoB;AACzB,eAAK,gBAAgB,QAAQ,YAAY;AACzC;AAAA,QACF;AAEA,YAAI,KAAK,QAAS;AAClB,YAAI,KAAK,aAAa;AACpB,eAAK,cAAc;AACnB;AAAA,QACF;AAIA,YAAI,CAAC,KAAK,WAAW,KAAK,gBAAgB,WAAW,GAAG;AACtD,gBAAM,KAAK,iBAAiB;AAAA,QAC9B;AACA,YAAI,CAAC,KAAK,QAAS,OAAM,KAAK,SAAS,MAAM;AAAA,MAC/C,WAAW,KAAK,WAAW,SAAS;AAClC,cAAM,KAAK,SAAS,MAAM;AAAA,MAC5B,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,oBAAsC;AAClD,QAAI,KAAK,oBAAoB,MAAM;AACjC,WAAK,kBAAkB,KAAK,IAAI,IAAI,KAAK,UAAU,OAAO;AAC1D,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AAAA,IACF;AACA,SAAK,gBAAgB,SAAS;AAC9B,QAAI,KAAK,WAAW,OAAQ,OAAM,KAAK,SAAS,MAAM;AACtD,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACjE,SAAK,UAAU,kBAAkB,WAAW;AAC5C,UAAM,aAAa,MAAM,KAAK,eAAe;AAC7C,SAAK,UAAU,mBAAmB;AAClC,QAAI,CAAC,WAAY,QAAO;AACxB,UAAM,iBACJ,WAAW,QAAQ,SAAS,KAAK,GAAG,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC,QAAQ,WAAW;AACxF,YAAQ,OAAO;AAAA,MACb,qEACY,WAAW,MAAM,YAAY,WAAW,UAAU,SAAS,cACzD,eAAe,QAAQ,OAAO,KAAK,CAAC;AAAA;AAAA,IACpD;AACA,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB,QAAQ,UAAU;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAKA,MAAc,qBAAuC;AACnD,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,YAAa,QAAO;AACnD,UAAM,gBAAgB,KAAK,KAAK;AAMhC,UAAM,WACJ,KAAK,gBAAgB,SAAS,IAC1B,WACC,KAAK,aAAa,sBAAsB,KAAK,WAAW,KAAK;AAMpE,UAAM,YACJ,kBAAkB,cAClB,kBAAkB,UAClB,kBAAkB,YAClB,aAAa;AAEf,QAAI,CAAC,WAAW;AACd,YAAM,KAAK,SAAS,MAAM;AAC1B,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,WAAW;AAK1B,YAAM,KAAK,SAAS,mBAAmB;AACvC,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,gBAAgB,MAAM,eAAe,SAAS,CAAC;AAGpF,UAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,YAAI,CAAC,KAAK,QAAS,OAAM,KAAK,SAAS,MAAM;AAC7C,eAAO;AAAA,MACT;AACA,WAAK,UAAU,eAAe;AAC9B,UAAI;AACF,cAAM,KAAK,aAAa,QAAW,QAAQ;AAAA,MAC7C,UAAE;AACA,aAAK,UAAU,gBAAgB;AAAA,MACjC;AAAA,IACF,OAAO;AACL,YAAM,KAAK,SAAS,SAAS;AAC7B,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,gBAAgB,MAAM,cAAc,CAAC;AAC1E,YAAM,KAAK,aAAa,QAAW,QAAQ;AAAA,IAC7C;AACA,QAAI,CAAC,KAAK,QAAS,OAAM,KAAK,SAAS,MAAM;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,iBAAkD;AACxD,QAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,aAAO,QAAQ,QAAQ,KAAK,gBAAgB,MAAM,KAAK,IAAI;AAAA,IAC7D;AACA,WAAO,IAAI,QAAgC,CAACC,aAAY;AACtD,WAAK,gBAAgBA;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,cAAc,KAA4B;AACxC,QAAI,KAAK,eAAe;AACtB,YAAMA,WAAU,KAAK;AACrB,WAAK,gBAAgB;AACrB,MAAAA,SAAQ,GAAG;AAAA,IACb,OAAO;AACL,WAAK,gBAAgB,KAAK,GAAG;AAI7B,UAAI,KAAK,WAAW,aAAa,KAAK,WAAW,qBAAqB;AACpE,aAAK,aAAa,KAAK;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAc,aACZ,iBACA,gBACe;AACf,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,YAAa;AAC5C,QAAI;AACF,YAAM,KAAK,YAAY,QAAQ,KAAK,aAAa,iBAAiB,cAAc;AAAA,IAClF,SAAS,KAAK;AACZ,UAAI,KAAK,eAAe,KAAK,SAAS;AACpC,gBAAQ,OAAO,MAAM,0DAA0D;AAC/E;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,mBAAkC;AAC9C,QAAI,KAAK,yBAAyB,KAAK,QAAS;AAChD,SAAK,wBAAwB;AAC7B,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,KAAK,OAAO,cAAc;AAAA,QACjE,YAAY;AAAA,QACZ,cAAc,YAAY;AACxB,cAAI;AACF,kBAAM,MAAM,MAAM,KAAK,WAAW,KAAK,sBAAsB;AAAA,cAC3D,WAAW,KAAK,WAAW;AAAA,YAC7B,CAAC;AACD,mBAAO,IAAI;AAAA,UACb,QAAQ;AACN,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,CAAC;AACD,UAAI,OAAO,SAAS;AAClB,gBAAQ,OAAO;AAAA,UACb,kDAAkD,OAAO,SAAS,WAAW,OAAO,MAAM;AAAA;AAAA,QAC5F;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER,UAAE;AACA,WAAK,wBAAwB;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAoC;AACxC,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,KAAK,OAAO,cAAc;AAAA,QACjE,YAAY;AAAA,QACZ,cAAc,YAAY;AACxB,cAAI;AACF,kBAAM,MAAM,MAAM,KAAK,WAAW,KAAK,sBAAsB;AAAA,cAC3D,WAAW,KAAK,WAAW;AAAA,YAC7B,CAAC;AACD,mBAAO,IAAI;AAAA,UACb,QAAQ;AACN,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,CAAC;AACD,UAAI,OAAO,SAAS;AAClB,gBAAQ,OAAO;AAAA,UACb,kDAAkD,OAAO,SAAS,WAAW,OAAO,MAAM;AAAA;AAAA,QAC5F;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,OAAO,MAAM,+CAA+C,GAAG;AAAA,CAAI;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,QAAQ;AACvB,SAAK,WAAW,WAAW;AAC3B,QAAI,KAAK,eAAe;AACtB,YAAM,WAAW,KAAK;AACtB,WAAK,gBAAgB;AACrB,eAAS,IAAI;AAAA,IACf;AAAA,EACF;AAAA,EAEA,WAAiB;AACf,SAAK,cAAc;AACnB,SAAK,aAAa,KAAK;AAIvB,QAAI,KAAK,iBAAiB,KAAK,gBAAgB,WAAW,GAAG;AAC3D,YAAM,WAAW,KAAK;AACtB,WAAK,gBAAgB;AACrB,eAAS,IAAI;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAIA,OAAwB,gBAAgB;AAAA,EAEhC,eAAwB;AAC9B,QAAI,CAAC,KAAK,KAAK,UAAU,KAAK,QAAS,QAAO;AAC9C,QAAI,KAAK,aAAa,eAAgB,QAAO;AAC7C,QAAI,KAAK,eAAe,eAAc,cAAe,QAAO;AAC5D,QAAI,CAAC,KAAK,YAAa,QAAO;AAC9B,WAAO,KAAK,YAAY,WAAW,gBAAgB,CAAC,KAAK,YAAY;AAAA,EACvE;AAAA,EAEA,MAAc,qBAAoC;AAChD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,WAAW,KAAK,kBAAkB;AAAA,QACvD,WAAW,KAAK;AAAA,QAChB,gBAAgB;AAAA,MAClB,CAAC;AACD,WAAK,cAAc;AAAA,QACjB,QAAQ,IAAI;AAAA,QACZ,MAAM,IAAI;AAAA,QACV,cACE,IAAI,gBAAgB,QAAQ,IAAI,gBAAgB,SAC5C,OACA,OAAO,IAAI,WAAW;AAAA,QAC5B,OAAO,IAAI;AAAA,QACX,aAAa,IAAI;AAAA,MACnB;AAEA,UAAI,KAAK,aAAa;AACpB,aAAK,YAAY,SAAS,IAAI;AAC9B,aAAK,YAAY,OAAO,IAAI;AAC5B,aAAK,YAAY,cAAc,IAAI;AACnC,aAAK,YAAY,QAAQ,IAAI;AAAA,MAC/B;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,mBAAkC;AAC9C,UAAM,KAAK,mBAAmB;AAC9B,QAAI,CAAC,KAAK,aAAa,EAAG;AAE1B,WAAO,CAAC,KAAK,WAAW,CAAC,KAAK,eAAe,KAAK,aAAa,GAAG;AAChE,WAAK;AAEL,UAAI,KAAK,eAAe,eAAc,eAAe;AACnD,aAAK,WAAW;AAAA,UACd,6CAA6C,eAAc,aAAa;AAAA,QAC1E;AACA,aAAK,KAAK;AACV;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,iBAAiB;AACtC,YAAM,UAAU,UACZ,qFACA,uBAAuB,KAAK,YAAY,IAAI,eAAc,aAAa;AAE3E,YAAM,SAAS,UACX,8QACA,oBAAoB,KAAK,YAAY,OAAO,eAAc,aAAa;AAE3E,WAAK,WAAW,gBAAgB,OAAO;AACvC,YAAM,KAAK,SAAS,SAAS;AAC7B,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,YAAY,OAAO,CAAC;AAGzD,UAAI,KAAK,eAAe,KAAK,QAAS;AACtC,YAAM,KAAK,aAAa,MAAM;AAC9B,UAAI,KAAK,eAAe,KAAK,QAAS;AAGtC,YAAM,KAAK,mBAAmB;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA,EAKQ,iBAAiB,KAAkC;AACzD,UAAM,cAAc,eAAe,IAAI,WAAW;AAElD,WAAO;AAAA,MACL,QAAQ,IAAI;AAAA,MACZ,WAAW,IAAI,aAAa;AAAA,MAC5B,OAAO,IAAI;AAAA,MACX,aAAa,IAAI;AAAA,MACjB,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,SAAS,IAAI,WAAW;AAAA,MACxB,kBAAkB,KAAK;AAAA,MACvB,mBAAmB,IAAI,qBAAqB;AAAA,MAC5C,OAAO,IAAI;AAAA,MACX,cAAc,IAAI,gBAAgB;AAAA,MAClC,YAAY,IAAI,cAAc;AAAA,MAC9B,aAAa,IAAI,eAAe;AAAA,MAChC,oBAAoB,IAAI,sBAAsB;AAAA,MAC9C,aAAa,IAAI;AAAA,MACjB,iBAAiB,IAAI,mBAAmB;AAAA,MACxC,mBAAmB,IAAI,qBAAqB;AAAA,MAC5C,cAAc,CAAC,CAAC,IAAI;AAAA,MACpB,aAAa,IAAI,eAAe;AAAA,MAChC,eAAe,IAAI,iBAAiB;AAAA,MACpC,aAAa,IAAI,eAAe;AAAA,MAChC,YAAY,IAAI,cAAc;AAAA,MAC9B,mBAAmB,IAAI,qBAAqB;AAAA,MAC5C,WAAW,IAAI,aAAa;AAAA,MAC5B,oBAAoB,IAAI,sBAAsB;AAAA,MAC9C,eAAe,IAAI,iBAAiB;AAAA,MACpC,WAAW,IAAI,aAAa;AAAA,MAC5B,QAAQ,IAAI;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,oBAAiC;AACvC,UAAM,eAAkC;AAAA,MACtC,gBAAgB,KAAK,OAAO,WAAW;AAAA,MACvC,WAAW,KAAK,OAAO,WAAW;AAAA,MAClC,QAAQ,KAAK,aAAa,UAAU;AAAA,MACpC,OAAO,KAAK,aAAa,SAAS;AAAA,MAClC,cAAc,KAAK,aAAa,qBAAqB;AAAA,MACrD,cAAc,KAAK,OAAO;AAAA,MAC1B,MAAM,KAAK,OAAO;AAAA,MAClB,QAAQ,KAAK,OAAO;AAAA,IACtB;AAEA,UAAM,SAAS,IAAI;AAAA,MACjB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE,gBAAgB,CAAC,WAAW;AAK1B,cAAI,WAAW,aAAa,KAAK,WAAW,qBAAqB;AAC/D,iBAAK,SAAS;AACd,iBAAK,UAAU,gBAAgB;AAAA,UACjC;AACA,iBAAO,KAAK,UAAU,eAAe,MAA2B;AAAA,QAClE;AAAA,QACA,SAAS,CAAC,UAAU;AAGlB,cAAK,MAAkC,SAAS,aAAa;AAC3D,iBAAK,oBAAoB;AAMzB,iBAAK,KAAK,WAAW,cAAc;AAAA,UACrC;AACA,iBAAO,KAAK,UAAU,QAAQ,KAAK;AAAA,QACrC;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AAAA,IACd;AAEA,WAAO,eAAe,KAAK,aAAa,gBAAgB;AACxD,WAAO,aAAa,MAAM;AACxB,cAAQ,OAAO,MAAM,iEAAiE;AACtF,WAAK,SAAS;AAAA,IAChB;AAEA,WAAO,mBAAmB,CAAC,YAAuB;AAChD,YAAM,UAAU,KAAK,KAAK;AAC1B,cAAQ,OAAO,MAAM,qCAAqC,OAAO,WAAM,OAAO;AAAA,CAAI;AAClF,WAAK,WAAW,UAAU,EAAE,MAAM,mBAAmB,MAAM,SAAS,IAAI,QAAQ,CAAC;AACjF,WAAK,KAAK,qBAAqB;AAC/B,WAAK,WAAW,gBAAgB,OAAO;AACvC,WAAK,SAAS;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,0BAAgC;AACtC,SAAK,WAAW,UAAU,CAAC,QAAQ,KAAK,cAAc,GAAG,CAAC;AAC1D,SAAK,WAAW,OAAO,MAAM,KAAK,KAAK,CAAC;AACxC,SAAK,WAAW,WAAW,MAAM,KAAK,SAAS,CAAC;AAChD,SAAK,WAAW,aAAa,CAAC,SAAS;AACrC,YAAM,SAAS,KAAK,KAAK,iBAAiB,KAAK,SAAS;AACxD,UAAI,OAAO,SAAS,cAAc;AAChC,aAAK,WAAW,gBAAgB,KAAK,KAAK,aAAa;AACvD,aAAK,SAAS;AAAA,MAChB,WAAW,OAAO,SAAS,iBAAiB;AAI1C,YAAI,KAAK,eAAe,OAAO,YAAY,UAAU;AACnD,eAAK,YAAY,kBAAkB;AAAA,QACrC;AAIA,YACE,KAAK,gBACJ,OAAO,YAAY,cACjB,OAAO,YAAY,UAAU,KAAK,KAAK,oBAC1C;AACA,eAAK,KAAK,yBAAyB;AAAA,QACrC;AAIA,aAAK,oBAAoB;AACzB,aAAK,WAAW,gBAAgB,OAAO,OAAO;AAC9C,aAAK,SAAS;AAAA,MAChB;AAAA,IACF,CAAC;AACD,SAAK,WAAW,eAAe,CAAC,SAAS;AACvC,UAAI,KAAK,gBAAgB;AACvB,gBAAQ,IAAI,0BAA0B,KAAK;AAC3C,eAAO,QAAQ,IAAI;AAInB,aAAK,wBAAwB;AAAA,MAC/B,OAAO;AACL,gBAAQ,IAAI,oBAAoB,KAAK;AACrC,eAAO,QAAQ,IAAI;AAGnB,aAAK,0BAA0B;AAAA,MACjC;AAAA,IACF,CAAC;AACD,SAAK,WAAW,aAAa,CAAC,EAAE,OAAO,MAAM;AAC3C,uBAAiB,KAAK,OAAO,cAAc,MAAM;AAAA,IACnD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,4BAA2C;AACvD,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,aAAa;AACnB,QAAI;AACF,YAAM,UAAU,IAAI,QAAc,CAACA,aAAY;AAC7C,mBAAW,MAAMA,SAAQ,IAAI,GAAG,UAAU;AAAA,MAC5C,CAAC;AACD,YAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,KAAK,WAAW,sBAAsB,GAAG,OAAO,CAAC;AACrF,UAAI,SAAS;AACX,aAAK,YAAY,gBAAgB,QAAQ,cAAc,QAAQ,UAAU;AACzE,gBAAQ,OAAO;AAAA,UACb,yCAAyC,QAAQ,aAAa,QAAQ,CAAC,CAAC,WAAW,QAAQ,WAAW,MAAM;AAAA;AAAA,QAC9G;AAAA,MACF,OAAO;AACL,gBAAQ,OAAO;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,OAAO,MAAM,6CAA6C,GAAG;AAAA,CAAqB;AAAA,IAC5F;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,qBAAoC;AAChD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,WAAW,KAAK,sBAAsB;AAAA,QAC3D,WAAW,KAAK,WAAW;AAAA,MAC7B,CAAC;AACD,wBAAkB,KAAK,OAAO,cAAc,IAAI,KAAK;AACrD,cAAQ,IAAI,eAAe,IAAI;AAC/B,cAAQ,IAAI,WAAW,IAAI;AAC3B,cAAQ,OAAO,MAAM,uDAAuD;AAAA,IAC9E,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,OAAO,MAAM,6DAA6D,GAAG;AAAA,CAAI;AAAA,IAC3F;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,2BAA0C;AACtD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,WAAW,KAAK,kBAAkB;AAAA,QACvD,WAAW,KAAK;AAAA,QAChB,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAI,KAAK,gBAAgB,KAAK,aAAa;AACzC,aAAK,YAAY,eAAe,IAAI;AACpC,2BAAmB,KAAK,OAAO,cAAc,IAAI,YAAY;AAAA,MAC/D;AAAA,IACF,QAAQ;AACN,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,SAAS,QAA0C;AAC/D,SAAK,SAAS;AACd,UAAM,KAAK,WAAW,WAAW,MAAM;AACvC,UAAM,KAAK,UAAU,eAAe,MAAM;AAAA,EAC5C;AAAA,EAEA,MAAc,SAAS,YAA8C;AACnE,YAAQ,OAAO,MAAM,qCAAqC,UAAU;AAAA,CAAI;AACxE,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,QAAQ,WAAW,CAAC;AAClE,SAAK,UAAU,QAAQ;AACvB,UAAM,KAAK,SAAS,UAAU;AAC9B,SAAK,WAAW,WAAW;AAC3B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,cAAwC;AAAA;AAAA,EAGhD,IAAI,aAAuC;AACzC,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,2BAAoD;AAC1D,WAAO;AAAA,MACL,cAAc,KAAK,aAAa,gBAAgB;AAAA,MAChD,QAAQ,KAAK,aAAa;AAAA,MAC1B,WAAW,KAAK,aAAa;AAAA,MAC7B,eAAe,CAAC,CAAC,KAAK,aAAa;AAAA,MACnC,oBAAoB,CAAC,CAAC,KAAK,aAAa;AAAA,MACxC,mBAAmB,KAAK,aAAa,aAAa,UAAU;AAAA,MAC5D,QAAQ,KAAK,aAAa,cAAc,CAAC;AAAA,IAC3C;AAAA,EACF;AAAA,EAEQ,6BAAsD;AAC5D,WAAO;AAAA,MACL,MAAM,KAAK,KAAK;AAAA,MAChB,YAAY,KAAK,OAAO,cAAc;AAAA,MACtC,WAAW,KAAK;AAAA,MAChB,GAAG,KAAK,yBAAyB;AAAA,MACjC,OAAO,KAAK,aAAa;AAAA,MACzB,QAAQ,KAAK,OAAO,UAAU;AAAA,MAC9B,sBAAsB,QAAQ,IAAI,mCAAmC;AAAA,IACvE;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,UAAM,UAAU,KAAK,2BAA2B;AAChD,YAAQ,OAAO,MAAM,iCAAiC,KAAK,UAAU,OAAO,CAAC;AAAA,CAAI;AACjF,SAAK,WAAW,UAAU,EAAE,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAAA,EACpE;AACF;;;ACv8BA,SAAS,MAAAC,WAAuB;AAShC,IAAMC,UAAS,oBAAoB,mBAAmB;AAqDtD,IAAMC,kBAAiB;AAEhB,IAAM,oBAAN,MAAwB;AAAA,EACrB,SAAwB;AAAA,EACf;AAAA,EACT,cAAyD,CAAC;AAAA,EAC1D,aAAmD;AAAA,EACnD,qBAAwC,CAAC;AAAA,EAEjD,YAAY,QAAiC;AAC3C,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,QAAQ,aAAa;AAAA,EACnC;AAAA;AAAA,EAIA,KACE,QACA,SACoD;AACpD,UAAM,SAAS,KAAK,cAAc;AAClC,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,aAAO;AAAA,QACL,uBAAuB,OAAO,MAAM,CAAC;AAAA,QACrC;AAAA,QACA,CAAC,aAAwE;AACvE,cAAI,SAAS,WAAW,SAAS,SAAS,QAAW;AACnD,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,wBAAwB,OAAO,MAAM,CAAC,EAAE,CAAC;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,UAAyB;AACvB,QAAI,CAAC,KAAK,OAAO,QAAQ;AACvB,aAAO,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC;AAAA,IACpE;AACA,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,MAAAF,QAAO,KAAK,cAAc,EAAE,QAAQ,KAAK,OAAO,QAAQ,WAAW,KAAK,OAAO,UAAU,CAAC;AAE1F,WAAK,SAASG,IAAG,KAAK,OAAO,QAAQ;AAAA,QACnC,MAAM;AAAA,UACJ,cAAc,KAAK,OAAO;AAAA,UAC1B,YAAY;AAAA,QACd;AAAA,QACA,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc,EAAE,8BAA8B,OAAO;AAAA,MACvD,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAE9B,aAAK,QAAQ,KAAK,4BAA4B,EAAE,SAAS,KAAK,OAAO,UAAU,CAAC;AAChF,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAD,SAAQ;AAAA,QACV;AACA,QAAAF,QAAO,KAAK,kBAAkB;AAAA,MAChC,CAAC;AAED,WAAK,OAAO,GAAG,iBAAiB,CAAC,UAAiB;AAChD;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV;AAAA,YACE,IAAI,MAAM,2BAA2B,kBAAkB,cAAc,MAAM,OAAO,EAAE;AAAA,UACtF;AAAA,QACF;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,cAAc,CAAC,WAAmB;AAC/C,QAAAA,QAAO,KAAK,yBAAyB,EAAE,OAAO,CAAC;AAAA,MACjD,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,aAAa,MAAM;AACnC,QAAAA,QAAO,KAAK,oBAAoB;AAChC,mBAAW,MAAM,KAAK,mBAAoB,IAAG;AAAA,MAC/C,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AACjB,QAAI,KAAK,YAAY;AACnB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,SAAK,YAAY;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,YAAY,UAA4B;AACtC,SAAK,mBAAmB,KAAK,QAAQ;AAAA,EACvC;AAAA;AAAA,EAIA,iBAAiB,UAAsD;AACrE,SAAK,cAAc,EAAE,GAAG,4BAA4B,QAAQ;AAAA,EAC9D;AAAA,EAEA,WAAW,UAAoD;AAC7D,SAAK,cAAc,EAAE,GAAG,0BAA0B,QAAQ;AAAA,EAC5D;AAAA,EAEA,WAAW,UAA4B;AACrC,SAAK,cAAc,EAAE,GAAG,0BAA0B,QAAQ;AAAA,EAC5D;AAAA,EAEA,aAAa,UAA4B;AACvC,SAAK,cAAc,EAAE,GAAG,4BAA4B,QAAQ;AAAA,EAC9D;AAAA,EAEA,cAAc,UAAoD;AAChE,SAAK,cAAc,EAAE,GAAG,qCAAqC,QAAQ;AAAA,EACvE;AAAA,EAEA,eACE,UAIM;AACN,SAAK,cAAc,EAAE,GAAG,8BAA8B,QAAQ;AAAA,EAChE;AAAA,EAEA,kBAAkB,UAA8E;AAC9F,SAAK,cAAc,EAAE,GAAG,iCAAiC,QAAQ;AAAA,EACnE;AAAA,EAEA,sBACE,UACM;AACN,SAAK,cAAc,EAAE,GAAG,qCAAqC,QAAQ;AAAA,EACvE;AAAA,EAEA,YAAY,UAA0D;AACpE,SAAK,cAAc,EAAE,GAAG,2BAA2B,QAAQ;AAAA,EAC7D;AAAA,EAEA,aAAa,UAA2D;AACtE,SAAK,cAAc,EAAE,GAAG,4BAA4B,QAAQ;AAAA,EAC9D;AAAA;AAAA,EAIA,gBAAsB;AACpB,SAAK,KAAK,KAAK,0BAA0B,EAAE,WAAW,KAAK,OAAO,UAAU,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC/F;AAAA,EAEA,UAAU,OAAsC;AAC9C,SAAK,YAAY,KAAK,EAAE,MAAM,CAAC;AAC/B,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,WAAW,MAAM,KAAK,YAAY,GAAGC,eAAc;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,WAAW,QAA+B;AACxC,SAAK,KAAK,KAAK,4BAA4B;AAAA,MACzC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAAA,EAEA,gBAAgB,QAAsB;AACpC,SAAK,UAAU,EAAE,MAAM,gBAAgB,OAAO,CAAC;AAAA,EACjD;AAAA,EAEA,gBAAgB,QAAgB,QAAsB;AACpD,SAAK,UAAU,EAAE,MAAM,gBAAgB,QAAQ,OAAO,CAAC;AAAA,EACzD;AAAA;AAAA,EAIQ,cAAoB;AAC1B,SAAK,aAAa;AAClB,QAAI,KAAK,YAAY,WAAW,EAAG;AACnC,UAAM,QAAQ,KAAK;AACnB,SAAK,cAAc,CAAC;AACpB,eAAW,EAAE,MAAM,KAAK,OAAO;AAC7B,WAAK,KAAK,KAAK,2BAA2B;AAAA,QACxC,WAAW,KAAK,OAAO;AAAA,QACvB;AAAA,MACF,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,gBAAwB;AAC9B,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,WAAO,KAAK;AAAA,EACd;AACF;;;ACjRA,SAAS,YAAAG,iBAAgB;AAGzB,IAAMC,UAAS,oBAAoB,eAAe;AAqB3C,IAAM,gBAAN,MAAoB;AAAA,EAOzB,YACU,QACA,WACR;AAFQ;AACA;AAAA,EACP;AAAA,EAFO;AAAA,EACA;AAAA,EARF,WAAkD;AAAA,EAClD,qBAAoC;AAAA,EACpC,SAAwB;AAAA,EACxB,gBAAsD;AAAA,EACtD,YAAY;AAAA,EAOpB,MAAM,QAAsB;AAC1B,SAAK,KAAK;AACV,SAAK,SAAS;AACd,SAAK,qBAAqB,KAAK,gBAAgB;AAC/C,SAAK,WAAW,YAAY,MAAM,KAAK,KAAK,KAAK,GAAG,KAAK,OAAO,cAAc;AAC9E,IAAAA,QAAO,KAAK,0BAA0B;AAAA,MACpC;AAAA,MACA,SAAS,KAAK,oBAAoB,MAAM,GAAG,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,SAAU,eAAc,KAAK,QAAQ;AAC9C,QAAI,KAAK,cAAe,cAAa,KAAK,aAAa;AACvD,SAAK,WAAW;AAChB,SAAK,gBAAgB;AACrB,SAAK,SAAS;AACd,SAAK,qBAAqB;AAC1B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEQ,kBAA0B;AAChC,WAAOC,UAAS,sBAAsB;AAAA,MACpC,KAAK,KAAK,OAAO;AAAA,MACjB,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK;AAAA,EACV;AAAA,EAEQ,OAAa;AACnB,QAAI,CAAC,KAAK,UAAU,KAAK,UAAW;AAEpC,QAAI;AACF,MAAAA,UAAS,oBAAoB,KAAK,MAAM,YAAY;AAAA,QAClD,KAAK,KAAK,OAAO;AAAA,QACjB,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAED,YAAM,YAAYA,UAAS,wBAAwB,KAAK,MAAM,IAAI;AAAA,QAChE,KAAK,KAAK,OAAO;AAAA,QACjB,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,MACpC,CAAC,EACE,SAAS,EACT,KAAK;AAER,UAAI,cAAc,KAAK,oBAAoB;AACzC,YAAI,KAAK,cAAe,cAAa,KAAK,aAAa;AACvD,aAAK,gBAAgB;AAAA,UACnB,MAAM,KAAK,KAAK,iBAAiB,SAAS;AAAA,UAC1C,KAAK,OAAO;AAAA,QACd;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,iBAAiB,WAAkC;AAC/D,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,cAAc,KAAK,sBAAsB;AAE/C,QAAI,cAAc;AAClB,QAAI,gBAAgB;AACpB,QAAI,eAAe;AACnB,QAAI;AACF,YAAM,cAAcA,UAAS,wBAAwB,WAAW,YAAY,KAAK,MAAM,IAAI;AAAA,QACzF,KAAK,KAAK,OAAO;AAAA,QACjB,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,MACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,oBAAc,SAAS,aAAa,EAAE,KAAK;AAE3C,YAAM,YAAYA,UAAS,yCAAyC,KAAK,MAAM,IAAI;AAAA,QACjF,KAAK,KAAK,OAAO;AAAA,QACjB,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,MACpC,CAAC,EACE,SAAS,EACT,KAAK;AACR,YAAM,QAAQ,UAAU,MAAM,KAAK;AACnC,sBAAgB,MAAM,CAAC,KAAK;AAC5B,qBAAe,MAAM,CAAC,KAAK;AAAA,IAC7B,QAAQ;AAAA,IAER;AAEA,SAAK,qBAAqB;AAC1B,SAAK,YAAY;AAEjB,IAAAD,QAAO,KAAK,wBAAwB;AAAA,MAClC,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,KAAK,UAAU,MAAM,GAAG,CAAC;AAAA,IAC3B,CAAC;AAED,QAAI;AACF,YAAM,KAAK,UAAU,aAAa;AAAA,QAChC,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,MAAAA,QAAO,MAAM,8BAA8B,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3D,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;;;ACrJA,SAAS,YAAAE,iBAAgB;AACzB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAGrB,IAAM,eAAe;AAEd,SAAS,eAAe,YAAoB,QAAgB,QAAyB;AAC1F,MAAI,WAAW,SAAS,IAAI,YAAY,GAAG,GAAG;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,eAAeC,MAAK,YAAY,cAAc,MAAM;AAE1D,MAAIC,YAAW,YAAY,GAAG;AAC5B,QAAI,QAAQ;AACV,UAAI,sBAAsB,YAAY,GAAG;AACvC,eAAO;AAAA,MACT;AACA,UAAI;AACF,QAAAC,UAAS,gCAAgC,MAAM,IAAI;AAAA,UACjD,KAAK;AAAA,UACL,OAAO;AAAA,QACT,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,SAAS,UAAU,MAAM,KAAK;AAC1C,EAAAA,UAAS,8BAA8B,YAAY,KAAK,GAAG,IAAI;AAAA,IAC7D,KAAK;AAAA,IACL,OAAO;AAAA,EACT,CAAC;AAED,SAAO;AACT;AAOO,SAAS,qBAAqB,YAAoB,QAAsB;AAC7E,MAAI;AACF,UAAM,SAASA,UAAS,iCAAiC;AAAA,MACvD,KAAK;AAAA,MACL,UAAU;AAAA,IACZ,CAAC;AACD,UAAM,UAAU,OAAO,MAAM,MAAM;AACnC,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,KAAK,EAAE,MAAM,IAAI;AACrC,YAAM,eAAe,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAChE,YAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;AAC5D,UAAI,CAAC,gBAAgB,eAAe,qBAAqB,MAAM,GAAI;AAEnE,YAAM,eAAe,aAAa,QAAQ,aAAa,EAAE;AACzD,UAAI,CAAC,aAAa,SAAS,IAAI,YAAY,GAAG,EAAG;AAEjD,UAAI;AACF,QAAAA,UAAS,yBAAyB,EAAE,KAAK,cAAc,OAAO,SAAS,CAAC;AAAA,MAC1E,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAMO,SAAS,eAAe,YAAoB,QAAsB;AACvE,QAAM,eAAeF,MAAK,YAAY,cAAc,MAAM;AAC1D,MAAI,CAACC,YAAW,YAAY,EAAG;AAC/B,MAAI;AACF,IAAAC,UAAS,wBAAwB,YAAY,aAAa;AAAA,MACxD,KAAK;AAAA,MACL,OAAO;AAAA,IACT,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;ACvFA,SAAS,OAAO,YAAAC,iBAAmC;AAE5C,SAAS,gBACd,KACA,KACA,UACe;AACf,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,UAAM,QAAQ,MAAM,MAAM,CAAC,MAAM,GAAG,GAAG;AAAA,MACrC;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,IACxB,CAAC;AAED,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,eAAS,UAAU,MAAM,SAAS,CAAC;AAAA,IACrC,CAAC;AAED,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,eAAS,UAAU,MAAM,SAAS,CAAC;AAAA,IACrC,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,UAAI,SAAS,GAAG;AACd,QAAAA,SAAQ;AAAA,MACV,OAAO;AACL,eAAO,IAAI,MAAM,kCAAkC,IAAI,EAAE,CAAC;AAAA,MAC5D;AAAA,IACF,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,aAAO,GAAG;AAAA,IACZ,CAAC;AAAA,EACH,CAAC;AACH;AAEA,IAAM,wBAAwB;AAEvB,SAAS,oBAAoB,KAAa,WAAmB,KAA4B;AAC9F,MAAI;AACF,UAAM,SAASD,UAAS,GAAG,GAAG,IAAI,KAAK,UAAU,SAAS,CAAC,IAAI;AAAA,MAC7D;AAAA,MACA,SAAS;AAAA,MACT,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,MAClC,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,IACxB,CAAC;AACD,UAAM,QAAQ,OAAO,SAAS,EAAE,KAAK;AACrC,WAAO,SAAS;AAAA,EAClB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBACd,KACA,KACA,UACc;AACd,QAAM,QAAQ,MAAM,MAAM,CAAC,MAAM,GAAG,GAAG;AAAA,IACrC;AAAA,IACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAChC,UAAU;AAAA,IACV,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,EACxB,CAAC;AAED,QAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,aAAS,UAAU,MAAM,SAAS,CAAC;AAAA,EACrC,CAAC;AAED,QAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,aAAS,UAAU,MAAM,SAAS,CAAC;AAAA,EACrC,CAAC;AAED,QAAM,MAAM;AACZ,SAAO;AACT;;;AC3EA,SAAS,KAAAE,WAAS;;;ACAlB,SAAS,KAAAC,WAAS;AAMlB,IAAMC,kBAAiB;AAEhB,SAAS,mBACd,SACA,qBACmC;AACnC,QAAM,mBAAmB,oBAAoB;AAC7C,SAAO,mBAAmB,EAAE,GAAG,SAAS,iBAAiB,IAAI;AAC/D;AAIA,SAAS,oBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOC,IAAE,OAAO,EAAE,SAAS,YAAY;AAAA,MACvC,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,MAC9D,MAAMA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,MACtE,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,IAC7E;AAAA,IACA,OAAO,WAAW;AAChB,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,mBAAmB,EAAE,WAAW,GAAG,OAAO,GAAG,mBAAmB;AAAA,QAClE;AACA,eAAO,WAAW,iBAAiB,OAAO,IAAI,SAAS,OAAO,EAAE,GAAG;AAAA,MACrE,SAAS,OAAO;AACd,eAAO,WAAW,0BAA0B,aAAa,KAAK,CAAC,EAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,2BACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACpD,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,WAAW;AAAA,MACjD,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,MAC7D,MAAMA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC3D,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,YAAY;AAAA,MACnD,gBAAgBA,IACb,OAAO,EACP,SAAS,EACT,SAAS,EACT,SAAS,wCAAwC;AAAA,IACtD;AAAA,IACA,OAAO,EAAE,SAAS,GAAG,OAAO,MAAM;AAChC,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,SAAS,GAAG,OAAO,GAAG,mBAAmB;AAAA,QACnF;AACA,eAAO,WAAW,4BAA4B;AAAA,MAChD,SAAS,OAAO;AACd,eAAO,WAAW,0BAA0B,aAAa,KAAK,CAAC,EAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACpD,MAAMA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MAChE,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,IACxE;AAAA,IACA,OAAO,EAAE,SAAS,MAAM,YAAY,MAAM;AACxC,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA,QAAQ;AAAA,cACR,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,cACjC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,YACjD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,WAAW,4BAA4B;AAAA,MAChD,SAAS,OAAO;AACd,eAAO,WAAW,0BAA0B,aAAa,KAAK,CAAC,EAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,2BACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACpD,QAAQA,IACL,KAAK,CAAC,YAAY,QAAQ,cAAc,YAAY,aAAa,cAAc,UAAU,CAAC,EAC1F,SAAS,6BAA6B;AAAA,IAC3C;AAAA,IACA,OAAO,EAAE,SAAS,OAAO,MAAM;AAC7B,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,SAAS,OAAO,GAAG,mBAAmB;AAAA,QAChF;AACA,eAAO,WAAW,0BAA0B,MAAM,GAAG;AAAA,MACvD,SAAS,OAAO;AACd,eAAO,WAAW,4BAA4B,aAAa,KAAK,CAAC,EAAE;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,mBAAmB,WAAmE;AAC7F,MAAI,UAAU,WAAW,EAAG,QAAO;AACnC,SAAO,UAAU,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,SAAS,KAAK,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI;AAC/E;AAEA,SAAS,qBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,MAClD,SAASA,IACN,OAAO,EACP,SAAS,+EAA+E;AAAA,IAC7F;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM;AAC9B,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,SAAS,QAAQ,QAAQ,GAAG,mBAAmB;AAAA,QACzF;AACA,eAAO;AAAA,UACL,0BAA0B,OAAO,MAAM,gBAAgB,mBAAmB,OAAO,SAAS,CAAC;AAAA,QAC7F;AAAA,MACF,SAAS,OAAO;AACd,eAAO,WAAW,2BAA2B,aAAa,KAAK,CAAC,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,MAClD,SAASA,IAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,IAClE;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM;AAC9B,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,SAAS,QAAQ,QAAQ,GAAG,mBAAmB;AAAA,QACzF;AACA,eAAO;AAAA,UACL,8BAA8B,OAAO,MAAM,gBAAgB,mBAAmB,OAAO,SAAS,CAAC;AAAA,QACjG;AAAA,MACF,SAAS,OAAO;AACd,eAAO,WAAW,8BAA8B,aAAa,KAAK,CAAC,EAAE;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAASC,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,gBAAgBD,IAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,MACxD,OAAOA,IAAE,OAAO,EAAE,SAAS,eAAe;AAAA,MAC1C,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC/D,MAAMA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,MACtE,SAASA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,MACrE,iBAAiBA,IAAE,OAAO,EAAE,SAAS,EAAE,SAASD,eAAc;AAAA,IAChE;AAAA,IACA,OAAO,EAAE,gBAAgB,OAAO,aAAa,MAAM,SAAS,gBAAgB,MAAM;AAChF,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA,cAAc;AAAA,cACd;AAAA,cACA,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,cAC/C,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,cACjC,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,cACvC,GAAI,oBAAoB,UAAa,EAAE,gBAAgB;AAAA,YACzD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,WAAW,oBAAoB,OAAO,IAAI,SAAS,OAAO,EAAE,GAAG;AAAA,MACxE,SAAS,OAAO;AACd,eAAO,WAAW,6BAA6B,aAAa,KAAK,CAAC,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAASG,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,YAAYF,IAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MAC1D,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,aAAaA,IAAE,OAAO,EAAE,SAAS;AAAA,MACjC,MAAMA,IAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,QAAQA,IAAE,OAAO,EAAE,SAAS;AAAA,MAC5B,SAASA,IAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,iBAAiBA,IAAE,OAAO,EAAE,SAAS,EAAE,SAASD,eAAc;AAAA,IAChE;AAAA,IACA,OAAO,EAAE,YAAY,GAAG,OAAO,MAAM;AACnC,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA,mBAAmB,EAAE,WAAW,WAAW,YAAY,GAAG,OAAO,GAAG,mBAAmB;AAAA,QACzF;AACA,eAAO,WAAW,kBAAkB;AAAA,MACtC,SAAS,OAAO;AACd,eAAO,WAAW,WAAW,aAAa,KAAK,CAAC,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAASI,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,YAAYH,IAAE,OAAO,EAAE,SAAS,0BAA0B,EAAE;AAAA,IAC9D,OAAO,EAAE,WAAW,MAAM;AACxB,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA,mBAAmB,EAAE,WAAW,WAAW,WAAW,GAAG,mBAAmB;AAAA,QAC9E;AACA,eAAO,WAAW,kBAAkB;AAAA,MACtC,SAAS,OAAO;AACd,eAAO,WAAW,WAAW,aAAa,KAAK,CAAC,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,mBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASA,IAAE,OAAO,EAAE,SAAS,kCAAkC,EAAE;AAAA,IACnE,OAAO,EAAE,QAAQ,MAAM;AACrB,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,QAAQ,GAAG,mBAAmB;AAAA,QACxE;AACA,eAAO;AAAA,UACL,gCAAgC,OAAO,MAAM,aAAa,OAAO,MAAM;AAAA,QACzE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,WAAW,yBAAyB,aAAa,KAAK,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASA,IAAE,OAAO,EAAE,SAAS,2CAA2C,EAAE;AAAA,IAC5E,OAAO,EAAE,QAAQ,MAAM;AACrB,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA,mBAAmB,EAAE,WAAW,QAAQ,QAAQ,GAAG,mBAAmB;AAAA,QACxE;AACA,eAAO,WAAW,6BAA6B,OAAO,GAAG;AAAA,MAC3D,SAAS,OAAO;AACd,eAAO,WAAW,wBAAwB,aAAa,KAAK,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,YAA+B,qBAA0C;AACjG,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASA,IAAE,OAAO,EAAE,SAAS,oDAAoD,EAAE;AAAA,IACrF,OAAO,EAAE,QAAQ,MAAM;AACrB,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,mBAAmB,EAAE,WAAW,aAAa,QAAQ,GAAG,mBAAmB;AAAA,QAC7E;AACA,YAAI,OAAO,QAAQ;AACjB,iBAAO;AAAA,YACL,OAAO,OAAO,QAAQ,iCAAiC,OAAO,WAAW;AAAA,UAC3E;AAAA,QACF;AACA,eAAO;AAAA,UACL,OAAO,OAAO,QAAQ,0BAA0B,OAAO,WAAW;AAAA,QACpE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,WAAW,uBAAuB,aAAa,KAAK,CAAC,EAAE;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;AAIO,SAAS,wBACd,YACA,sBAA2C,MAAM,QACjD;AACA,SAAO;AAAA,IACL,oBAAoB,YAAY,mBAAmB;AAAA,IACnD,2BAA2B,YAAY,mBAAmB;AAAA,IAC1D,wBAAwB,YAAY,mBAAmB;AAAA,IACvD,2BAA2B,YAAY,mBAAmB;AAAA,IAC1D,qBAAqB,YAAY,mBAAmB;AAAA,IACpD,wBAAwB,YAAY,mBAAmB;AAAA,IACvDC,wBAAuB,YAAY,mBAAmB;AAAA,IACtDC,wBAAuB,YAAY,mBAAmB;AAAA,IACtDC,wBAAuB,YAAY,mBAAmB;AAAA,IACtD,mBAAmB,YAAY,mBAAmB;AAAA,IAClD,kBAAkB,YAAY,mBAAmB;AAAA,IACjD,iBAAiB,YAAY,mBAAmB;AAAA,EAClD;AACF;;;AClZA,SAAS,KAAAC,WAAS;AAYlB,SAASC,2BACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAOC,IAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,MAC3D,aAAaA,IACV,OAAO,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,MACrE,WAAWA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,IAC7F;AAAA,IACA,OAAO,EAAE,OAAO,aAAa,UAAU,MAAM;AAC3C,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA;AAAA,cACA,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,cAC/C,GAAI,cAAc,UAAa,EAAE,UAAU,UAAU;AAAA,YACvD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,YAAI,OAAO,QAAQ;AACjB,iBAAO;AAAA,YACL,wDAAwD,OAAO,gBAAgB,OAAO,EAAE;AAAA,UAC1F;AAAA,QACF;AACA,eAAO,WAAW,2BAA2B,OAAO,EAAE,IAAI;AAAA,MAC5D,SAAS,OAAO;AACd,eAAO,WAAW,gCAAgC,aAAa,KAAK,CAAC,EAAE;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAASC,yBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,eAAeD,IAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,MACjE,OAAOA,IACJ,OAAO,EACP,OAAO,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,EAAE,SAAS,wBAAwB,CAAC,EACvE,SAAS,8BAA8B;AAAA,IAC5C;AAAA,IACA,OAAO,EAAE,eAAe,MAAM,MAAM;AAClC,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA,cAAc;AAAA,cACd;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,WAAW,iCAAiC,OAAO,KAAK,EAAE;AAAA,MACnE,SAAS,OAAO;AACd,eAAO,WAAW,mBAAmB,aAAa,KAAK,CAAC,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAASE,wBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASF,IAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,MAC9D,uBAAuBA,IAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,IAC1F;AAAA,IACA,OAAO,EAAE,SAAS,sBAAsB,MAAM;AAC5C,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA,QAAQ;AAAA,cACR,mBAAmB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,0BAA0B,OAAO,oBAAoB,qBAAqB;AAAA,QAC5E;AAAA,MACF,SAAS,OAAO;AACd,eAAO,WAAW,6BAA6B,aAAa,KAAK,CAAC,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAASG,2BACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASH,IAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,MACjD,uBAAuBA,IAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,IAC7F;AAAA,IACA,OAAO,EAAE,SAAS,sBAAsB,MAAM;AAC5C,UAAI;AACF,cAAM,WAAW;AAAA,UACf;AAAA,UACA;AAAA,YACE;AAAA,cACE;AAAA,cACA,QAAQ;AAAA,cACR,mBAAmB;AAAA,YACrB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,WAAW,oBAAoB;AAAA,MACxC,SAAS,OAAO;AACd,eAAO,WAAW,gCAAgC,aAAa,KAAK,CAAC,EAAE;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AACF;AAIO,SAAS,sCACd,YACA,sBAA2C,MAAM,QACjD;AACA,SAAO;AAAA,IACLD,2BAA0B,YAAY,mBAAmB;AAAA,IACzDE,yBAAwB,YAAY,mBAAmB;AAAA,IACvDC,wBAAuB,YAAY,mBAAmB;AAAA,IACtDC,2BAA0B,YAAY,mBAAmB;AAAA,EAC3D;AACF;;;AF9JO,SAAS,aAAa,OAAwB;AACnD,SAAO,iBAAiB,QAAQ,MAAM,UAAU;AAClD;AAIA,IAAM,4BAA4B;AAGlC,SAAS,cAAc,MAAwB;AAC7C,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,EAAE,MAAM,aAAa,GAAG,KAAK,IAAI;AACvC,QAAM,UAAmC,EAAE,GAAG,KAAK;AACnD,UAAQ,cACN,OAAO,gBAAgB,YAAY,YAAY,SAAS,4BACpD,GAAG,YAAY,MAAM,GAAG,yBAAyB,CAAC,4EACjD,eAAe;AACtB,UAAQ,UAAU,OAAO,SAAS,YAAY,KAAK,SAAS;AAC5D,SAAO;AACT;AAEA,SAAS,eAAe,OAAyB;AAC/C,SAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,aAAa,IAAI;AAC3D;AAEA,SAAS,mBAAmB,YAA+B;AACzD,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQC,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,YAAYA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,MACvE,YAAYA,IACT,QAAQ,EACR,SAAS,EACT,SAAS,yEAAyE;AAAA,MACrF,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,IACpF;AAAA,IACA,OAAO,WAAW;AAChB,UAAI;AACF,cAAM,QAAQ,MAAM,WAAW,KAAK,oBAAoB,EAAE,WAAW,GAAG,OAAO,CAAC;AAChF,eAAO,WAAW,KAAK,UAAU,eAAe,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,MAClE,SAAS,OAAO;AACd,eAAO,WAAW,yBAAyB,aAAa,KAAK,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,wBAAwB,YAA+B;AAC9D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASA,IAAE,OAAO,EAAE,SAAS,wBAAwB,EAAE;AAAA,IACzD,OAAO,EAAE,QAAQ,MAAM;AACrB,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,kBAAkB,EAAE,WAAW,QAAQ,QAAQ,CAAC;AACnF,eAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO,WAAW,uBAAuB,aAAa,KAAK,CAAC,EAAE;AAAA,MAChE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,qBAAqB,YAA+B;AAC3D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,UAAUA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,MACvE,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MAC9E,eAAeA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,MAC3E,YAAYA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,MACvE,YAAYA,IACT,QAAQ,EACR,SAAS,EACT,SAAS,yEAAyE;AAAA,MACrF,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,IAClE;AAAA,IACA,OAAO,WAAW;AAChB,UAAI;AACF,cAAM,QAAQ,MAAM,WAAW,KAAK,sBAAsB,EAAE,WAAW,GAAG,OAAO,CAAC;AAClF,eAAO,WAAW,KAAK,UAAU,eAAe,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,MAClE,SAAS,OAAO;AACd,eAAO,WAAW,2BAA2B,aAAa,KAAK,CAAC,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAASC,uBAAsB,YAA+B;AAC5D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASD,IAAE,OAAO,EAAE,SAAS,gBAAgB,EAAE;AAAA,IACjD,OAAO,EAAE,QAAQ,MAAM;AACrB,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,KAAK,uBAAuB;AAAA,UAC5D;AAAA,UACA,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MACrD,SAAS,OAAO;AACd,eAAO,WAAW,4BAA4B,aAAa,KAAK,CAAC,EAAE;AAAA,MACrE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,kBAAkB,YAA+B;AACxD,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,mBAAmB,EAAE,UAAU,CAAC;AACnE,eAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO,WAAW,wBAAwB,aAAa,KAAK,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,4BAA4B,YAA+B;AAClE,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,UAAU,MAAM,WAAW,KAAK,sBAAsB,EAAE,UAAU,CAAC;AACzE,eAAO,WAAW,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,MACpD,SAAS,OAAO;AACd,eAAO,WAAW,mCAAmC,aAAa,KAAK,CAAC,EAAE;AAAA,MAC5E;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,2BAA2B,YAA+B;AACjE,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI;AACF,cAAM,UAAU,MAAM,WAAW,KAAK,qBAAqB,EAAE,UAAU,CAAC;AACxE,eAAO,WAAW,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,MACpD,SAAS,OAAO;AACd,eAAO,WAAW,kCAAkC,aAAa,KAAK,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAIA,SAASE,qBACP,YACA,qBACA;AACA,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASF,IAAE,OAAO,EAAE,SAAS,6BAA6B;AAAA,MAC1D,SAASA,IACN,OAAO,EACP,SAAS,EACT,SAAS,yEAAyE;AAAA,IACvF;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM;AAC9B,UAAI;AACF,cAAM,mBAAmB,oBAAoB;AAC7C,YAAI,SAAS;AACX,gBAAM,WAAW,KAAK,yBAAyB;AAAA,YAC7C;AAAA,YACA,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,UACjD,CAAC;AACD,iBAAO,WAAW,KAAK,UAAU,EAAE,QAAQ,MAAM,QAAQ,QAAQ,OAAO,GAAG,CAAC,CAAC;AAAA,QAC/E;AACA,cAAM,WAAW,KAAK,2BAA2B,EAAE,WAAW,SAAS,QAAQ,CAAC;AAChF,eAAO,WAAW,KAAK,UAAU,EAAE,QAAQ,MAAM,QAAQ,UAAU,CAAC,CAAC;AAAA,MACvE,SAAS,OAAO;AACd,eAAO,WAAW,2BAA2B,aAAa,KAAK,CAAC,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,YAA+B;AAC/D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,MACrF,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,IACzF;AAAA,IACA,OAAO,EAAE,SAAS,MAAM,MAAM;AAC5B,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,KAAK,yBAAyB;AAAA,UAC9D;AAAA,UACA,GAAI,YAAY,UAAa,EAAE,QAAQ,QAAQ;AAAA,UAC/C,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,QACrC,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MACrD,SAAS,OAAO;AACd,eAAO,WAAW,gCAAgC,aAAa,KAAK,CAAC,EAAE;AAAA,MACzE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAASG,uBAAsB,YAA+B;AAC5D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASH,IAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,MAC7D,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,IACzF;AAAA,IACA,OAAO,EAAE,SAAS,MAAM,MAAM;AAC5B,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,KAAK,sBAAsB;AAAA,UAC3D;AAAA,UACA,QAAQ;AAAA,UACR,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,QACrC,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MACrD,SAAS,OAAO;AACd,eAAO,WAAW,6BAA6B,aAAa,KAAK,CAAC,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,qBAAqB,YAA+B;AAC3D,QAAM,YAAY,WAAW;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,IAAE,OAAO,EAAE,SAAS,2BAA2B;AAAA,MACxD,QAAQA,IACL,KAAK,CAAC,SAAS,aAAa,CAAC,EAC7B,SAAS,EACT,SAAS,0CAA0C;AAAA,MACtD,OAAOA,IACJ,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM,MAAM;AACpC,UAAI;AACF,cAAM,OAAO,MAAM,WAAW,KAAK,qBAAqB;AAAA,UACtD;AAAA,UACA,QAAQ;AAAA,UACR,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,UACrC,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,QACrC,CAAC;AACD,eAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO,WAAW,8BAA8B,aAAa,KAAK,CAAC,EAAE;AAAA,MACvE;AAAA,IACF;AAAA,IACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,EACxC;AACF;AAIO,SAAS,kBACd,YACA,sBAA2C,MAAM,QACjD;AACA,SAAO;AAAA,IACL,mBAAmB,UAAU;AAAA,IAC7B,wBAAwB,UAAU;AAAA,IAClC,qBAAqB,UAAU;AAAA,IAC/BC,uBAAsB,UAAU;AAAA,IAChC,kBAAkB,UAAU;AAAA,IAC5B,4BAA4B,UAAU;AAAA,IACtC,2BAA2B,UAAU;AAAA,IACrCC,qBAAoB,YAAY,mBAAmB;AAAA,IACnD,yBAAyB,UAAU;AAAA,IACnCC,uBAAsB,UAAU;AAAA,IAChC,qBAAqB,UAAU;AAAA,IAC/B,GAAG,wBAAwB,YAAY,mBAAmB;AAAA,IAC1D,GAAG,sCAAsC,YAAY,mBAAmB;AAAA,EAC1E;AACF;;;AGhUA,IAAMC,UAAS,oBAAoB,aAAa;AAEhD,IAAM,iBAAiB;AAoBvB,SAASC,mBAAkB,YAAoB,UAAuC;AACpF,QAAM,QAAkB,CAAC;AAEzB,MAAI,UAAU,mBAAmB;AAC/B,UAAM,KAAK,SAAS,iBAAiB;AAAA,EACvC;AAEA,QAAM,cAAc,UAAU,eAAe;AAC7C,QAAM,KAAK;AAAA,+CAAkD,WAAW,GAAG;AAC3E,MAAI,UAAU,oBAAoB;AAChC,UAAM,KAAK,wBAAwB,SAAS,kBAAkB,EAAE;AAAA,EAClE;AAEA,QAAM;AAAA,IACJ,2FAA2F,UAAU;AAAA,IACrG;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,YAAY,SAA8B,aAA2C;AAC5F,QAAM,QAAkB,CAAC;AAEzB,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,8BAA8B;AACzC,eAAW,OAAO,YAAY,MAAM,GAAG,GAAG;AACxC,YAAM,SAAS,IAAI,SAAS,cAAc,UAAW,IAAI,YAAY;AACrE,YAAM,KAAK,IAAI,MAAM,MAAM,IAAI,OAAO,EAAE;AAAA,IAC1C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK;AAAA,EAAkC,QAAQ,OAAO,EAAE;AAC9D,SAAO,MAAM,KAAK,IAAI;AACxB;AAIA,eAAe,aACb,YACA,QAC+E;AAC/E,MAAI,WAAgC;AACpC,MAAI;AACF,eAAW,MAAM,WAAW,KAAK,0BAA0B;AAAA,MACzD,WAAW,WAAW;AAAA,IACxB,CAAC;AAAA,EACH,QAAQ;AACN,IAAAD,QAAO,KAAK,+CAA+C;AAAA,EAC7D;AAEA,MAAI,cAAoC,CAAC;AACzC,MAAI;AACF,kBAAc,MAAM,WAAW,KAAK,yBAAyB;AAAA,MAC3D,WAAW,WAAW;AAAA,MACtB,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AACN,IAAAA,QAAO,KAAK,qDAAqD;AAAA,EACnE;AAEA,SAAO,EAAE,UAAU,YAAY;AACjC;AAIA,SAAS,sBACP,UACA,YACA,YACA,qBAC6E;AAC7E,QAAM,QAAQ,UAAU,SAAS;AACjC,QAAM,WAAW,UAAU,iBAAiB,CAAC;AAE7C,QAAM,UAAU,cAAc;AAC9B,QAAM,YAAY,QAAQ,gBAAgB;AAAA,IACxC,MAAM;AAAA,IACN,OAAO,kBAAkB,YAAY,mBAAmB;AAAA,EAC1D,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQC,mBAAkB,YAAY,QAAQ;AAAA,MAChD;AAAA,MACA,KAAK;AAAA,MACL,gBAAgB;AAAA,MAChB,iCAAiC;AAAA,MACjC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,MACjE,YAAY,EAAE,UAAU,UAAU;AAAA,MAClC,UAAW,SAAS,YAAmC;AAAA,MACvD,cAAe,SAAS,gBAAuC;AAAA,MAC/D,QAAQ,SAAS;AAAA,MACjB,UAAU,SAAS;AAAA,IAKrB;AAAA,IACA;AAAA,EACF;AACF;AAUA,SAAS,oBACP,OACA,eACA,eACM;AACN,MAAI,MAAM,SAAS,UAAU,MAAM,MAAM;AACvC,kBAAc,KAAK,MAAM,IAAI;AAAA,EAC/B,WAAW,MAAM,SAAS,cAAc,MAAM,MAAM;AAClD,UAAM,WAAW,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK;AAC3F,kBAAc,KAAK;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,OAAO,SAAS,MAAM,GAAG,GAAM;AAAA,MAC/B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AACF;AAEA,SAAS,aACP,OACA,YACA,eACA,eACA,UACS;AACT,MAAI,MAAM,SAAS,aAAa;AAC9B,QAAI,CAAC,SAAS,OAAO;AACnB,iBAAW,MAAM,WAAW,UAAU,EAAE,MAAM,qBAAqB,CAAC,GAAG,GAAG;AAC1E,eAAS,QAAQ;AAAA,IACnB;AAEA,UAAM,iBAAiB;AACvB,eAAW,SAAS,eAAe,QAAQ,SAAS;AAClD,0BAAoB,OAAO,eAAe,aAAa;AAAA,IACzD;AAEA,QAAI,cAAc,SAAS,GAAG;AAC5B,iBAAW,UAAU,EAAE,MAAM,kBAAkB,QAAQ,CAAC,GAAG,aAAa,EAAE,CAAC;AAC3E,oBAAc,SAAS;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,UAAU;AAC3B,QAAI,SAAS,OAAO;AAClB,iBAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClD,eAAS,QAAQ;AAAA,IACnB;AACA,mBAAe,OAAO,UAAU;AAChC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAyB,YAAqC;AACpF,QAAM,cAAc;AAKpB,MAAI,YAAY,mBAAmB,UAAa,YAAY,iBAAiB,GAAG;AAC9E,eAAW,UAAU,EAAE,MAAM,eAAe,SAAS,YAAY,eAAe,CAAC;AAAA,EACnF;AACF;AAIA,eAAe,aACb,SACA,YACA,YACA,WAC6B;AAC7B,QAAM,EAAE,UAAU,YAAY,IAAI,MAAM,aAAa,YAAY,QAAQ,MAAM;AAK/E,QAAM,mBAAmB,QAAQ;AACjC,QAAM,EAAE,SAAS,QAAQ,IAAI;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACA,QAAM,SAAS,YAAY,SAAS,WAAW;AAE/C,aAAW,WAAW,MAAM;AAC5B,QAAM,SAAS,QAAQ,aAAa;AAAA,IAClC;AAAA,IACA;AAAA,IACA,GAAI,YAAY,EAAE,QAAQ,UAAU,IAAI,CAAC;AAAA,EAC3C,CAAC;AAED,QAAM,gBAA0B,CAAC;AACjC,QAAM,gBAAmC,CAAC;AAC1C,QAAM,WAAW,EAAE,OAAO,MAAM;AAChC,MAAI;AAEJ,mBAAiB,SAAS,QAAQ;AAChC,QAAI,MAAM,SAAS,UAAU;AAC3B,YAAM,cAAc;AACpB,wBAAkB,YAAY;AAAA,IAChC;AACA,UAAM,OAAO,aAAa,OAAO,YAAY,eAAe,eAAe,QAAQ;AACnF,QAAI,KAAM;AAAA,EACZ;AAEA,MAAI,SAAS,OAAO;AAClB,eAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,EACpD;AAEA,QAAM,eAAe,cAAc,KAAK,MAAM,EAAE,KAAK;AACrD,MAAI,cAAc;AAChB,UAAM,WAAW,KAAK,2BAA2B;AAAA,MAC/C,WAAW,WAAW;AAAA,MACtB,SAAS;AAAA,MACT,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAsB,yBACpB,SACA,YACA,YACA,WAC6B;AAC7B,aAAW,WAAW,MAAM;AAE5B,MAAI;AACF,WAAO,MAAM,aAAa,SAAS,YAAY,YAAY,SAAS;AAAA,EACtE,SAAS,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,IAAAD,QAAO,MAAM,4BAA4B,EAAE,OAAO,IAAI,CAAC;AACvD,QAAI;AACF,YAAM,WAAW,KAAK,2BAA2B;AAAA,QAC/C,WAAW,WAAW;AAAA,QACtB,SAAS;AAAA,QACT,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT,UAAE;AACA,eAAW,WAAW,MAAM;AAAA,EAC9B;AACF;;;AC9SO,SAAS,kBAAkB,OAAwB;AACxD,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;ACHA,SAAS,YAA+B;AACxC,SAAS,YAAAE,iBAAgB;AACzB,YAAY,UAAU;AACtB,SAAS,iBAAAC,sBAAqB;;;ACH9B,SAAS,YAAAC,iBAAgB;;;ACCzB,SAAS,YAAAC,iBAAgB;AAOzB,IAAMC,UAAS,oBAAoB,eAAe;AAElD,IAAM,4BAA4B;AASlC,eAAsB,oBACpB,YACA,YACe;AACf,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,IAAK;AAEV,EAAAA,QAAO,KAAK,yBAAyB,EAAE,SAAS,IAAI,CAAC;AACrD,MAAI;AACF,UAAM,gBAAgB,KAAK,YAAY,CAAC,QAAQ,SAAS;AACvD,iBAAW,UAAU,EAAE,MAAM,gBAAgB,QAAQ,KAAK,CAAC;AAC3D,OAAC,WAAW,WAAW,QAAQ,SAAS,QAAQ,QAAQ,MAAM,IAAI;AAAA,IACpE,CAAC;AACD,IAAAA,QAAO,KAAK,yBAAyB;AAAA,EACvC,SAAS,OAAO;AACd,UAAM,MAAM,kBAAkB,KAAK;AACnC,IAAAA,QAAO,MAAM,wBAAwB,EAAE,OAAO,IAAI,CAAC;AACnD,eAAW,UAAU,EAAE,MAAM,eAAe,SAAS,IAAI,CAAC;AAC1D,UAAM;AAAA,EACR;AACF;AAEO,SAAS,oBACd,YACA,OACA,YACM;AACN,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,IAAK;AAEV,EAAAA,QAAO,KAAK,yBAAyB,EAAE,SAAS,IAAI,CAAC;AACrD,QAAM,QAAQ,gBAAgB,KAAK,YAAY,CAAC,QAAQ,SAAS;AAC/D,eAAW,UAAU,EAAE,MAAM,wBAAwB,QAAQ,KAAK,CAAC;AACnE,KAAC,WAAW,WAAW,QAAQ,SAAS,QAAQ,QAAQ,MAAM,IAAI;AAAA,EACpE,CAAC;AAED,QAAM,QAAQ;AACd,QAAM,UAAU;AAEhB,QAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AACjC,UAAM,UAAU;AAChB,UAAM,QAAQ;AACd,IAAAA,QAAO,KAAK,wBAAwB,EAAE,MAAM,OAAO,CAAC;AACpD,eAAW,UAAU,EAAE,MAAM,wBAAwB,MAAM,OAAO,CAAC;AAAA,EACrE,CAAC;AAED,QAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,UAAM,UAAU;AAChB,UAAM,QAAQ;AACd,IAAAA,QAAO,MAAM,uBAAuB,EAAE,OAAO,IAAI,QAAQ,CAAC;AAAA,EAC5D,CAAC;AACH;AAEA,eAAsB,iBAAiB,OAAyC;AAC9E,QAAM,QAAQ,MAAM;AACpB,MAAI,CAAC,SAAS,CAAC,MAAM,QAAS;AAE9B,MAAI;AACF,QAAI,MAAM,IAAK,SAAQ,KAAK,CAAC,MAAM,KAAK,SAAS;AAAA,EACnD,QAAQ;AACN,UAAM,KAAK,SAAS;AAAA,EACtB;AAEA,QAAM,IAAI,QAAc,CAACC,aAAY;AACnC,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,MAAM,WAAW,MAAM,KAAK;AAC9B,YAAI;AACF,kBAAQ,KAAK,CAAC,MAAM,KAAK,SAAS;AAAA,QACpC,QAAQ;AACN,gBAAM,KAAK,SAAS;AAAA,QACtB;AAAA,MACF;AACA,MAAAA,SAAQ;AAAA,IACV,GAAG,yBAAyB;AAE5B,UAAM,GAAG,QAAQ,MAAM;AACrB,mBAAa,KAAK;AAClB,MAAAA,SAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAED,QAAM,QAAQ;AACd,QAAM,UAAU;AAClB;AAEA,eAAsB,oBACpB,YACA,OACA,YACe;AACf,QAAM,iBAAiB,KAAK;AAC5B,sBAAoB,YAAY,OAAO,UAAU;AACnD;AAIA,eAAsB,sBACpB,YACA,qBACA,OACA,YACA,UACe;AACf,MAAI;AACF,UAAM,iBAAiB,KAAK;AAE5B,UAAM,MAAM,uBAAuB,QAAQ,IAAI;AAC/C,QAAI,KAAK;AACP,UAAI;AACF,cAAM,gBAAgB,KAAK,YAAY,CAAC,QAAQ,SAAS;AACvD,qBAAW,UAAU,EAAE,MAAM,eAAe,QAAQ,KAAK,CAAC;AAAA,QAC5D,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,MAAM,kBAAkB,GAAG;AACjC,QAAAD,QAAO,MAAM,qCAAqC,EAAE,OAAO,IAAI,CAAC;AAAA,MAClE;AAAA,IACF;AAEA,wBAAoB,YAAY,OAAO,UAAU;AACjD,eAAW,EAAE,IAAI,KAAK,CAAC;AAAA,EACzB,SAAS,KAAK;AACZ,UAAM,MAAM,kBAAkB,GAAG;AACjC,IAAAA,QAAO,MAAM,2BAA2B,EAAE,OAAO,IAAI,CAAC;AACtD,eAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,EACtC;AACF;AAIO,SAAS,gBAAgB,YAAoB,aAAqB,QAA0B;AACjG,MAAI;AACF,WAAOE,UAAS,wBAAwB,WAAW,KAAK,MAAM,IAAI;AAAA,MAChE,KAAK;AAAA,MACL,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC,EACE,SAAS,EACT,KAAK,EACL,MAAM,IAAI,EACV,OAAO,OAAO;AAAA,EACnB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,uBACP,YACA,cACA,aACA,UACM;AACN,MAAI,cAAc;AAChB,QAAI;AACF,MAAAA,UAAS,eAAe,EAAE,KAAK,YAAY,SAAS,MAAS,OAAO,OAAO,CAAC;AAC5E,eAAS,KAAK,SAAS;AAAA,IACzB,SAAS,KAAK;AACZ,YAAM,MAAM,kBAAkB,GAAG;AACjC,MAAAF,QAAO,MAAM,sBAAsB,EAAE,OAAO,IAAI,CAAC;AAAA,IACnD;AAAA,EACF;AACA,MAAI,aAAa;AACf,QAAI;AACF,MAAAE,UAAS,wBAAwB,EAAE,KAAK,YAAY,SAAS,KAAQ,OAAO,OAAO,CAAC;AACpF,MAAAA,UAAS,0CAA0C;AAAA,QACjD,KAAK;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT,CAAC;AACD,eAAS,KAAK,QAAQ;AAAA,IACxB,SAAS,KAAK;AACZ,YAAM,MAAM,kBAAkB,GAAG;AACjC,MAAAF,QAAO,MAAM,sBAAsB,EAAE,OAAO,IAAI,CAAC;AAAA,IACnD;AAAA,EACF;AACF;AAEA,eAAsB,iBACpB,YACA,qBACA,YACA,cACA,UACe;AACf,QAAM,eAAe,aAAa;AAAA,IAChC,CAAC,MACC,MAAM,kBACN,MAAM,eACN,EAAE,SAAS,eAAe,KAC1B,EAAE,SAAS,YAAY;AAAA,EAC3B;AACA,QAAM,cAAc,aAAa;AAAA,IAC/B,CAAC,MAAM,EAAE,SAAS,sBAAsB,KAAK,EAAE,SAAS,oBAAoB;AAAA,EAC9E;AAEA,QAAM,MAAM,uBAAuB,QAAQ,IAAI;AAC/C,MAAI,QAAQ,gBAAgB,cAAc;AACxC,QAAI;AACF,YAAM,gBAAgB,KAAK,YAAY,CAAC,QAAQ,SAAS;AACvD,mBAAW,UAAU,EAAE,MAAM,eAAe,QAAQ,KAAK,CAAC;AAAA,MAC5D,CAAC;AACD,eAAS,KAAK,qBAAqB;AAAA,IACrC,SAAS,KAAK;AACZ,YAAM,MAAM,kBAAkB,GAAG;AACjC,MAAAA,QAAO,MAAM,gCAAgC,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF,WAAW,CAAC,KAAK;AACf,2BAAuB,YAAY,cAAc,aAAa,QAAQ;AAAA,EACxE;AACF;AAEA,eAAsB,UACpB,YACA,qBACA,OACA,YACA,aACA,QACA,QACmB;AACnB,MAAI,sBAAsB,UAAU,GAAG;AACrC,eAAW,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AACD,WAAO,CAAC,oBAAoB;AAAA,EAC9B;AAEA,QAAM,iBAAiB,KAAK;AAE5B,MAAI;AACF,IAAAE,UAAS,mBAAmB,MAAM,IAAI;AAAA,MACpC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,MAAM,kBAAkB,GAAG;AACjC,IAAAF,QAAO,MAAM,sCAAsC,EAAE,OAAO,IAAI,CAAC;AACjE,wBAAoB,YAAY,OAAO,UAAU;AACjD,WAAO,CAAC,YAAY;AAAA,EACtB;AAEA,QAAM,WAAW,CAAC,MAAM;AACxB,QAAM,eAAe,gBAAgB,YAAY,aAAa,MAAM;AACpE,QAAM,iBAAiB,YAAY,qBAAqB,YAAY,cAAc,QAAQ;AAE1F,sBAAoB,YAAY,OAAO,UAAU;AACjD,WAAS,KAAK,cAAc;AAC5B,SAAO;AACT;;;ADjQA,IAAMG,UAAS,oBAAoB,eAAe;AAI3C,SAAS,aACd,YACA,YAC4C;AAC5C,QAAM,EAAE,QAAQ,QAAQ,WAAW,YAAY,IAAI;AACnD,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,QAAM,iBAAiB,gBAAgB;AAEvC,MAAI;AACJ,MAAI,gBAAgB;AAClB,cAAU,eAAe,YAAY,QAAQ,SAAS;AAAA,EACxD,OAAO;AACL,cAAU;AAAA,EACZ;AAEA,MAAI,UAAU,WAAW,WAAW;AAClC,QAAI,sBAAsB,OAAO,GAAG;AAClC,MAAAA,QAAO,KAAK,0CAA0C,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,IACnF,OAAO;AACL,UAAI;AACF,QAAAC,UAAS,gBAAgB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,MACtE,QAAQ;AACN,YAAI;AACF,UAAAA,UAAS,mBAAmB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,QACzE,QAAQ;AACN,UAAAD,QAAO,KAAK,6BAA6B,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,cAAc,eAAe;AACjD;AAEO,SAAS,wBAAwB,YAA0B;AAChE,QAAM,kBAAkB,QAAQ,IAAI;AACpC,MAAI,CAAC,gBAAiB;AAEtB,QAAM,gBAAgB,iBAAoB,UAAU;AACpD,MAAI,kBAAkB,gBAAiB;AAEvC,MAAI,sBAAsB,UAAU,GAAG;AACrC,IAAAA,QAAO,KAAK,yDAAyD;AACrE;AAAA,EACF;AAEA,MAAI;AACF,IAAAC,UAAS,oBAAoB,eAAe,IAAI,EAAE,KAAK,YAAY,OAAO,OAAO,CAAC;AAClF,IAAAA,UAAS,gBAAgB,eAAe,IAAI,EAAE,KAAK,YAAY,OAAO,OAAO,CAAC;AAC9E,IAAAD,QAAO,KAAK,gCAAgC,EAAE,gBAAgB,CAAC;AAAA,EACjE,QAAQ;AACN,IAAAA,QAAO,KAAK,uCAAuC,EAAE,gBAAgB,CAAC;AAAA,EACxE;AACF;AAIA,eAAsB,mBACpB,YACA,qBACA,UACA,YACA,eACA,MACA,UACe;AACf,MAAI;AACF,QAAI;AACF,MAAAC,UAAS,oBAAoB,EAAE,KAAK,YAAY,OAAO,OAAO,CAAC;AAAA,IACjE,QAAQ;AACN,MAAAD,QAAO,KAAK,uCAAuC;AAAA,IACrD;AAEA,yBAAqB,YAAY,KAAK,MAAM;AAE5C,QAAI;AACF,MAAAC,UAAS,gBAAgB,KAAK,MAAM,IAAI,EAAE,KAAK,YAAY,OAAO,OAAO,CAAC;AAAA,IAC5E,SAAS,KAAK;AACZ,YAAM,MAAM,kBAAkB,GAAG;AACjC,eAAS,EAAE,IAAI,OAAO,OAAO,8BAA8B,GAAG,GAAG,CAAC;AAClE;AAAA,IACF;AAEA,QAAI;AACF,MAAAA,UAAS,mBAAmB,KAAK,MAAM,IAAI,EAAE,KAAK,YAAY,OAAO,OAAO,CAAC;AAAA,IAC/E,QAAQ;AACN,MAAAD,QAAO,KAAK,sCAAsC;AAAA,IACpD;AAEA,QAAI,KAAK,cAAc,OAAO;AAC5B,YAAM,sBAAsB,YAAY,qBAAqB,UAAU,UAAU;AAAA,IACnF;AAEA,kBAAc,MAAM,KAAK,MAAM;AAC/B,aAAS,EAAE,IAAI,KAAK,CAAC;AAAA,EACvB,SAAS,KAAK;AACZ,UAAM,MAAM,kBAAkB,GAAG;AACjC,IAAAA,QAAO,MAAM,wBAAwB,EAAE,OAAO,IAAI,CAAC;AACnD,aAAS,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,EACpC;AACF;AAIA,eAAsB,iBACpB,YACA,qBACA,UACA,YACA,eACA,MAQe;AACf,QAAM,WAAW,KAAK,4BAA4B;AAAA,IAChD,WAAW,WAAW;AAAA,IACtB,QAAQ,KAAK;AAAA,IACb,SAAS;AAAA,MACP;AAAA,QACE,KAAK,KAAK;AAAA,QACV,SAAS,KAAK;AAAA,QACd,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEA,QAAM,WAAW,KAAK,0BAA0B;AAAA,IAC9C,WAAW,WAAW;AAAA,IACtB,QAAQ,KAAK;AAAA,IACb;AAAA,IACA,qBAAqB,SAAS;AAAA,EAChC,CAAC;AAED,EAAAA,QAAO,KAAK,wBAAwB,EAAE,OAAO,SAAS,KAAK,IAAI,EAAE,CAAC;AACpE;;;ADxJA,IAAME,UAAS,oBAAoB,eAAe;AAElD,IAAM,aAAaC,eAAc,YAAY,GAAG;AAChD,IAAM,YAAiB,aAAQ,UAAU;AAElC,IAAM,kBAAkB;AAC/B,IAAM,iBAAiB,KAAK,IAAI,GAAG,SAAS,QAAQ,IAAI,2BAA2B,MAAM,EAAE,KAAK,EAAE;AAyBlG,SAAS,qBACP,UACA,OACwB;AACxB,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,SAAS;AAChB,SAAO,EAAE,yBAAyB,MAAM;AAC1C;AAEO,SAAS,gBAAgB,YAA4B,SAA+B;AACzF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,UAAe,aAAQ,WAAW,QAAQ;AAEhD,QAAM,WAAW,EAAE,GAAG,QAAQ,IAAI;AAClC,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO,SAAS;AAEhB,QAAM,gBAAgB,qBAAqB,UAAU,oBAAoB;AAEzE,QAAM,qBAAqB,cAAc,SAAS,SAAS;AAI3D,QAAM,kBAAkB,UAAU,QAAQ,IAAI,oBAAoB;AAClE,MAAI,CAAC,iBAAiB;AACpB,IAAAD,QAAO,MAAM,wCAAwC,EAAE,QAAQ,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;AAAA,EACrF;AAEA,QAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;AAAA,IAC9B,KAAK;AAAA,MACH,GAAG;AAAA,MACH,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,kBAAkB;AAAA,MAClB,GAAI,YAAY,EAAE,qBAAqB,UAAU,IAAI,CAAC;AAAA,MACtD,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,MACvB,qBAAqB;AAAA,MACrB,kBAAkB,SAAS,SAAS;AAAA,MACpC,sBAAsB,eAAe,OAAO,SAAS;AAAA,MACrD,GAAI,MAAM,EAAE,kBAAkB,MAAM,IAAI,CAAC;AAAA,MACzC,GAAG;AAAA,IACL;AAAA,IACA,KAAK;AAAA,IACL,OAAO,CAAC,QAAQ,QAAQ,QAAQ,KAAK;AAAA,EACvC,CAAC;AAED,QAAM,OAAO,GAAG,SAAS,MAAM;AAAA,EAAC,CAAC;AACjC,QAAM,QAAQ,GAAG,SAAS,MAAM;AAAA,EAAC,CAAC;AAClC,QAAM,QAAQ,GAAG,SAAS,MAAM;AAAA,EAAC,CAAC;AAElC,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,QAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,eAAW,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG;AACxD,MAAAA,QAAO,KAAK,MAAM,EAAE,QAAQ,QAAQ,CAAC;AAAA,IACvC;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,eAAW,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG;AAExD,MAAAA,QAAO,KAAK,MAAM,EAAE,QAAQ,QAAQ,CAAC;AAAA,IACvC;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,eAAsB,UAAU,OAAoB,QAA+B;AACjF,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AAGjC,MAAI,MAAM,QAAQ,aAAa,MAAM;AACnC,IAAAA,QAAO,KAAK,gCAAgC,EAAE,QAAQ,QAAQ,CAAC;AAC/D;AAAA,EACF;AAEA,EAAAA,QAAO,KAAK,yBAAyB,EAAE,QAAQ,QAAQ,CAAC;AACxD,QAAM,QAAQ,KAAK,SAAS;AAE5B,QAAM,IAAI,QAAc,CAACE,aAAY;AACnC,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,MAAM,QAAQ,aAAa,MAAM;AACnC,QAAAF,QAAO,KAAK,qDAAqD,EAAE,QAAQ,QAAQ,CAAC;AACpF,cAAM,QAAQ,KAAK,SAAS;AAAA,MAC9B;AACA,MAAAE,SAAQ;AAAA,IACV,GAAG,eAAe;AAElB,UAAM,QAAQ,GAAG,QAAQ,MAAM;AAC7B,mBAAa,KAAK;AAClB,MAAAA,SAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,iBACpB,YACA,cACA,YACA,YACe;AACf,QAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,QAAM,WAAW,SAAS,gBAAgB,GAAG,MAAM,iBAAiB;AAEpE,QAAM,WAAW,aAAa,IAAI,QAAQ;AAC1C,MAAI,UAAU;AACZ,QAAI,SAAS,QAAQ,aAAa,MAAM;AAEtC,MAAAF,QAAO,KAAK,kDAAkD,EAAE,QAAQ,QAAQ,CAAC;AACjF,YAAM,UAAU,UAAU,MAAM;AAAA,IAClC,OAAO;AAEL,MAAAA,QAAO,KAAK,2DAA2D,EAAE,QAAQ,QAAQ,CAAC;AAAA,IAC5F;AACA,iBAAa,OAAO,QAAQ;AAAA,EAC9B;AAEA,MAAI,aAAa,QAAQ,gBAAgB;AACvC,IAAAA,QAAO,KAAK,iCAAiC,EAAE,eAAe,eAAe,CAAC;AAC9E,eAAW,gBAAgB,QAAQ,wBAAwB;AAC3D;AAAA,EACF;AAEA,MAAI;AACF,QAAI;AACF,MAAAG,UAAS,oBAAoB,EAAE,KAAK,YAAY,OAAO,SAAS,CAAC;AAAA,IACnE,QAAQ;AACN,MAAAH,QAAO,KAAK,oBAAoB,EAAE,QAAQ,QAAQ,CAAC;AAAA,IACrD;AAEA,UAAM,EAAE,SAAS,aAAa,IAAI,aAAa,YAAY,UAAU;AAErE,QAAI,WAAW,WAAW;AACxB,yBAAmB,SAAS,WAAW,SAAS;AAAA,IAClD;AAEA,UAAM,QAAQ,gBAAgB,YAAY,OAAO;AAEjD,iBAAa,IAAI,UAAU;AAAA,MACzB,SAAS;AAAA,MACT,cAAc;AAAA,MACd;AAAA,MACA;AAAA,IACF,CAAC;AACD,eAAW,gBAAgB,MAAM;AACjC,IAAAA,QAAO,KAAK,gBAAgB,EAAE,QAAQ,SAAS,MAAM,QAAQ,CAAC;AAE9D,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,mBAAa,OAAO,QAAQ;AAC5B,YAAM,SAAS,SAAS,IAAI,cAAc,oBAAoB,IAAI;AAClE,iBAAW,gBAAgB,QAAQ,MAAM;AACzC,MAAAA,QAAO,KAAK,eAAe,EAAE,QAAQ,SAAS,OAAO,CAAC;AACtD,UAAI,SAAS,KAAK,cAAc;AAC9B,YAAI;AACF,yBAAe,YAAY,MAAM;AAAA,QACnC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,MAAM,kBAAkB,KAAK;AACnC,IAAAA,QAAO,MAAM,wBAAwB,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AACpE,eAAW,gBAAgB,QAAQ,iBAAiB,GAAG,EAAE;AAAA,EAC3D;AACF;AAEO,SAAS,eACd,QACA,cACA,YACM;AACN,QAAM,WAAW,aAAa,IAAI,MAAM,IAAI,SAAS,GAAG,MAAM;AAC9D,QAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,MAAO;AAEZ,EAAAA,QAAO,KAAK,iBAAiB,EAAE,QAAQ,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;AAE3D,OAAK,UAAU,OAAO,MAAM,EAAE,KAAK,MAAM;AACvC,QAAI,MAAM,cAAc;AACtB,UAAI;AACF,uBAAe,YAAY,MAAM;AAAA,MACnC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AGpNA,IAAMI,WAAS,oBAAoB,eAAe;AAElD,IAAM,wBAAwB;AAWvB,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,eAAe,oBAAI,IAAyB;AAAA,EAC5C,iBAAwD;AAAA,EACxD,WAAW;AAAA,EACX,mBAAwC;AAAA,EACxC,iBAAiB,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA,EAIzC,mBAAkC;AAAA,EAElC,WAA8B,EAAE,OAAO,MAAM,SAAS,MAAM;AAAA,EAC5D,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EAER,YAAY,QAA6B;AACvC,SAAK,aAAa,OAAO;AACzB,SAAK,aAAa,IAAI,kBAAkB;AAAA,MACtC,QAAQ,OAAO;AAAA,MACf,cAAc,OAAO;AAAA,MACrB,WAAW,OAAO;AAAA,IACpB,CAAC;AACD,SAAK,gBAAgB,IAAI;AAAA,MACvB;AAAA,QACE,YAAY,KAAK;AAAA,QACjB,gBAAgB,OAAO,QAAQ,IAAI,6BAA6B,KAAK;AAAA,QACrE,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,cAAc,OAAO,SAAS;AAC5B,gBAAM;AAAA,YACJ,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,QAAuB;AAC3B,4BAAwB,KAAK,UAAU;AACvC,UAAM,KAAK,WAAW,QAAQ;AAG9B,UAAM,eAAe,MAAM,KAAK,WAAW,KAAK,wBAAwB;AAAA,MACtE,WAAW,KAAK,WAAW;AAAA,MAC3B,cAAc,CAAC,QAAQ,MAAM,eAAe,OAAO;AAAA,IACrD,CAAC;AACD,SAAK,mBAAmB,aAAa;AACrC,SAAK,sBACH,aAAa,uBAAuB,QAAQ,IAAI;AAElD,IAAAA,SAAO,KAAK,+BAA+B,EAAE,WAAW,aAAa,UAAU,CAAC;AAGhF,QAAI;AACF,YAAM,oBAAoB,KAAK,YAAY,KAAK,UAAU;AAC1D,0BAAoB,KAAK,YAAY,KAAK,UAAU,KAAK,UAAU;AACnE,WAAK,gBAAgB;AACrB,WAAK,WAAW,UAAU;AAAA,QACxB,MAAM;AAAA,QACN,qBAAqB,KAAK,SAAS;AAAA,MACrC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,MAAM,kBAAkB,KAAK;AACnC,MAAAA,SAAO,MAAM,4BAA4B,EAAE,OAAO,IAAI,CAAC;AACvD,WAAK,gBAAgB;AAAA,IACvB;AAGA,SAAK,kBAAkB;AAGvB,SAAK,WAAW,YAAY,MAAM,KAAK,KAAK,gBAAgB,CAAC;AAG7D,SAAK,iBAAiB,YAAY,MAAM;AACtC,WAAK,WAAW,cAAc;AAAA,IAChC,GAAG,qBAAqB;AAGxB,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAI,eAAe;AACjB,WAAK,cAAc,MAAM,aAAa;AAAA,IACxC;AAEA,IAAAA,SAAO,KAAK,yCAAyC;AAErD,UAAM,IAAI,QAAc,CAACC,aAAY;AACnC,WAAK,mBAAmBA;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAoC;AACxC,UAAM,OAAO,oBAAI,IAAY,CAAC,KAAK,UAAU,CAAC;AAC9C,eAAW,SAAS,KAAK,aAAa,OAAO,GAAG;AAC9C,UAAI,MAAM,aAAc,MAAK,IAAI,MAAM,YAAY;AAAA,IACrD;AAEA,eAAW,OAAO,MAAM;AACtB,UAAI;AACF,cAAM,SAAS,MAAM,oBAAoB,KAAK;AAAA,UAC5C,YAAY;AAAA,QACd,CAAC;AACD,YAAI,OAAO,SAAS;AAClB,UAAAD,SAAO,KAAK,sBAAsB;AAAA,YAChC;AAAA,YACA,WAAW,OAAO;AAAA,YAClB,QAAQ,OAAO;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,cAAM,MAAM,kBAAkB,GAAG;AACjC,QAAAA,SAAO,KAAK,6BAA6B,EAAE,KAAK,OAAO,IAAI,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAChB,IAAAA,SAAO,KAAK,eAAe;AAE3B,SAAK,cAAc,KAAK;AACxB,UAAM,iBAAiB,KAAK,QAAQ;AAEpC,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAEA,UAAM,eAAe,CAAC,GAAG,KAAK,aAAa,KAAK,CAAC,EAAE;AAAA,MACjD,CAAC,QACC,IAAI,QAAc,CAACC,aAAY;AAC7B,cAAM,QAAQ,KAAK,aAAa,IAAI,GAAG;AACvC,YAAI,CAAC,OAAO;AACV,UAAAA,SAAQ;AACR;AAAA,QACF;AACA,cAAM,QAAQ,GAAG,QAAQ,MAAMA,SAAQ,CAAC;AACxC,uBAAe,KAAK,KAAK,cAAc,KAAK,UAAU;AAAA,MACxD,CAAC;AAAA,IACL;AAEA,UAAM,QAAQ,KAAK;AAAA,MACjB,QAAQ,IAAI,YAAY;AAAA,MACxB,IAAI,QAAc,CAACA,aAAY;AAC7B,mBAAWA,UAAS,kBAAkB,GAAK;AAAA,MAC7C,CAAC;AAAA,IACH,CAAC;AAID,UAAM,KAAK,mBAAmB;AAG9B,QAAI;AACF,YAAM,KAAK,WAAW,KAAK,2BAA2B;AAAA,QACpD,WAAW,KAAK,WAAW;AAAA,MAC7B,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AACA,SAAK,WAAW,WAAW;AAC3B,IAAAD,SAAO,KAAK,mBAAmB;AAE/B,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA,EAIQ,oBAA0B;AAChC,SAAK,WAAW;AAAA,MACd,CAAC,eACC,KAAK,iBAAiB,YAAY,KAAK,cAAc,KAAK,YAAY,KAAK,UAAU;AAAA,IACzF;AACA,SAAK,WAAW;AAAA,MAAW,CAAC,SAC1B,eAAe,KAAK,QAAQ,KAAK,cAAc,KAAK,UAAU;AAAA,IAChE;AACA,SAAK,WAAW,WAAW,MAAM,KAAK,KAAK,KAAK,CAAC;AAGjD,SAAK,WAAW,aAAa,MAAM,KAAK,KAAK,KAAK,CAAC;AAEnD,SAAK,WAAW,cAAc,CAAC,QAAQ;AAIrC,UACE,IAAI,mBACJ,KAAK,oBACL,IAAI,oBAAoB,KAAK,kBAC7B;AACA;AAAA,MACF;AACA,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,oBAAoB,KAAK,eAAe,IAAI,MAAM;AACxD,WAAK,yBAAyB,KAAK,KAAK,YAAY,KAAK,YAAY,iBAAiB,EAAE;AAAA,QACtF,CAAC,iBAAiB;AAChB,cAAI,aAAc,MAAK,eAAe,IAAI,QAAQ,YAAY;AAAA,QAChE;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,WAAW,YAAY,CAAC,YAAY,KAAK,KAAK,gBAAgB,OAAO,CAAC;AAC3E,SAAK,WAAW,aAAa,CAAC,YAAY,KAAK,KAAK,iBAAiB,OAAO,CAAC;AAE7E,SAAK,WAAW;AAAA,MACd,CAAC,MAAM,OACL,KAAK;AAAA,QACH,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACJ;AACA,SAAK,WAAW;AAAA,MACd,CAAC,OACC,KAAK;AAAA,QACH,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACJ;AACA,SAAK,WAAW,sBAAsB,CAAC,OAAO;AAC5C,WAAK,oBAAoB,KAAK,YAAY,KAAK,UAAU,KAAK,UAAU,EACrE,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,CAAC,CAAC,EAC3B;AAAA,QAAM,CAAC,QACN,GAAG,EAAE,IAAI,OAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,iBAAiB,CAAC;AAAA,MAChF;AAAA,IACJ,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,kBAAiC;AAC7C,QAAI;AACF,YAAM,eAAe,MAAM,KAAK,WAAW,KAAK,wBAAwB;AAAA,QACtE,WAAW,KAAK,WAAW;AAAA,QAC3B,cAAc,CAAC,QAAQ,MAAM,eAAe,OAAO;AAAA,MACrD,CAAC;AACD,WAAK,mBAAmB,aAAa;AACrC,WAAK,WAAW,WAAW,KAAK,aAAa,OAAO,IAAI,SAAS,MAAM;AACvE,MAAAA,SAAO,KAAK,+BAA+B;AAAA,IAC7C,SAAS,OAAO;AACd,YAAM,MAAM,kBAAkB,KAAK;AACnC,MAAAA,SAAO,MAAM,yCAAyC,EAAE,OAAO,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,gBACZ,SACe;AACf,SAAK,WAAW,WAAW,MAAM;AACjC,QAAI;AACF,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,iCAAwB;AAChE,YAAM,eAAe,SAAS,KAAK,YAAY,KAAK,UAAU;AAAA,IAChE,SAAS,OAAO;AACd,YAAM,MAAM,kBAAkB,KAAK;AACnC,MAAAA,SAAO,MAAM,oBAAoB,EAAE,OAAO,KAAK,WAAW,QAAQ,UAAU,CAAC;AAC7E,UAAI;AACF,cAAM,KAAK,WAAW,KAAK,wBAAwB;AAAA,UACjD,WAAW,KAAK,WAAW;AAAA,UAC3B,WAAW,QAAQ;AAAA,UACnB,iBAAiB,CAAC;AAAA,UAClB,SAAS,iBAAiB,GAAG;AAAA,UAC7B,UAAU;AAAA,QACZ,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF,UAAE;AACA,WAAK,WAAW,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,iBACZ,SACe;AACf,SAAK,WAAW,WAAW,MAAM;AACjC,QAAI;AACF,YAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,kCAAyB;AAClE,YAAM,gBAAgB,SAAS,KAAK,YAAY,KAAK,UAAU;AAAA,IACjE,SAAS,OAAO;AACd,YAAM,MAAM,kBAAkB,KAAK;AACnC,MAAAA,SAAO,MAAM,qBAAqB,EAAE,OAAO,KAAK,WAAW,QAAQ,UAAU,CAAC;AAC9E,iBAAW,QAAQ,QAAQ,OAAO;AAChC,YAAI;AACF,gBAAM,KAAK,WAAW,KAAK,yBAAyB;AAAA,YAClD,WAAW,KAAK,WAAW;AAAA,YAC3B,WAAW,QAAQ;AAAA,YACnB,QAAQ,KAAK;AAAA,YACb,SAAS;AAAA,YACT,YAAY,CAAC;AAAA,YACb,kBAAkB;AAAA,YAClB,kBAAkB;AAAA,YAClB,eAAe;AAAA,YACf,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,cAAc;AAAA,YACd,cAAc;AAAA,YACd,cAAc;AAAA,YACd,eAAe,CAAC;AAAA,YAChB,cAAc;AAAA,YACd,OAAO;AAAA,YACP,OAAO,iBAAiB,GAAG;AAAA,UAC7B,CAAC;AAAA,QACH,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,KAAK,WACR,KAAK,gCAAgC;AAAA,QACpC,WAAW,KAAK,WAAW;AAAA,QAC3B,WAAW,QAAQ;AAAA,MACrB,CAAC,EACA,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB,UAAE;AACA,WAAK,WAAW,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,mBAAkC;AACxC,WAAO,iBAAoB,KAAK,UAAU;AAAA,EAC5C;AACF;;;AC7YA,SAAS,YAAAE,iBAAgB;AACzB,SAAS,QAAAC,aAAY;AAcrB,IAAM,oBAAoB;AAG1B,IAAM,8BAA8B,oBAAI,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC;AAE9D,eAAsB,iBAAiB,cAAmD;AACxF,MAAI;AACF,UAAM,MAAM,MAAMD,UAASC,MAAK,cAAc,iBAAiB,GAAG,OAAO;AACzE,UAAM,SAAS,KAAK,MAAM,GAAG;AAI7B,UAAM,SAAS,OAAO,gBAAgB,CAAC,GAAG;AAAA,MACxC,CAAC,MAAM,OAAO,MAAM,YAAY,CAAC,4BAA4B,IAAI,CAAC;AAAA,IACpE;AACA,UAAM,aAA+C,CAAC;AACtD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,mBAAmB,CAAC,CAAC,GAAG;AACvE,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,YAAM,QAA+D,CAAC;AACtE,UAAI,OAAO,MAAM,UAAU,SAAU,OAAM,QAAQ,MAAM;AACzD,UAAI,MAAM,eAAe,YAAY,MAAM,eAAe,WAAW;AACnE,cAAM,aAAa,MAAM;AAAA,MAC3B;AACA,iBAAW,GAAG,IAAI;AAAA,IACpB;AACA,WAAO,EAAE,OAAO,WAAW;AAAA,EAC7B,QAAQ;AACN,WAAO,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC,EAAE;AAAA,EACrC;AACF;AAKO,SAAS,yBAAyB,QAAkD;AACzF,SAAO,OAAO,MACX,OAAO,CAAC,SAAS,CAAC,4BAA4B,IAAI,IAAI,CAAC,EACvD,IAAI,CAAC,SAAS;AACb,UAAM,OAAO,OAAO,WAAW,OAAO,IAAI,CAAC;AAC3C,UAAM,QAA4B,EAAE,KAAK;AACzC,QAAI,MAAM,MAAO,OAAM,QAAQ,KAAK;AACpC,QAAI,MAAM,WAAY,OAAM,aAAa,KAAK;AAC9C,WAAO;AAAA,EACT,CAAC;AACL;AAGO,SAAS,qBAA4C;AAC1D,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,UAAU,QAAQ,IAAI;AAC5B,MAAI,YAAY,UAAU;AACxB,WAAO;AAAA,MACL,cAAc;AAAA,MACd,cAAc;AAAA,MACd,aAAa,UAAU,OAAO,OAAO,IAAI;AAAA,IAC3C;AAAA,EACF;AACA,SAAO;AACT;;;AC1EA,SAAS,YAAAC,iBAAgB;AAGlB,SAAS,cAAc,cAA4B;AACxD,MAAI;AACF,IAAAA,UAAS,yBAAyB;AAAA,MAChC,KAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;","names":["resolve","resolve","stat","readFileSync","findLastAgentMessageIndex","hasNewUserMessages","parts","z","z","z","z","z","z","result","readFile","stat","join","z","z","path","join","stat","readFile","z","z","z","z","z","SP_DESCRIPTION","z","z","z","z","z","z","z","formatError","z","requireDebugClient","formatError","z","isAuthError","result","resolve","logger","IMAGE_ERROR_PATTERN","RETRY_DELAYS_MS","path","readFileSync","resolve","isAuthError","logger","readFileSync","join","execSync","execSync","resolve","io","logger","EVENT_BATCH_MS","resolve","io","execSync","logger","execSync","execSync","existsSync","join","join","existsSync","execSync","execSync","resolve","z","z","SP_DESCRIPTION","z","buildCreateSubtaskTool","buildUpdateSubtaskTool","buildDeleteSubtaskTool","z","buildCreateSuggestionTool","z","buildVoteSuggestionTool","buildAddDependencyTool","buildRemoveDependencyTool","z","buildListSubtasksTool","buildPostToChatTool","buildReadTaskChatTool","logger","buildSystemPrompt","execSync","fileURLToPath","execSync","execSync","logger","resolve","execSync","logger","execSync","logger","fileURLToPath","resolve","execSync","logger","resolve","readFile","join","execSync"]}