@rallycry/conveyor-agent 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -276,6 +276,23 @@ var ConveyorConnection = class _ConveyorConnection {
276
276
  });
277
277
  });
278
278
  }
279
+ fetchCliHistory(taskId, limit, source) {
280
+ const socket = this.socket;
281
+ if (!socket) throw new Error("Not connected");
282
+ return new Promise((resolve2, reject) => {
283
+ socket.emit(
284
+ "agentRunner:getCliHistory",
285
+ { taskId: taskId ?? this.config.taskId, limit, source },
286
+ (response) => {
287
+ if (response.success && response.data) {
288
+ resolve2(response.data);
289
+ } else {
290
+ reject(new Error(response.error ?? "Failed to fetch CLI history"));
291
+ }
292
+ }
293
+ );
294
+ });
295
+ }
279
296
  fetchTask(slugOrId) {
280
297
  const socket = this.socket;
281
298
  if (!socket) throw new Error("Not connected");
@@ -1159,6 +1176,39 @@ import { createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
1159
1176
  // src/tools/common-tools.ts
1160
1177
  import { tool } from "@anthropic-ai/claude-agent-sdk";
1161
1178
  import { z } from "zod";
1179
+ function formatCliEvent(e) {
1180
+ switch (e.type) {
1181
+ case "thinking":
1182
+ return e.message ?? "";
1183
+ case "tool_use": {
1184
+ const tu = e;
1185
+ return `${tu.tool}: ${tu.input?.slice(0, 1e3) ?? ""}`;
1186
+ }
1187
+ case "tool_result": {
1188
+ const tr = e;
1189
+ return `${tr.tool} \u2192 ${tr.output?.slice(0, 500) ?? ""}${tr.isError ? " [ERROR]" : ""}`;
1190
+ }
1191
+ case "message":
1192
+ return e.content ?? "";
1193
+ case "error":
1194
+ return `ERROR: ${e.message ?? ""}`;
1195
+ case "completed": {
1196
+ const c = e;
1197
+ return `Completed: ${c.summary ?? ""} (cost: $${c.costUsd ?? "?"}, duration: ${c.durationMs ?? "?"}ms)`;
1198
+ }
1199
+ case "setup_output":
1200
+ case "start_command_output": {
1201
+ const so = e;
1202
+ return `[${so.stream ?? "stdout"}] ${so.data ?? ""}`;
1203
+ }
1204
+ case "turn_end": {
1205
+ const te = e;
1206
+ return `Turn complete (${te.toolCalls?.length ?? 0} tool calls)`;
1207
+ }
1208
+ default:
1209
+ return JSON.stringify(e);
1210
+ }
1211
+ }
1162
1212
  function buildCommonTools(connection, config) {
1163
1213
  return [
1164
1214
  tool(
@@ -1233,6 +1283,32 @@ function buildCommonTools(connection, config) {
1233
1283
  },
1234
1284
  { annotations: { readOnlyHint: true } }
1235
1285
  ),
1286
+ tool(
1287
+ "get_task_cli",
1288
+ "Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events. Use 'source' to filter: 'agent' for agent reasoning/tool calls only, 'application' for setup/dev-server output only.",
1289
+ {
1290
+ task_id: z.string().optional().describe("Task ID or slug. Omit to read logs from the current task."),
1291
+ source: z.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
1292
+ limit: z.number().optional().describe("Max number of log entries to return (default 100, max 500).")
1293
+ },
1294
+ async ({ task_id, source, limit }) => {
1295
+ try {
1296
+ const effectiveLimit = Math.min(limit ?? 100, 500);
1297
+ const result = await connection.fetchCliHistory(task_id, effectiveLimit, source);
1298
+ const formatted = result.map((entry) => {
1299
+ const time = entry.time;
1300
+ const e = entry.event;
1301
+ return `[${time}] [${e.type}] ${formatCliEvent(e)}`;
1302
+ }).join("\n");
1303
+ return textResult(formatted || "No CLI logs found.");
1304
+ } catch (error) {
1305
+ return textResult(
1306
+ `Failed to fetch CLI logs: ${error instanceof Error ? error.message : "Unknown error"}`
1307
+ );
1308
+ }
1309
+ },
1310
+ { annotations: { readOnlyHint: true } }
1311
+ ),
1236
1312
  tool(
1237
1313
  "list_task_files",
1238
1314
  "List all files attached to this task with metadata (name, type, size) and download URLs",
@@ -1829,6 +1905,7 @@ var PlanSync = class {
1829
1905
 
1830
1906
  // src/runner/agent-runner.ts
1831
1907
  var HEARTBEAT_INTERVAL_MS = 3e4;
1908
+ var IDLE_TIMEOUT_MS = 10 * 60 * 1e3;
1832
1909
  var AgentRunner = class _AgentRunner {
1833
1910
  config;
1834
1911
  connection;
@@ -2124,12 +2201,25 @@ ${f.content}
2124
2201
  const checkStopped = setInterval(() => {
2125
2202
  if (this.stopped) {
2126
2203
  clearInterval(checkStopped);
2204
+ clearTimeout(idleTimer);
2127
2205
  this.inputResolver = null;
2128
2206
  resolve2(null);
2129
2207
  }
2130
2208
  }, 1e3);
2209
+ const idleTimer = setTimeout(() => {
2210
+ clearInterval(checkStopped);
2211
+ this.inputResolver = null;
2212
+ console.log(
2213
+ `[conveyor-agent] Idle for ${IDLE_TIMEOUT_MS / 6e4} minutes \u2014 shutting down.`
2214
+ );
2215
+ this.connection.postChatMessage(
2216
+ `Agent idle for ${IDLE_TIMEOUT_MS / 6e4} minutes with no new messages \u2014 shutting down.`
2217
+ );
2218
+ resolve2(null);
2219
+ }, IDLE_TIMEOUT_MS);
2131
2220
  this.inputResolver = (msg) => {
2132
2221
  clearInterval(checkStopped);
2222
+ clearTimeout(idleTimer);
2133
2223
  resolve2(msg);
2134
2224
  };
2135
2225
  });
@@ -2620,4 +2710,4 @@ export {
2620
2710
  ProjectRunner,
2621
2711
  FileCache
2622
2712
  };
2623
- //# sourceMappingURL=chunk-22ME6AB3.js.map
2713
+ //# sourceMappingURL=chunk-HWMZ626Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/task-connection.ts","../src/connection/project-connection.ts","../src/setup/config.ts","../src/setup/commands.ts","../src/setup/codespace.ts","../src/runner/worktree.ts","../src/runner/agent-runner.ts","../src/execution/event-processor.ts","../src/execution/query-executor.ts","../src/execution/prompt-builder.ts","../src/tools/index.ts","../src/tools/common-tools.ts","../src/tools/pm-tools.ts","../src/tools/task-tools.ts","../src/execution/cost-tracker.ts","../src/runner/plan-sync.ts","../src/runner/project-runner.ts","../src/runner/project-chat-handler.ts","../src/runner/file-cache.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type {\n AgentRunnerConfig,\n TaskContext,\n AgentEvent,\n IncomingMessagePayload,\n QuestionAnswerPayload,\n AgentQuestion,\n SocketResponse,\n ChatMessageResponse,\n TaskFileResponse,\n TaskLookupResponse,\n SubtaskCreatePayload,\n SubtaskUpdateFields,\n SubtaskResponse,\n PmSubMode,\n SetModePayload,\n} from \"../types.js\";\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\n private eventBuffer: { event: AgentEvent }[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly EVENT_BATCH_MS = 500;\n\n private earlyMessages: IncomingMessagePayload[] = [];\n private earlyStop = false;\n private earlyModeChanges: SetModePayload[] = [];\n private chatMessageCallback: ((msg: IncomingMessagePayload) => void) | null = null;\n private stopCallback: (() => void) | null = null;\n private modeChangeCallback: ((data: SetModePayload) => void) | null = null;\n private pendingQuestionResolvers = new Map<string, (answers: Record<string, string>) => void>();\n\n constructor(config: AgentRunnerConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.conveyorApiUrl, {\n auth: { taskToken: this.config.taskToken, runnerMode: this.config.mode ?? \"task\" },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n this.socket.on(\"agentRunner:incomingMessage\", (msg: IncomingMessagePayload) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyMessages.push(msg);\n }\n });\n\n this.socket.on(\"agentRunner:stop\", () => {\n if (this.stopCallback) {\n this.stopCallback();\n } else {\n this.earlyStop = true;\n }\n });\n\n this.socket.on(\"agentRunner:questionAnswer\", (data: QuestionAnswerPayload) => {\n const resolver = this.pendingQuestionResolvers.get(data.requestId);\n if (resolver) {\n this.pendingQuestionResolvers.delete(data.requestId);\n resolver(data.answers);\n }\n });\n\n this.socket.on(\"agentRunner:setMode\", (data: SetModePayload) => {\n if (this.modeChangeCallback) {\n this.modeChangeCallback(data);\n } else {\n this.earlyModeChanges.push(data);\n }\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n fetchChatMessages(limit?: number): Promise<ChatMessageResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getChatMessages\",\n { limit },\n (response: SocketResponse<ChatMessageResponse[]>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch chat messages\"));\n }\n },\n );\n });\n }\n\n fetchTaskFiles(): Promise<TaskFileResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskFiles\",\n {},\n (response: SocketResponse<TaskFileResponse[]>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task files\"));\n }\n },\n );\n });\n }\n\n fetchTaskFile(fileId: string): Promise<TaskFileResponse> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskFile\",\n { fileId },\n (response: SocketResponse<TaskFileResponse>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task file\"));\n }\n },\n );\n });\n }\n\n fetchTaskContext(): Promise<TaskContext> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskContext\",\n {},\n (response: SocketResponse<TaskContext>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task context\"));\n }\n },\n );\n });\n }\n\n sendEvent(event: AgentEvent): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.eventBuffer.push({ event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => this.flushEvents(), ConveyorConnection.EVENT_BATCH_MS);\n }\n }\n\n flushEvents(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (!this.socket || this.eventBuffer.length === 0) return;\n for (const entry of this.eventBuffer) {\n this.socket.emit(\"agentRunner:event\", entry);\n }\n this.eventBuffer = [];\n }\n\n updateStatus(status: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:statusUpdate\", { status });\n }\n\n postChatMessage(content: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:chatMessage\", { content });\n }\n\n createPR(params: {\n title: string;\n body: string;\n baseBranch?: string;\n }): Promise<{ url: string; number: number }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:createPR\",\n params,\n (response: SocketResponse<{ url: string; number: number }>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to create pull request\"));\n }\n },\n );\n });\n }\n\n askUserQuestion(requestId: string, questions: AgentQuestion[]): Promise<Record<string, string>> {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:askUserQuestion\", { requestId, questions });\n\n return new Promise((resolve) => {\n this.pendingQuestionResolvers.set(requestId, resolve);\n });\n }\n\n cancelPendingQuestions(): void {\n this.pendingQuestionResolvers.clear();\n }\n\n storeSessionId(sessionId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:storeSessionId\", { sessionId });\n }\n\n updateTaskFields(fields: { plan?: string; description?: string }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateTaskFields\", { fields });\n }\n\n onChatMessage(callback: (message: IncomingMessagePayload) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyMessages) {\n callback(msg);\n }\n this.earlyMessages = [];\n }\n\n onStopRequested(callback: () => void): void {\n this.stopCallback = callback;\n if (this.earlyStop) {\n callback();\n this.earlyStop = false;\n }\n }\n\n onModeChange(callback: (data: SetModePayload) => void): void {\n this.modeChangeCallback = callback;\n for (const data of this.earlyModeChanges) {\n callback(data);\n }\n this.earlyModeChanges = [];\n }\n\n emitModeChanged(mode: PmSubMode): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:modeChanged\", { mode });\n }\n\n trackSpending(params: {\n agentId: string;\n sessionId: string;\n totalCostUsd: number;\n onSubscription: boolean;\n modelUsage?: {\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadInputTokens: number;\n cacheCreationInputTokens: number;\n costUSD: number;\n }[];\n }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:trackSpending\", params);\n }\n\n emitStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:statusUpdate\", { status });\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:heartbeat\", {});\n }\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 createSubtask(data: SubtaskCreatePayload): Promise<{ id: string }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n return new Promise((resolve, reject) => {\n socket.emit(\"agentRunner:createSubtask\", data, (response: SocketResponse<{ id: string }>) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to create subtask\"));\n });\n });\n }\n\n updateSubtask(subtaskId: string, fields: SubtaskUpdateFields): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateSubtask\", { subtaskId, fields });\n }\n\n deleteSubtask(subtaskId: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:deleteSubtask\", { subtaskId });\n }\n\n listSubtasks(): Promise<SubtaskResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n return new Promise((resolve, reject) => {\n socket.emit(\"agentRunner:listSubtasks\", {}, (response: SocketResponse<SubtaskResponse[]>) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to list subtasks\"));\n });\n });\n }\n\n fetchCliHistory(\n taskId?: string,\n limit?: number,\n source?: string,\n ): Promise<{ event: AgentEvent; time: string }[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getCliHistory\",\n { taskId: taskId ?? this.config.taskId, limit, source },\n (response: SocketResponse<{ event: AgentEvent; time: string }[]>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch CLI history\"));\n }\n },\n );\n });\n }\n\n fetchTask(slugOrId: string): Promise<TaskLookupResponse> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTask\",\n { slugOrId },\n (response: SocketResponse<TaskLookupResponse>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task\"));\n }\n },\n );\n });\n }\n\n disconnect(): void {\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\n\nexport interface ProjectConnectionConfig {\n apiUrl: string;\n projectToken: string;\n projectId: string;\n}\n\nexport interface TaskAssignment {\n taskId: string;\n taskToken: string;\n apiUrl: string;\n mode: string;\n branch: string;\n devBranch: string;\n useWorktree?: boolean;\n}\n\nexport interface IncomingChatMessage {\n content: string;\n userId: string;\n files?: {\n id: string;\n fileName: string;\n mimeType: string;\n downloadUrl: string;\n content?: string;\n contentEncoding?: \"base64\" | \"utf-8\";\n }[];\n}\n\nexport interface ChatHistoryMessage {\n role: string;\n content: string;\n userId: string | null;\n userName?: string;\n createdAt: string;\n}\n\nexport interface AgentContext {\n projectName: string;\n projectDescription: string | null;\n agentId: string | null;\n agentName: string | null;\n agentInstructions: string;\n model: string;\n agentSettings: Record<string, unknown> | null;\n}\n\nexport class ProjectConnection {\n private socket: Socket | null = null;\n private config: ProjectConnectionConfig;\n private taskAssignmentCallback: ((assignment: TaskAssignment) => void) | null = null;\n private stopTaskCallback: ((data: { taskId: string }) => void) | null = null;\n private shutdownCallback: (() => void) | null = null;\n private chatMessageCallback: ((msg: IncomingChatMessage) => void) | null = null;\n private earlyChatMessages: IncomingChatMessage[] = [];\n\n constructor(config: ProjectConnectionConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.apiUrl, {\n auth: { projectToken: this.config.projectToken },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n this.socket.on(\"projectRunner:assignTask\", (data: TaskAssignment) => {\n if (this.taskAssignmentCallback) {\n this.taskAssignmentCallback(data);\n }\n });\n\n this.socket.on(\"projectRunner:stopTask\", (data: { taskId: string }) => {\n if (this.stopTaskCallback) {\n this.stopTaskCallback(data);\n }\n });\n\n this.socket.on(\"projectRunner:shutdown\", () => {\n if (this.shutdownCallback) {\n this.shutdownCallback();\n }\n });\n\n this.socket.on(\"projectRunner:incomingChatMessage\", (msg: IncomingChatMessage) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyChatMessages.push(msg);\n }\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n onTaskAssignment(callback: (assignment: TaskAssignment) => void): void {\n this.taskAssignmentCallback = callback;\n }\n\n onStopTask(callback: (data: { taskId: string }) => void): void {\n this.stopTaskCallback = callback;\n }\n\n onShutdown(callback: () => void): void {\n this.shutdownCallback = callback;\n }\n\n onChatMessage(callback: (msg: IncomingChatMessage) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyChatMessages) {\n callback(msg);\n }\n this.earlyChatMessages = [];\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:heartbeat\", {});\n }\n\n emitTaskStarted(taskId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:taskStarted\", { taskId });\n }\n\n emitTaskStopped(taskId: string, reason: string): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:taskStopped\", { taskId, reason });\n }\n\n emitEvent(event: Record<string, unknown>): void {\n if (!this.socket) return;\n this.socket.emit(\"conveyor:projectAgentEvent\", event);\n }\n\n emitChatMessage(content: string): Promise<void> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"conveyor:projectAgentChatMessage\",\n { content },\n (response: { success: boolean; error?: string }) => {\n if (response.success) resolve();\n else reject(new Error(response.error ?? \"Failed to send chat message\"));\n },\n );\n });\n }\n\n emitAgentStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"conveyor:projectAgentStatus\", { status });\n }\n\n fetchAgentContext(): Promise<AgentContext | null> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"projectRunner:getAgentContext\",\n (response: { success: boolean; data?: AgentContext | null; error?: string }) => {\n if (response.success) resolve(response.data ?? null);\n else reject(new Error(response.error ?? \"Failed to fetch agent context\"));\n },\n );\n });\n }\n\n fetchChatHistory(limit?: number): Promise<ChatHistoryMessage[]> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"projectRunner:getChatHistory\",\n { limit },\n (response: { success: boolean; data?: ChatHistoryMessage[]; error?: string }) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to fetch chat history\"));\n },\n );\n });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ConveyorConfig {\n setupCommand?: string;\n startCommand?: string;\n previewPort?: number;\n}\n\nconst CONVEYOR_CONFIG_PATH = \".conveyor/config.json\";\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport async function loadForwardPorts(workspaceDir: string): Promise<number[]> {\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { forwardPorts?: number[] };\n return parsed.forwardPorts ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function loadConveyorConfig(workspaceDir: string): Promise<ConveyorConfig | null> {\n try {\n const raw = await readFile(join(workspaceDir, CONVEYOR_CONFIG_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as ConveyorConfig;\n if (parsed.setupCommand || parsed.startCommand) return parsed;\n } catch {\n // Not found or invalid — try fallback\n }\n\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { conveyor?: ConveyorConfig };\n if (parsed.conveyor && (parsed.conveyor.startCommand || parsed.conveyor.setupCommand)) {\n return parsed.conveyor;\n }\n } catch {\n // Not found or invalid\n }\n\n return null;\n}\n","import { spawn, 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\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 { execSync } from \"node:child_process\";\n\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport function cleanDevcontainerFromGit(\n workspaceDir: string,\n taskBranch: string,\n baseBranch: string,\n): { cleaned: boolean; message: string } {\n const git = (cmd: string): string =>\n execSync(cmd, { cwd: workspaceDir, encoding: \"utf-8\", timeout: 30_000 }).trim();\n\n try {\n git(`git fetch origin ${baseBranch}`);\n } catch {\n return { cleaned: false, message: `Failed to fetch origin/${baseBranch}` };\n }\n\n try {\n git(`git diff --quiet origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already matches base\" };\n } catch {\n // diff --quiet exits non-zero when there IS a diff — expected path\n }\n\n try {\n const ahead = parseInt(git(`git rev-list --count origin/${baseBranch}..HEAD`), 10);\n\n if (ahead <= 1) {\n git(`git reset --hard origin/${baseBranch}`);\n } else {\n git(`git checkout origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n git(`git add ${DEVCONTAINER_PATH}`);\n\n try {\n git(`git diff --cached --quiet -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already clean in working tree\" };\n } catch {\n git(`git commit -m \"chore: reset devcontainer config\"`);\n }\n }\n\n try {\n git(`git push --force-with-lease origin ${taskBranch}`);\n } catch {\n git(`git push --force origin ${taskBranch}`);\n }\n return { cleaned: true, message: \"devcontainer.json cleaned from git history\" };\n } catch (err) {\n try {\n git(`git checkout ${taskBranch}`);\n } catch {\n /* best effort */\n }\n const msg = err instanceof Error ? err.message : \"Unknown error\";\n return { cleaned: false, message: `Git cleanup failed: ${msg}` };\n }\n}\n\nexport function initRtk(): void {\n try {\n execSync(\"rtk --version\", { stdio: \"ignore\" });\n execSync(\"rtk init --global --auto-patch\", { stdio: \"ignore\" });\n } catch {\n // RTK not installed — skip silently\n }\n}\n\nexport function unshallowRepo(workspaceDir: string): void {\n try {\n execSync(\"git fetch --unshallow\", {\n cwd: workspaceDir,\n stdio: \"ignore\",\n timeout: 60_000,\n });\n } catch {\n // Already unshallowed or not a shallow clone — ignore\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst WORKTREE_DIR = \".worktrees\";\n\nexport function ensureWorktree(projectDir: string, taskId: string, branch?: string): string {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n\n if (existsSync(worktreePath)) {\n if (branch) {\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\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 { randomUUID } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport type { SDKUserMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n AgentRunnerStatus,\n AgentEvent,\n TaskContext,\n MultimodalBlock,\n PmSubMode,\n} from \"../types.js\";\nimport { ConveyorConnection } from \"../connection/index.js\";\nimport {\n cleanDevcontainerFromGit,\n initRtk,\n unshallowRepo,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"../setup/index.js\";\nimport { runSdkQuery, CostTracker, type QueryHost } from \"../execution/index.js\";\nimport { ensureWorktree } from \"./worktree.js\";\nimport { PlanSync } from \"./plan-sync.js\";\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst IDLE_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private _state: AgentRunnerStatus = \"connecting\";\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage | null) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private setupLog: string[] = [];\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private taskContext: TaskContext | null = null;\n private planSync: PlanSync;\n private costTracker = new CostTracker();\n private worktreeActive = false;\n private activeMode: PmSubMode = \"planning\";\n private static readonly MAX_SETUP_LOG_LINES = 50;\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n this.planSync = new PlanSync(config.workspaceDir, this.connection);\n }\n\n get state(): AgentRunnerStatus {\n return this._state;\n }\n\n private async setState(status: AgentRunnerStatus): Promise<void> {\n this._state = status;\n this.connection.emitStatus(status);\n await this.callbacks.onStatusChange(status);\n }\n\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(() => {\n if (!this.stopped) {\n this.connection.sendHeartbeat();\n }\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n async start(): Promise<void> {\n await this.setState(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => this.stop());\n this.connection.onChatMessage((message) =>\n this.injectHumanMessage(message.content, message.files),\n );\n this.connection.onModeChange((data) => this.handleModeChange(data.mode));\n\n await this.setState(\"connected\");\n this.connection.sendEvent({ type: \"connected\", taskId: this.config.taskId });\n this.startHeartbeat();\n\n if (this.config.mode !== \"pm\" && process.env.CODESPACES === \"true\") {\n const setupOk = await this.runSetupSafe();\n if (!setupOk) {\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n }\n\n initRtk();\n\n if (\n process.env.CONVEYOR_USE_WORKTREE !== \"false\" &&\n (this.config.mode === \"pm\" || process.env.CONVEYOR_USE_WORKTREE === \"true\")\n ) {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.planSync.updateWorkspaceDir(worktreePath);\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree: ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n await this.setState(\"fetching_context\");\n try {\n this.taskContext = await this.connection.fetchTaskContext();\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 this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n\n this.taskContext._runnerSessionId = randomUUID();\n this.logEffectiveSettings();\n\n if (process.env.CODESPACES === \"true\") {\n unshallowRepo(this.config.workspaceDir);\n }\n\n if (process.env.CODESPACES === \"true\" && this.taskContext.baseBranch) {\n const result = cleanDevcontainerFromGit(\n this.config.workspaceDir,\n this.taskContext.githubBranch,\n this.taskContext.baseBranch,\n );\n if (result.cleaned) {\n this.setupLog.push(`[conveyor] ${result.message}`);\n }\n }\n\n if (!this.worktreeActive && this.taskContext.useWorktree) {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.planSync.updateWorkspaceDir(worktreePath);\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree (from task config): ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n if (this.worktreeActive && this.taskContext.githubBranch) {\n try {\n const branch = this.taskContext.githubBranch;\n execSync(`git fetch origin ${branch} && git checkout ${branch}`, {\n cwd: this.config.workspaceDir,\n stdio: \"ignore\",\n });\n } catch {\n /* branch may not exist remotely yet or already checked out */\n }\n }\n\n const isPm = this.config.mode === \"pm\";\n if (isPm) {\n await this.setState(\"idle\");\n } else {\n await this.setState(\"running\");\n await this.runQuerySafe(this.taskContext);\n if (!this.stopped) await this.setState(\"idle\");\n }\n\n await this.runCoreLoop();\n\n this.stopHeartbeat();\n await this.setState(\"finished\");\n this.connection.disconnect();\n }\n\n private async runQuerySafe(\n context: TaskContext,\n followUp?: string | MultimodalBlock[],\n ): Promise<void> {\n try {\n await runSdkQuery(this.asQueryHost(), context, followUp);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n await this.setState(\"error\");\n }\n }\n\n private async runCoreLoop(): Promise<void> {\n if (!this.taskContext) return;\n while (!this.stopped) {\n if (this._state === \"idle\") {\n const msg = await this.waitForUserContent();\n if (!msg) break;\n await this.setState(\"running\");\n await this.runQuerySafe(this.taskContext, msg);\n if (!this.stopped && (this._state as string) !== \"error\") await this.setState(\"idle\");\n } else if (this._state === \"error\") {\n await this.setState(\"idle\");\n } else {\n break;\n }\n }\n }\n\n private async runSetupSafe(): Promise<boolean> {\n await this.setState(\"setup\");\n\n const ports = await loadForwardPorts(this.config.workspaceDir);\n if (ports.length > 0 && process.env.CODESPACE_NAME) {\n const visibility = ports.map((p) => `${p}:public`).join(\" \");\n runStartCommand(\n `gh codespace ports visibility ${visibility} -c \"${process.env.CODESPACE_NAME}\" 2>/dev/null`,\n this.config.workspaceDir,\n () => undefined,\n );\n }\n\n const config = await loadConveyorConfig(this.config.workspaceDir);\n if (!config) {\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\n return true;\n }\n\n try {\n await this.executeSetupConfig(config);\n const setupEvent: AgentEvent = {\n type: \"setup_complete\",\n previewPort: config.previewPort ?? undefined,\n };\n this.connection.sendEvent(setupEvent);\n await this.callbacks.onEvent(setupEvent);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Setup failed\";\n this.connection.sendEvent({ type: \"setup_error\", message });\n await this.callbacks.onEvent({ type: \"setup_error\", message });\n this.connection.postChatMessage(\n `Environment setup failed: ${message}\\nThe agent cannot start until this is resolved.`,\n );\n return false;\n }\n }\n\n private logEffectiveSettings(): void {\n if (!this.taskContext) return;\n const s = this.taskContext.agentSettings ?? this.config.agentSettings ?? {};\n const model = this.taskContext.model || this.config.model;\n const thinking =\n s.thinking?.type === \"enabled\"\n ? `enabled(${(s.thinking as { budgetTokens?: number }).budgetTokens ?? \"?\"})`\n : (s.thinking?.type ?? \"default\");\n const parts = [\n `model=${model}`,\n `mode=${this.config.mode ?? \"task\"}`,\n `effort=${s.effort ?? \"default\"}`,\n `thinking=${thinking}`,\n `maxBudget=$${s.maxBudgetUsd ?? 50}`,\n `maxTurns=${s.maxTurns ?? \"unlimited\"}`,\n ];\n if (s.betas?.length) parts.push(`betas=${s.betas.join(\",\")}`);\n if (s.disallowedTools?.length) parts.push(`disallowed=[${s.disallowedTools.join(\",\")}]`);\n if (s.enableFileCheckpointing) parts.push(`checkpointing=on`);\n /* oxlint-disable no-console */\n console.log(`[conveyor-agent] ${parts.join(\", \")}`);\n /* oxlint-enable no-console */\n }\n\n private pushSetupLog(line: string): void {\n this.setupLog.push(line);\n if (this.setupLog.length > AgentRunner.MAX_SETUP_LOG_LINES) {\n this.setupLog.splice(0, this.setupLog.length - AgentRunner.MAX_SETUP_LOG_LINES);\n }\n }\n\n private async executeSetupConfig(config: ConveyorConfig): Promise<void> {\n if (config.setupCommand) {\n this.pushSetupLog(`$ ${config.setupCommand}`);\n await runSetupCommand(config.setupCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"setup_output\", stream, data });\n for (const line of data.split(\"\\n\").filter(Boolean)) {\n this.pushSetupLog(`[${stream}] ${line}`);\n }\n });\n this.pushSetupLog(\"(exit 0)\");\n }\n\n if (config.startCommand) {\n this.pushSetupLog(`$ ${config.startCommand} & (background)`);\n runStartCommand(config.startCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"start_command_output\", stream, data });\n });\n }\n }\n\n private injectHumanMessage(\n content: string,\n files?: {\n id: string;\n fileName: string;\n mimeType: string;\n downloadUrl: string;\n content?: string;\n contentEncoding?: \"base64\" | \"utf-8\";\n }[],\n ): void {\n type ImageMediaType = \"image/gif\" | \"image/jpeg\" | \"image/png\" | \"image/webp\";\n type TextBlock = { type: \"text\"; text: string };\n type ImageBlock = {\n type: \"image\";\n source: { type: \"base64\"; media_type: ImageMediaType; data: string };\n };\n type ContentBlock = TextBlock | ImageBlock;\n\n let messageContent: string | ContentBlock[];\n if (files?.length) {\n const blocks: ContentBlock[] = [{ type: \"text\", text: content }];\n for (const f of files) {\n if (f.content && f.contentEncoding === \"base64\") {\n blocks.push({\n type: \"image\",\n source: { type: \"base64\", media_type: f.mimeType as ImageMediaType, data: f.content },\n });\n blocks.push({\n type: \"text\",\n text: `[Attached image: ${f.fileName} (${f.mimeType})]`,\n });\n } else if (f.content && f.contentEncoding === \"utf-8\") {\n blocks.push({\n type: \"text\",\n text: `[Attached file: ${f.fileName} (${f.mimeType})]\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``,\n });\n } else {\n blocks.push({\n type: \"text\",\n text: `[Attached file: ${f.fileName} (${f.mimeType})] Download: ${f.downloadUrl}`,\n });\n }\n }\n messageContent = blocks;\n } else {\n messageContent = content;\n }\n\n const msg: SDKUserMessage = {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content: messageContent },\n parent_tool_use_id: null,\n };\n\n if (this.inputResolver) {\n const resolve = this.inputResolver;\n this.inputResolver = null;\n resolve(msg);\n } else {\n this.pendingMessages.push(msg);\n }\n }\n\n private waitForMessage(): Promise<SDKUserMessage | null> {\n return new Promise<SDKUserMessage | null>((resolve) => {\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n clearTimeout(idleTimer);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n\n const idleTimer = setTimeout(() => {\n clearInterval(checkStopped);\n this.inputResolver = null;\n /* oxlint-disable no-console */\n console.log(\n `[conveyor-agent] Idle for ${IDLE_TIMEOUT_MS / 60_000} minutes — shutting down.`,\n );\n /* oxlint-enable no-console */\n this.connection.postChatMessage(\n `Agent idle for ${IDLE_TIMEOUT_MS / 60_000} minutes with no new messages — shutting down.`,\n );\n resolve(null);\n }, IDLE_TIMEOUT_MS);\n\n this.inputResolver = (msg: SDKUserMessage | null) => {\n clearInterval(checkStopped);\n clearTimeout(idleTimer);\n resolve(msg);\n };\n });\n }\n\n private async waitForUserContent(): Promise<string | MultimodalBlock[] | null> {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n const content = next?.message.content;\n if (!content) return null;\n return content as string | MultimodalBlock[];\n }\n const msg = await this.waitForMessage();\n if (!msg) return null;\n const content = msg.message.content;\n if (!content) return null;\n return content as string | MultimodalBlock[];\n }\n\n async *createInputStream(\n initialPrompt: string | MultimodalBlock[],\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n const makeUserMessage = (content: string | MultimodalBlock[]): SDKUserMessage => ({\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n });\n\n yield makeUserMessage(initialPrompt);\n\n while (!this.stopped) {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n if (next) yield next;\n continue;\n }\n\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await this.waitForMessage();\n\n if (!msg) break;\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n yield msg;\n }\n }\n\n private asQueryHost(): QueryHost {\n const getActiveMode = (): PmSubMode => this.activeMode;\n return {\n config: this.config,\n connection: this.connection,\n callbacks: this.callbacks,\n setupLog: this.setupLog,\n costTracker: this.costTracker,\n get activeMode(): PmSubMode {\n return getActiveMode();\n },\n isStopped: () => this.stopped,\n createInputStream: (prompt: string) => this.createInputStream(prompt),\n snapshotPlanFiles: () => this.planSync.snapshotPlanFiles(),\n syncPlanFile: () => this.planSync.syncPlanFile(),\n };\n }\n\n private handleModeChange(mode: PmSubMode): void {\n if (this.config.mode !== \"pm\") return;\n this.activeMode = mode;\n this.connection.emitModeChanged(mode);\n this.connection.postChatMessage(\n `Mode switched to **${mode}**${mode === \"active\" ? \" — I now have direct coding access.\" : \" — back to planning only.\"}`,\n );\n }\n\n stop(): void {\n this.stopped = true;\n if (this.inputResolver) {\n this.inputResolver(null);\n this.inputResolver = null;\n }\n }\n}\n","import type {\n SDKMessage,\n SDKAssistantMessage,\n SDKResultMessage,\n SDKResultSuccess,\n SDKResultError,\n SDKSystemMessage,\n SDKRateLimitEvent,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { TaskContext, ActivityEventSummary } from \"../types.js\";\nimport type { QueryHost } from \"./query-executor.js\";\n\nasync function processAssistantEvent(\n event: SDKAssistantMessage,\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\") {\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\") {\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 if (turnTextParts.length > 0) {\n host.connection.postChatMessage(turnTextParts.join(\"\\n\\n\"));\n }\n\n if (turnToolCalls.length > 0) {\n host.connection.sendEvent({ type: \"turn_end\", toolCalls: [...turnToolCalls] });\n turnToolCalls.length = 0;\n }\n}\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\n\nfunction handleResultEvent(\n event: SDKResultMessage,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n): { totalCostUsd: number; retriable: boolean } {\n let totalCostUsd = 0;\n let retriable = false;\n\n if (event.subtype === \"success\") {\n const successEvent = event as SDKResultSuccess;\n const queryCostUsd = successEvent.total_cost_usd;\n const durationMs = Date.now() - startTime;\n const summary = successEvent.result || \"Task completed.\";\n\n if (API_ERROR_PATTERN.test(summary) && durationMs < 30_000) {\n retriable = true;\n }\n\n // Accumulate cost across retries and follow-up queries\n const cumulativeTotal = host.costTracker.addQueryCost(queryCostUsd);\n totalCostUsd = cumulativeTotal;\n\n // Extract per-model usage from typed SDK field\n const { modelUsage } = successEvent;\n if (modelUsage && typeof modelUsage === \"object\") {\n host.costTracker.addModelUsage(modelUsage);\n }\n\n host.connection.sendEvent({ type: \"completed\", summary, costUsd: cumulativeTotal, durationMs });\n\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 } else {\n const errorEvent = event as SDKResultError;\n const errorMsg =\n errorEvent.errors.length > 0\n ? errorEvent.errors.join(\", \")\n : `Agent stopped: ${errorEvent.subtype}`;\n\n if (API_ERROR_PATTERN.test(errorMsg)) {\n retriable = true;\n }\n\n host.connection.sendEvent({ type: \"error\", message: errorMsg });\n }\n\n return { totalCostUsd, retriable };\n}\n\nasync function emitResultEvent(\n event: SDKResultMessage,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n): Promise<boolean> {\n const result = handleResultEvent(event, host, context, startTime);\n const durationMs = Date.now() - startTime;\n\n if (event.subtype === \"success\") {\n const successEvent = event as SDKResultSuccess;\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 {\n const errorEvent = event as SDKResultError;\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 result.retriable;\n}\n\nfunction handleRateLimitEvent(event: SDKRateLimitEvent, host: QueryHost): void {\n const { rate_limit_info } = event;\n const status = rate_limit_info.status;\n\n if (status === \"rejected\") {\n const resetsAt = rate_limit_info.resetsAt\n ? new Date(rate_limit_info.resetsAt).toISOString()\n : \"unknown\";\n const message = `Rate limit rejected (type: ${rate_limit_info.rateLimitType ?? \"unknown\"}, resets at: ${resetsAt})`;\n host.connection.sendEvent({ type: \"error\", message });\n void host.callbacks.onEvent({ type: \"error\", message });\n } else if (status === \"allowed_warning\") {\n const utilization = rate_limit_info.utilization\n ? `${Math.round(rate_limit_info.utilization * 100)}%`\n : \"high\";\n const message = `Rate limit warning: ${utilization} utilization (type: ${rate_limit_info.rateLimitType ?? \"unknown\"})`;\n host.connection.sendEvent({ type: \"thinking\", message });\n void host.callbacks.onEvent({ type: \"thinking\", message });\n }\n}\n\nexport async function processEvents(\n events: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n host: QueryHost,\n): Promise<{ retriable: boolean }> {\n const startTime = Date.now();\n let sessionIdStored = false;\n let isTyping = false;\n let retriable = false;\n const turnToolCalls: ActivityEventSummary[] = [];\n\n for await (const event of events) {\n if (host.isStopped()) break;\n\n switch (event.type) {\n case \"system\": {\n const systemEvent = event as SDKSystemMessage;\n if (systemEvent.subtype === \"init\") {\n if (systemEvent.session_id && !sessionIdStored) {\n sessionIdStored = true;\n host.connection.storeSessionId(systemEvent.session_id);\n context.claudeSessionId = systemEvent.session_id;\n }\n await host.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${systemEvent.model})`,\n });\n }\n break;\n }\n\n case \"assistant\": {\n if (!isTyping) {\n setTimeout(() => host.connection.sendTypingStart(), 200);\n isTyping = true;\n }\n await processAssistantEvent(event as SDKAssistantMessage, host, turnToolCalls);\n break;\n }\n\n case \"result\": {\n if (isTyping) {\n host.connection.sendTypingStop();\n isTyping = false;\n }\n retriable = await emitResultEvent(event as SDKResultMessage, host, context, startTime);\n break;\n }\n\n case \"rate_limit_event\": {\n handleRateLimitEvent(event as SDKRateLimitEvent, host);\n break;\n }\n }\n }\n\n if (isTyping) {\n host.connection.sendTypingStop();\n }\n\n return { retriable };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n query,\n type SDKMessage,\n type SDKUserMessage,\n type HookEvent,\n type HookCallbackMatcher,\n type HookJSONOutput,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n TaskContext,\n MultimodalBlock,\n PmSubMode,\n} from \"../types.js\";\nimport { buildInitialPrompt, buildSystemPrompt } from \"./prompt-builder.js\";\nimport { createConveyorMcpServer } from \"../tools/index.js\";\nimport { processEvents } from \"./event-processor.js\";\nimport type { CostTracker } from \"./cost-tracker.js\";\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\nconst RETRY_DELAYS_MS = [60_000, 120_000, 180_000, 300_000];\nconst PM_PLAN_FILE_TOOLS = new Set([\"Write\", \"Edit\", \"MultiEdit\"]);\nconst DESTRUCTIVE_CMD_PATTERN =\n /git\\s+push\\s+--force(?!\\s*-with-lease)|git\\s+reset\\s+--hard|rm\\s+-rf\\s+\\//;\n\nexport interface QueryHost {\n config: AgentRunnerConfig;\n connection: ConveyorConnection;\n callbacks: AgentRunnerCallbacks;\n setupLog: string[];\n costTracker: CostTracker;\n activeMode: PmSubMode;\n isStopped(): boolean;\n createInputStream(\n prompt: string | MultimodalBlock[],\n ): AsyncGenerator<SDKUserMessage, void, unknown>;\n snapshotPlanFiles(): void;\n syncPlanFile(): void;\n}\n\nfunction buildCanUseTool(\n host: QueryHost,\n): (\n toolName: string,\n input: Record<string, unknown>,\n) => Promise<\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string }\n> {\n const QUESTION_TIMEOUT_MS = 5 * 60 * 1000;\n\n return async (toolName, input) => {\n const isPmPlanning = host.config.mode === \"pm\" && host.activeMode === \"planning\";\n const isPmActive = host.config.mode === \"pm\" && host.activeMode === \"active\";\n\n // In PM planning mode, restrict writes to plan files only\n if (isPmPlanning && PM_PLAN_FILE_TOOLS.has(toolName)) {\n const filePath = String(input.file_path ?? input.path ?? \"\");\n if (filePath.includes(\".claude/plans/\")) {\n return { behavior: \"allow\", updatedInput: input };\n }\n return {\n behavior: \"deny\",\n message: \"File write tools are only available for plan files in PM mode.\",\n };\n }\n\n // In PM active mode, block destructive commands\n if (isPmActive && toolName === \"Bash\") {\n const cmd = String(input.command ?? \"\");\n if (DESTRUCTIVE_CMD_PATTERN.test(cmd)) {\n return {\n behavior: \"deny\",\n message: \"Destructive operation blocked in active mode. Use safer alternatives.\",\n };\n }\n }\n\n if (toolName !== \"AskUserQuestion\") {\n return { behavior: \"allow\", updatedInput: input };\n }\n\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 const requestId = randomUUID();\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(requestId, 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) {\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}\n\nfunction buildQueryOptions(host: QueryHost, context: TaskContext): Record<string, unknown> {\n const settings = context.agentSettings ?? host.config.agentSettings ?? {};\n const isPmActive = host.config.mode === \"pm\" && host.activeMode === \"active\";\n const systemPromptText = buildSystemPrompt(\n host.config.mode,\n context,\n host.config,\n host.setupLog,\n isPmActive ? \"active\" : \"planning\",\n );\n const conveyorMcp = createConveyorMcpServer(host.connection, host.config, context);\n const isPm = host.config.mode === \"pm\";\n const pmDisallowedTools = isPm && !isPmActive ? [\"TodoWrite\", \"TodoRead\", \"NotebookEdit\"] : [];\n const disallowedTools = [...(settings.disallowedTools ?? []), ...pmDisallowedTools];\n const settingSources = (settings.settingSources ?? [\"user\", \"project\"]) as (\n | \"user\"\n | \"project\"\n | \"local\"\n )[];\n\n const hooks: Partial<Record<HookEvent, HookCallbackMatcher[]>> = {\n PostToolUse: [\n {\n hooks: [\n async (input): Promise<HookJSONOutput> => {\n if (input.hook_event_name === \"PostToolUse\") {\n const output =\n typeof input.tool_response === \"string\"\n ? input.tool_response.slice(0, 500)\n : JSON.stringify(input.tool_response).slice(0, 500);\n host.connection.sendEvent({\n type: \"tool_result\",\n tool: input.tool_name,\n output,\n isError: false,\n });\n }\n return { continue: true };\n },\n ],\n timeout: 5,\n },\n ],\n };\n\n const baseOptions: Record<string, unknown> = {\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: isPmActive ? \"acceptEdits\" : \"bypassPermissions\",\n allowDangerouslySkipPermissions: !isPmActive,\n canUseTool: buildCanUseTool(host),\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: { conveyor: conveyorMcp },\n hooks,\n maxTurns: settings.maxTurns,\n effort: settings.effort,\n thinking: settings.thinking,\n betas: settings.betas,\n maxBudgetUsd: settings.maxBudgetUsd ?? 50,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n if (isPmActive) {\n const apiHostname = new URL(host.config.conveyorApiUrl).hostname;\n baseOptions.sandbox = {\n enabled: true,\n autoAllowBashIfSandboxed: true,\n allowUnsandboxedCommands: false,\n filesystem: {\n allowWrite: [`${host.config.workspaceDir}/**`],\n denyRead: [\"/etc/shadow\", \"/etc/passwd\", \"**/.env\", \"**/.env.*\"],\n denyWrite: [\"**/.env\", \"**/.env.*\", \"**/node_modules/**\"],\n },\n network: {\n allowedDomains: [apiHostname, \"api.anthropic.com\"],\n allowManagedDomainsOnly: true,\n allowLocalBinding: true,\n },\n };\n }\n\n return baseOptions;\n}\n\ntype ImageMediaType = \"image/gif\" | \"image/jpeg\" | \"image/png\" | \"image/webp\";\n\nfunction buildMultimodalPrompt(\n textPrompt: string,\n context: TaskContext,\n): string | MultimodalBlock[] {\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({\n type: \"text\",\n text: `[Attached image: ${file.fileName} (${file.mimeType})]`,\n });\n }\n for (const file of chatImages) {\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({\n type: \"text\",\n text: `[Chat image: ${file.fileName} (${file.mimeType})]`,\n });\n }\n return blocks;\n}\n\nexport async function runSdkQuery(\n host: QueryHost,\n context: TaskContext,\n followUpContent?: string | MultimodalBlock[],\n): Promise<void> {\n if (host.isStopped()) return;\n\n const isPm = host.config.mode === \"pm\";\n const isPmPlanning = isPm && host.activeMode === \"planning\";\n if (isPmPlanning) {\n host.snapshotPlanFiles();\n }\n\n const options = buildQueryOptions(host, context);\n const resume = context.claudeSessionId ?? undefined;\n\n if (followUpContent) {\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 = isPm\n ? `${buildInitialPrompt(host.config.mode, context)}\\n\\n---\\n\\nThe team says:\\n${followUpText}`\n : followUpText;\n\n let prompt: string | MultimodalBlock[];\n if (isPm) {\n prompt = buildMultimodalPrompt(textPrompt, context);\n if (followUpImages.length > 0 && Array.isArray(prompt)) {\n prompt.push(...followUpImages);\n }\n } else if (followUpImages.length > 0) {\n prompt = [{ type: \"text\", text: textPrompt }, ...followUpImages];\n } else {\n prompt = textPrompt;\n }\n\n const agentQuery = query({\n prompt: typeof prompt === \"string\" ? prompt : host.createInputStream(prompt),\n options: { ...options, resume },\n });\n await runWithRetry(agentQuery, context, host, options);\n } else if (isPmPlanning) {\n return;\n } else {\n const initialPrompt = buildInitialPrompt(host.config.mode, context);\n const prompt = buildMultimodalPrompt(initialPrompt, context);\n const agentQuery = query({\n prompt: host.createInputStream(prompt),\n options: { ...options, resume },\n });\n await runWithRetry(agentQuery, context, host, options);\n }\n\n if (isPmPlanning) {\n host.syncPlanFile();\n }\n}\n\nasync function runWithRetry(\n initialQuery: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n host: QueryHost,\n options: Record<string, unknown>,\n): Promise<void> {\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 : (() => {\n const retryPrompt = buildMultimodalPrompt(\n buildInitialPrompt(host.config.mode, context),\n context,\n );\n return query({\n prompt: host.createInputStream(retryPrompt),\n options: { ...options, resume: undefined },\n });\n })();\n\n try {\n const { retriable } = await processEvents(agentQuery, context, host);\n if (!retriable || host.isStopped()) return;\n } catch (error) {\n const isStaleSession =\n error instanceof Error && error.message.includes(\"No conversation found with session ID\");\n\n if (isStaleSession && context.claudeSessionId) {\n context.claudeSessionId = null;\n host.connection.storeSessionId(\"\");\n const freshPrompt = buildMultimodalPrompt(\n buildInitialPrompt(host.config.mode, context),\n context,\n );\n const freshQuery = query({\n prompt: host.createInputStream(freshPrompt),\n options: { ...options, resume: undefined },\n });\n return runWithRetry(freshQuery, context, host, options);\n }\n\n const isApiError = error instanceof Error && API_ERROR_PATTERN.test(error.message);\n if (!isApiError) throw error;\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 const delayMs = RETRY_DELAYS_MS[attempt];\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 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 host.connection.emitStatus(\"running\");\n await host.callbacks.onStatusChange(\"running\");\n }\n}\n","import type { RunnerMode, PmSubMode, TaskContext, ChatMessage } from \"../types.js\";\n\nconst ACTIVE_STATUSES = new Set([\"InProgress\", \"ReviewPR\", \"ReviewDev\", \"ReviewLive\"]);\n\nfunction 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\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 detectRelaunchScenario(\n context: TaskContext,\n): \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\" {\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n if (lastAgentIdx === -1) return \"fresh\";\n\n const hasPriorWork =\n !!context.githubPRUrl || !!context.claudeSessionId || ACTIVE_STATUSES.has(context.status ?? \"\");\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 buildRelaunchWithSession(\n mode: RunnerMode | undefined,\n context: TaskContext,\n): string | null {\n const scenario = detectRelaunchScenario(context);\n if (!context.claudeSessionId || scenario === \"fresh\") return null;\n\n const parts: string[] = [];\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n\n if (mode === \"pm\") {\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .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 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 } else if (scenario === \"feedback_relaunch\") {\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 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 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 `Reply with a brief status update (visible in chat), then wait for further instructions.`,\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\nfunction buildTaskBody(context: TaskContext): string[] {\n const parts: string[] = [];\n parts.push(`# Task: ${context.title}`);\n if (context.description) {\n parts.push(`\\n## Description\\n${context.description}`);\n }\n if (context.plan) {\n parts.push(`\\n## Plan\\n${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 if (file.content && file.contentEncoding === \"utf-8\") {\n parts.push(`\\n### ${file.fileName} (${file.mimeType})`);\n parts.push(\"```\");\n parts.push(file.content);\n parts.push(\"```\");\n } else if (!file.content) {\n parts.push(`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`);\n }\n }\n }\n\n if (context.repoRefs && context.repoRefs.length > 0) {\n parts.push(`\\n## Repository References`);\n for (const ref of context.repoRefs) {\n const icon = ref.refType === \"folder\" ? \"folder\" : \"file\";\n parts.push(`- [${icon}] \\`${ref.path}\\``);\n }\n }\n\n if (context.chatHistory.length > 0) {\n const relevant = context.chatHistory.slice(-20);\n parts.push(`\\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 const sizeStr = file.fileSize ? `, ${formatFileSize(file.fileSize)}` : \"\";\n if (file.content && file.contentEncoding === \"utf-8\") {\n parts.push(`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`);\n parts.push(\"```\");\n parts.push(file.content);\n parts.push(\"```\");\n } else if (!file.content) {\n parts.push(\n `[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]: ${file.downloadUrl}`,\n );\n } else {\n parts.push(`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`);\n }\n }\n }\n }\n }\n\n return parts;\n}\n\nfunction buildInstructions(\n mode: RunnerMode | undefined,\n context: TaskContext,\n scenario: \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\",\n): string[] {\n const parts: string[] = [`\\n## Instructions`];\n const isPm = mode === \"pm\";\n\n if (scenario === \"fresh\") {\n if (isPm && context.isParentTask) {\n parts.push(\n `You are the project manager for this task and its subtasks.`,\n `Use list_subtasks to review the current state of child tasks.`,\n `The task details are provided above. Wait for the team to provide instructions before taking action.`,\n `When you finish planning, save the plan with update_task and end your turn. Your reply will be visible to the team in chat.`,\n );\n } else if (isPm) {\n parts.push(\n `You are the project manager for this task.`,\n `The task details are provided above. Wait for the team to ask questions or provide additional requirements before starting to plan.`,\n `When you finish planning, save the plan with update_task 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 } else {\n parts.push(\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 `When finished, commit your changes, then run \\`git fetch origin ${context.githubBranch}\\` and \\`git push origin ${context.githubBranch}\\` (use --force-with-lease if push fails). Then use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n } else if (scenario === \"idle_relaunch\") {\n if (isPm) {\n parts.push(\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 } 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, then verify the current state is correct.`,\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 if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\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 if (isPm) {\n parts.push(\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 `\\nReview these messages and wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\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 `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 to update it. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n }\n }\n\n return parts;\n}\n\nexport function buildInitialPrompt(mode: RunnerMode | undefined, context: TaskContext): string {\n const sessionRelaunch = buildRelaunchWithSession(mode, context);\n if (sessionRelaunch) return sessionRelaunch;\n\n const scenario = detectRelaunchScenario(context);\n const body = buildTaskBody(context);\n const instructions = buildInstructions(mode, context, scenario);\n return [...body, ...instructions].join(\"\\n\");\n}\n\nexport function buildSystemPrompt(\n mode: RunnerMode | undefined,\n context: TaskContext,\n config: { instructions: string; workspaceDir: string },\n setupLog: string[],\n pmSubMode: PmSubMode = \"planning\",\n): string {\n const isPm = mode === \"pm\";\n const isPmActive = isPm && pmSubMode === \"active\";\n const pmParts = [\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 read files, search code, and run shell commands (e.g. git log, git diff) to understand the codebase. 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 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 (isPm && context.isParentTask) {\n pmParts.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 (isPm && context.storyPoints && context.storyPoints.length > 0) {\n pmParts.push(`\\nStory Point Tiers:`);\n for (const sp of context.storyPoints) {\n const desc = sp.description ? ` — ${sp.description}` : \"\";\n pmParts.push(`- Value ${sp.value}: \"${sp.name}\"${desc}`);\n }\n }\n if (isPm && context.projectAgents && context.projectAgents.length > 0) {\n pmParts.push(`\\nProject Agents:`);\n for (const pa of context.projectAgents) {\n const role = pa.role ? `role: ${pa.role}` : \"role: unassigned\";\n const sp = pa.storyPoints != null ? `, story points: ${pa.storyPoints}` : \"\";\n pmParts.push(`- ${pa.agent.name} (${role}${sp})`);\n }\n }\n const activeParts = [\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 ${config.workspaceDir}.`,\n `You can edit files, run tests, and make commits.`,\n `You still have access to all PM tools (subtasks, update_task, 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 (${config.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 const parts = isPmActive\n ? activeParts\n : isPm\n ? pmParts\n : [\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 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 create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`,\n );\n }\n return parts.join(\"\\n\");\n}\n","import { createSdkMcpServer } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { AgentRunnerConfig, TaskContext } from \"../types.js\";\nimport { buildCommonTools } from \"./common-tools.js\";\nimport { buildPmTools } from \"./pm-tools.js\";\nimport { buildTaskTools } from \"./task-tools.js\";\n\nexport function textResult(text: string): { content: { type: \"text\"; text: string }[] } {\n return { content: [{ type: \"text\" as const, text }] };\n}\n\n// oxlint-disable-next-line typescript/explicit-function-return-type\nexport function createConveyorMcpServer(\n connection: ConveyorConnection,\n config: AgentRunnerConfig,\n context?: TaskContext,\n) {\n const commonTools = buildCommonTools(connection, config);\n const modeTools =\n config.mode === \"pm\"\n ? buildPmTools(connection, context?.storyPoints)\n : buildTaskTools(connection);\n\n return createSdkMcpServer({\n name: \"conveyor\",\n tools: [...commonTools, ...modeTools],\n });\n}\n","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { AgentRunnerConfig, AgentEvent } from \"../types.js\";\nimport { textResult } from \"./index.js\";\n\nfunction formatCliEvent(e: AgentEvent): string {\n switch (e.type) {\n case \"thinking\":\n return (e as unknown as { message: string }).message ?? \"\";\n case \"tool_use\": {\n const tu = e as unknown as { tool: string; input?: string };\n return `${tu.tool}: ${tu.input?.slice(0, 1000) ?? \"\"}`;\n }\n case \"tool_result\": {\n const tr = e as unknown as { tool: string; output?: string; isError?: boolean };\n return `${tr.tool} → ${tr.output?.slice(0, 500) ?? \"\"}${tr.isError ? \" [ERROR]\" : \"\"}`;\n }\n case \"message\":\n return (e as unknown as { content: string }).content ?? \"\";\n case \"error\":\n return `ERROR: ${(e as unknown as { message: string }).message ?? \"\"}`;\n case \"completed\": {\n const c = e as unknown as { summary?: string; costUsd?: number; durationMs?: number };\n return `Completed: ${c.summary ?? \"\"} (cost: $${c.costUsd ?? \"?\"}, duration: ${c.durationMs ?? \"?\"}ms)`;\n }\n case \"setup_output\":\n case \"start_command_output\": {\n const so = e as unknown as { stream?: string; data?: string };\n return `[${so.stream ?? \"stdout\"}] ${so.data ?? \"\"}`;\n }\n case \"turn_end\": {\n const te = e as unknown as { toolCalls?: unknown[] };\n return `Turn complete (${te.toolCalls?.length ?? 0} tool calls)`;\n }\n default:\n return JSON.stringify(e);\n }\n}\n\nexport function buildCommonTools(connection: ConveyorConnection, config: AgentRunnerConfig) {\n return [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n {\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n },\n async ({ limit }) => {\n try {\n const messages = await connection.fetchChatMessages(limit);\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 tool(\n \"post_to_chat\",\n \"Post a message to the task chat. Your normal replies already appear in chat — only use this for explicit out-of-band updates or posting to a different task's chat\",\n { message: z.string().describe(\"The message to post to the team\") },\n ({ message }) => {\n connection.postChatMessage(message);\n return Promise.resolve(textResult(\"Message posted to task chat.\"));\n },\n ),\n tool(\n \"update_task_status\",\n \"Update the task status on the Kanban board\",\n {\n status: z\n .enum([\"InProgress\", \"ReviewPR\", \"Complete\"])\n .describe(\"The new status for the task\"),\n },\n ({ status }) => {\n connection.updateStatus(status);\n return Promise.resolve(textResult(`Task status updated to ${status}.`));\n },\n ),\n tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const ctx = await connection.fetchTaskContext();\n return textResult(ctx.plan ?? \"No plan available.\");\n } catch {\n return textResult(`Task ID: ${config.taskId} - could not fetch updated plan.`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n tool(\n \"get_task\",\n \"Look up a task by slug or ID to get its title, description, plan, and status\",\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.fetchTask(slug_or_id);\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 tool(\n \"get_task_cli\",\n \"Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events. Use 'source' to filter: 'agent' for agent reasoning/tool calls only, 'application' for setup/dev-server output only.\",\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 100, max 500).\"),\n },\n async ({ task_id, source, limit }) => {\n try {\n const effectiveLimit = Math.min(limit ?? 100, 500);\n const result = await connection.fetchCliHistory(task_id, effectiveLimit, source);\n const formatted = result\n .map((entry) => {\n const time = entry.time;\n const e = entry.event;\n return `[${time}] [${e.type}] ${formatCliEvent(e)}`;\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 tool(\n \"list_task_files\",\n \"List all files attached to this task with metadata (name, type, size) and download URLs\",\n {},\n async () => {\n try {\n const files = await connection.fetchTaskFiles();\n return textResult(JSON.stringify(files, null, 2));\n } catch {\n return textResult(\"Failed to list task files.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n tool(\n \"get_task_file\",\n \"Get a specific task file's content and download URL by file ID\",\n { fileId: z.string().describe(\"The file ID to retrieve\") },\n async ({ fileId }) => {\n try {\n const file = await connection.fetchTaskFile(fileId);\n return textResult(JSON.stringify(file, null, 2));\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","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { TaskContext } from \"../types.js\";\nimport { textResult } from \"./index.js\";\n\nexport function buildStoryPointDescription(storyPoints?: TaskContext[\"storyPoints\"]): string {\n if (storyPoints && storyPoints.length > 0) {\n const tiers = storyPoints.map((sp) => `${sp.value}=${sp.name}`).join(\", \");\n return `Story point value (${tiers})`;\n }\n return \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n}\n\nexport function buildPmTools(\n connection: ConveyorConnection,\n storyPoints?: TaskContext[\"storyPoints\"],\n) {\n const spDescription = buildStoryPointDescription(storyPoints);\n return [\n tool(\n \"update_task\",\n \"Save the finalized task plan and/or description\",\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 Promise.resolve(connection.updateTaskFields({ plan, description }));\n return textResult(\"Task updated successfully.\");\n } catch {\n return textResult(\"Failed to update task.\");\n }\n },\n ),\n tool(\n \"create_subtask\",\n \"Create a subtask under the current parent task. Use for breaking complex tasks into smaller pieces.\",\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(spDescription),\n },\n async (params) => {\n try {\n const result = await connection.createSubtask(params);\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 tool(\n \"update_subtask\",\n \"Update an existing subtask's fields\",\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(spDescription),\n },\n async ({ subtaskId, ...fields }) => {\n try {\n await Promise.resolve(connection.updateSubtask(subtaskId, fields));\n return textResult(\"Subtask updated.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n ),\n tool(\n \"delete_subtask\",\n \"Delete a subtask\",\n { subtaskId: z.string().describe(\"The subtask ID to delete\") },\n async ({ subtaskId }) => {\n try {\n await Promise.resolve(connection.deleteSubtask(subtaskId));\n return textResult(\"Subtask deleted.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n ),\n tool(\n \"list_subtasks\",\n \"List all subtasks under the current parent task\",\n {},\n async () => {\n try {\n const subtasks = await connection.listSubtasks();\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}\n","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport { textResult } from \"./index.js\";\n\nexport function buildTaskTools(connection: ConveyorConnection) {\n return [\n tool(\n \"create_pull_request\",\n \"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.\",\n {\n title: z.string().describe(\"The PR title\"),\n body: z.string().describe(\"The PR description/body in markdown\"),\n },\n async ({ title, body }) => {\n try {\n const result = await connection.createPR({ title, body });\n connection.sendEvent({\n type: \"pr_created\",\n url: result.url,\n number: result.number,\n });\n return textResult(`Pull request #${result.number} created: ${result.url}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(`Failed to create pull request: ${msg}`);\n }\n },\n ),\n ];\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\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","import { readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { ConveyorConnection } from \"../connection/index.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: ConveyorConnection;\n\n constructor(workspaceDir: string, connection: ConveyorConnection) {\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(homedir(), \".claude\", \"plans\"), 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 syncPlanFile(): void {\n if (this.lockedPlanFile) {\n try {\n const content = readFileSync(this.lockedPlanFile, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n const fileName = this.lockedPlanFile.split(\"/\").pop()!;\n this.connection.postChatMessage(`Synced local plan file (${fileName}) to the task plan.`);\n }\n } catch {\n /* locked file was deleted */\n }\n return;\n }\n\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\n if (newest) {\n this.lockedPlanFile = newest.path;\n const content = readFileSync(newest.path, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n const fileName = newest.path.split(\"/\").pop()!;\n this.connection.postChatMessage(\n `Detected local plan file (${fileName}) and synced it to the task plan.`,\n );\n }\n }\n }\n}\n","/* oxlint-disable no-console */\n\nimport { 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 { ProjectConnection, type TaskAssignment } from \"../connection/index.js\";\nimport { ensureWorktree, removeWorktree } from \"./worktree.js\";\nimport { handleProjectChatMessage } from \"./project-chat-handler.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface ProjectRunnerConfig {\n conveyorApiUrl: string;\n projectToken: string;\n projectId: string;\n projectDir: string;\n}\n\ninterface ActiveAgent {\n process: ChildProcess;\n worktreePath: string;\n mode: string;\n}\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst MAX_CONCURRENT = 3;\nconst STOP_TIMEOUT_MS = 30_000;\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\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 }\n\n async start(): Promise<void> {\n await this.connection.connect();\n\n this.connection.onTaskAssignment((assignment) => {\n void this.handleAssignment(assignment);\n });\n\n this.connection.onStopTask((data) => {\n this.handleStopTask(data.taskId);\n });\n\n this.connection.onShutdown(() => {\n console.log(\"[project-runner] Received shutdown signal from server\");\n void this.stop();\n });\n\n this.connection.onChatMessage((msg) => {\n console.log(\"[project-runner] Received project chat message\");\n void handleProjectChatMessage(msg, this.connection, this.projectDir);\n });\n\n this.heartbeatTimer = setInterval(() => {\n this.connection.sendHeartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n\n console.log(\"[project-runner] Connected, waiting for task assignments...\");\n\n await new Promise<void>((resolve) => {\n this.resolveLifecycle = resolve;\n process.on(\"SIGTERM\", () => void this.stop());\n process.on(\"SIGINT\", () => void this.stop());\n });\n }\n\n private async handleAssignment(assignment: TaskAssignment): Promise<void> {\n const { taskId, taskToken, apiUrl, mode, branch, devBranch, useWorktree } = assignment;\n const shortId = taskId.slice(0, 8);\n\n if (this.activeAgents.has(taskId)) {\n console.log(`[project-runner] Task ${shortId} already running, skipping`);\n return;\n }\n\n if (this.activeAgents.size >= MAX_CONCURRENT) {\n console.log(\n `[project-runner] Max concurrent agents (${MAX_CONCURRENT}) reached, rejecting task ${shortId}`,\n );\n this.connection.emitTaskStopped(taskId, \"max_concurrent_reached\");\n return;\n }\n\n try {\n try {\n execSync(\"git fetch origin\", { cwd: this.projectDir, stdio: \"ignore\" });\n } catch {\n console.log(`[task:${shortId}] Warning: git fetch failed`);\n }\n\n let workDir: string;\n const shouldWorktree = useWorktree !== false;\n if (shouldWorktree) {\n workDir = ensureWorktree(this.projectDir, taskId, devBranch);\n } else {\n workDir = this.projectDir;\n }\n\n if (branch && branch !== devBranch) {\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 console.log(`[task:${shortId}] Warning: could not checkout branch ${branch}`);\n }\n }\n }\n\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\n const child = fork(cliPath, [], {\n env: {\n ...childEnv,\n CONVEYOR_API_URL: apiUrl,\n CONVEYOR_TASK_TOKEN: taskToken,\n CONVEYOR_TASK_ID: taskId,\n CONVEYOR_MODE: mode,\n CONVEYOR_WORKSPACE: workDir,\n CONVEYOR_USE_WORKTREE: \"false\",\n },\n cwd: workDir,\n stdio: [\"pipe\", \"pipe\", \"pipe\", \"ipc\"],\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trimEnd().split(\"\\n\");\n for (const line of lines) {\n console.log(`[task:${shortId}] ${line}`);\n }\n });\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trimEnd().split(\"\\n\");\n for (const line of lines) {\n console.error(`[task:${shortId}] ${line}`);\n }\n });\n\n this.activeAgents.set(taskId, { process: child, worktreePath: workDir, mode });\n this.connection.emitTaskStarted(taskId);\n\n console.log(`[project-runner] Started task ${shortId} in ${mode} mode at ${workDir}`);\n\n child.on(\"exit\", (code) => {\n this.activeAgents.delete(taskId);\n const reason = code === 0 ? \"completed\" : `exited with code ${code}`;\n this.connection.emitTaskStopped(taskId, reason);\n console.log(`[project-runner] Task ${shortId} ${reason}`);\n\n if (code === 0) {\n try {\n removeWorktree(this.projectDir, taskId);\n } catch {\n // best effort\n }\n }\n });\n } catch (error) {\n console.error(\n `[project-runner] Failed to start task ${shortId}:`,\n error instanceof Error ? error.message : error,\n );\n this.connection.emitTaskStopped(\n taskId,\n `start_failed: ${error instanceof Error ? error.message : \"Unknown\"}`,\n );\n }\n }\n\n private handleStopTask(taskId: string): void {\n const agent = this.activeAgents.get(taskId);\n if (!agent) return;\n\n const shortId = taskId.slice(0, 8);\n console.log(`[project-runner] Stopping task ${shortId}`);\n\n agent.process.kill(\"SIGTERM\");\n\n const timer = setTimeout(() => {\n if (this.activeAgents.has(taskId)) {\n agent.process.kill(\"SIGKILL\");\n }\n }, STOP_TIMEOUT_MS);\n\n agent.process.on(\"exit\", () => {\n clearTimeout(timer);\n try {\n removeWorktree(this.projectDir, taskId);\n } catch {\n // best effort\n }\n });\n }\n\n async stop(): Promise<void> {\n if (this.stopping) return;\n this.stopping = true;\n\n console.log(\"[project-runner] Shutting down...\");\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n const stopPromises = [...this.activeAgents.keys()].map(\n (taskId) =>\n new Promise<void>((resolve) => {\n const agent = this.activeAgents.get(taskId);\n if (!agent) {\n resolve();\n return;\n }\n agent.process.on(\"exit\", () => {\n resolve();\n });\n this.handleStopTask(taskId);\n }),\n );\n\n await Promise.race([\n Promise.all(stopPromises),\n new Promise<void>((resolve) => setTimeout(resolve, 60_000)),\n ]);\n\n this.connection.disconnect();\n console.log(\"[project-runner] Shutdown complete\");\n\n if (this.resolveLifecycle) {\n this.resolveLifecycle();\n this.resolveLifecycle = null;\n }\n }\n}\n","/* oxlint-disable no-console */\n\nimport { query, type SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n ProjectConnection,\n IncomingChatMessage,\n ChatHistoryMessage,\n AgentContext,\n} from \"../connection/index.js\";\n\nconst FALLBACK_MODEL = \"claude-sonnet-4-20250514\";\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 `You have access to the local filesystem through your tools. Use them to read code,`,\n `understand the project structure, and provide informed answers.`,\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\ninterface ToolCallSummary {\n tool: string;\n input?: string;\n timestamp: string;\n}\n\nexport async function handleProjectChatMessage(\n message: IncomingChatMessage,\n connection: ProjectConnection,\n projectDir: string,\n): Promise<void> {\n connection.emitAgentStatus(\"busy\");\n\n try {\n let agentCtx: AgentContext | null = null;\n try {\n agentCtx = await connection.fetchAgentContext();\n } catch {\n console.log(\"[project-chat] Could not fetch agent context, using defaults\");\n }\n\n let chatHistory: ChatHistoryMessage[] = [];\n try {\n chatHistory = await connection.fetchChatHistory(30);\n } catch {\n console.log(\"[project-chat] Could not fetch chat history, proceeding without it\");\n }\n\n const model = agentCtx?.model || FALLBACK_MODEL;\n const settings = agentCtx?.agentSettings ?? {};\n const systemPrompt = buildSystemPrompt(projectDir, agentCtx);\n const prompt = buildPrompt(message, chatHistory);\n\n const events = query({\n prompt,\n options: {\n model,\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: systemPrompt,\n },\n cwd: projectDir,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n maxTurns: (settings.maxTurns as number | undefined) ?? 15,\n maxBudgetUsd: (settings.maxBudgetUsd as number | undefined) ?? 5,\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 });\n\n const responseParts: string[] = [];\n const turnToolCalls: ToolCallSummary[] = [];\n let isTyping = false;\n\n for await (const event of events) {\n if (event.type === \"assistant\") {\n if (!isTyping) {\n setTimeout(() => connection.emitEvent({ type: \"agent_typing_start\" }), 200);\n isTyping = true;\n }\n\n const assistantEvent = event as SDKAssistantMessage;\n const { content } = assistantEvent.message;\n\n for (const block of content) {\n if (block.type === \"text\") {\n responseParts.push(block.text);\n } else if (block.type === \"tool_use\") {\n const inputStr =\n 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 console.log(`[project-chat] [tool_use] ${block.name}`);\n }\n }\n\n if (turnToolCalls.length > 0) {\n connection.emitEvent({ type: \"activity_block\", events: [...turnToolCalls] });\n turnToolCalls.length = 0;\n }\n } else if (event.type === \"result\") {\n if (isTyping) {\n connection.emitEvent({ type: \"agent_typing_stop\" });\n isTyping = false;\n }\n break;\n }\n }\n\n if (isTyping) {\n connection.emitEvent({ type: \"agent_typing_stop\" });\n }\n\n const responseText = responseParts.join(\"\\n\\n\").trim();\n if (responseText) {\n await connection.emitChatMessage(responseText);\n }\n } catch (error) {\n console.error(\n \"[project-chat] Failed to handle message:\",\n error instanceof Error ? error.message : error,\n );\n try {\n await connection.emitChatMessage(\n \"I encountered an error processing your message. Please try again.\",\n );\n } catch {\n // best effort\n }\n } finally {\n connection.emitAgentStatus(\"idle\");\n }\n}\n","const DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024; // 50MB\nconst DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour\n\ninterface CacheEntry {\n content: Buffer;\n mimeType: string;\n fileName: string;\n createdAt: number;\n size: number;\n}\n\nexport class FileCache {\n private cache = new Map<string, CacheEntry>();\n private currentSize = 0;\n private readonly maxSizeBytes: number;\n private readonly ttlMs: number;\n\n constructor(maxSizeBytes = DEFAULT_MAX_SIZE_BYTES, ttlMs = DEFAULT_TTL_MS) {\n this.maxSizeBytes = maxSizeBytes;\n this.ttlMs = ttlMs;\n }\n\n get(fileId: string): CacheEntry | null {\n const entry = this.cache.get(fileId);\n if (!entry) return null;\n\n if (Date.now() - entry.createdAt > this.ttlMs) {\n this.delete(fileId);\n return null;\n }\n\n this.cache.delete(fileId);\n this.cache.set(fileId, entry);\n return entry;\n }\n\n set(fileId: string, content: Buffer, mimeType: string, fileName: string): void {\n if (this.cache.has(fileId)) {\n this.delete(fileId);\n }\n\n const size = content.byteLength;\n\n if (size > this.maxSizeBytes) return;\n\n while (this.currentSize + size > this.maxSizeBytes && this.cache.size > 0) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey !== undefined) {\n this.delete(oldestKey);\n }\n }\n\n this.cache.set(fileId, {\n content,\n mimeType,\n fileName,\n createdAt: Date.now(),\n size,\n });\n this.currentSize += size;\n }\n\n private delete(fileId: string): void {\n const entry = this.cache.get(fileId);\n if (entry) {\n this.currentSize -= entry.size;\n this.cache.delete(fileId);\n }\n }\n\n clear(): void {\n this.cache.clear();\n this.currentSize = 0;\n }\n\n get stats(): { entries: number; sizeBytes: number; maxSizeBytes: number } {\n return {\n entries: this.cache.size,\n sizeBytes: this.currentSize,\n maxSizeBytes: this.maxSizeBytes,\n };\n }\n}\n"],"mappings":";AAAA,SAAS,UAAuB;AAmBzB,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EACtB,SAAwB;AAAA,EACxB;AAAA,EACA,cAAuC,CAAC;AAAA,EACxC,aAAmD;AAAA,EAC3D,OAAwB,iBAAiB;AAAA,EAEjC,gBAA0C,CAAC;AAAA,EAC3C,YAAY;AAAA,EACZ,mBAAqC,CAAC;AAAA,EACtC,sBAAsE;AAAA,EACtE,eAAoC;AAAA,EACpC,qBAA8D;AAAA,EAC9D,2BAA2B,oBAAI,IAAuD;AAAA,EAE9F,YAAY,QAA2B;AACrC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,UAAyB;AACvB,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,WAAK,SAAS,GAAG,KAAK,OAAO,gBAAgB;AAAA,QAC3C,MAAM,EAAE,WAAW,KAAK,OAAO,WAAW,YAAY,KAAK,OAAO,QAAQ,OAAO;AAAA,QACjF,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc;AAAA,UACZ,8BAA8B;AAAA,QAChC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,+BAA+B,CAAC,QAAgC;AAC7E,YAAI,KAAK,qBAAqB;AAC5B,eAAK,oBAAoB,GAAG;AAAA,QAC9B,OAAO;AACL,eAAK,cAAc,KAAK,GAAG;AAAA,QAC7B;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,oBAAoB,MAAM;AACvC,YAAI,KAAK,cAAc;AACrB,eAAK,aAAa;AAAA,QACpB,OAAO;AACL,eAAK,YAAY;AAAA,QACnB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,8BAA8B,CAAC,SAAgC;AAC5E,cAAM,WAAW,KAAK,yBAAyB,IAAI,KAAK,SAAS;AACjE,YAAI,UAAU;AACZ,eAAK,yBAAyB,OAAO,KAAK,SAAS;AACnD,mBAAS,KAAK,OAAO;AAAA,QACvB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,uBAAuB,CAAC,SAAyB;AAC9D,YAAI,KAAK,oBAAoB;AAC3B,eAAK,mBAAmB,IAAI;AAAA,QAC9B,OAAO;AACL,eAAK,iBAAiB,KAAK,IAAI;AAAA,QACjC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,qBAAqB,MAAM;AAC3C;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV,iBAAO,IAAI,MAAM,2BAA2B,kBAAkB,WAAW,CAAC;AAAA,QAC5E;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,OAAgD;AAChE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,MAAM;AAAA,QACR,CAAC,aAA0D;AACzD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,UACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,iBAA8C;AAC5C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC;AAAA,QACD,CAAC,aAAuD;AACtD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,4BAA4B,CAAC;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAA2C;AACvD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,OAAO;AAAA,QACT,CAAC,aAAqD;AACpD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,2BAA2B,CAAC;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,mBAAyC;AACvC,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC;AAAA,QACD,CAAC,aAAgD;AAC/C,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,8BAA8B,CAAC;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,OAAyB;AACjC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,YAAY,KAAK,EAAE,MAAM,CAAC;AAC/B,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,WAAW,MAAM,KAAK,YAAY,GAAG,oBAAmB,cAAc;AAAA,IAC1F;AAAA,EACF;AAAA,EAEA,cAAoB;AAClB,QAAI,KAAK,YAAY;AACnB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,QAAI,CAAC,KAAK,UAAU,KAAK,YAAY,WAAW,EAAG;AACnD,eAAW,SAAS,KAAK,aAAa;AACpC,WAAK,OAAO,KAAK,qBAAqB,KAAK;AAAA,IAC7C;AACA,SAAK,cAAc,CAAC;AAAA,EACtB;AAAA,EAEA,aAAa,QAAsB;AACjC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,4BAA4B,EAAE,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,gBAAgB,SAAuB;AACrC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,2BAA2B,EAAE,QAAQ,CAAC;AAAA,EACzD;AAAA,EAEA,SAAS,QAIoC;AAC3C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,CAAC,aAAoE;AACnE,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,UACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,WAAmB,WAA6D;AAC9F,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,+BAA+B,EAAE,WAAW,UAAU,CAAC;AAExE,WAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,WAAK,yBAAyB,IAAI,WAAWA,QAAO;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,yBAA+B;AAC7B,SAAK,yBAAyB,MAAM;AAAA,EACtC;AAAA,EAEA,eAAe,WAAyB;AACtC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,8BAA8B,EAAE,UAAU,CAAC;AAAA,EAC9D;AAAA,EAEA,iBAAiB,QAAuD;AACtE,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,gCAAgC,EAAE,OAAO,CAAC;AAAA,EAC7D;AAAA,EAEA,cAAc,UAA2D;AACvE,SAAK,sBAAsB;AAC3B,eAAW,OAAO,KAAK,eAAe;AACpC,eAAS,GAAG;AAAA,IACd;AACA,SAAK,gBAAgB,CAAC;AAAA,EACxB;AAAA,EAEA,gBAAgB,UAA4B;AAC1C,SAAK,eAAe;AACpB,QAAI,KAAK,WAAW;AAClB,eAAS;AACT,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,aAAa,UAAgD;AAC3D,SAAK,qBAAqB;AAC1B,eAAW,QAAQ,KAAK,kBAAkB;AACxC,eAAS,IAAI;AAAA,IACf;AACA,SAAK,mBAAmB,CAAC;AAAA,EAC3B;AAAA,EAEA,gBAAgB,MAAuB;AACrC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,2BAA2B,EAAE,KAAK,CAAC;AAAA,EACtD;AAAA,EAEA,cAAc,QAaL;AACP,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,6BAA6B,MAAM;AAAA,EACtD;AAAA,EAEA,WAAW,QAAsB;AAC/B,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,4BAA4B,EAAE,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,yBAAyB,CAAC,CAAC;AAAA,EAC9C;AAAA,EAEA,kBAAwB;AACtB,SAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAAA,EAC/C;AAAA,EAEA,iBAAuB;AACrB,SAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,EAC9C;AAAA,EAEA,cAAc,MAAqD;AACjE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO,KAAK,6BAA6B,MAAM,CAAC,aAA6C;AAC3F,YAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,YACvD,QAAO,IAAI,MAAM,SAAS,SAAS,0BAA0B,CAAC;AAAA,MACrE,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,WAAmB,QAAmC;AAClE,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,6BAA6B,EAAE,WAAW,OAAO,CAAC;AAAA,EACrE;AAAA,EAEA,cAAc,WAAyB;AACrC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,6BAA6B,EAAE,UAAU,CAAC;AAAA,EAC7D;AAAA,EAEA,eAA2C;AACzC,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO,KAAK,4BAA4B,CAAC,GAAG,CAAC,aAAgD;AAC3F,YAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,YACvD,QAAO,IAAI,MAAM,SAAS,SAAS,yBAAyB,CAAC;AAAA,MACpE,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,gBACE,QACA,OACA,QACgD;AAChD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,QAAQ,UAAU,KAAK,OAAO,QAAQ,OAAO,OAAO;AAAA,QACtD,CAAC,aAA0E;AACzE,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,6BAA6B,CAAC;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,UAA+C;AACvD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,SAAS;AAAA,QACX,CAAC,aAAuD;AACtD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,sBAAsB,CAAC;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AACjB,SAAK,YAAY;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;;;ACvZA,SAAS,MAAAC,WAAuB;AAiDzB,IAAM,oBAAN,MAAwB;AAAA,EACrB,SAAwB;AAAA,EACxB;AAAA,EACA,yBAAwE;AAAA,EACxE,mBAAgE;AAAA,EAChE,mBAAwC;AAAA,EACxC,sBAAmE;AAAA,EACnE,oBAA2C,CAAC;AAAA,EAEpD,YAAY,QAAiC;AAC3C,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,UAAyB;AACvB,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,WAAK,SAASD,IAAG,KAAK,OAAO,QAAQ;AAAA,QACnC,MAAM,EAAE,cAAc,KAAK,OAAO,aAAa;AAAA,QAC/C,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc;AAAA,UACZ,8BAA8B;AAAA,QAChC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,4BAA4B,CAAC,SAAyB;AACnE,YAAI,KAAK,wBAAwB;AAC/B,eAAK,uBAAuB,IAAI;AAAA,QAClC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,0BAA0B,CAAC,SAA6B;AACrE,YAAI,KAAK,kBAAkB;AACzB,eAAK,iBAAiB,IAAI;AAAA,QAC5B;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,0BAA0B,MAAM;AAC7C,YAAI,KAAK,kBAAkB;AACzB,eAAK,iBAAiB;AAAA,QACxB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,qCAAqC,CAAC,QAA6B;AAChF,YAAI,KAAK,qBAAqB;AAC5B,eAAK,oBAAoB,GAAG;AAAA,QAC9B,OAAO;AACL,eAAK,kBAAkB,KAAK,GAAG;AAAA,QACjC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAC,SAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,qBAAqB,MAAM;AAC3C;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV,iBAAO,IAAI,MAAM,2BAA2B,kBAAkB,WAAW,CAAC;AAAA,QAC5E;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,UAAsD;AACrE,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,WAAW,UAAoD;AAC7D,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,WAAW,UAA4B;AACrC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,cAAc,UAAoD;AAChE,SAAK,sBAAsB;AAC3B,eAAW,OAAO,KAAK,mBAAmB;AACxC,eAAS,GAAG;AAAA,IACd;AACA,SAAK,oBAAoB,CAAC;AAAA,EAC5B;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,2BAA2B,CAAC,CAAC;AAAA,EAChD;AAAA,EAEA,gBAAgB,QAAsB;AACpC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,6BAA6B,EAAE,OAAO,CAAC;AAAA,EAC1D;AAAA,EAEA,gBAAgB,QAAgB,QAAsB;AACpD,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,6BAA6B,EAAE,QAAQ,OAAO,CAAC;AAAA,EAClE;AAAA,EAEA,UAAU,OAAsC;AAC9C,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,8BAA8B,KAAK;AAAA,EACtD;AAAA,EAEA,gBAAgB,SAAgC;AAC9C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,QAAQ;AAAA,QACV,CAAC,aAAmD;AAClD,cAAI,SAAS,QAAS,CAAAA,SAAQ;AAAA,cACzB,QAAO,IAAI,MAAM,SAAS,SAAS,6BAA6B,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,QAAsB;AACpC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,+BAA+B,EAAE,OAAO,CAAC;AAAA,EAC5D;AAAA,EAEA,oBAAkD;AAChD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC,aAA+E;AAC9E,cAAI,SAAS,QAAS,CAAAA,SAAQ,SAAS,QAAQ,IAAI;AAAA,cAC9C,QAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,OAA+C;AAC9D,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,MAAM;AAAA,QACR,CAAC,aAAgF;AAC/E,cAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,cACvD,QAAO,IAAI,MAAM,SAAS,SAAS,8BAA8B,CAAC;AAAA,QACzE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;;;AC5NA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AAQrB,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAE1B,eAAsB,iBAAiB,cAAyC;AAC9E,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,iBAAiB,GAAG,OAAO;AACzE,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,OAAO,gBAAgB,CAAC;AAAA,EACjC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,mBAAmB,cAAsD;AAC7F,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,oBAAoB,GAAG,OAAO;AAC5E,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,gBAAgB,OAAO,aAAc,QAAO;AAAA,EACzD,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,iBAAiB,GAAG,OAAO;AACzE,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,aAAa,OAAO,SAAS,gBAAgB,OAAO,SAAS,eAAe;AACrF,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;;;AC1CA,SAAS,aAAgC;AAElC,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;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;;;AC1DA,SAAS,gBAAgB;AAEzB,IAAMC,qBAAoB;AAEnB,SAAS,yBACd,cACA,YACA,YACuC;AACvC,QAAM,MAAM,CAAC,QACX,SAAS,KAAK,EAAE,KAAK,cAAc,UAAU,SAAS,SAAS,IAAO,CAAC,EAAE,KAAK;AAEhF,MAAI;AACF,QAAI,oBAAoB,UAAU,EAAE;AAAA,EACtC,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,SAAS,0BAA0B,UAAU,GAAG;AAAA,EAC3E;AAEA,MAAI;AACF,QAAI,2BAA2B,UAAU,OAAOA,kBAAiB,EAAE;AACnE,WAAO,EAAE,SAAS,OAAO,SAAS,yCAAyC;AAAA,EAC7E,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,QAAQ,SAAS,IAAI,+BAA+B,UAAU,QAAQ,GAAG,EAAE;AAEjF,QAAI,SAAS,GAAG;AACd,UAAI,2BAA2B,UAAU,EAAE;AAAA,IAC7C,OAAO;AACL,UAAI,uBAAuB,UAAU,OAAOA,kBAAiB,EAAE;AAC/D,UAAI,WAAWA,kBAAiB,EAAE;AAElC,UAAI;AACF,YAAI,gCAAgCA,kBAAiB,EAAE;AACvD,eAAO,EAAE,SAAS,OAAO,SAAS,kDAAkD;AAAA,MACtF,QAAQ;AACN,YAAI,kDAAkD;AAAA,MACxD;AAAA,IACF;AAEA,QAAI;AACF,UAAI,sCAAsC,UAAU,EAAE;AAAA,IACxD,QAAQ;AACN,UAAI,2BAA2B,UAAU,EAAE;AAAA,IAC7C;AACA,WAAO,EAAE,SAAS,MAAM,SAAS,6CAA6C;AAAA,EAChF,SAAS,KAAK;AACZ,QAAI;AACF,UAAI,gBAAgB,UAAU,EAAE;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU;AACjD,WAAO,EAAE,SAAS,OAAO,SAAS,uBAAuB,GAAG,GAAG;AAAA,EACjE;AACF;AAEO,SAAS,UAAgB;AAC9B,MAAI;AACF,aAAS,iBAAiB,EAAE,OAAO,SAAS,CAAC;AAC7C,aAAS,kCAAkC,EAAE,OAAO,SAAS,CAAC;AAAA,EAChE,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,cAAc,cAA4B;AACxD,MAAI;AACF,aAAS,yBAAyB;AAAA,MAChC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;AC9EA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAErB,IAAM,eAAe;AAEd,SAAS,eAAe,YAAoB,QAAgB,QAAyB;AAC1F,QAAM,eAAeA,MAAK,YAAY,cAAc,MAAM;AAE1D,MAAI,WAAW,YAAY,GAAG;AAC5B,QAAI,QAAQ;AACV,UAAI;AACF,QAAAD,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;AAEO,SAAS,eAAe,YAAoB,QAAsB;AACvE,QAAM,eAAeC,MAAK,YAAY,cAAc,MAAM;AAC1D,MAAI,CAAC,WAAW,YAAY,EAAG;AAC/B,MAAI;AACF,IAAAD,UAAS,wBAAwB,YAAY,aAAa;AAAA,MACxD,KAAK;AAAA,MACL,OAAO;AAAA,IACT,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;AC3CA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;;;ACWzB,eAAe,sBACb,OACA,MACA,eACe;AACf,QAAM,EAAE,QAAQ,IAAI,MAAM;AAC1B,QAAM,gBAA0B,CAAC;AAEjC,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,SAAS,QAAQ;AACzB,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,YAAY;AACpC,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;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,SAAK,WAAW,gBAAgB,cAAc,KAAK,MAAM,CAAC;AAAA,EAC5D;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,WAAW,CAAC,GAAG,aAAa,EAAE,CAAC;AAC7E,kBAAc,SAAS;AAAA,EACzB;AACF;AAEA,IAAM,oBAAoB;AAE1B,SAAS,kBACP,OACA,MACA,SACA,WAC8C;AAC9C,MAAI,eAAe;AACnB,MAAI,YAAY;AAEhB,MAAI,MAAM,YAAY,WAAW;AAC/B,UAAM,eAAe;AACrB,UAAM,eAAe,aAAa;AAClC,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,UAAM,UAAU,aAAa,UAAU;AAEvC,QAAI,kBAAkB,KAAK,OAAO,KAAK,aAAa,KAAQ;AAC1D,kBAAY;AAAA,IACd;AAGA,UAAM,kBAAkB,KAAK,YAAY,aAAa,YAAY;AAClE,mBAAe;AAGf,UAAM,EAAE,WAAW,IAAI;AACvB,QAAI,cAAc,OAAO,eAAe,UAAU;AAChD,WAAK,YAAY,cAAc,UAAU;AAAA,IAC3C;AAEA,SAAK,WAAW,UAAU,EAAE,MAAM,aAAa,SAAS,SAAS,iBAAiB,WAAW,CAAC;AAE9F,QAAI,kBAAkB,KAAK,QAAQ,WAAW,QAAQ,kBAAkB;AACtE,YAAM,YAAY,KAAK,YAAY;AACnC,WAAK,WAAW,cAAc;AAAA,QAC5B,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,QACnB,cAAc;AAAA,QACd,gBAAgB,KAAK,OAAO,SAAS,QAAQ,CAAC,CAAC,QAAQ,IAAI;AAAA,QAC3D,YAAY,UAAU,SAAS,IAAI,YAAY;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,UAAM,aAAa;AACnB,UAAM,WACJ,WAAW,OAAO,SAAS,IACvB,WAAW,OAAO,KAAK,IAAI,IAC3B,kBAAkB,WAAW,OAAO;AAE1C,QAAI,kBAAkB,KAAK,QAAQ,GAAG;AACpC,kBAAY;AAAA,IACd;AAEA,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,SAAS,SAAS,CAAC;AAAA,EAChE;AAEA,SAAO,EAAE,cAAc,UAAU;AACnC;AAEA,eAAe,gBACb,OACA,MACA,SACA,WACkB;AAClB,QAAM,SAAS,kBAAkB,OAAO,MAAM,SAAS,SAAS;AAChE,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,OAAO;AACL,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,OAAO;AAChB;AAEA,SAAS,qBAAqB,OAA0B,MAAuB;AAC7E,QAAM,EAAE,gBAAgB,IAAI;AAC5B,QAAM,SAAS,gBAAgB;AAE/B,MAAI,WAAW,YAAY;AACzB,UAAM,WAAW,gBAAgB,WAC7B,IAAI,KAAK,gBAAgB,QAAQ,EAAE,YAAY,IAC/C;AACJ,UAAM,UAAU,8BAA8B,gBAAgB,iBAAiB,SAAS,gBAAgB,QAAQ;AAChH,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,QAAQ,CAAC;AACpD,SAAK,KAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,QAAQ,CAAC;AAAA,EACxD,WAAW,WAAW,mBAAmB;AACvC,UAAM,cAAc,gBAAgB,cAChC,GAAG,KAAK,MAAM,gBAAgB,cAAc,GAAG,CAAC,MAChD;AACJ,UAAM,UAAU,uBAAuB,WAAW,uBAAuB,gBAAgB,iBAAiB,SAAS;AACnH,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,QAAQ,CAAC;AACvD,SAAK,KAAK,UAAU,QAAQ,EAAE,MAAM,YAAY,QAAQ,CAAC;AAAA,EAC3D;AACF;AAEA,eAAsB,cACpB,QACA,SACA,MACiC;AACjC,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,kBAAkB;AACtB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,QAAM,gBAAwC,CAAC;AAE/C,mBAAiB,SAAS,QAAQ;AAChC,QAAI,KAAK,UAAU,EAAG;AAEtB,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,UAAU;AACb,cAAM,cAAc;AACpB,YAAI,YAAY,YAAY,QAAQ;AAClC,cAAI,YAAY,cAAc,CAAC,iBAAiB;AAC9C,8BAAkB;AAClB,iBAAK,WAAW,eAAe,YAAY,UAAU;AACrD,oBAAQ,kBAAkB,YAAY;AAAA,UACxC;AACA,gBAAM,KAAK,UAAU,QAAQ;AAAA,YAC3B,MAAM;AAAA,YACN,SAAS,6BAA6B,YAAY,KAAK;AAAA,UACzD,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAAA,MAEA,KAAK,aAAa;AAChB,YAAI,CAAC,UAAU;AACb,qBAAW,MAAM,KAAK,WAAW,gBAAgB,GAAG,GAAG;AACvD,qBAAW;AAAA,QACb;AACA,cAAM,sBAAsB,OAA8B,MAAM,aAAa;AAC7E;AAAA,MACF;AAAA,MAEA,KAAK,UAAU;AACb,YAAI,UAAU;AACZ,eAAK,WAAW,eAAe;AAC/B,qBAAW;AAAA,QACb;AACA,oBAAY,MAAM,gBAAgB,OAA2B,MAAM,SAAS,SAAS;AACrF;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,6BAAqB,OAA4B,IAAI;AACrD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,SAAK,WAAW,eAAe;AAAA,EACjC;AAEA,SAAO,EAAE,UAAU;AACrB;;;AC9NA,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,OAMK;;;ACNP,IAAM,kBAAkB,oBAAI,IAAI,CAAC,cAAc,YAAY,aAAa,YAAY,CAAC;AAErF,SAAS,eAAe,OAAmC;AACzD,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;AAEA,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,uBACP,SACiD;AACjD,QAAM,eAAe,0BAA0B,QAAQ,WAAW;AAClE,MAAI,iBAAiB,GAAI,QAAO;AAEhC,QAAM,eACJ,CAAC,CAAC,QAAQ,eAAe,CAAC,CAAC,QAAQ,mBAAmB,gBAAgB,IAAI,QAAQ,UAAU,EAAE;AAChG,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,yBACP,MACA,SACe;AACf,QAAM,WAAW,uBAAuB,OAAO;AAC/C,MAAI,CAAC,QAAQ,mBAAmB,aAAa,QAAS,QAAO;AAE7D,QAAM,QAAkB,CAAC;AACzB,QAAM,eAAe,0BAA0B,QAAQ,WAAW;AAElE,MAAI,SAAS,MAAM;AACjB,UAAM,cAAc,QAAQ,YACzB,MAAM,eAAe,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAClC,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,MACrE;AAAA,IACF,OAAO;AACL,YAAM,KAAK,oEAAoE;AAAA,IACjF;AACA,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,aAAa,qBAAqB;AAC3C,UAAM,cAAc,QAAQ,YACzB,MAAM,eAAe,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAClC,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,MACA;AAAA,IACF;AACA,QAAI,QAAQ,aAAa;AACvB,YAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,IACxF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,cAAc,SAAgC;AACrD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,WAAW,QAAQ,KAAK,EAAE;AACrC,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAAqB,QAAQ,WAAW,EAAE;AAAA,EACvD;AACA,MAAI,QAAQ,MAAM;AAChB,UAAM,KAAK;AAAA;AAAA,EAAc,QAAQ,IAAI,EAAE;AAAA,EACzC;AAEA,MAAI,QAAQ,SAAS,QAAQ,MAAM,SAAS,GAAG;AAC7C,UAAM,KAAK;AAAA,kBAAqB;AAChC,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,cAAM,KAAK;AAAA,MAAS,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG;AACtD,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,KAAK,OAAO;AACvB,cAAM,KAAK,KAAK;AAAA,MAClB,WAAW,CAAC,KAAK,SAAS;AACxB,cAAM,KAAK,OAAO,KAAK,QAAQ,OAAO,KAAK,QAAQ,MAAM,KAAK,WAAW,EAAE;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,GAAG;AACnD,UAAM,KAAK;AAAA,yBAA4B;AACvC,eAAW,OAAO,QAAQ,UAAU;AAClC,YAAM,OAAO,IAAI,YAAY,WAAW,WAAW;AACnD,YAAM,KAAK,MAAM,IAAI,OAAO,IAAI,IAAI,IAAI;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,UAAM,WAAW,QAAQ,YAAY,MAAM,GAAG;AAC9C,UAAM,KAAK;AAAA,uBAA0B;AACrC,eAAW,OAAO,UAAU;AAC1B,YAAM,SAAS,IAAI,YAAY,IAAI;AACnC,YAAM,KAAK,IAAI,MAAM,MAAM,IAAI,OAAO,EAAE;AACxC,UAAI,IAAI,OAAO,QAAQ;AACrB,mBAAW,QAAQ,IAAI,OAAO;AAC5B,gBAAM,UAAU,KAAK,WAAW,KAAK,eAAe,KAAK,QAAQ,CAAC,KAAK;AACvE,cAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,kBAAM,KAAK,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,IAAI;AACtE,kBAAM,KAAK,KAAK;AAChB,kBAAM,KAAK,KAAK,OAAO;AACvB,kBAAM,KAAK,KAAK;AAAA,UAClB,WAAW,CAAC,KAAK,SAAS;AACxB,kBAAM;AAAA,cACJ,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,OAAO,KAAK,WAAW;AAAA,YAChF;AAAA,UACF,OAAO;AACL,kBAAM,KAAK,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,IAAI;AAAA,UACxE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,MACA,SACA,UACU;AACV,QAAM,QAAkB,CAAC;AAAA,gBAAmB;AAC5C,QAAM,OAAO,SAAS;AAEtB,MAAI,aAAa,SAAS;AACxB,QAAI,QAAQ,QAAQ,cAAc;AAChC,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,MAAM;AACf,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA,mEAAmE,QAAQ,YAAY,4BAA4B,QAAQ,YAAY;AAAA,MACzI;AAAA,IACF;AAAA,EACF,WAAW,aAAa,iBAAiB;AACvC,QAAI,MAAM;AACR,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,aAAa;AACvB,cAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,MACxF;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,QAAI,MAAM;AACR,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,QACnE;AAAA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA;AAAA;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,QACnE;AAAA;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,aAAa;AACvB,cAAM;AAAA,UACJ,6BAA6B,QAAQ,WAAW;AAAA,QAClD;AAAA,MACF,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,MAA8B,SAA8B;AAC7F,QAAM,kBAAkB,yBAAyB,MAAM,OAAO;AAC9D,MAAI,gBAAiB,QAAO;AAE5B,QAAM,WAAW,uBAAuB,OAAO;AAC/C,QAAM,OAAO,cAAc,OAAO;AAClC,QAAM,eAAe,kBAAkB,MAAM,SAAS,QAAQ;AAC9D,SAAO,CAAC,GAAG,MAAM,GAAG,YAAY,EAAE,KAAK,IAAI;AAC7C;AAEO,SAAS,kBACd,MACA,SACA,QACA,UACA,YAAuB,YACf;AACR,QAAM,OAAO,SAAS;AACtB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,UAAU;AAAA,IACd,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,QAAQ,cAAc;AAChC,YAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACjE,YAAQ,KAAK;AAAA,mBAAsB;AACnC,eAAW,MAAM,QAAQ,aAAa;AACpC,YAAM,OAAO,GAAG,cAAc,WAAM,GAAG,WAAW,KAAK;AACvD,cAAQ,KAAK,WAAW,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,IACzD;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,GAAG;AACrE,YAAQ,KAAK;AAAA,gBAAmB;AAChC,eAAW,MAAM,QAAQ,eAAe;AACtC,YAAM,OAAO,GAAG,OAAO,SAAS,GAAG,IAAI,KAAK;AAC5C,YAAM,KAAK,GAAG,eAAe,OAAO,mBAAmB,GAAG,WAAW,KAAK;AAC1E,cAAQ,KAAK,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG;AAAA,IAClD;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB,yDAAyD,QAAQ,KAAK;AAAA,IACtE,sDAAsD,OAAO,YAAY;AAAA,IACzE;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,OAAO,YAAY;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,OAAO,OAAO;AAEhB,QAAM,QAAQ,aACV,cACA,OACE,UACA;AAAA,IACE,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;AAEN,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;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACxXA,SAAS,0BAA0B;;;ACAnC,SAAS,YAAY;AACrB,SAAS,SAAS;AAKlB,SAAS,eAAe,GAAuB;AAC7C,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAQ,EAAqC,WAAW;AAAA,IAC1D,KAAK,YAAY;AACf,YAAM,KAAK;AACX,aAAO,GAAG,GAAG,IAAI,KAAK,GAAG,OAAO,MAAM,GAAG,GAAI,KAAK,EAAE;AAAA,IACtD;AAAA,IACA,KAAK,eAAe;AAClB,YAAM,KAAK;AACX,aAAO,GAAG,GAAG,IAAI,WAAM,GAAG,QAAQ,MAAM,GAAG,GAAG,KAAK,EAAE,GAAG,GAAG,UAAU,aAAa,EAAE;AAAA,IACtF;AAAA,IACA,KAAK;AACH,aAAQ,EAAqC,WAAW;AAAA,IAC1D,KAAK;AACH,aAAO,UAAW,EAAqC,WAAW,EAAE;AAAA,IACtE,KAAK,aAAa;AAChB,YAAM,IAAI;AACV,aAAO,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,GAAG,eAAe,EAAE,cAAc,GAAG;AAAA,IACpG;AAAA,IACA,KAAK;AAAA,IACL,KAAK,wBAAwB;AAC3B,YAAM,KAAK;AACX,aAAO,IAAI,GAAG,UAAU,QAAQ,KAAK,GAAG,QAAQ,EAAE;AAAA,IACpD;AAAA,IACA,KAAK,YAAY;AACf,YAAM,KAAK;AACX,aAAO,kBAAkB,GAAG,WAAW,UAAU,CAAC;AAAA,IACpD;AAAA,IACA;AACE,aAAO,KAAK,UAAU,CAAC;AAAA,EAC3B;AACF;AAEO,SAAS,iBAAiB,YAAgC,QAA2B;AAC1F,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACzF;AAAA,MACA,OAAO,EAAE,MAAM,MAAM;AACnB,YAAI;AACF,gBAAM,WAAW,MAAM,WAAW,kBAAkB,KAAK;AACzD,iBAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QACrD,QAAQ;AACN,iBAAO;AAAA,YACL,KAAK,UAAU;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,iCAAiC,EAAE;AAAA,MAClE,CAAC,EAAE,QAAQ,MAAM;AACf,mBAAW,gBAAgB,OAAO;AAClC,eAAO,QAAQ,QAAQ,WAAW,8BAA8B,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQ,EACL,KAAK,CAAC,cAAc,YAAY,UAAU,CAAC,EAC3C,SAAS,6BAA6B;AAAA,MAC3C;AAAA,MACA,CAAC,EAAE,OAAO,MAAM;AACd,mBAAW,aAAa,MAAM;AAC9B,eAAO,QAAQ,QAAQ,WAAW,0BAA0B,MAAM,GAAG,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,MAAM,MAAM,WAAW,iBAAiB;AAC9C,iBAAO,WAAW,IAAI,QAAQ,oBAAoB;AAAA,QACpD,QAAQ;AACN,iBAAO,WAAW,YAAY,OAAO,MAAM,kCAAkC;AAAA,QAC/E;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAY,EAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MAC1E;AAAA,MACA,OAAO,EAAE,WAAW,MAAM;AACxB,YAAI;AACF,gBAAM,OAAO,MAAM,WAAW,UAAU,UAAU;AAClD,iBAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,QACjD,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACjF;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS,EACN,OAAO,EACP,SAAS,EACT,SAAS,2DAA2D;AAAA,QACvE,QAAQ,EACL,KAAK,CAAC,SAAS,aAAa,CAAC,EAC7B,SAAS,EACT,SAAS,0CAA0C;AAAA,QACtD,OAAO,EACJ,OAAO,EACP,SAAS,EACT,SAAS,6DAA6D;AAAA,MAC3E;AAAA,MACA,OAAO,EAAE,SAAS,QAAQ,MAAM,MAAM;AACpC,YAAI;AACF,gBAAM,iBAAiB,KAAK,IAAI,SAAS,KAAK,GAAG;AACjD,gBAAM,SAAS,MAAM,WAAW,gBAAgB,SAAS,gBAAgB,MAAM;AAC/E,gBAAM,YAAY,OACf,IAAI,CAAC,UAAU;AACd,kBAAM,OAAO,MAAM;AACnB,kBAAM,IAAI,MAAM;AAChB,mBAAO,IAAI,IAAI,MAAM,EAAE,IAAI,KAAK,eAAe,CAAC,CAAC;AAAA,UACnD,CAAC,EACA,KAAK,IAAI;AACZ,iBAAO,WAAW,aAAa,oBAAoB;AAAA,QACrD,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,QAAQ,MAAM,WAAW,eAAe;AAC9C,iBAAO,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,QAClD,QAAQ;AACN,iBAAO,WAAW,4BAA4B;AAAA,QAChD;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,yBAAyB,EAAE;AAAA,MACzD,OAAO,EAAE,OAAO,MAAM;AACpB,YAAI;AACF,gBAAM,OAAO,MAAM,WAAW,cAAc,MAAM;AAClD,iBAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,QACjD,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACtF;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;;;ACxLA,SAAS,QAAAC,aAAY;AACrB,SAAS,KAAAC,UAAS;AAKX,SAAS,2BAA2B,aAAkD;AAC3F,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,UAAM,QAAQ,YAAY,IAAI,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,GAAG,IAAI,EAAE,EAAE,KAAK,IAAI;AACzE,WAAO,sBAAsB,KAAK;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,aACd,YACA,aACA;AACA,QAAM,gBAAgB,2BAA2B,WAAW;AAC5D,SAAO;AAAA,IACLC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAMC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,QAChE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MACxE;AAAA,MACA,OAAO,EAAE,MAAM,YAAY,MAAM;AAC/B,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,iBAAiB,EAAE,MAAM,YAAY,CAAC,CAAC;AACxE,iBAAO,WAAW,4BAA4B;AAAA,QAChD,QAAQ;AACN,iBAAO,WAAW,wBAAwB;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAOC,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QAC1C,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,QAC/D,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,QACtE,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,QACrE,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAC/D;AAAA,MACA,OAAO,WAAW;AAChB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,cAAc,MAAM;AACpD,iBAAO,WAAW,4BAA4B,OAAO,EAAE,EAAE;AAAA,QAC3D,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAWC,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,QACzD,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC3B,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,QACjC,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAC/D;AAAA,MACA,OAAO,EAAE,WAAW,GAAG,OAAO,MAAM;AAClC,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,cAAc,WAAW,MAAM,CAAC;AACjE,iBAAO,WAAW,kBAAkB;AAAA,QACtC,SAAS,OAAO;AACd,iBAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,WAAWC,GAAE,OAAO,EAAE,SAAS,0BAA0B,EAAE;AAAA,MAC7D,OAAO,EAAE,UAAU,MAAM;AACvB,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,cAAc,SAAS,CAAC;AACzD,iBAAO,WAAW,kBAAkB;AAAA,QACtC,SAAS,OAAO;AACd,iBAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,WAAW,MAAM,WAAW,aAAa;AAC/C,iBAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QACrD,QAAQ;AACN,iBAAO,WAAW,0BAA0B;AAAA,QAC9C;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;;;ACzGA,SAAS,QAAAE,aAAY;AACrB,SAAS,KAAAC,UAAS;AAIX,SAAS,eAAe,YAAgC;AAC7D,SAAO;AAAA,IACLC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAOC,GAAE,OAAO,EAAE,SAAS,cAAc;AAAA,QACzC,MAAMA,GAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MACjE;AAAA,MACA,OAAO,EAAE,OAAO,KAAK,MAAM;AACzB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,SAAS,EAAE,OAAO,KAAK,CAAC;AACxD,qBAAW,UAAU;AAAA,YACnB,MAAM;AAAA,YACN,KAAK,OAAO;AAAA,YACZ,QAAQ,OAAO;AAAA,UACjB,CAAC;AACD,iBAAO,WAAW,iBAAiB,OAAO,MAAM,aAAa,OAAO,GAAG,EAAE;AAAA,QAC3E,SAAS,OAAO;AACd,gBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,iBAAO,WAAW,kCAAkC,GAAG,EAAE;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AHvBO,SAAS,WAAW,MAA6D;AACtF,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AACtD;AAGO,SAAS,wBACd,YACA,QACA,SACA;AACA,QAAM,cAAc,iBAAiB,YAAY,MAAM;AACvD,QAAM,YACJ,OAAO,SAAS,OACZ,aAAa,YAAY,SAAS,WAAW,IAC7C,eAAe,UAAU;AAE/B,SAAO,mBAAmB;AAAA,IACxB,MAAM;AAAA,IACN,OAAO,CAAC,GAAG,aAAa,GAAG,SAAS;AAAA,EACtC,CAAC;AACH;;;AFLA,IAAMC,qBAAoB;AAC1B,IAAM,kBAAkB,CAAC,KAAQ,MAAS,MAAS,GAAO;AAC1D,IAAM,qBAAqB,oBAAI,IAAI,CAAC,SAAS,QAAQ,WAAW,CAAC;AACjE,IAAM,0BACJ;AAiBF,SAAS,gBACP,MAOA;AACA,QAAM,sBAAsB,IAAI,KAAK;AAErC,SAAO,OAAO,UAAU,UAAU;AAChC,UAAM,eAAe,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AACtE,UAAM,aAAa,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AAGpE,QAAI,gBAAgB,mBAAmB,IAAI,QAAQ,GAAG;AACpD,YAAM,WAAW,OAAO,MAAM,aAAa,MAAM,QAAQ,EAAE;AAC3D,UAAI,SAAS,SAAS,gBAAgB,GAAG;AACvC,eAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,MAClD;AACA,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,MACX;AAAA,IACF;AAGA,QAAI,cAAc,aAAa,QAAQ;AACrC,YAAM,MAAM,OAAO,MAAM,WAAW,EAAE;AACtC,UAAI,wBAAwB,KAAK,GAAG,GAAG;AACrC,eAAO;AAAA,UACL,UAAU;AAAA,UACV,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa,mBAAmB;AAClC,aAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,IAClD;AAEA,UAAM,YAAY,MAAM;AAOxB,UAAM,YAAY,WAAW;AAC7B,SAAK,WAAW,WAAW,mBAAmB;AAC9C,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,KAAK,UAAU,KAAK;AAAA,IAC7B,CAAC;AAED,UAAM,gBAAgB,KAAK,WAAW,gBAAgB,WAAW,SAAS;AAC1E,UAAM,iBAAiB,IAAI,QAAc,CAACC,aAAY;AACpD,iBAAW,MAAMA,SAAQ,IAAI,GAAG,mBAAmB;AAAA,IACrD,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,eAAe,cAAc,CAAC;AAClE,SAAK,WAAW,WAAW,SAAS;AAEpC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SACE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,SAAS,cAAc,EAAE,WAAW,MAAM,WAAW,QAAQ,EAAE;AAAA,EACpF;AACF;AAEA,SAAS,kBAAkB,MAAiB,SAA+C;AACzF,QAAM,WAAW,QAAQ,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AACxE,QAAM,aAAa,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AACpE,QAAM,mBAAmB;AAAA,IACvB,KAAK,OAAO;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,aAAa,WAAW;AAAA,EAC1B;AACA,QAAM,cAAc,wBAAwB,KAAK,YAAY,KAAK,QAAQ,OAAO;AACjF,QAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAM,oBAAoB,QAAQ,CAAC,aAAa,CAAC,aAAa,YAAY,cAAc,IAAI,CAAC;AAC7F,QAAM,kBAAkB,CAAC,GAAI,SAAS,mBAAmB,CAAC,GAAI,GAAG,iBAAiB;AAClF,QAAM,iBAAkB,SAAS,kBAAkB,CAAC,QAAQ,SAAS;AAMrE,QAAM,QAA2D;AAAA,IAC/D,aAAa;AAAA,MACX;AAAA,QACE,OAAO;AAAA,UACL,OAAO,UAAmC;AACxC,gBAAI,MAAM,oBAAoB,eAAe;AAC3C,oBAAM,SACJ,OAAO,MAAM,kBAAkB,WAC3B,MAAM,cAAc,MAAM,GAAG,GAAG,IAChC,KAAK,UAAU,MAAM,aAAa,EAAE,MAAM,GAAG,GAAG;AACtD,mBAAK,WAAW,UAAU;AAAA,gBACxB,MAAM;AAAA,gBACN,MAAM,MAAM;AAAA,gBACZ;AAAA,gBACA,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AACA,mBAAO,EAAE,UAAU,KAAK;AAAA,UAC1B;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAuC;AAAA,IAC3C,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,aAAa,gBAAgB;AAAA,IAC7C,iCAAiC,CAAC;AAAA,IAClC,YAAY,gBAAgB,IAAI;AAAA,IAChC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,IACjE,YAAY,EAAE,UAAU,YAAY;AAAA,IACpC;AAAA,IACA,UAAU,SAAS;AAAA,IACnB,QAAQ,SAAS;AAAA,IACjB,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,cAAc,SAAS,gBAAgB;AAAA,IACvC,iBAAiB,gBAAgB,SAAS,IAAI,kBAAkB;AAAA,IAChE,yBAAyB,SAAS;AAAA,EACpC;AAEA,MAAI,YAAY;AACd,UAAM,cAAc,IAAI,IAAI,KAAK,OAAO,cAAc,EAAE;AACxD,gBAAY,UAAU;AAAA,MACpB,SAAS;AAAA,MACT,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,YAAY;AAAA,QACV,YAAY,CAAC,GAAG,KAAK,OAAO,YAAY,KAAK;AAAA,QAC7C,UAAU,CAAC,eAAe,eAAe,WAAW,WAAW;AAAA,QAC/D,WAAW,CAAC,WAAW,aAAa,oBAAoB;AAAA,MAC1D;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB,CAAC,aAAa,mBAAmB;AAAA,QACjD,yBAAyB;AAAA,QACzB,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,sBACP,YACA,SAC4B;AAC5B,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;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM,oBAAoB,KAAK,QAAQ,KAAK,KAAK,QAAQ;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,aAAW,QAAQ,YAAY;AAC7B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,YAAY,KAAK;AAAA,QACjB,MAAM,KAAK;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM,gBAAgB,KAAK,QAAQ,KAAK,KAAK,QAAQ;AAAA,IACvD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAsB,YACpB,MACA,SACA,iBACe;AACf,MAAI,KAAK,UAAU,EAAG;AAEtB,QAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAM,eAAe,QAAQ,KAAK,eAAe;AACjD,MAAI,cAAc;AAChB,SAAK,kBAAkB;AAAA,EACzB;AAEA,QAAM,UAAU,kBAAkB,MAAM,OAAO;AAC/C,QAAM,SAAS,QAAQ,mBAAmB;AAE1C,MAAI,iBAAiB;AACnB,UAAM,eACJ,OAAO,oBAAoB,WACvB,kBACA,gBACG,OAAO,CAAC,MAAuD,EAAE,SAAS,MAAM,EAChF,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AAElB,UAAM,iBACJ,OAAO,oBAAoB,WACvB,CAAC,IACD,gBAAgB;AAAA,MACd,CAAC,MAAwD,EAAE,SAAS;AAAA,IACtE;AAEN,UAAM,aAAa,OACf,GAAG,mBAAmB,KAAK,OAAO,MAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAA8B,YAAY,KAC1F;AAEJ,QAAI;AACJ,QAAI,MAAM;AACR,eAAS,sBAAsB,YAAY,OAAO;AAClD,UAAI,eAAe,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;AACtD,eAAO,KAAK,GAAG,cAAc;AAAA,MAC/B;AAAA,IACF,WAAW,eAAe,SAAS,GAAG;AACpC,eAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,GAAG,GAAG,cAAc;AAAA,IACjE,OAAO;AACL,eAAS;AAAA,IACX;AAEA,UAAM,aAAa,MAAM;AAAA,MACvB,QAAQ,OAAO,WAAW,WAAW,SAAS,KAAK,kBAAkB,MAAM;AAAA,MAC3E,SAAS,EAAE,GAAG,SAAS,OAAO;AAAA,IAChC,CAAC;AACD,UAAM,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,EACvD,WAAW,cAAc;AACvB;AAAA,EACF,OAAO;AACL,UAAM,gBAAgB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAClE,UAAM,SAAS,sBAAsB,eAAe,OAAO;AAC3D,UAAM,aAAa,MAAM;AAAA,MACvB,QAAQ,KAAK,kBAAkB,MAAM;AAAA,MACrC,SAAS,EAAE,GAAG,SAAS,OAAO;AAAA,IAChC,CAAC;AACD,UAAM,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,EACvD;AAEA,MAAI,cAAc;AAChB,SAAK,aAAa;AAAA,EACpB;AACF;AAEA,eAAe,aACb,cACA,SACA,MACA,SACe;AACf,WAAS,UAAU,GAAG,WAAW,gBAAgB,QAAQ,WAAW;AAClE,QAAI,KAAK,UAAU,EAAG;AAEtB,UAAM,aACJ,YAAY,IACR,gBACC,MAAM;AACL,YAAM,cAAc;AAAA,QAClB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAAA,QAC5C;AAAA,MACF;AACA,aAAO,MAAM;AAAA,QACX,QAAQ,KAAK,kBAAkB,WAAW;AAAA,QAC1C,SAAS,EAAE,GAAG,SAAS,QAAQ,OAAU;AAAA,MAC3C,CAAC;AAAA,IACH,GAAG;AAET,QAAI;AACF,YAAM,EAAE,UAAU,IAAI,MAAM,cAAc,YAAY,SAAS,IAAI;AACnE,UAAI,CAAC,aAAa,KAAK,UAAU,EAAG;AAAA,IACtC,SAAS,OAAO;AACd,YAAM,iBACJ,iBAAiB,SAAS,MAAM,QAAQ,SAAS,uCAAuC;AAE1F,UAAI,kBAAkB,QAAQ,iBAAiB;AAC7C,gBAAQ,kBAAkB;AAC1B,aAAK,WAAW,eAAe,EAAE;AACjC,cAAM,cAAc;AAAA,UAClB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAAA,UAC5C;AAAA,QACF;AACA,cAAM,aAAa,MAAM;AAAA,UACvB,QAAQ,KAAK,kBAAkB,WAAW;AAAA,UAC1C,SAAS,EAAE,GAAG,SAAS,QAAQ,OAAU;AAAA,QAC3C,CAAC;AACD,eAAO,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,MACxD;AAEA,YAAM,aAAa,iBAAiB,SAASD,mBAAkB,KAAK,MAAM,OAAO;AACjF,UAAI,CAAC,WAAY,OAAM;AAAA,IACzB;AAEA,QAAI,WAAW,gBAAgB,QAAQ;AACrC,WAAK,WAAW;AAAA,QACd,6BAA6B,gBAAgB,MAAM;AAAA,MAErD;AACA;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,OAAO;AACvC,UAAM,WAAW,KAAK,MAAM,UAAU,GAAM;AAC5C,SAAK,WAAW;AAAA,MACd,sCAAsC,QAAQ,UAAU,WAAW,IAAI,MAAM,EAAE,gBAAgB,UAAU,CAAC,IAAI,gBAAgB,MAAM;AAAA,IACtI;AACA,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,SAAS,0BAA0B,QAAQ,MAAM,UAAU,CAAC,IAAI,gBAAgB,MAAM;AAAA,IACxF,CAAC;AACD,SAAK,WAAW,WAAW,mBAAmB;AAC9C,UAAM,KAAK,UAAU,eAAe,mBAAmB;AAEvD,UAAM,IAAI,QAAc,CAACC,aAAY;AACnC,YAAM,QAAQ,WAAWA,UAAS,OAAO;AACzC,YAAM,eAAe,YAAY,MAAM;AACrC,YAAI,KAAK,UAAU,GAAG;AACpB,uBAAa,KAAK;AAClB,wBAAc,YAAY;AAC1B,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF,GAAG,GAAI;AACP,iBAAW,MAAM,cAAc,YAAY,GAAG,UAAU,GAAG;AAAA,IAC7D,CAAC;AAED,SAAK,WAAW,WAAW,SAAS;AACpC,UAAM,KAAK,UAAU,eAAe,SAAS;AAAA,EAC/C;AACF;;;AMvZO,IAAM,cAAN,MAAkB;AAAA,EACf,oBAAoB;AAAA,EACpB,aAAa,oBAAI,IAA6B;AAAA;AAAA,EAGtD,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,SAAS,aAAa,UAAU,oBAAoB;AACpD,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAGd,IAAM,WAAN,MAAe;AAAA,EACZ,mBAAmB,oBAAI,IAAoB;AAAA,EAC3C,iBAAgC;AAAA,EAChC;AAAA,EACA;AAAA,EAER,YAAY,cAAsB,YAAgC;AAChE,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,mBAAmB,cAA4B;AAC7C,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,cAAwB;AAC9B,WAAO,CAACA,MAAK,QAAQ,GAAG,WAAW,OAAO,GAAGA,MAAK,KAAK,cAAc,WAAW,OAAO,CAAC;AAAA,EAC1F;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,WAAWA,MAAK,UAAU,IAAI;AACpC,kBAAM,OAAO,SAAS,QAAQ;AAC9B,iBAAK,iBAAiB,IAAI,UAAU,KAAK,OAAO;AAAA,UAClD,QAAQ;AACN;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAqB;AACnB,QAAI,KAAK,gBAAgB;AACvB,UAAI;AACF,cAAM,UAAU,aAAa,KAAK,gBAAgB,OAAO,EAAE,KAAK;AAChE,YAAI,SAAS;AACX,eAAK,WAAW,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAClD,gBAAM,WAAW,KAAK,eAAe,MAAM,GAAG,EAAE,IAAI;AACpD,eAAK,WAAW,gBAAgB,2BAA2B,QAAQ,qBAAqB;AAAA,QAC1F;AAAA,MACF,QAAQ;AAAA,MAER;AACA;AAAA,IACF;AAEA,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,WAAWA,MAAK,UAAU,IAAI;AACpC,YAAI;AACF,gBAAM,OAAO,SAAS,QAAQ;AAC9B,gBAAM,YAAY,KAAK,iBAAiB,IAAI,QAAQ;AACpD,gBAAM,QAAQ,cAAc,UAAa,KAAK,UAAU;AACxD,cAAI,UAAU,CAAC,UAAU,KAAK,UAAU,OAAO,QAAQ;AACrD,qBAAS,EAAE,MAAM,UAAU,OAAO,KAAK,QAAQ;AAAA,UACjD;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,WAAK,iBAAiB,OAAO;AAC7B,YAAM,UAAU,aAAa,OAAO,MAAM,OAAO,EAAE,KAAK;AACxD,UAAI,SAAS;AACX,aAAK,WAAW,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAClD,cAAM,WAAW,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI;AAC5C,aAAK,WAAW;AAAA,UACd,6BAA6B,QAAQ;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ATpEA,IAAM,wBAAwB;AAC9B,IAAM,kBAAkB,KAAK,KAAK;AAE3B,IAAM,cAAN,MAAM,aAAY;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA4B;AAAA,EAC5B,UAAU;AAAA,EACV,gBAA+D;AAAA,EAC/D,kBAAoC,CAAC;AAAA,EACrC,WAAqB,CAAC;AAAA,EACtB,iBAAwD;AAAA,EACxD,cAAkC;AAAA,EAClC;AAAA,EACA,cAAc,IAAI,YAAY;AAAA,EAC9B,iBAAiB;AAAA,EACjB,aAAwB;AAAA,EAChC,OAAwB,sBAAsB;AAAA,EAE9C,YAAY,QAA2B,WAAiC;AACtE,SAAK,SAAS;AACd,SAAK,aAAa,IAAI,mBAAmB,MAAM;AAC/C,SAAK,YAAY;AACjB,SAAK,WAAW,IAAI,SAAS,OAAO,cAAc,KAAK,UAAU;AAAA,EACnE;AAAA,EAEA,IAAI,QAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,SAAS,QAA0C;AAC/D,SAAK,SAAS;AACd,SAAK,WAAW,WAAW,MAAM;AACjC,UAAM,KAAK,UAAU,eAAe,MAAM;AAAA,EAC5C;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,iBAAiB,YAAY,MAAM;AACtC,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,WAAW,cAAc;AAAA,MAChC;AAAA,IACF,GAAG,qBAAqB;AAAA,EAC1B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,SAAS,YAAY;AAChC,UAAM,KAAK,WAAW,QAAQ;AAE9B,SAAK,WAAW,gBAAgB,MAAM,KAAK,KAAK,CAAC;AACjD,SAAK,WAAW;AAAA,MAAc,CAAC,YAC7B,KAAK,mBAAmB,QAAQ,SAAS,QAAQ,KAAK;AAAA,IACxD;AACA,SAAK,WAAW,aAAa,CAAC,SAAS,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAEvE,UAAM,KAAK,SAAS,WAAW;AAC/B,SAAK,WAAW,UAAU,EAAE,MAAM,aAAa,QAAQ,KAAK,OAAO,OAAO,CAAC;AAC3E,SAAK,eAAe;AAEpB,QAAI,KAAK,OAAO,SAAS,QAAQ,QAAQ,IAAI,eAAe,QAAQ;AAClE,YAAM,UAAU,MAAM,KAAK,aAAa;AACxC,UAAI,CAAC,SAAS;AACZ,aAAK,cAAc;AACnB,cAAM,KAAK,SAAS,OAAO;AAC3B,aAAK,WAAW,WAAW;AAC3B;AAAA,MACF;AAAA,IACF;AAEA,YAAQ;AAER,QACE,QAAQ,IAAI,0BAA0B,YACrC,KAAK,OAAO,SAAS,QAAQ,QAAQ,IAAI,0BAA0B,SACpE;AACA,UAAI;AACF,cAAM,eAAe,eAAe,KAAK,OAAO,cAAc,KAAK,OAAO,MAAM;AAChF,aAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,cAAc,aAAa;AAC3D,aAAK,SAAS,mBAAmB,YAAY;AAC7C,aAAK,iBAAiB;AACtB,aAAK,SAAS,KAAK,8BAA8B,YAAY,EAAE;AAAA,MACjE,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,aAAK,SAAS,KAAK,gEAAgE,GAAG,EAAE;AAAA,MAC1F;AAAA,IACF;AAEA,UAAM,KAAK,SAAS,kBAAkB;AACtC,QAAI;AACF,WAAK,cAAc,MAAM,KAAK,WAAW,iBAAiB;AAAA,IAC5D,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,WAAK,cAAc;AACnB,YAAM,KAAK,SAAS,OAAO;AAC3B,WAAK,WAAW,WAAW;AAC3B;AAAA,IACF;AAEA,SAAK,YAAY,mBAAmBC,YAAW;AAC/C,SAAK,qBAAqB;AAE1B,QAAI,QAAQ,IAAI,eAAe,QAAQ;AACrC,oBAAc,KAAK,OAAO,YAAY;AAAA,IACxC;AAEA,QAAI,QAAQ,IAAI,eAAe,UAAU,KAAK,YAAY,YAAY;AACpE,YAAM,SAAS;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,KAAK,YAAY;AAAA,QACjB,KAAK,YAAY;AAAA,MACnB;AACA,UAAI,OAAO,SAAS;AAClB,aAAK,SAAS,KAAK,cAAc,OAAO,OAAO,EAAE;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,kBAAkB,KAAK,YAAY,aAAa;AACxD,UAAI;AACF,cAAM,eAAe,eAAe,KAAK,OAAO,cAAc,KAAK,OAAO,MAAM;AAChF,aAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,cAAc,aAAa;AAC3D,aAAK,SAAS,mBAAmB,YAAY;AAC7C,aAAK,iBAAiB;AACtB,aAAK,SAAS,KAAK,iDAAiD,YAAY,EAAE;AAAA,MACpF,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,aAAK,SAAS,KAAK,gEAAgE,GAAG,EAAE;AAAA,MAC1F;AAAA,IACF;AAEA,QAAI,KAAK,kBAAkB,KAAK,YAAY,cAAc;AACxD,UAAI;AACF,cAAM,SAAS,KAAK,YAAY;AAChC,QAAAC,UAAS,oBAAoB,MAAM,oBAAoB,MAAM,IAAI;AAAA,UAC/D,KAAK,KAAK,OAAO;AAAA,UACjB,OAAO;AAAA,QACT,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAI,MAAM;AACR,YAAM,KAAK,SAAS,MAAM;AAAA,IAC5B,OAAO;AACL,YAAM,KAAK,SAAS,SAAS;AAC7B,YAAM,KAAK,aAAa,KAAK,WAAW;AACxC,UAAI,CAAC,KAAK,QAAS,OAAM,KAAK,SAAS,MAAM;AAAA,IAC/C;AAEA,UAAM,KAAK,YAAY;AAEvB,SAAK,cAAc;AACnB,UAAM,KAAK,SAAS,UAAU;AAC9B,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,MAAc,aACZ,SACA,UACe;AACf,QAAI;AACF,YAAM,YAAY,KAAK,YAAY,GAAG,SAAS,QAAQ;AAAA,IACzD,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;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAc,cAA6B;AACzC,QAAI,CAAC,KAAK,YAAa;AACvB,WAAO,CAAC,KAAK,SAAS;AACpB,UAAI,KAAK,WAAW,QAAQ;AAC1B,cAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAI,CAAC,IAAK;AACV,cAAM,KAAK,SAAS,SAAS;AAC7B,cAAM,KAAK,aAAa,KAAK,aAAa,GAAG;AAC7C,YAAI,CAAC,KAAK,WAAY,KAAK,WAAsB,QAAS,OAAM,KAAK,SAAS,MAAM;AAAA,MACtF,WAAW,KAAK,WAAW,SAAS;AAClC,cAAM,KAAK,SAAS,MAAM;AAAA,MAC5B,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAiC;AAC7C,UAAM,KAAK,SAAS,OAAO;AAE3B,UAAM,QAAQ,MAAM,iBAAiB,KAAK,OAAO,YAAY;AAC7D,QAAI,MAAM,SAAS,KAAK,QAAQ,IAAI,gBAAgB;AAClD,YAAM,aAAa,MAAM,IAAI,CAAC,MAAM,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG;AAC3D;AAAA,QACE,iCAAiC,UAAU,QAAQ,QAAQ,IAAI,cAAc;AAAA,QAC7E,KAAK,OAAO;AAAA,QACZ,MAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAChE,QAAI,CAAC,QAAQ;AACX,WAAK,WAAW,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACvD,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,KAAK,mBAAmB,MAAM;AACpC,YAAM,aAAyB;AAAA,QAC7B,MAAM;AAAA,QACN,aAAa,OAAO,eAAe;AAAA,MACrC;AACA,WAAK,WAAW,UAAU,UAAU;AACpC,YAAM,KAAK,UAAU,QAAQ,UAAU;AACvC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,WAAW,UAAU,EAAE,MAAM,eAAe,QAAQ,CAAC;AAC1D,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,eAAe,QAAQ,CAAC;AAC7D,WAAK,WAAW;AAAA,QACd,6BAA6B,OAAO;AAAA;AAAA,MACtC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,IAAI,KAAK,YAAY,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AAC1E,UAAM,QAAQ,KAAK,YAAY,SAAS,KAAK,OAAO;AACpD,UAAM,WACJ,EAAE,UAAU,SAAS,YACjB,WAAY,EAAE,SAAuC,gBAAgB,GAAG,MACvE,EAAE,UAAU,QAAQ;AAC3B,UAAM,QAAQ;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK,OAAO,QAAQ,MAAM;AAAA,MAClC,UAAU,EAAE,UAAU,SAAS;AAAA,MAC/B,YAAY,QAAQ;AAAA,MACpB,cAAc,EAAE,gBAAgB,EAAE;AAAA,MAClC,YAAY,EAAE,YAAY,WAAW;AAAA,IACvC;AACA,QAAI,EAAE,OAAO,OAAQ,OAAM,KAAK,SAAS,EAAE,MAAM,KAAK,GAAG,CAAC,EAAE;AAC5D,QAAI,EAAE,iBAAiB,OAAQ,OAAM,KAAK,eAAe,EAAE,gBAAgB,KAAK,GAAG,CAAC,GAAG;AACvF,QAAI,EAAE,wBAAyB,OAAM,KAAK,kBAAkB;AAE5D,YAAQ,IAAI,oBAAoB,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EAEpD;AAAA,EAEQ,aAAa,MAAoB;AACvC,SAAK,SAAS,KAAK,IAAI;AACvB,QAAI,KAAK,SAAS,SAAS,aAAY,qBAAqB;AAC1D,WAAK,SAAS,OAAO,GAAG,KAAK,SAAS,SAAS,aAAY,mBAAmB;AAAA,IAChF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,QAAuC;AACtE,QAAI,OAAO,cAAc;AACvB,WAAK,aAAa,KAAK,OAAO,YAAY,EAAE;AAC5C,YAAM,gBAAgB,OAAO,cAAc,KAAK,OAAO,cAAc,CAAC,QAAQ,SAAS;AACrF,aAAK,WAAW,UAAU,EAAE,MAAM,gBAAgB,QAAQ,KAAK,CAAC;AAChE,mBAAW,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACnD,eAAK,aAAa,IAAI,MAAM,KAAK,IAAI,EAAE;AAAA,QACzC;AAAA,MACF,CAAC;AACD,WAAK,aAAa,UAAU;AAAA,IAC9B;AAEA,QAAI,OAAO,cAAc;AACvB,WAAK,aAAa,KAAK,OAAO,YAAY,kBAAkB;AAC5D,sBAAgB,OAAO,cAAc,KAAK,OAAO,cAAc,CAAC,QAAQ,SAAS;AAC/E,aAAK,WAAW,UAAU,EAAE,MAAM,wBAAwB,QAAQ,KAAK,CAAC;AAAA,MAC1E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBACN,SACA,OAQM;AASN,QAAI;AACJ,QAAI,OAAO,QAAQ;AACjB,YAAM,SAAyB,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAC/D,iBAAW,KAAK,OAAO;AACrB,YAAI,EAAE,WAAW,EAAE,oBAAoB,UAAU;AAC/C,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,UAAU,YAAY,EAAE,UAA4B,MAAM,EAAE,QAAQ;AAAA,UACtF,CAAC;AACD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,oBAAoB,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAAA,UACrD,CAAC;AAAA,QACH,WAAW,EAAE,WAAW,EAAE,oBAAoB,SAAS;AACrD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,mBAAmB,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAAA;AAAA,EAAe,EAAE,OAAO;AAAA;AAAA,UAC5E,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,mBAAmB,EAAE,QAAQ,KAAK,EAAE,QAAQ,gBAAgB,EAAE,WAAW;AAAA,UACjF,CAAC;AAAA,QACH;AAAA,MACF;AACA,uBAAiB;AAAA,IACnB,OAAO;AACL,uBAAiB;AAAA,IACnB;AAEA,UAAM,MAAsB;AAAA,MAC1B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,EAAE,MAAM,QAAiB,SAAS,eAAe;AAAA,MAC1D,oBAAoB;AAAA,IACtB;AAEA,QAAI,KAAK,eAAe;AACtB,YAAMC,WAAU,KAAK;AACrB,WAAK,gBAAgB;AACrB,MAAAA,SAAQ,GAAG;AAAA,IACb,OAAO;AACL,WAAK,gBAAgB,KAAK,GAAG;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,iBAAiD;AACvD,WAAO,IAAI,QAA+B,CAACA,aAAY;AACrD,YAAM,eAAe,YAAY,MAAM;AACrC,YAAI,KAAK,SAAS;AAChB,wBAAc,YAAY;AAC1B,uBAAa,SAAS;AACtB,eAAK,gBAAgB;AACrB,UAAAA,SAAQ,IAAI;AAAA,QACd;AAAA,MACF,GAAG,GAAI;AAEP,YAAM,YAAY,WAAW,MAAM;AACjC,sBAAc,YAAY;AAC1B,aAAK,gBAAgB;AAErB,gBAAQ;AAAA,UACN,6BAA6B,kBAAkB,GAAM;AAAA,QACvD;AAEA,aAAK,WAAW;AAAA,UACd,kBAAkB,kBAAkB,GAAM;AAAA,QAC5C;AACA,QAAAA,SAAQ,IAAI;AAAA,MACd,GAAG,eAAe;AAElB,WAAK,gBAAgB,CAAC,QAA+B;AACnD,sBAAc,YAAY;AAC1B,qBAAa,SAAS;AACtB,QAAAA,SAAQ,GAAG;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,qBAAiE;AAC7E,QAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,YAAM,OAAO,KAAK,gBAAgB,MAAM;AACxC,YAAMC,WAAU,MAAM,QAAQ;AAC9B,UAAI,CAACA,SAAS,QAAO;AACrB,aAAOA;AAAA,IACT;AACA,UAAM,MAAM,MAAM,KAAK,eAAe;AACtC,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,UAAU,IAAI,QAAQ;AAC5B,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,kBACL,eAC+C;AAC/C,UAAM,kBAAkB,CAAC,aAAyD;AAAA,MAChF,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,EAAE,MAAM,QAAiB,QAAQ;AAAA,MAC1C,oBAAoB;AAAA,IACtB;AAEA,UAAM,gBAAgB,aAAa;AAEnC,WAAO,CAAC,KAAK,SAAS;AACpB,UAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,cAAM,OAAO,KAAK,gBAAgB,MAAM;AACxC,YAAI,KAAM,OAAM;AAChB;AAAA,MACF;AAEA,WAAK,WAAW,WAAW,mBAAmB;AAC9C,YAAM,KAAK,UAAU,eAAe,mBAAmB;AACvD,YAAM,MAAM,MAAM,KAAK,eAAe;AAEtC,UAAI,CAAC,IAAK;AACV,WAAK,WAAW,WAAW,SAAS;AACpC,YAAM,KAAK,UAAU,eAAe,SAAS;AAC7C,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,cAAyB;AAC/B,UAAM,gBAAgB,MAAiB,KAAK;AAC5C,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,IAAI,aAAwB;AAC1B,eAAO,cAAc;AAAA,MACvB;AAAA,MACA,WAAW,MAAM,KAAK;AAAA,MACtB,mBAAmB,CAAC,WAAmB,KAAK,kBAAkB,MAAM;AAAA,MACpE,mBAAmB,MAAM,KAAK,SAAS,kBAAkB;AAAA,MACzD,cAAc,MAAM,KAAK,SAAS,aAAa;AAAA,IACjD;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAuB;AAC9C,QAAI,KAAK,OAAO,SAAS,KAAM;AAC/B,SAAK,aAAa;AAClB,SAAK,WAAW,gBAAgB,IAAI;AACpC,SAAK,WAAW;AAAA,MACd,sBAAsB,IAAI,KAAK,SAAS,WAAW,6CAAwC,gCAA2B;AAAA,IACxH;AAAA,EACF;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc,IAAI;AACvB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AACF;;;AUzeA,SAAS,YAA+B;AACxC,SAAS,YAAAC,iBAAgB;AACzB,YAAY,UAAU;AACtB,SAAS,qBAAqB;;;ACH9B,SAAS,SAAAC,cAAuC;AAQhD,IAAM,iBAAiB;AAEvB,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,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;AAQA,eAAsB,yBACpB,SACA,YACA,YACe;AACf,aAAW,gBAAgB,MAAM;AAEjC,MAAI;AACF,QAAI,WAAgC;AACpC,QAAI;AACF,iBAAW,MAAM,WAAW,kBAAkB;AAAA,IAChD,QAAQ;AACN,cAAQ,IAAI,8DAA8D;AAAA,IAC5E;AAEA,QAAI,cAAoC,CAAC;AACzC,QAAI;AACF,oBAAc,MAAM,WAAW,iBAAiB,EAAE;AAAA,IACpD,QAAQ;AACN,cAAQ,IAAI,oEAAoE;AAAA,IAClF;AAEA,UAAM,QAAQ,UAAU,SAAS;AACjC,UAAM,WAAW,UAAU,iBAAiB,CAAC;AAC7C,UAAM,eAAeA,mBAAkB,YAAY,QAAQ;AAC3D,UAAM,SAAS,YAAY,SAAS,WAAW;AAE/C,UAAM,SAASD,OAAM;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA,KAAK;AAAA,QACL,gBAAgB;AAAA,QAChB,iCAAiC;AAAA,QACjC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,QACjE,UAAW,SAAS,YAAmC;AAAA,QACvD,cAAe,SAAS,gBAAuC;AAAA,QAC/D,QAAQ,SAAS;AAAA,QACjB,UAAU,SAAS;AAAA,MAKrB;AAAA,IACF,CAAC;AAED,UAAM,gBAA0B,CAAC;AACjC,UAAM,gBAAmC,CAAC;AAC1C,QAAI,WAAW;AAEf,qBAAiB,SAAS,QAAQ;AAChC,UAAI,MAAM,SAAS,aAAa;AAC9B,YAAI,CAAC,UAAU;AACb,qBAAW,MAAM,WAAW,UAAU,EAAE,MAAM,qBAAqB,CAAC,GAAG,GAAG;AAC1E,qBAAW;AAAA,QACb;AAEA,cAAM,iBAAiB;AACvB,cAAM,EAAE,QAAQ,IAAI,eAAe;AAEnC,mBAAW,SAAS,SAAS;AAC3B,cAAI,MAAM,SAAS,QAAQ;AACzB,0BAAc,KAAK,MAAM,IAAI;AAAA,UAC/B,WAAW,MAAM,SAAS,YAAY;AACpC,kBAAM,WACJ,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK;AAC5E,0BAAc,KAAK;AAAA,cACjB,MAAM,MAAM;AAAA,cACZ,OAAO,SAAS,MAAM,GAAG,GAAM;AAAA,cAC/B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AACD,oBAAQ,IAAI,6BAA6B,MAAM,IAAI,EAAE;AAAA,UACvD;AAAA,QACF;AAEA,YAAI,cAAc,SAAS,GAAG;AAC5B,qBAAW,UAAU,EAAE,MAAM,kBAAkB,QAAQ,CAAC,GAAG,aAAa,EAAE,CAAC;AAC3E,wBAAc,SAAS;AAAA,QACzB;AAAA,MACF,WAAW,MAAM,SAAS,UAAU;AAClC,YAAI,UAAU;AACZ,qBAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClD,qBAAW;AAAA,QACb;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU;AACZ,iBAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,IACpD;AAEA,UAAM,eAAe,cAAc,KAAK,MAAM,EAAE,KAAK;AACrD,QAAI,cAAc;AAChB,YAAM,WAAW,gBAAgB,YAAY;AAAA,IAC/C;AAAA,EACF,SAAS,OAAO;AACd,YAAQ;AAAA,MACN;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC3C;AACA,QAAI;AACF,YAAM,WAAW;AAAA,QACf;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF,UAAE;AACA,eAAW,gBAAgB,MAAM;AAAA,EACnC;AACF;;;AD3KA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAiB,aAAQ,UAAU;AAezC,IAAME,yBAAwB;AAC9B,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAEjB,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,eAAe,oBAAI,IAAyB;AAAA,EAC5C,iBAAwD;AAAA,EACxD,WAAW;AAAA,EACX,mBAAwC;AAAA,EAEhD,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;AAAA,EACH;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,WAAW,QAAQ;AAE9B,SAAK,WAAW,iBAAiB,CAAC,eAAe;AAC/C,WAAK,KAAK,iBAAiB,UAAU;AAAA,IACvC,CAAC;AAED,SAAK,WAAW,WAAW,CAAC,SAAS;AACnC,WAAK,eAAe,KAAK,MAAM;AAAA,IACjC,CAAC;AAED,SAAK,WAAW,WAAW,MAAM;AAC/B,cAAQ,IAAI,uDAAuD;AACnE,WAAK,KAAK,KAAK;AAAA,IACjB,CAAC;AAED,SAAK,WAAW,cAAc,CAAC,QAAQ;AACrC,cAAQ,IAAI,gDAAgD;AAC5D,WAAK,yBAAyB,KAAK,KAAK,YAAY,KAAK,UAAU;AAAA,IACrE,CAAC;AAED,SAAK,iBAAiB,YAAY,MAAM;AACtC,WAAK,WAAW,cAAc;AAAA,IAChC,GAAGA,sBAAqB;AAExB,YAAQ,IAAI,6DAA6D;AAEzE,UAAM,IAAI,QAAc,CAACC,aAAY;AACnC,WAAK,mBAAmBA;AACxB,cAAQ,GAAG,WAAW,MAAM,KAAK,KAAK,KAAK,CAAC;AAC5C,cAAQ,GAAG,UAAU,MAAM,KAAK,KAAK,KAAK,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,iBAAiB,YAA2C;AACxE,UAAM,EAAE,QAAQ,WAAW,QAAQ,MAAM,QAAQ,WAAW,YAAY,IAAI;AAC5E,UAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AAEjC,QAAI,KAAK,aAAa,IAAI,MAAM,GAAG;AACjC,cAAQ,IAAI,yBAAyB,OAAO,4BAA4B;AACxE;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,QAAQ,gBAAgB;AAC5C,cAAQ;AAAA,QACN,2CAA2C,cAAc,6BAA6B,OAAO;AAAA,MAC/F;AACA,WAAK,WAAW,gBAAgB,QAAQ,wBAAwB;AAChE;AAAA,IACF;AAEA,QAAI;AACF,UAAI;AACF,QAAAC,UAAS,oBAAoB,EAAE,KAAK,KAAK,YAAY,OAAO,SAAS,CAAC;AAAA,MACxE,QAAQ;AACN,gBAAQ,IAAI,SAAS,OAAO,6BAA6B;AAAA,MAC3D;AAEA,UAAI;AACJ,YAAM,iBAAiB,gBAAgB;AACvC,UAAI,gBAAgB;AAClB,kBAAU,eAAe,KAAK,YAAY,QAAQ,SAAS;AAAA,MAC7D,OAAO;AACL,kBAAU,KAAK;AAAA,MACjB;AAEA,UAAI,UAAU,WAAW,WAAW;AAClC,YAAI;AACF,UAAAA,UAAS,gBAAgB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,QACtE,QAAQ;AACN,cAAI;AACF,YAAAA,UAAS,mBAAmB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,UACzE,QAAQ;AACN,oBAAQ,IAAI,SAAS,OAAO,wCAAwC,MAAM,EAAE;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAe,aAAQ,WAAW,QAAQ;AAEhD,YAAM,WAAW,EAAE,GAAG,QAAQ,IAAI;AAClC,aAAO,SAAS;AAChB,aAAO,SAAS;AAEhB,YAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;AAAA,QAC9B,KAAK;AAAA,UACH,GAAG;AAAA,UACH,kBAAkB;AAAA,UAClB,qBAAqB;AAAA,UACrB,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,oBAAoB;AAAA,UACpB,uBAAuB;AAAA,QACzB;AAAA,QACA,KAAK;AAAA,QACL,OAAO,CAAC,QAAQ,QAAQ,QAAQ,KAAK;AAAA,MACvC,CAAC;AAED,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI;AAClD,mBAAW,QAAQ,OAAO;AACxB,kBAAQ,IAAI,SAAS,OAAO,KAAK,IAAI,EAAE;AAAA,QACzC;AAAA,MACF,CAAC;AACD,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI;AAClD,mBAAW,QAAQ,OAAO;AACxB,kBAAQ,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE;AAAA,QAC3C;AAAA,MACF,CAAC;AAED,WAAK,aAAa,IAAI,QAAQ,EAAE,SAAS,OAAO,cAAc,SAAS,KAAK,CAAC;AAC7E,WAAK,WAAW,gBAAgB,MAAM;AAEtC,cAAQ,IAAI,iCAAiC,OAAO,OAAO,IAAI,YAAY,OAAO,EAAE;AAEpF,YAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,aAAK,aAAa,OAAO,MAAM;AAC/B,cAAM,SAAS,SAAS,IAAI,cAAc,oBAAoB,IAAI;AAClE,aAAK,WAAW,gBAAgB,QAAQ,MAAM;AAC9C,gBAAQ,IAAI,yBAAyB,OAAO,IAAI,MAAM,EAAE;AAExD,YAAI,SAAS,GAAG;AACd,cAAI;AACF,2BAAe,KAAK,YAAY,MAAM;AAAA,UACxC,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,yCAAyC,OAAO;AAAA,QAChD,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AACA,WAAK,WAAW;AAAA,QACd;AAAA,QACA,iBAAiB,iBAAiB,QAAQ,MAAM,UAAU,SAAS;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,QAAsB;AAC3C,UAAM,QAAQ,KAAK,aAAa,IAAI,MAAM;AAC1C,QAAI,CAAC,MAAO;AAEZ,UAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,YAAQ,IAAI,kCAAkC,OAAO,EAAE;AAEvD,UAAM,QAAQ,KAAK,SAAS;AAE5B,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,KAAK,aAAa,IAAI,MAAM,GAAG;AACjC,cAAM,QAAQ,KAAK,SAAS;AAAA,MAC9B;AAAA,IACF,GAAG,eAAe;AAElB,UAAM,QAAQ,GAAG,QAAQ,MAAM;AAC7B,mBAAa,KAAK;AAClB,UAAI;AACF,uBAAe,KAAK,YAAY,MAAM;AAAA,MACxC,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAEhB,YAAQ,IAAI,mCAAmC;AAE/C,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,WACC,IAAI,QAAc,CAACD,aAAY;AAC7B,cAAM,QAAQ,KAAK,aAAa,IAAI,MAAM;AAC1C,YAAI,CAAC,OAAO;AACV,UAAAA,SAAQ;AACR;AAAA,QACF;AACA,cAAM,QAAQ,GAAG,QAAQ,MAAM;AAC7B,UAAAA,SAAQ;AAAA,QACV,CAAC;AACD,aAAK,eAAe,MAAM;AAAA,MAC5B,CAAC;AAAA,IACL;AAEA,UAAM,QAAQ,KAAK;AAAA,MACjB,QAAQ,IAAI,YAAY;AAAA,MACxB,IAAI,QAAc,CAACA,aAAY,WAAWA,UAAS,GAAM,CAAC;AAAA,IAC5D,CAAC;AAED,SAAK,WAAW,WAAW;AAC3B,YAAQ,IAAI,oCAAoC;AAEhD,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AACF;;;AE7PA,IAAM,yBAAyB,KAAK,OAAO;AAC3C,IAAM,iBAAiB,KAAK,KAAK;AAU1B,IAAM,YAAN,MAAgB;AAAA,EACb,QAAQ,oBAAI,IAAwB;AAAA,EACpC,cAAc;AAAA,EACL;AAAA,EACA;AAAA,EAEjB,YAAY,eAAe,wBAAwB,QAAQ,gBAAgB;AACzE,SAAK,eAAe;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,IAAI,QAAmC;AACrC,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM;AACnC,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI,KAAK,IAAI,IAAI,MAAM,YAAY,KAAK,OAAO;AAC7C,WAAK,OAAO,MAAM;AAClB,aAAO;AAAA,IACT;AAEA,SAAK,MAAM,OAAO,MAAM;AACxB,SAAK,MAAM,IAAI,QAAQ,KAAK;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,QAAgB,SAAiB,UAAkB,UAAwB;AAC7E,QAAI,KAAK,MAAM,IAAI,MAAM,GAAG;AAC1B,WAAK,OAAO,MAAM;AAAA,IACpB;AAEA,UAAM,OAAO,QAAQ;AAErB,QAAI,OAAO,KAAK,aAAc;AAE9B,WAAO,KAAK,cAAc,OAAO,KAAK,gBAAgB,KAAK,MAAM,OAAO,GAAG;AACzE,YAAM,YAAY,KAAK,MAAM,KAAK,EAAE,KAAK,EAAE;AAC3C,UAAI,cAAc,QAAW;AAC3B,aAAK,OAAO,SAAS;AAAA,MACvB;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AACD,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,OAAO,QAAsB;AACnC,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM;AACnC,QAAI,OAAO;AACT,WAAK,eAAe,MAAM;AAC1B,WAAK,MAAM,OAAO,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AACjB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,IAAI,QAAsE;AACxE,WAAO;AAAA,MACL,SAAS,KAAK,MAAM;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AACF;","names":["resolve","io","resolve","resolve","DEVCONTAINER_PATH","execSync","join","randomUUID","execSync","tool","z","tool","z","tool","z","tool","z","API_ERROR_PATTERN","resolve","join","randomUUID","execSync","resolve","content","execSync","query","buildSystemPrompt","HEARTBEAT_INTERVAL_MS","resolve","execSync"]}
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AgentRunner,
4
4
  ProjectRunner
5
- } from "./chunk-22ME6AB3.js";
5
+ } from "./chunk-HWMZ626Q.js";
6
6
 
7
7
  // src/cli.ts
8
8
  var CONVEYOR_API_URL = process.env.CONVEYOR_API_URL;
package/dist/index.d.ts CHANGED
@@ -142,6 +142,10 @@ declare class ConveyorConnection {
142
142
  updateSubtask(subtaskId: string, fields: SubtaskUpdateFields): void;
143
143
  deleteSubtask(subtaskId: string): void;
144
144
  listSubtasks(): Promise<SubtaskResponse[]>;
145
+ fetchCliHistory(taskId?: string, limit?: number, source?: string): Promise<{
146
+ event: AgentEvent;
147
+ time: string;
148
+ }[]>;
145
149
  fetchTask(slugOrId: string): Promise<TaskLookupResponse>;
146
150
  disconnect(): void;
147
151
  }
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  removeWorktree,
10
10
  runSetupCommand,
11
11
  runStartCommand
12
- } from "./chunk-22ME6AB3.js";
12
+ } from "./chunk-HWMZ626Q.js";
13
13
  export {
14
14
  AgentRunner,
15
15
  ConveyorConnection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rallycry/conveyor-agent",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Conveyor cloud build agent runner - executes task plans inside GitHub Codespaces",
5
5
  "keywords": [
6
6
  "agent",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/connection/task-connection.ts","../src/connection/project-connection.ts","../src/setup/config.ts","../src/setup/commands.ts","../src/setup/codespace.ts","../src/runner/worktree.ts","../src/runner/agent-runner.ts","../src/execution/event-processor.ts","../src/execution/query-executor.ts","../src/execution/prompt-builder.ts","../src/tools/index.ts","../src/tools/common-tools.ts","../src/tools/pm-tools.ts","../src/tools/task-tools.ts","../src/execution/cost-tracker.ts","../src/runner/plan-sync.ts","../src/runner/project-runner.ts","../src/runner/project-chat-handler.ts","../src/runner/file-cache.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport type {\n AgentRunnerConfig,\n TaskContext,\n AgentEvent,\n IncomingMessagePayload,\n QuestionAnswerPayload,\n AgentQuestion,\n SocketResponse,\n ChatMessageResponse,\n TaskFileResponse,\n TaskLookupResponse,\n SubtaskCreatePayload,\n SubtaskUpdateFields,\n SubtaskResponse,\n PmSubMode,\n SetModePayload,\n} from \"../types.js\";\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: AgentRunnerConfig;\n private eventBuffer: { event: AgentEvent }[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly EVENT_BATCH_MS = 500;\n\n private earlyMessages: IncomingMessagePayload[] = [];\n private earlyStop = false;\n private earlyModeChanges: SetModePayload[] = [];\n private chatMessageCallback: ((msg: IncomingMessagePayload) => void) | null = null;\n private stopCallback: (() => void) | null = null;\n private modeChangeCallback: ((data: SetModePayload) => void) | null = null;\n private pendingQuestionResolvers = new Map<string, (answers: Record<string, string>) => void>();\n\n constructor(config: AgentRunnerConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.conveyorApiUrl, {\n auth: { taskToken: this.config.taskToken, runnerMode: this.config.mode ?? \"task\" },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n this.socket.on(\"agentRunner:incomingMessage\", (msg: IncomingMessagePayload) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyMessages.push(msg);\n }\n });\n\n this.socket.on(\"agentRunner:stop\", () => {\n if (this.stopCallback) {\n this.stopCallback();\n } else {\n this.earlyStop = true;\n }\n });\n\n this.socket.on(\"agentRunner:questionAnswer\", (data: QuestionAnswerPayload) => {\n const resolver = this.pendingQuestionResolvers.get(data.requestId);\n if (resolver) {\n this.pendingQuestionResolvers.delete(data.requestId);\n resolver(data.answers);\n }\n });\n\n this.socket.on(\"agentRunner:setMode\", (data: SetModePayload) => {\n if (this.modeChangeCallback) {\n this.modeChangeCallback(data);\n } else {\n this.earlyModeChanges.push(data);\n }\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n fetchChatMessages(limit?: number): Promise<ChatMessageResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getChatMessages\",\n { limit },\n (response: SocketResponse<ChatMessageResponse[]>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch chat messages\"));\n }\n },\n );\n });\n }\n\n fetchTaskFiles(): Promise<TaskFileResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskFiles\",\n {},\n (response: SocketResponse<TaskFileResponse[]>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task files\"));\n }\n },\n );\n });\n }\n\n fetchTaskFile(fileId: string): Promise<TaskFileResponse> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskFile\",\n { fileId },\n (response: SocketResponse<TaskFileResponse>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task file\"));\n }\n },\n );\n });\n }\n\n fetchTaskContext(): Promise<TaskContext> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTaskContext\",\n {},\n (response: SocketResponse<TaskContext>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task context\"));\n }\n },\n );\n });\n }\n\n sendEvent(event: AgentEvent): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.eventBuffer.push({ event });\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => this.flushEvents(), ConveyorConnection.EVENT_BATCH_MS);\n }\n }\n\n flushEvents(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (!this.socket || this.eventBuffer.length === 0) return;\n for (const entry of this.eventBuffer) {\n this.socket.emit(\"agentRunner:event\", entry);\n }\n this.eventBuffer = [];\n }\n\n updateStatus(status: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:statusUpdate\", { status });\n }\n\n postChatMessage(content: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:chatMessage\", { content });\n }\n\n createPR(params: {\n title: string;\n body: string;\n baseBranch?: string;\n }): Promise<{ url: string; number: number }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:createPR\",\n params,\n (response: SocketResponse<{ url: string; number: number }>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to create pull request\"));\n }\n },\n );\n });\n }\n\n askUserQuestion(requestId: string, questions: AgentQuestion[]): Promise<Record<string, string>> {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:askUserQuestion\", { requestId, questions });\n\n return new Promise((resolve) => {\n this.pendingQuestionResolvers.set(requestId, resolve);\n });\n }\n\n cancelPendingQuestions(): void {\n this.pendingQuestionResolvers.clear();\n }\n\n storeSessionId(sessionId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:storeSessionId\", { sessionId });\n }\n\n updateTaskFields(fields: { plan?: string; description?: string }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateTaskFields\", { fields });\n }\n\n onChatMessage(callback: (message: IncomingMessagePayload) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyMessages) {\n callback(msg);\n }\n this.earlyMessages = [];\n }\n\n onStopRequested(callback: () => void): void {\n this.stopCallback = callback;\n if (this.earlyStop) {\n callback();\n this.earlyStop = false;\n }\n }\n\n onModeChange(callback: (data: SetModePayload) => void): void {\n this.modeChangeCallback = callback;\n for (const data of this.earlyModeChanges) {\n callback(data);\n }\n this.earlyModeChanges = [];\n }\n\n emitModeChanged(mode: PmSubMode): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:modeChanged\", { mode });\n }\n\n trackSpending(params: {\n agentId: string;\n sessionId: string;\n totalCostUsd: number;\n onSubscription: boolean;\n modelUsage?: {\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadInputTokens: number;\n cacheCreationInputTokens: number;\n costUSD: number;\n }[];\n }): void {\n if (!this.socket) throw new Error(\"Not connected\");\n\n this.socket.emit(\"agentRunner:trackSpending\", params);\n }\n\n emitStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:statusUpdate\", { status });\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"agentRunner:heartbeat\", {});\n }\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 createSubtask(data: SubtaskCreatePayload): Promise<{ id: string }> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n return new Promise((resolve, reject) => {\n socket.emit(\"agentRunner:createSubtask\", data, (response: SocketResponse<{ id: string }>) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to create subtask\"));\n });\n });\n }\n\n updateSubtask(subtaskId: string, fields: SubtaskUpdateFields): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:updateSubtask\", { subtaskId, fields });\n }\n\n deleteSubtask(subtaskId: string): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"agentRunner:deleteSubtask\", { subtaskId });\n }\n\n listSubtasks(): Promise<SubtaskResponse[]> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n return new Promise((resolve, reject) => {\n socket.emit(\"agentRunner:listSubtasks\", {}, (response: SocketResponse<SubtaskResponse[]>) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to list subtasks\"));\n });\n });\n }\n\n fetchTask(slugOrId: string): Promise<TaskLookupResponse> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"agentRunner:getTask\",\n { slugOrId },\n (response: SocketResponse<TaskLookupResponse>): void => {\n if (response.success && response.data) {\n resolve(response.data);\n } else {\n reject(new Error(response.error ?? \"Failed to fetch task\"));\n }\n },\n );\n });\n }\n\n disconnect(): void {\n this.flushEvents();\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\n\nexport interface ProjectConnectionConfig {\n apiUrl: string;\n projectToken: string;\n projectId: string;\n}\n\nexport interface TaskAssignment {\n taskId: string;\n taskToken: string;\n apiUrl: string;\n mode: string;\n branch: string;\n devBranch: string;\n useWorktree?: boolean;\n}\n\nexport interface IncomingChatMessage {\n content: string;\n userId: string;\n files?: {\n id: string;\n fileName: string;\n mimeType: string;\n downloadUrl: string;\n content?: string;\n contentEncoding?: \"base64\" | \"utf-8\";\n }[];\n}\n\nexport interface ChatHistoryMessage {\n role: string;\n content: string;\n userId: string | null;\n userName?: string;\n createdAt: string;\n}\n\nexport interface AgentContext {\n projectName: string;\n projectDescription: string | null;\n agentId: string | null;\n agentName: string | null;\n agentInstructions: string;\n model: string;\n agentSettings: Record<string, unknown> | null;\n}\n\nexport class ProjectConnection {\n private socket: Socket | null = null;\n private config: ProjectConnectionConfig;\n private taskAssignmentCallback: ((assignment: TaskAssignment) => void) | null = null;\n private stopTaskCallback: ((data: { taskId: string }) => void) | null = null;\n private shutdownCallback: (() => void) | null = null;\n private chatMessageCallback: ((msg: IncomingChatMessage) => void) | null = null;\n private earlyChatMessages: IncomingChatMessage[] = [];\n\n constructor(config: ProjectConnectionConfig) {\n this.config = config;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxInitialAttempts = 30;\n\n this.socket = io(this.config.apiUrl, {\n auth: { projectToken: this.config.projectToken },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: {\n \"ngrok-skip-browser-warning\": \"true\",\n },\n });\n\n this.socket.on(\"projectRunner:assignTask\", (data: TaskAssignment) => {\n if (this.taskAssignmentCallback) {\n this.taskAssignmentCallback(data);\n }\n });\n\n this.socket.on(\"projectRunner:stopTask\", (data: { taskId: string }) => {\n if (this.stopTaskCallback) {\n this.stopTaskCallback(data);\n }\n });\n\n this.socket.on(\"projectRunner:shutdown\", () => {\n if (this.shutdownCallback) {\n this.shutdownCallback();\n }\n });\n\n this.socket.on(\"projectRunner:incomingChatMessage\", (msg: IncomingChatMessage) => {\n if (this.chatMessageCallback) {\n this.chatMessageCallback(msg);\n } else {\n this.earlyChatMessages.push(msg);\n }\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n resolve();\n }\n });\n\n this.socket.io.on(\"reconnect_attempt\", () => {\n attempts++;\n if (!settled && attempts >= maxInitialAttempts) {\n settled = true;\n reject(new Error(`Failed to connect after ${maxInitialAttempts} attempts`));\n }\n });\n });\n }\n\n onTaskAssignment(callback: (assignment: TaskAssignment) => void): void {\n this.taskAssignmentCallback = callback;\n }\n\n onStopTask(callback: (data: { taskId: string }) => void): void {\n this.stopTaskCallback = callback;\n }\n\n onShutdown(callback: () => void): void {\n this.shutdownCallback = callback;\n }\n\n onChatMessage(callback: (msg: IncomingChatMessage) => void): void {\n this.chatMessageCallback = callback;\n for (const msg of this.earlyChatMessages) {\n callback(msg);\n }\n this.earlyChatMessages = [];\n }\n\n sendHeartbeat(): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:heartbeat\", {});\n }\n\n emitTaskStarted(taskId: string): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:taskStarted\", { taskId });\n }\n\n emitTaskStopped(taskId: string, reason: string): void {\n if (!this.socket) return;\n this.socket.emit(\"projectRunner:taskStopped\", { taskId, reason });\n }\n\n emitEvent(event: Record<string, unknown>): void {\n if (!this.socket) return;\n this.socket.emit(\"conveyor:projectAgentEvent\", event);\n }\n\n emitChatMessage(content: string): Promise<void> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"conveyor:projectAgentChatMessage\",\n { content },\n (response: { success: boolean; error?: string }) => {\n if (response.success) resolve();\n else reject(new Error(response.error ?? \"Failed to send chat message\"));\n },\n );\n });\n }\n\n emitAgentStatus(status: string): void {\n if (!this.socket) return;\n this.socket.emit(\"conveyor:projectAgentStatus\", { status });\n }\n\n fetchAgentContext(): Promise<AgentContext | null> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"projectRunner:getAgentContext\",\n (response: { success: boolean; data?: AgentContext | null; error?: string }) => {\n if (response.success) resolve(response.data ?? null);\n else reject(new Error(response.error ?? \"Failed to fetch agent context\"));\n },\n );\n });\n }\n\n fetchChatHistory(limit?: number): Promise<ChatHistoryMessage[]> {\n const socket = this.socket;\n if (!socket) return Promise.reject(new Error(\"Not connected\"));\n\n return new Promise((resolve, reject) => {\n socket.emit(\n \"projectRunner:getChatHistory\",\n { limit },\n (response: { success: boolean; data?: ChatHistoryMessage[]; error?: string }) => {\n if (response.success && response.data) resolve(response.data);\n else reject(new Error(response.error ?? \"Failed to fetch chat history\"));\n },\n );\n });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ConveyorConfig {\n setupCommand?: string;\n startCommand?: string;\n previewPort?: number;\n}\n\nconst CONVEYOR_CONFIG_PATH = \".conveyor/config.json\";\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport async function loadForwardPorts(workspaceDir: string): Promise<number[]> {\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { forwardPorts?: number[] };\n return parsed.forwardPorts ?? [];\n } catch {\n return [];\n }\n}\n\nexport async function loadConveyorConfig(workspaceDir: string): Promise<ConveyorConfig | null> {\n try {\n const raw = await readFile(join(workspaceDir, CONVEYOR_CONFIG_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as ConveyorConfig;\n if (parsed.setupCommand || parsed.startCommand) return parsed;\n } catch {\n // Not found or invalid — try fallback\n }\n\n try {\n const raw = await readFile(join(workspaceDir, DEVCONTAINER_PATH), \"utf-8\");\n const parsed = JSON.parse(raw) as { conveyor?: ConveyorConfig };\n if (parsed.conveyor && (parsed.conveyor.startCommand || parsed.conveyor.setupCommand)) {\n return parsed.conveyor;\n }\n } catch {\n // Not found or invalid\n }\n\n return null;\n}\n","import { spawn, 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\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 { execSync } from \"node:child_process\";\n\nconst DEVCONTAINER_PATH = \".devcontainer/conveyor/devcontainer.json\";\n\nexport function cleanDevcontainerFromGit(\n workspaceDir: string,\n taskBranch: string,\n baseBranch: string,\n): { cleaned: boolean; message: string } {\n const git = (cmd: string): string =>\n execSync(cmd, { cwd: workspaceDir, encoding: \"utf-8\", timeout: 30_000 }).trim();\n\n try {\n git(`git fetch origin ${baseBranch}`);\n } catch {\n return { cleaned: false, message: `Failed to fetch origin/${baseBranch}` };\n }\n\n try {\n git(`git diff --quiet origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already matches base\" };\n } catch {\n // diff --quiet exits non-zero when there IS a diff — expected path\n }\n\n try {\n const ahead = parseInt(git(`git rev-list --count origin/${baseBranch}..HEAD`), 10);\n\n if (ahead <= 1) {\n git(`git reset --hard origin/${baseBranch}`);\n } else {\n git(`git checkout origin/${baseBranch} -- ${DEVCONTAINER_PATH}`);\n git(`git add ${DEVCONTAINER_PATH}`);\n\n try {\n git(`git diff --cached --quiet -- ${DEVCONTAINER_PATH}`);\n return { cleaned: false, message: \"devcontainer.json already clean in working tree\" };\n } catch {\n git(`git commit -m \"chore: reset devcontainer config\"`);\n }\n }\n\n try {\n git(`git push --force-with-lease origin ${taskBranch}`);\n } catch {\n git(`git push --force origin ${taskBranch}`);\n }\n return { cleaned: true, message: \"devcontainer.json cleaned from git history\" };\n } catch (err) {\n try {\n git(`git checkout ${taskBranch}`);\n } catch {\n /* best effort */\n }\n const msg = err instanceof Error ? err.message : \"Unknown error\";\n return { cleaned: false, message: `Git cleanup failed: ${msg}` };\n }\n}\n\nexport function initRtk(): void {\n try {\n execSync(\"rtk --version\", { stdio: \"ignore\" });\n execSync(\"rtk init --global --auto-patch\", { stdio: \"ignore\" });\n } catch {\n // RTK not installed — skip silently\n }\n}\n\nexport function unshallowRepo(workspaceDir: string): void {\n try {\n execSync(\"git fetch --unshallow\", {\n cwd: workspaceDir,\n stdio: \"ignore\",\n timeout: 60_000,\n });\n } catch {\n // Already unshallowed or not a shallow clone — ignore\n }\n}\n","import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst WORKTREE_DIR = \".worktrees\";\n\nexport function ensureWorktree(projectDir: string, taskId: string, branch?: string): string {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n\n if (existsSync(worktreePath)) {\n if (branch) {\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\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 { randomUUID } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport type { SDKUserMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n AgentRunnerStatus,\n AgentEvent,\n TaskContext,\n MultimodalBlock,\n PmSubMode,\n} from \"../types.js\";\nimport { ConveyorConnection } from \"../connection/index.js\";\nimport {\n cleanDevcontainerFromGit,\n initRtk,\n unshallowRepo,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n type ConveyorConfig,\n} from \"../setup/index.js\";\nimport { runSdkQuery, CostTracker, type QueryHost } from \"../execution/index.js\";\nimport { ensureWorktree } from \"./worktree.js\";\nimport { PlanSync } from \"./plan-sync.js\";\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\n\nexport class AgentRunner {\n private config: AgentRunnerConfig;\n private connection: ConveyorConnection;\n private callbacks: AgentRunnerCallbacks;\n private _state: AgentRunnerStatus = \"connecting\";\n private stopped = false;\n private inputResolver: ((msg: SDKUserMessage | null) => void) | null = null;\n private pendingMessages: SDKUserMessage[] = [];\n private setupLog: string[] = [];\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private taskContext: TaskContext | null = null;\n private planSync: PlanSync;\n private costTracker = new CostTracker();\n private worktreeActive = false;\n private activeMode: PmSubMode = \"planning\";\n private static readonly MAX_SETUP_LOG_LINES = 50;\n\n constructor(config: AgentRunnerConfig, callbacks: AgentRunnerCallbacks) {\n this.config = config;\n this.connection = new ConveyorConnection(config);\n this.callbacks = callbacks;\n this.planSync = new PlanSync(config.workspaceDir, this.connection);\n }\n\n get state(): AgentRunnerStatus {\n return this._state;\n }\n\n private async setState(status: AgentRunnerStatus): Promise<void> {\n this._state = status;\n this.connection.emitStatus(status);\n await this.callbacks.onStatusChange(status);\n }\n\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(() => {\n if (!this.stopped) {\n this.connection.sendHeartbeat();\n }\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n async start(): Promise<void> {\n await this.setState(\"connecting\");\n await this.connection.connect();\n\n this.connection.onStopRequested(() => this.stop());\n this.connection.onChatMessage((message) =>\n this.injectHumanMessage(message.content, message.files),\n );\n this.connection.onModeChange((data) => this.handleModeChange(data.mode));\n\n await this.setState(\"connected\");\n this.connection.sendEvent({ type: \"connected\", taskId: this.config.taskId });\n this.startHeartbeat();\n\n if (this.config.mode !== \"pm\" && process.env.CODESPACES === \"true\") {\n const setupOk = await this.runSetupSafe();\n if (!setupOk) {\n this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n }\n\n initRtk();\n\n if (\n process.env.CONVEYOR_USE_WORKTREE !== \"false\" &&\n (this.config.mode === \"pm\" || process.env.CONVEYOR_USE_WORKTREE === \"true\")\n ) {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.planSync.updateWorkspaceDir(worktreePath);\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree: ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n await this.setState(\"fetching_context\");\n try {\n this.taskContext = await this.connection.fetchTaskContext();\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 this.stopHeartbeat();\n await this.setState(\"error\");\n this.connection.disconnect();\n return;\n }\n\n this.taskContext._runnerSessionId = randomUUID();\n this.logEffectiveSettings();\n\n if (process.env.CODESPACES === \"true\") {\n unshallowRepo(this.config.workspaceDir);\n }\n\n if (process.env.CODESPACES === \"true\" && this.taskContext.baseBranch) {\n const result = cleanDevcontainerFromGit(\n this.config.workspaceDir,\n this.taskContext.githubBranch,\n this.taskContext.baseBranch,\n );\n if (result.cleaned) {\n this.setupLog.push(`[conveyor] ${result.message}`);\n }\n }\n\n if (!this.worktreeActive && this.taskContext.useWorktree) {\n try {\n const worktreePath = ensureWorktree(this.config.workspaceDir, this.config.taskId);\n this.config = { ...this.config, workspaceDir: worktreePath };\n this.planSync.updateWorkspaceDir(worktreePath);\n this.worktreeActive = true;\n this.setupLog.push(`[conveyor] Using worktree (from task config): ${worktreePath}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n this.setupLog.push(`[conveyor] Worktree creation failed, using shared workspace: ${msg}`);\n }\n }\n\n if (this.worktreeActive && this.taskContext.githubBranch) {\n try {\n const branch = this.taskContext.githubBranch;\n execSync(`git fetch origin ${branch} && git checkout ${branch}`, {\n cwd: this.config.workspaceDir,\n stdio: \"ignore\",\n });\n } catch {\n /* branch may not exist remotely yet or already checked out */\n }\n }\n\n const isPm = this.config.mode === \"pm\";\n if (isPm) {\n await this.setState(\"idle\");\n } else {\n await this.setState(\"running\");\n await this.runQuerySafe(this.taskContext);\n if (!this.stopped) await this.setState(\"idle\");\n }\n\n await this.runCoreLoop();\n\n this.stopHeartbeat();\n await this.setState(\"finished\");\n this.connection.disconnect();\n }\n\n private async runQuerySafe(\n context: TaskContext,\n followUp?: string | MultimodalBlock[],\n ): Promise<void> {\n try {\n await runSdkQuery(this.asQueryHost(), context, followUp);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.connection.sendEvent({ type: \"error\", message });\n await this.callbacks.onEvent({ type: \"error\", message });\n await this.setState(\"error\");\n }\n }\n\n private async runCoreLoop(): Promise<void> {\n if (!this.taskContext) return;\n while (!this.stopped) {\n if (this._state === \"idle\") {\n const msg = await this.waitForUserContent();\n if (!msg) break;\n await this.setState(\"running\");\n await this.runQuerySafe(this.taskContext, msg);\n if (!this.stopped && (this._state as string) !== \"error\") await this.setState(\"idle\");\n } else if (this._state === \"error\") {\n await this.setState(\"idle\");\n } else {\n break;\n }\n }\n }\n\n private async runSetupSafe(): Promise<boolean> {\n await this.setState(\"setup\");\n\n const ports = await loadForwardPorts(this.config.workspaceDir);\n if (ports.length > 0 && process.env.CODESPACE_NAME) {\n const visibility = ports.map((p) => `${p}:public`).join(\" \");\n runStartCommand(\n `gh codespace ports visibility ${visibility} -c \"${process.env.CODESPACE_NAME}\" 2>/dev/null`,\n this.config.workspaceDir,\n () => undefined,\n );\n }\n\n const config = await loadConveyorConfig(this.config.workspaceDir);\n if (!config) {\n this.connection.sendEvent({ type: \"setup_complete\" });\n await this.callbacks.onEvent({ type: \"setup_complete\" });\n return true;\n }\n\n try {\n await this.executeSetupConfig(config);\n const setupEvent: AgentEvent = {\n type: \"setup_complete\",\n previewPort: config.previewPort ?? undefined,\n };\n this.connection.sendEvent(setupEvent);\n await this.callbacks.onEvent(setupEvent);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Setup failed\";\n this.connection.sendEvent({ type: \"setup_error\", message });\n await this.callbacks.onEvent({ type: \"setup_error\", message });\n this.connection.postChatMessage(\n `Environment setup failed: ${message}\\nThe agent cannot start until this is resolved.`,\n );\n return false;\n }\n }\n\n private logEffectiveSettings(): void {\n if (!this.taskContext) return;\n const s = this.taskContext.agentSettings ?? this.config.agentSettings ?? {};\n const model = this.taskContext.model || this.config.model;\n const thinking =\n s.thinking?.type === \"enabled\"\n ? `enabled(${(s.thinking as { budgetTokens?: number }).budgetTokens ?? \"?\"})`\n : (s.thinking?.type ?? \"default\");\n const parts = [\n `model=${model}`,\n `mode=${this.config.mode ?? \"task\"}`,\n `effort=${s.effort ?? \"default\"}`,\n `thinking=${thinking}`,\n `maxBudget=$${s.maxBudgetUsd ?? 50}`,\n `maxTurns=${s.maxTurns ?? \"unlimited\"}`,\n ];\n if (s.betas?.length) parts.push(`betas=${s.betas.join(\",\")}`);\n if (s.disallowedTools?.length) parts.push(`disallowed=[${s.disallowedTools.join(\",\")}]`);\n if (s.enableFileCheckpointing) parts.push(`checkpointing=on`);\n /* oxlint-disable no-console */\n console.log(`[conveyor-agent] ${parts.join(\", \")}`);\n /* oxlint-enable no-console */\n }\n\n private pushSetupLog(line: string): void {\n this.setupLog.push(line);\n if (this.setupLog.length > AgentRunner.MAX_SETUP_LOG_LINES) {\n this.setupLog.splice(0, this.setupLog.length - AgentRunner.MAX_SETUP_LOG_LINES);\n }\n }\n\n private async executeSetupConfig(config: ConveyorConfig): Promise<void> {\n if (config.setupCommand) {\n this.pushSetupLog(`$ ${config.setupCommand}`);\n await runSetupCommand(config.setupCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"setup_output\", stream, data });\n for (const line of data.split(\"\\n\").filter(Boolean)) {\n this.pushSetupLog(`[${stream}] ${line}`);\n }\n });\n this.pushSetupLog(\"(exit 0)\");\n }\n\n if (config.startCommand) {\n this.pushSetupLog(`$ ${config.startCommand} & (background)`);\n runStartCommand(config.startCommand, this.config.workspaceDir, (stream, data) => {\n this.connection.sendEvent({ type: \"start_command_output\", stream, data });\n });\n }\n }\n\n private injectHumanMessage(\n content: string,\n files?: {\n id: string;\n fileName: string;\n mimeType: string;\n downloadUrl: string;\n content?: string;\n contentEncoding?: \"base64\" | \"utf-8\";\n }[],\n ): void {\n type ImageMediaType = \"image/gif\" | \"image/jpeg\" | \"image/png\" | \"image/webp\";\n type TextBlock = { type: \"text\"; text: string };\n type ImageBlock = {\n type: \"image\";\n source: { type: \"base64\"; media_type: ImageMediaType; data: string };\n };\n type ContentBlock = TextBlock | ImageBlock;\n\n let messageContent: string | ContentBlock[];\n if (files?.length) {\n const blocks: ContentBlock[] = [{ type: \"text\", text: content }];\n for (const f of files) {\n if (f.content && f.contentEncoding === \"base64\") {\n blocks.push({\n type: \"image\",\n source: { type: \"base64\", media_type: f.mimeType as ImageMediaType, data: f.content },\n });\n blocks.push({\n type: \"text\",\n text: `[Attached image: ${f.fileName} (${f.mimeType})]`,\n });\n } else if (f.content && f.contentEncoding === \"utf-8\") {\n blocks.push({\n type: \"text\",\n text: `[Attached file: ${f.fileName} (${f.mimeType})]\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``,\n });\n } else {\n blocks.push({\n type: \"text\",\n text: `[Attached file: ${f.fileName} (${f.mimeType})] Download: ${f.downloadUrl}`,\n });\n }\n }\n messageContent = blocks;\n } else {\n messageContent = content;\n }\n\n const msg: SDKUserMessage = {\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content: messageContent },\n parent_tool_use_id: null,\n };\n\n if (this.inputResolver) {\n const resolve = this.inputResolver;\n this.inputResolver = null;\n resolve(msg);\n } else {\n this.pendingMessages.push(msg);\n }\n }\n\n private waitForMessage(): Promise<SDKUserMessage | null> {\n return new Promise<SDKUserMessage | null>((resolve) => {\n const checkStopped = setInterval(() => {\n if (this.stopped) {\n clearInterval(checkStopped);\n this.inputResolver = null;\n resolve(null);\n }\n }, 1000);\n\n this.inputResolver = (msg: SDKUserMessage | null) => {\n clearInterval(checkStopped);\n resolve(msg);\n };\n });\n }\n\n private async waitForUserContent(): Promise<string | MultimodalBlock[] | null> {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n const content = next?.message.content;\n if (!content) return null;\n return content as string | MultimodalBlock[];\n }\n const msg = await this.waitForMessage();\n if (!msg) return null;\n const content = msg.message.content;\n if (!content) return null;\n return content as string | MultimodalBlock[];\n }\n\n async *createInputStream(\n initialPrompt: string | MultimodalBlock[],\n ): AsyncGenerator<SDKUserMessage, void, unknown> {\n const makeUserMessage = (content: string | MultimodalBlock[]): SDKUserMessage => ({\n type: \"user\" as const,\n session_id: \"\",\n message: { role: \"user\" as const, content },\n parent_tool_use_id: null,\n });\n\n yield makeUserMessage(initialPrompt);\n\n while (!this.stopped) {\n if (this.pendingMessages.length > 0) {\n const next = this.pendingMessages.shift();\n if (next) yield next;\n continue;\n }\n\n this.connection.emitStatus(\"waiting_for_input\");\n await this.callbacks.onStatusChange(\"waiting_for_input\");\n const msg = await this.waitForMessage();\n\n if (!msg) break;\n this.connection.emitStatus(\"running\");\n await this.callbacks.onStatusChange(\"running\");\n yield msg;\n }\n }\n\n private asQueryHost(): QueryHost {\n const getActiveMode = (): PmSubMode => this.activeMode;\n return {\n config: this.config,\n connection: this.connection,\n callbacks: this.callbacks,\n setupLog: this.setupLog,\n costTracker: this.costTracker,\n get activeMode(): PmSubMode {\n return getActiveMode();\n },\n isStopped: () => this.stopped,\n createInputStream: (prompt: string) => this.createInputStream(prompt),\n snapshotPlanFiles: () => this.planSync.snapshotPlanFiles(),\n syncPlanFile: () => this.planSync.syncPlanFile(),\n };\n }\n\n private handleModeChange(mode: PmSubMode): void {\n if (this.config.mode !== \"pm\") return;\n this.activeMode = mode;\n this.connection.emitModeChanged(mode);\n this.connection.postChatMessage(\n `Mode switched to **${mode}**${mode === \"active\" ? \" — I now have direct coding access.\" : \" — back to planning only.\"}`,\n );\n }\n\n stop(): void {\n this.stopped = true;\n if (this.inputResolver) {\n this.inputResolver(null);\n this.inputResolver = null;\n }\n }\n}\n","import type {\n SDKMessage,\n SDKAssistantMessage,\n SDKResultMessage,\n SDKResultSuccess,\n SDKResultError,\n SDKSystemMessage,\n SDKRateLimitEvent,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { TaskContext, ActivityEventSummary } from \"../types.js\";\nimport type { QueryHost } from \"./query-executor.js\";\n\nasync function processAssistantEvent(\n event: SDKAssistantMessage,\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\") {\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\") {\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 if (turnTextParts.length > 0) {\n host.connection.postChatMessage(turnTextParts.join(\"\\n\\n\"));\n }\n\n if (turnToolCalls.length > 0) {\n host.connection.sendEvent({ type: \"turn_end\", toolCalls: [...turnToolCalls] });\n turnToolCalls.length = 0;\n }\n}\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\n\nfunction handleResultEvent(\n event: SDKResultMessage,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n): { totalCostUsd: number; retriable: boolean } {\n let totalCostUsd = 0;\n let retriable = false;\n\n if (event.subtype === \"success\") {\n const successEvent = event as SDKResultSuccess;\n const queryCostUsd = successEvent.total_cost_usd;\n const durationMs = Date.now() - startTime;\n const summary = successEvent.result || \"Task completed.\";\n\n if (API_ERROR_PATTERN.test(summary) && durationMs < 30_000) {\n retriable = true;\n }\n\n // Accumulate cost across retries and follow-up queries\n const cumulativeTotal = host.costTracker.addQueryCost(queryCostUsd);\n totalCostUsd = cumulativeTotal;\n\n // Extract per-model usage from typed SDK field\n const { modelUsage } = successEvent;\n if (modelUsage && typeof modelUsage === \"object\") {\n host.costTracker.addModelUsage(modelUsage);\n }\n\n host.connection.sendEvent({ type: \"completed\", summary, costUsd: cumulativeTotal, durationMs });\n\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 } else {\n const errorEvent = event as SDKResultError;\n const errorMsg =\n errorEvent.errors.length > 0\n ? errorEvent.errors.join(\", \")\n : `Agent stopped: ${errorEvent.subtype}`;\n\n if (API_ERROR_PATTERN.test(errorMsg)) {\n retriable = true;\n }\n\n host.connection.sendEvent({ type: \"error\", message: errorMsg });\n }\n\n return { totalCostUsd, retriable };\n}\n\nasync function emitResultEvent(\n event: SDKResultMessage,\n host: QueryHost,\n context: TaskContext,\n startTime: number,\n): Promise<boolean> {\n const result = handleResultEvent(event, host, context, startTime);\n const durationMs = Date.now() - startTime;\n\n if (event.subtype === \"success\") {\n const successEvent = event as SDKResultSuccess;\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 {\n const errorEvent = event as SDKResultError;\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 result.retriable;\n}\n\nfunction handleRateLimitEvent(event: SDKRateLimitEvent, host: QueryHost): void {\n const { rate_limit_info } = event;\n const status = rate_limit_info.status;\n\n if (status === \"rejected\") {\n const resetsAt = rate_limit_info.resetsAt\n ? new Date(rate_limit_info.resetsAt).toISOString()\n : \"unknown\";\n const message = `Rate limit rejected (type: ${rate_limit_info.rateLimitType ?? \"unknown\"}, resets at: ${resetsAt})`;\n host.connection.sendEvent({ type: \"error\", message });\n void host.callbacks.onEvent({ type: \"error\", message });\n } else if (status === \"allowed_warning\") {\n const utilization = rate_limit_info.utilization\n ? `${Math.round(rate_limit_info.utilization * 100)}%`\n : \"high\";\n const message = `Rate limit warning: ${utilization} utilization (type: ${rate_limit_info.rateLimitType ?? \"unknown\"})`;\n host.connection.sendEvent({ type: \"thinking\", message });\n void host.callbacks.onEvent({ type: \"thinking\", message });\n }\n}\n\nexport async function processEvents(\n events: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n host: QueryHost,\n): Promise<{ retriable: boolean }> {\n const startTime = Date.now();\n let sessionIdStored = false;\n let isTyping = false;\n let retriable = false;\n const turnToolCalls: ActivityEventSummary[] = [];\n\n for await (const event of events) {\n if (host.isStopped()) break;\n\n switch (event.type) {\n case \"system\": {\n const systemEvent = event as SDKSystemMessage;\n if (systemEvent.subtype === \"init\") {\n if (systemEvent.session_id && !sessionIdStored) {\n sessionIdStored = true;\n host.connection.storeSessionId(systemEvent.session_id);\n context.claudeSessionId = systemEvent.session_id;\n }\n await host.callbacks.onEvent({\n type: \"thinking\",\n message: `Agent initialized (model: ${systemEvent.model})`,\n });\n }\n break;\n }\n\n case \"assistant\": {\n if (!isTyping) {\n setTimeout(() => host.connection.sendTypingStart(), 200);\n isTyping = true;\n }\n await processAssistantEvent(event as SDKAssistantMessage, host, turnToolCalls);\n break;\n }\n\n case \"result\": {\n if (isTyping) {\n host.connection.sendTypingStop();\n isTyping = false;\n }\n retriable = await emitResultEvent(event as SDKResultMessage, host, context, startTime);\n break;\n }\n\n case \"rate_limit_event\": {\n handleRateLimitEvent(event as SDKRateLimitEvent, host);\n break;\n }\n }\n }\n\n if (isTyping) {\n host.connection.sendTypingStop();\n }\n\n return { retriable };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n query,\n type SDKMessage,\n type SDKUserMessage,\n type HookEvent,\n type HookCallbackMatcher,\n type HookJSONOutput,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type {\n AgentRunnerConfig,\n AgentRunnerCallbacks,\n TaskContext,\n MultimodalBlock,\n PmSubMode,\n} from \"../types.js\";\nimport { buildInitialPrompt, buildSystemPrompt } from \"./prompt-builder.js\";\nimport { createConveyorMcpServer } from \"../tools/index.js\";\nimport { processEvents } from \"./event-processor.js\";\nimport type { CostTracker } from \"./cost-tracker.js\";\n\nconst API_ERROR_PATTERN = /API Error: [45]\\d\\d/;\nconst RETRY_DELAYS_MS = [60_000, 120_000, 180_000, 300_000];\nconst PM_PLAN_FILE_TOOLS = new Set([\"Write\", \"Edit\", \"MultiEdit\"]);\nconst DESTRUCTIVE_CMD_PATTERN =\n /git\\s+push\\s+--force(?!\\s*-with-lease)|git\\s+reset\\s+--hard|rm\\s+-rf\\s+\\//;\n\nexport interface QueryHost {\n config: AgentRunnerConfig;\n connection: ConveyorConnection;\n callbacks: AgentRunnerCallbacks;\n setupLog: string[];\n costTracker: CostTracker;\n activeMode: PmSubMode;\n isStopped(): boolean;\n createInputStream(\n prompt: string | MultimodalBlock[],\n ): AsyncGenerator<SDKUserMessage, void, unknown>;\n snapshotPlanFiles(): void;\n syncPlanFile(): void;\n}\n\nfunction buildCanUseTool(\n host: QueryHost,\n): (\n toolName: string,\n input: Record<string, unknown>,\n) => Promise<\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown> }\n | { behavior: \"deny\"; message: string }\n> {\n const QUESTION_TIMEOUT_MS = 5 * 60 * 1000;\n\n return async (toolName, input) => {\n const isPmPlanning = host.config.mode === \"pm\" && host.activeMode === \"planning\";\n const isPmActive = host.config.mode === \"pm\" && host.activeMode === \"active\";\n\n // In PM planning mode, restrict writes to plan files only\n if (isPmPlanning && PM_PLAN_FILE_TOOLS.has(toolName)) {\n const filePath = String(input.file_path ?? input.path ?? \"\");\n if (filePath.includes(\".claude/plans/\")) {\n return { behavior: \"allow\", updatedInput: input };\n }\n return {\n behavior: \"deny\",\n message: \"File write tools are only available for plan files in PM mode.\",\n };\n }\n\n // In PM active mode, block destructive commands\n if (isPmActive && toolName === \"Bash\") {\n const cmd = String(input.command ?? \"\");\n if (DESTRUCTIVE_CMD_PATTERN.test(cmd)) {\n return {\n behavior: \"deny\",\n message: \"Destructive operation blocked in active mode. Use safer alternatives.\",\n };\n }\n }\n\n if (toolName !== \"AskUserQuestion\") {\n return { behavior: \"allow\", updatedInput: input };\n }\n\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 const requestId = randomUUID();\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(requestId, 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) {\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}\n\nfunction buildQueryOptions(host: QueryHost, context: TaskContext): Record<string, unknown> {\n const settings = context.agentSettings ?? host.config.agentSettings ?? {};\n const isPmActive = host.config.mode === \"pm\" && host.activeMode === \"active\";\n const systemPromptText = buildSystemPrompt(\n host.config.mode,\n context,\n host.config,\n host.setupLog,\n isPmActive ? \"active\" : \"planning\",\n );\n const conveyorMcp = createConveyorMcpServer(host.connection, host.config, context);\n const isPm = host.config.mode === \"pm\";\n const pmDisallowedTools = isPm && !isPmActive ? [\"TodoWrite\", \"TodoRead\", \"NotebookEdit\"] : [];\n const disallowedTools = [...(settings.disallowedTools ?? []), ...pmDisallowedTools];\n const settingSources = (settings.settingSources ?? [\"user\", \"project\"]) as (\n | \"user\"\n | \"project\"\n | \"local\"\n )[];\n\n const hooks: Partial<Record<HookEvent, HookCallbackMatcher[]>> = {\n PostToolUse: [\n {\n hooks: [\n async (input): Promise<HookJSONOutput> => {\n if (input.hook_event_name === \"PostToolUse\") {\n const output =\n typeof input.tool_response === \"string\"\n ? input.tool_response.slice(0, 500)\n : JSON.stringify(input.tool_response).slice(0, 500);\n host.connection.sendEvent({\n type: \"tool_result\",\n tool: input.tool_name,\n output,\n isError: false,\n });\n }\n return { continue: true };\n },\n ],\n timeout: 5,\n },\n ],\n };\n\n const baseOptions: Record<string, unknown> = {\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: isPmActive ? \"acceptEdits\" : \"bypassPermissions\",\n allowDangerouslySkipPermissions: !isPmActive,\n canUseTool: buildCanUseTool(host),\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n mcpServers: { conveyor: conveyorMcp },\n hooks,\n maxTurns: settings.maxTurns,\n effort: settings.effort,\n thinking: settings.thinking,\n betas: settings.betas,\n maxBudgetUsd: settings.maxBudgetUsd ?? 50,\n disallowedTools: disallowedTools.length > 0 ? disallowedTools : undefined,\n enableFileCheckpointing: settings.enableFileCheckpointing,\n };\n\n if (isPmActive) {\n const apiHostname = new URL(host.config.conveyorApiUrl).hostname;\n baseOptions.sandbox = {\n enabled: true,\n autoAllowBashIfSandboxed: true,\n allowUnsandboxedCommands: false,\n filesystem: {\n allowWrite: [`${host.config.workspaceDir}/**`],\n denyRead: [\"/etc/shadow\", \"/etc/passwd\", \"**/.env\", \"**/.env.*\"],\n denyWrite: [\"**/.env\", \"**/.env.*\", \"**/node_modules/**\"],\n },\n network: {\n allowedDomains: [apiHostname, \"api.anthropic.com\"],\n allowManagedDomainsOnly: true,\n allowLocalBinding: true,\n },\n };\n }\n\n return baseOptions;\n}\n\ntype ImageMediaType = \"image/gif\" | \"image/jpeg\" | \"image/png\" | \"image/webp\";\n\nfunction buildMultimodalPrompt(\n textPrompt: string,\n context: TaskContext,\n): string | MultimodalBlock[] {\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({\n type: \"text\",\n text: `[Attached image: ${file.fileName} (${file.mimeType})]`,\n });\n }\n for (const file of chatImages) {\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({\n type: \"text\",\n text: `[Chat image: ${file.fileName} (${file.mimeType})]`,\n });\n }\n return blocks;\n}\n\nexport async function runSdkQuery(\n host: QueryHost,\n context: TaskContext,\n followUpContent?: string | MultimodalBlock[],\n): Promise<void> {\n if (host.isStopped()) return;\n\n const isPm = host.config.mode === \"pm\";\n const isPmPlanning = isPm && host.activeMode === \"planning\";\n if (isPmPlanning) {\n host.snapshotPlanFiles();\n }\n\n const options = buildQueryOptions(host, context);\n const resume = context.claudeSessionId ?? undefined;\n\n if (followUpContent) {\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 = isPm\n ? `${buildInitialPrompt(host.config.mode, context)}\\n\\n---\\n\\nThe team says:\\n${followUpText}`\n : followUpText;\n\n let prompt: string | MultimodalBlock[];\n if (isPm) {\n prompt = buildMultimodalPrompt(textPrompt, context);\n if (followUpImages.length > 0 && Array.isArray(prompt)) {\n prompt.push(...followUpImages);\n }\n } else if (followUpImages.length > 0) {\n prompt = [{ type: \"text\", text: textPrompt }, ...followUpImages];\n } else {\n prompt = textPrompt;\n }\n\n const agentQuery = query({\n prompt: typeof prompt === \"string\" ? prompt : host.createInputStream(prompt),\n options: { ...options, resume },\n });\n await runWithRetry(agentQuery, context, host, options);\n } else if (isPmPlanning) {\n return;\n } else {\n const initialPrompt = buildInitialPrompt(host.config.mode, context);\n const prompt = buildMultimodalPrompt(initialPrompt, context);\n const agentQuery = query({\n prompt: host.createInputStream(prompt),\n options: { ...options, resume },\n });\n await runWithRetry(agentQuery, context, host, options);\n }\n\n if (isPmPlanning) {\n host.syncPlanFile();\n }\n}\n\nasync function runWithRetry(\n initialQuery: AsyncGenerator<SDKMessage, void>,\n context: TaskContext,\n host: QueryHost,\n options: Record<string, unknown>,\n): Promise<void> {\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 : (() => {\n const retryPrompt = buildMultimodalPrompt(\n buildInitialPrompt(host.config.mode, context),\n context,\n );\n return query({\n prompt: host.createInputStream(retryPrompt),\n options: { ...options, resume: undefined },\n });\n })();\n\n try {\n const { retriable } = await processEvents(agentQuery, context, host);\n if (!retriable || host.isStopped()) return;\n } catch (error) {\n const isStaleSession =\n error instanceof Error && error.message.includes(\"No conversation found with session ID\");\n\n if (isStaleSession && context.claudeSessionId) {\n context.claudeSessionId = null;\n host.connection.storeSessionId(\"\");\n const freshPrompt = buildMultimodalPrompt(\n buildInitialPrompt(host.config.mode, context),\n context,\n );\n const freshQuery = query({\n prompt: host.createInputStream(freshPrompt),\n options: { ...options, resume: undefined },\n });\n return runWithRetry(freshQuery, context, host, options);\n }\n\n const isApiError = error instanceof Error && API_ERROR_PATTERN.test(error.message);\n if (!isApiError) throw error;\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 const delayMs = RETRY_DELAYS_MS[attempt];\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 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 host.connection.emitStatus(\"running\");\n await host.callbacks.onStatusChange(\"running\");\n }\n}\n","import type { RunnerMode, PmSubMode, TaskContext, ChatMessage } from \"../types.js\";\n\nconst ACTIVE_STATUSES = new Set([\"InProgress\", \"ReviewPR\", \"ReviewDev\", \"ReviewLive\"]);\n\nfunction 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\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 detectRelaunchScenario(\n context: TaskContext,\n): \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\" {\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n if (lastAgentIdx === -1) return \"fresh\";\n\n const hasPriorWork =\n !!context.githubPRUrl || !!context.claudeSessionId || ACTIVE_STATUSES.has(context.status ?? \"\");\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 buildRelaunchWithSession(\n mode: RunnerMode | undefined,\n context: TaskContext,\n): string | null {\n const scenario = detectRelaunchScenario(context);\n if (!context.claudeSessionId || scenario === \"fresh\") return null;\n\n const parts: string[] = [];\n const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);\n\n if (mode === \"pm\") {\n const newMessages = context.chatHistory\n .slice(lastAgentIdx + 1)\n .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 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 } else if (scenario === \"feedback_relaunch\") {\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 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 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 `Reply with a brief status update (visible in chat), then wait for further instructions.`,\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\nfunction buildTaskBody(context: TaskContext): string[] {\n const parts: string[] = [];\n parts.push(`# Task: ${context.title}`);\n if (context.description) {\n parts.push(`\\n## Description\\n${context.description}`);\n }\n if (context.plan) {\n parts.push(`\\n## Plan\\n${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 if (file.content && file.contentEncoding === \"utf-8\") {\n parts.push(`\\n### ${file.fileName} (${file.mimeType})`);\n parts.push(\"```\");\n parts.push(file.content);\n parts.push(\"```\");\n } else if (!file.content) {\n parts.push(`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`);\n }\n }\n }\n\n if (context.repoRefs && context.repoRefs.length > 0) {\n parts.push(`\\n## Repository References`);\n for (const ref of context.repoRefs) {\n const icon = ref.refType === \"folder\" ? \"folder\" : \"file\";\n parts.push(`- [${icon}] \\`${ref.path}\\``);\n }\n }\n\n if (context.chatHistory.length > 0) {\n const relevant = context.chatHistory.slice(-20);\n parts.push(`\\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 const sizeStr = file.fileSize ? `, ${formatFileSize(file.fileSize)}` : \"\";\n if (file.content && file.contentEncoding === \"utf-8\") {\n parts.push(`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`);\n parts.push(\"```\");\n parts.push(file.content);\n parts.push(\"```\");\n } else if (!file.content) {\n parts.push(\n `[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]: ${file.downloadUrl}`,\n );\n } else {\n parts.push(`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]`);\n }\n }\n }\n }\n }\n\n return parts;\n}\n\nfunction buildInstructions(\n mode: RunnerMode | undefined,\n context: TaskContext,\n scenario: \"fresh\" | \"idle_relaunch\" | \"feedback_relaunch\",\n): string[] {\n const parts: string[] = [`\\n## Instructions`];\n const isPm = mode === \"pm\";\n\n if (scenario === \"fresh\") {\n if (isPm && context.isParentTask) {\n parts.push(\n `You are the project manager for this task and its subtasks.`,\n `Use list_subtasks to review the current state of child tasks.`,\n `The task details are provided above. Wait for the team to provide instructions before taking action.`,\n `When you finish planning, save the plan with update_task and end your turn. Your reply will be visible to the team in chat.`,\n );\n } else if (isPm) {\n parts.push(\n `You are the project manager for this task.`,\n `The task details are provided above. Wait for the team to ask questions or provide additional requirements before starting to plan.`,\n `When you finish planning, save the plan with update_task 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 } else {\n parts.push(\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 `When finished, commit your changes, then run \\`git fetch origin ${context.githubBranch}\\` and \\`git push origin ${context.githubBranch}\\` (use --force-with-lease if push fails). Then use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n } else if (scenario === \"idle_relaunch\") {\n if (isPm) {\n parts.push(\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 } 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, then verify the current state is correct.`,\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 if (context.githubPRUrl) {\n parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);\n }\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 if (isPm) {\n parts.push(\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 `\\nReview these messages and wait for the team to provide instructions before taking action.`,\n );\n } else {\n parts.push(\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 `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 to update it. Do NOT create a new PR.`,\n );\n } else {\n parts.push(\n `When finished, use the create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`,\n );\n }\n }\n }\n\n return parts;\n}\n\nexport function buildInitialPrompt(mode: RunnerMode | undefined, context: TaskContext): string {\n const sessionRelaunch = buildRelaunchWithSession(mode, context);\n if (sessionRelaunch) return sessionRelaunch;\n\n const scenario = detectRelaunchScenario(context);\n const body = buildTaskBody(context);\n const instructions = buildInstructions(mode, context, scenario);\n return [...body, ...instructions].join(\"\\n\");\n}\n\nexport function buildSystemPrompt(\n mode: RunnerMode | undefined,\n context: TaskContext,\n config: { instructions: string; workspaceDir: string },\n setupLog: string[],\n pmSubMode: PmSubMode = \"planning\",\n): string {\n const isPm = mode === \"pm\";\n const isPmActive = isPm && pmSubMode === \"active\";\n const pmParts = [\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 read files, search code, and run shell commands (e.g. git log, git diff) to understand the codebase. 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 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 (isPm && context.isParentTask) {\n pmParts.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 (isPm && context.storyPoints && context.storyPoints.length > 0) {\n pmParts.push(`\\nStory Point Tiers:`);\n for (const sp of context.storyPoints) {\n const desc = sp.description ? ` — ${sp.description}` : \"\";\n pmParts.push(`- Value ${sp.value}: \"${sp.name}\"${desc}`);\n }\n }\n if (isPm && context.projectAgents && context.projectAgents.length > 0) {\n pmParts.push(`\\nProject Agents:`);\n for (const pa of context.projectAgents) {\n const role = pa.role ? `role: ${pa.role}` : \"role: unassigned\";\n const sp = pa.storyPoints != null ? `, story points: ${pa.storyPoints}` : \"\";\n pmParts.push(`- ${pa.agent.name} (${role}${sp})`);\n }\n }\n const activeParts = [\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 ${config.workspaceDir}.`,\n `You can edit files, run tests, and make commits.`,\n `You still have access to all PM tools (subtasks, update_task, 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 (${config.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 const parts = isPmActive\n ? activeParts\n : isPm\n ? pmParts\n : [\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 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 create_pull_request tool to open PRs — do NOT use gh CLI or shell commands for PR creation.`,\n );\n }\n return parts.join(\"\\n\");\n}\n","import { createSdkMcpServer } from \"@anthropic-ai/claude-agent-sdk\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { AgentRunnerConfig, TaskContext } from \"../types.js\";\nimport { buildCommonTools } from \"./common-tools.js\";\nimport { buildPmTools } from \"./pm-tools.js\";\nimport { buildTaskTools } from \"./task-tools.js\";\n\nexport function textResult(text: string): { content: { type: \"text\"; text: string }[] } {\n return { content: [{ type: \"text\" as const, text }] };\n}\n\n// oxlint-disable-next-line typescript/explicit-function-return-type\nexport function createConveyorMcpServer(\n connection: ConveyorConnection,\n config: AgentRunnerConfig,\n context?: TaskContext,\n) {\n const commonTools = buildCommonTools(connection, config);\n const modeTools =\n config.mode === \"pm\"\n ? buildPmTools(connection, context?.storyPoints)\n : buildTaskTools(connection);\n\n return createSdkMcpServer({\n name: \"conveyor\",\n tools: [...commonTools, ...modeTools],\n });\n}\n","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { AgentRunnerConfig } from \"../types.js\";\nimport { textResult } from \"./index.js\";\n\nexport function buildCommonTools(connection: ConveyorConnection, config: AgentRunnerConfig) {\n return [\n tool(\n \"read_task_chat\",\n \"Read recent messages from the task chat to see team feedback or instructions\",\n {\n limit: z.number().optional().describe(\"Number of recent messages to fetch (default 20)\"),\n },\n async ({ limit }) => {\n try {\n const messages = await connection.fetchChatMessages(limit);\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 tool(\n \"post_to_chat\",\n \"Post a message to the task chat. Your normal replies already appear in chat — only use this for explicit out-of-band updates or posting to a different task's chat\",\n { message: z.string().describe(\"The message to post to the team\") },\n ({ message }) => {\n connection.postChatMessage(message);\n return Promise.resolve(textResult(\"Message posted to task chat.\"));\n },\n ),\n tool(\n \"update_task_status\",\n \"Update the task status on the Kanban board\",\n {\n status: z\n .enum([\"InProgress\", \"ReviewPR\", \"Complete\"])\n .describe(\"The new status for the task\"),\n },\n ({ status }) => {\n connection.updateStatus(status);\n return Promise.resolve(textResult(`Task status updated to ${status}.`));\n },\n ),\n tool(\n \"get_task_plan\",\n \"Re-read the latest task plan in case it was updated\",\n {},\n async () => {\n try {\n const ctx = await connection.fetchTaskContext();\n return textResult(ctx.plan ?? \"No plan available.\");\n } catch {\n return textResult(`Task ID: ${config.taskId} - could not fetch updated plan.`);\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n tool(\n \"get_task\",\n \"Look up a task by slug or ID to get its title, description, plan, and status\",\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.fetchTask(slug_or_id);\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 tool(\n \"list_task_files\",\n \"List all files attached to this task with metadata (name, type, size) and download URLs\",\n {},\n async () => {\n try {\n const files = await connection.fetchTaskFiles();\n return textResult(JSON.stringify(files, null, 2));\n } catch {\n return textResult(\"Failed to list task files.\");\n }\n },\n { annotations: { readOnlyHint: true } },\n ),\n tool(\n \"get_task_file\",\n \"Get a specific task file's content and download URL by file ID\",\n { fileId: z.string().describe(\"The file ID to retrieve\") },\n async ({ fileId }) => {\n try {\n const file = await connection.fetchTaskFile(fileId);\n return textResult(JSON.stringify(file, null, 2));\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","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport type { TaskContext } from \"../types.js\";\nimport { textResult } from \"./index.js\";\n\nexport function buildStoryPointDescription(storyPoints?: TaskContext[\"storyPoints\"]): string {\n if (storyPoints && storyPoints.length > 0) {\n const tiers = storyPoints.map((sp) => `${sp.value}=${sp.name}`).join(\", \");\n return `Story point value (${tiers})`;\n }\n return \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n}\n\nexport function buildPmTools(\n connection: ConveyorConnection,\n storyPoints?: TaskContext[\"storyPoints\"],\n) {\n const spDescription = buildStoryPointDescription(storyPoints);\n return [\n tool(\n \"update_task\",\n \"Save the finalized task plan and/or description\",\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 Promise.resolve(connection.updateTaskFields({ plan, description }));\n return textResult(\"Task updated successfully.\");\n } catch {\n return textResult(\"Failed to update task.\");\n }\n },\n ),\n tool(\n \"create_subtask\",\n \"Create a subtask under the current parent task. Use for breaking complex tasks into smaller pieces.\",\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(spDescription),\n },\n async (params) => {\n try {\n const result = await connection.createSubtask(params);\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 tool(\n \"update_subtask\",\n \"Update an existing subtask's fields\",\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(spDescription),\n },\n async ({ subtaskId, ...fields }) => {\n try {\n await Promise.resolve(connection.updateSubtask(subtaskId, fields));\n return textResult(\"Subtask updated.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n ),\n tool(\n \"delete_subtask\",\n \"Delete a subtask\",\n { subtaskId: z.string().describe(\"The subtask ID to delete\") },\n async ({ subtaskId }) => {\n try {\n await Promise.resolve(connection.deleteSubtask(subtaskId));\n return textResult(\"Subtask deleted.\");\n } catch (error) {\n return textResult(`Failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n }\n },\n ),\n tool(\n \"list_subtasks\",\n \"List all subtasks under the current parent task\",\n {},\n async () => {\n try {\n const subtasks = await connection.listSubtasks();\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}\n","import { tool } from \"@anthropic-ai/claude-agent-sdk\";\nimport { z } from \"zod\";\nimport type { ConveyorConnection } from \"../connection/index.js\";\nimport { textResult } from \"./index.js\";\n\nexport function buildTaskTools(connection: ConveyorConnection) {\n return [\n tool(\n \"create_pull_request\",\n \"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.\",\n {\n title: z.string().describe(\"The PR title\"),\n body: z.string().describe(\"The PR description/body in markdown\"),\n },\n async ({ title, body }) => {\n try {\n const result = await connection.createPR({ title, body });\n connection.sendEvent({\n type: \"pr_created\",\n url: result.url,\n number: result.number,\n });\n return textResult(`Pull request #${result.number} created: ${result.url}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return textResult(`Failed to create pull request: ${msg}`);\n }\n },\n ),\n ];\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\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","import { readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { ConveyorConnection } from \"../connection/index.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: ConveyorConnection;\n\n constructor(workspaceDir: string, connection: ConveyorConnection) {\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(homedir(), \".claude\", \"plans\"), 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 syncPlanFile(): void {\n if (this.lockedPlanFile) {\n try {\n const content = readFileSync(this.lockedPlanFile, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n const fileName = this.lockedPlanFile.split(\"/\").pop()!;\n this.connection.postChatMessage(`Synced local plan file (${fileName}) to the task plan.`);\n }\n } catch {\n /* locked file was deleted */\n }\n return;\n }\n\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\n if (newest) {\n this.lockedPlanFile = newest.path;\n const content = readFileSync(newest.path, \"utf-8\").trim();\n if (content) {\n this.connection.updateTaskFields({ plan: content });\n const fileName = newest.path.split(\"/\").pop()!;\n this.connection.postChatMessage(\n `Detected local plan file (${fileName}) and synced it to the task plan.`,\n );\n }\n }\n }\n}\n","/* oxlint-disable no-console */\n\nimport { 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 { ProjectConnection, type TaskAssignment } from \"../connection/index.js\";\nimport { ensureWorktree, removeWorktree } from \"./worktree.js\";\nimport { handleProjectChatMessage } from \"./project-chat-handler.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface ProjectRunnerConfig {\n conveyorApiUrl: string;\n projectToken: string;\n projectId: string;\n projectDir: string;\n}\n\ninterface ActiveAgent {\n process: ChildProcess;\n worktreePath: string;\n mode: string;\n}\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst MAX_CONCURRENT = 3;\nconst STOP_TIMEOUT_MS = 30_000;\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\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 }\n\n async start(): Promise<void> {\n await this.connection.connect();\n\n this.connection.onTaskAssignment((assignment) => {\n void this.handleAssignment(assignment);\n });\n\n this.connection.onStopTask((data) => {\n this.handleStopTask(data.taskId);\n });\n\n this.connection.onShutdown(() => {\n console.log(\"[project-runner] Received shutdown signal from server\");\n void this.stop();\n });\n\n this.connection.onChatMessage((msg) => {\n console.log(\"[project-runner] Received project chat message\");\n void handleProjectChatMessage(msg, this.connection, this.projectDir);\n });\n\n this.heartbeatTimer = setInterval(() => {\n this.connection.sendHeartbeat();\n }, HEARTBEAT_INTERVAL_MS);\n\n console.log(\"[project-runner] Connected, waiting for task assignments...\");\n\n await new Promise<void>((resolve) => {\n this.resolveLifecycle = resolve;\n process.on(\"SIGTERM\", () => void this.stop());\n process.on(\"SIGINT\", () => void this.stop());\n });\n }\n\n private async handleAssignment(assignment: TaskAssignment): Promise<void> {\n const { taskId, taskToken, apiUrl, mode, branch, devBranch, useWorktree } = assignment;\n const shortId = taskId.slice(0, 8);\n\n if (this.activeAgents.has(taskId)) {\n console.log(`[project-runner] Task ${shortId} already running, skipping`);\n return;\n }\n\n if (this.activeAgents.size >= MAX_CONCURRENT) {\n console.log(\n `[project-runner] Max concurrent agents (${MAX_CONCURRENT}) reached, rejecting task ${shortId}`,\n );\n this.connection.emitTaskStopped(taskId, \"max_concurrent_reached\");\n return;\n }\n\n try {\n try {\n execSync(\"git fetch origin\", { cwd: this.projectDir, stdio: \"ignore\" });\n } catch {\n console.log(`[task:${shortId}] Warning: git fetch failed`);\n }\n\n let workDir: string;\n const shouldWorktree = useWorktree !== false;\n if (shouldWorktree) {\n workDir = ensureWorktree(this.projectDir, taskId, devBranch);\n } else {\n workDir = this.projectDir;\n }\n\n if (branch && branch !== devBranch) {\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 console.log(`[task:${shortId}] Warning: could not checkout branch ${branch}`);\n }\n }\n }\n\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\n const child = fork(cliPath, [], {\n env: {\n ...childEnv,\n CONVEYOR_API_URL: apiUrl,\n CONVEYOR_TASK_TOKEN: taskToken,\n CONVEYOR_TASK_ID: taskId,\n CONVEYOR_MODE: mode,\n CONVEYOR_WORKSPACE: workDir,\n CONVEYOR_USE_WORKTREE: \"false\",\n },\n cwd: workDir,\n stdio: [\"pipe\", \"pipe\", \"pipe\", \"ipc\"],\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trimEnd().split(\"\\n\");\n for (const line of lines) {\n console.log(`[task:${shortId}] ${line}`);\n }\n });\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trimEnd().split(\"\\n\");\n for (const line of lines) {\n console.error(`[task:${shortId}] ${line}`);\n }\n });\n\n this.activeAgents.set(taskId, { process: child, worktreePath: workDir, mode });\n this.connection.emitTaskStarted(taskId);\n\n console.log(`[project-runner] Started task ${shortId} in ${mode} mode at ${workDir}`);\n\n child.on(\"exit\", (code) => {\n this.activeAgents.delete(taskId);\n const reason = code === 0 ? \"completed\" : `exited with code ${code}`;\n this.connection.emitTaskStopped(taskId, reason);\n console.log(`[project-runner] Task ${shortId} ${reason}`);\n\n if (code === 0) {\n try {\n removeWorktree(this.projectDir, taskId);\n } catch {\n // best effort\n }\n }\n });\n } catch (error) {\n console.error(\n `[project-runner] Failed to start task ${shortId}:`,\n error instanceof Error ? error.message : error,\n );\n this.connection.emitTaskStopped(\n taskId,\n `start_failed: ${error instanceof Error ? error.message : \"Unknown\"}`,\n );\n }\n }\n\n private handleStopTask(taskId: string): void {\n const agent = this.activeAgents.get(taskId);\n if (!agent) return;\n\n const shortId = taskId.slice(0, 8);\n console.log(`[project-runner] Stopping task ${shortId}`);\n\n agent.process.kill(\"SIGTERM\");\n\n const timer = setTimeout(() => {\n if (this.activeAgents.has(taskId)) {\n agent.process.kill(\"SIGKILL\");\n }\n }, STOP_TIMEOUT_MS);\n\n agent.process.on(\"exit\", () => {\n clearTimeout(timer);\n try {\n removeWorktree(this.projectDir, taskId);\n } catch {\n // best effort\n }\n });\n }\n\n async stop(): Promise<void> {\n if (this.stopping) return;\n this.stopping = true;\n\n console.log(\"[project-runner] Shutting down...\");\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n const stopPromises = [...this.activeAgents.keys()].map(\n (taskId) =>\n new Promise<void>((resolve) => {\n const agent = this.activeAgents.get(taskId);\n if (!agent) {\n resolve();\n return;\n }\n agent.process.on(\"exit\", () => {\n resolve();\n });\n this.handleStopTask(taskId);\n }),\n );\n\n await Promise.race([\n Promise.all(stopPromises),\n new Promise<void>((resolve) => setTimeout(resolve, 60_000)),\n ]);\n\n this.connection.disconnect();\n console.log(\"[project-runner] Shutdown complete\");\n\n if (this.resolveLifecycle) {\n this.resolveLifecycle();\n this.resolveLifecycle = null;\n }\n }\n}\n","/* oxlint-disable no-console */\n\nimport { query, type SDKAssistantMessage } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n ProjectConnection,\n IncomingChatMessage,\n ChatHistoryMessage,\n AgentContext,\n} from \"../connection/index.js\";\n\nconst FALLBACK_MODEL = \"claude-sonnet-4-20250514\";\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 `You have access to the local filesystem through your tools. Use them to read code,`,\n `understand the project structure, and provide informed answers.`,\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\ninterface ToolCallSummary {\n tool: string;\n input?: string;\n timestamp: string;\n}\n\nexport async function handleProjectChatMessage(\n message: IncomingChatMessage,\n connection: ProjectConnection,\n projectDir: string,\n): Promise<void> {\n connection.emitAgentStatus(\"busy\");\n\n try {\n let agentCtx: AgentContext | null = null;\n try {\n agentCtx = await connection.fetchAgentContext();\n } catch {\n console.log(\"[project-chat] Could not fetch agent context, using defaults\");\n }\n\n let chatHistory: ChatHistoryMessage[] = [];\n try {\n chatHistory = await connection.fetchChatHistory(30);\n } catch {\n console.log(\"[project-chat] Could not fetch chat history, proceeding without it\");\n }\n\n const model = agentCtx?.model || FALLBACK_MODEL;\n const settings = agentCtx?.agentSettings ?? {};\n const systemPrompt = buildSystemPrompt(projectDir, agentCtx);\n const prompt = buildPrompt(message, chatHistory);\n\n const events = query({\n prompt,\n options: {\n model,\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: systemPrompt,\n },\n cwd: projectDir,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n tools: { type: \"preset\" as const, preset: \"claude_code\" as const },\n maxTurns: (settings.maxTurns as number | undefined) ?? 15,\n maxBudgetUsd: (settings.maxBudgetUsd as number | undefined) ?? 5,\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 });\n\n const responseParts: string[] = [];\n const turnToolCalls: ToolCallSummary[] = [];\n let isTyping = false;\n\n for await (const event of events) {\n if (event.type === \"assistant\") {\n if (!isTyping) {\n setTimeout(() => connection.emitEvent({ type: \"agent_typing_start\" }), 200);\n isTyping = true;\n }\n\n const assistantEvent = event as SDKAssistantMessage;\n const { content } = assistantEvent.message;\n\n for (const block of content) {\n if (block.type === \"text\") {\n responseParts.push(block.text);\n } else if (block.type === \"tool_use\") {\n const inputStr =\n 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 console.log(`[project-chat] [tool_use] ${block.name}`);\n }\n }\n\n if (turnToolCalls.length > 0) {\n connection.emitEvent({ type: \"activity_block\", events: [...turnToolCalls] });\n turnToolCalls.length = 0;\n }\n } else if (event.type === \"result\") {\n if (isTyping) {\n connection.emitEvent({ type: \"agent_typing_stop\" });\n isTyping = false;\n }\n break;\n }\n }\n\n if (isTyping) {\n connection.emitEvent({ type: \"agent_typing_stop\" });\n }\n\n const responseText = responseParts.join(\"\\n\\n\").trim();\n if (responseText) {\n await connection.emitChatMessage(responseText);\n }\n } catch (error) {\n console.error(\n \"[project-chat] Failed to handle message:\",\n error instanceof Error ? error.message : error,\n );\n try {\n await connection.emitChatMessage(\n \"I encountered an error processing your message. Please try again.\",\n );\n } catch {\n // best effort\n }\n } finally {\n connection.emitAgentStatus(\"idle\");\n }\n}\n","const DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024; // 50MB\nconst DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour\n\ninterface CacheEntry {\n content: Buffer;\n mimeType: string;\n fileName: string;\n createdAt: number;\n size: number;\n}\n\nexport class FileCache {\n private cache = new Map<string, CacheEntry>();\n private currentSize = 0;\n private readonly maxSizeBytes: number;\n private readonly ttlMs: number;\n\n constructor(maxSizeBytes = DEFAULT_MAX_SIZE_BYTES, ttlMs = DEFAULT_TTL_MS) {\n this.maxSizeBytes = maxSizeBytes;\n this.ttlMs = ttlMs;\n }\n\n get(fileId: string): CacheEntry | null {\n const entry = this.cache.get(fileId);\n if (!entry) return null;\n\n if (Date.now() - entry.createdAt > this.ttlMs) {\n this.delete(fileId);\n return null;\n }\n\n this.cache.delete(fileId);\n this.cache.set(fileId, entry);\n return entry;\n }\n\n set(fileId: string, content: Buffer, mimeType: string, fileName: string): void {\n if (this.cache.has(fileId)) {\n this.delete(fileId);\n }\n\n const size = content.byteLength;\n\n if (size > this.maxSizeBytes) return;\n\n while (this.currentSize + size > this.maxSizeBytes && this.cache.size > 0) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey !== undefined) {\n this.delete(oldestKey);\n }\n }\n\n this.cache.set(fileId, {\n content,\n mimeType,\n fileName,\n createdAt: Date.now(),\n size,\n });\n this.currentSize += size;\n }\n\n private delete(fileId: string): void {\n const entry = this.cache.get(fileId);\n if (entry) {\n this.currentSize -= entry.size;\n this.cache.delete(fileId);\n }\n }\n\n clear(): void {\n this.cache.clear();\n this.currentSize = 0;\n }\n\n get stats(): { entries: number; sizeBytes: number; maxSizeBytes: number } {\n return {\n entries: this.cache.size,\n sizeBytes: this.currentSize,\n maxSizeBytes: this.maxSizeBytes,\n };\n }\n}\n"],"mappings":";AAAA,SAAS,UAAuB;AAmBzB,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EACtB,SAAwB;AAAA,EACxB;AAAA,EACA,cAAuC,CAAC;AAAA,EACxC,aAAmD;AAAA,EAC3D,OAAwB,iBAAiB;AAAA,EAEjC,gBAA0C,CAAC;AAAA,EAC3C,YAAY;AAAA,EACZ,mBAAqC,CAAC;AAAA,EACtC,sBAAsE;AAAA,EACtE,eAAoC;AAAA,EACpC,qBAA8D;AAAA,EAC9D,2BAA2B,oBAAI,IAAuD;AAAA,EAE9F,YAAY,QAA2B;AACrC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,UAAyB;AACvB,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,WAAK,SAAS,GAAG,KAAK,OAAO,gBAAgB;AAAA,QAC3C,MAAM,EAAE,WAAW,KAAK,OAAO,WAAW,YAAY,KAAK,OAAO,QAAQ,OAAO;AAAA,QACjF,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc;AAAA,UACZ,8BAA8B;AAAA,QAChC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,+BAA+B,CAAC,QAAgC;AAC7E,YAAI,KAAK,qBAAqB;AAC5B,eAAK,oBAAoB,GAAG;AAAA,QAC9B,OAAO;AACL,eAAK,cAAc,KAAK,GAAG;AAAA,QAC7B;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,oBAAoB,MAAM;AACvC,YAAI,KAAK,cAAc;AACrB,eAAK,aAAa;AAAA,QACpB,OAAO;AACL,eAAK,YAAY;AAAA,QACnB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,8BAA8B,CAAC,SAAgC;AAC5E,cAAM,WAAW,KAAK,yBAAyB,IAAI,KAAK,SAAS;AACjE,YAAI,UAAU;AACZ,eAAK,yBAAyB,OAAO,KAAK,SAAS;AACnD,mBAAS,KAAK,OAAO;AAAA,QACvB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,uBAAuB,CAAC,SAAyB;AAC9D,YAAI,KAAK,oBAAoB;AAC3B,eAAK,mBAAmB,IAAI;AAAA,QAC9B,OAAO;AACL,eAAK,iBAAiB,KAAK,IAAI;AAAA,QACjC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,qBAAqB,MAAM;AAC3C;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV,iBAAO,IAAI,MAAM,2BAA2B,kBAAkB,WAAW,CAAC;AAAA,QAC5E;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,OAAgD;AAChE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,MAAM;AAAA,QACR,CAAC,aAA0D;AACzD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,UACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,iBAA8C;AAC5C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC;AAAA,QACD,CAAC,aAAuD;AACtD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,4BAA4B,CAAC;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAA2C;AACvD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,OAAO;AAAA,QACT,CAAC,aAAqD;AACpD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,2BAA2B,CAAC;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,mBAAyC;AACvC,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC;AAAA,QACD,CAAC,aAAgD;AAC/C,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,8BAA8B,CAAC;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,OAAyB;AACjC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,YAAY,KAAK,EAAE,MAAM,CAAC;AAC/B,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,WAAW,MAAM,KAAK,YAAY,GAAG,oBAAmB,cAAc;AAAA,IAC1F;AAAA,EACF;AAAA,EAEA,cAAoB;AAClB,QAAI,KAAK,YAAY;AACnB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,QAAI,CAAC,KAAK,UAAU,KAAK,YAAY,WAAW,EAAG;AACnD,eAAW,SAAS,KAAK,aAAa;AACpC,WAAK,OAAO,KAAK,qBAAqB,KAAK;AAAA,IAC7C;AACA,SAAK,cAAc,CAAC;AAAA,EACtB;AAAA,EAEA,aAAa,QAAsB;AACjC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,4BAA4B,EAAE,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,gBAAgB,SAAuB;AACrC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,2BAA2B,EAAE,QAAQ,CAAC;AAAA,EACzD;AAAA,EAEA,SAAS,QAIoC;AAC3C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,CAAC,aAAoE;AACnE,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,UACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,WAAmB,WAA6D;AAC9F,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,+BAA+B,EAAE,WAAW,UAAU,CAAC;AAExE,WAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,WAAK,yBAAyB,IAAI,WAAWA,QAAO;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,yBAA+B;AAC7B,SAAK,yBAAyB,MAAM;AAAA,EACtC;AAAA,EAEA,eAAe,WAAyB;AACtC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,8BAA8B,EAAE,UAAU,CAAC;AAAA,EAC9D;AAAA,EAEA,iBAAiB,QAAuD;AACtE,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,gCAAgC,EAAE,OAAO,CAAC;AAAA,EAC7D;AAAA,EAEA,cAAc,UAA2D;AACvE,SAAK,sBAAsB;AAC3B,eAAW,OAAO,KAAK,eAAe;AACpC,eAAS,GAAG;AAAA,IACd;AACA,SAAK,gBAAgB,CAAC;AAAA,EACxB;AAAA,EAEA,gBAAgB,UAA4B;AAC1C,SAAK,eAAe;AACpB,QAAI,KAAK,WAAW;AAClB,eAAS;AACT,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,aAAa,UAAgD;AAC3D,SAAK,qBAAqB;AAC1B,eAAW,QAAQ,KAAK,kBAAkB;AACxC,eAAS,IAAI;AAAA,IACf;AACA,SAAK,mBAAmB,CAAC;AAAA,EAC3B;AAAA,EAEA,gBAAgB,MAAuB;AACrC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,2BAA2B,EAAE,KAAK,CAAC;AAAA,EACtD;AAAA,EAEA,cAAc,QAaL;AACP,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AAEjD,SAAK,OAAO,KAAK,6BAA6B,MAAM;AAAA,EACtD;AAAA,EAEA,WAAW,QAAsB;AAC/B,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,4BAA4B,EAAE,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,yBAAyB,CAAC,CAAC;AAAA,EAC9C;AAAA,EAEA,kBAAwB;AACtB,SAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAAA,EAC/C;AAAA,EAEA,iBAAuB;AACrB,SAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,EAC9C;AAAA,EAEA,cAAc,MAAqD;AACjE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO,KAAK,6BAA6B,MAAM,CAAC,aAA6C;AAC3F,YAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,YACvD,QAAO,IAAI,MAAM,SAAS,SAAS,0BAA0B,CAAC;AAAA,MACrE,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,WAAmB,QAAmC;AAClE,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,6BAA6B,EAAE,WAAW,OAAO,CAAC;AAAA,EACrE;AAAA,EAEA,cAAc,WAAyB;AACrC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,eAAe;AACjD,SAAK,OAAO,KAAK,6BAA6B,EAAE,UAAU,CAAC;AAAA,EAC7D;AAAA,EAEA,eAA2C;AACzC,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO,KAAK,4BAA4B,CAAC,GAAG,CAAC,aAAgD;AAC3F,YAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,YACvD,QAAO,IAAI,MAAM,SAAS,SAAS,yBAAyB,CAAC;AAAA,MACpE,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,UAA+C;AACvD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,SAAS;AAAA,QACX,CAAC,aAAuD;AACtD,cAAI,SAAS,WAAW,SAAS,MAAM;AACrC,YAAAA,SAAQ,SAAS,IAAI;AAAA,UACvB,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,sBAAsB,CAAC;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AACjB,SAAK,YAAY;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;;;AChYA,SAAS,MAAAC,WAAuB;AAiDzB,IAAM,oBAAN,MAAwB;AAAA,EACrB,SAAwB;AAAA,EACxB;AAAA,EACA,yBAAwE;AAAA,EACxE,mBAAgE;AAAA,EAChE,mBAAwC;AAAA,EACxC,sBAAmE;AAAA,EACnE,oBAA2C,CAAC;AAAA,EAEpD,YAAY,QAAiC;AAC3C,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,UAAyB;AACvB,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,qBAAqB;AAE3B,WAAK,SAASD,IAAG,KAAK,OAAO,QAAQ;AAAA,QACnC,MAAM,EAAE,cAAc,KAAK,OAAO,aAAa;AAAA,QAC/C,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc;AAAA,UACZ,8BAA8B;AAAA,QAChC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,4BAA4B,CAAC,SAAyB;AACnE,YAAI,KAAK,wBAAwB;AAC/B,eAAK,uBAAuB,IAAI;AAAA,QAClC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,0BAA0B,CAAC,SAA6B;AACrE,YAAI,KAAK,kBAAkB;AACzB,eAAK,iBAAiB,IAAI;AAAA,QAC5B;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,0BAA0B,MAAM;AAC7C,YAAI,KAAK,kBAAkB;AACzB,eAAK,iBAAiB;AAAA,QACxB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,qCAAqC,CAAC,QAA6B;AAChF,YAAI,KAAK,qBAAqB;AAC5B,eAAK,oBAAoB,GAAG;AAAA,QAC9B,OAAO;AACL,eAAK,kBAAkB,KAAK,GAAG;AAAA,QACjC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,UAAAC,SAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,GAAG,qBAAqB,MAAM;AAC3C;AACA,YAAI,CAAC,WAAW,YAAY,oBAAoB;AAC9C,oBAAU;AACV,iBAAO,IAAI,MAAM,2BAA2B,kBAAkB,WAAW,CAAC;AAAA,QAC5E;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,UAAsD;AACrE,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,WAAW,UAAoD;AAC7D,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,WAAW,UAA4B;AACrC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,cAAc,UAAoD;AAChE,SAAK,sBAAsB;AAC3B,eAAW,OAAO,KAAK,mBAAmB;AACxC,eAAS,GAAG;AAAA,IACd;AACA,SAAK,oBAAoB,CAAC;AAAA,EAC5B;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,2BAA2B,CAAC,CAAC;AAAA,EAChD;AAAA,EAEA,gBAAgB,QAAsB;AACpC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,6BAA6B,EAAE,OAAO,CAAC;AAAA,EAC1D;AAAA,EAEA,gBAAgB,QAAgB,QAAsB;AACpD,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,6BAA6B,EAAE,QAAQ,OAAO,CAAC;AAAA,EAClE;AAAA,EAEA,UAAU,OAAsC;AAC9C,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,8BAA8B,KAAK;AAAA,EACtD;AAAA,EAEA,gBAAgB,SAAgC;AAC9C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,QAAQ;AAAA,QACV,CAAC,aAAmD;AAClD,cAAI,SAAS,QAAS,CAAAA,SAAQ;AAAA,cACzB,QAAO,IAAI,MAAM,SAAS,SAAS,6BAA6B,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,QAAsB;AACpC,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,KAAK,+BAA+B,EAAE,OAAO,CAAC;AAAA,EAC5D;AAAA,EAEA,oBAAkD;AAChD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,CAAC,aAA+E;AAC9E,cAAI,SAAS,QAAS,CAAAA,SAAQ,SAAS,QAAQ,IAAI;AAAA,cAC9C,QAAO,IAAI,MAAM,SAAS,SAAS,+BAA+B,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,OAA+C;AAC9D,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAE7D,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,aAAO;AAAA,QACL;AAAA,QACA,EAAE,MAAM;AAAA,QACR,CAAC,aAAgF;AAC/E,cAAI,SAAS,WAAW,SAAS,KAAM,CAAAA,SAAQ,SAAS,IAAI;AAAA,cACvD,QAAO,IAAI,MAAM,SAAS,SAAS,8BAA8B,CAAC;AAAA,QACzE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAmB;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;;;AC5NA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AAQrB,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAE1B,eAAsB,iBAAiB,cAAyC;AAC9E,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,iBAAiB,GAAG,OAAO;AACzE,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,OAAO,gBAAgB,CAAC;AAAA,EACjC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,mBAAmB,cAAsD;AAC7F,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,oBAAoB,GAAG,OAAO;AAC5E,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,gBAAgB,OAAO,aAAc,QAAO;AAAA,EACzD,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,KAAK,cAAc,iBAAiB,GAAG,OAAO;AACzE,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,aAAa,OAAO,SAAS,gBAAgB,OAAO,SAAS,eAAe;AACrF,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;;;AC1CA,SAAS,aAAgC;AAElC,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;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;;;AC1DA,SAAS,gBAAgB;AAEzB,IAAMC,qBAAoB;AAEnB,SAAS,yBACd,cACA,YACA,YACuC;AACvC,QAAM,MAAM,CAAC,QACX,SAAS,KAAK,EAAE,KAAK,cAAc,UAAU,SAAS,SAAS,IAAO,CAAC,EAAE,KAAK;AAEhF,MAAI;AACF,QAAI,oBAAoB,UAAU,EAAE;AAAA,EACtC,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,SAAS,0BAA0B,UAAU,GAAG;AAAA,EAC3E;AAEA,MAAI;AACF,QAAI,2BAA2B,UAAU,OAAOA,kBAAiB,EAAE;AACnE,WAAO,EAAE,SAAS,OAAO,SAAS,yCAAyC;AAAA,EAC7E,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,QAAQ,SAAS,IAAI,+BAA+B,UAAU,QAAQ,GAAG,EAAE;AAEjF,QAAI,SAAS,GAAG;AACd,UAAI,2BAA2B,UAAU,EAAE;AAAA,IAC7C,OAAO;AACL,UAAI,uBAAuB,UAAU,OAAOA,kBAAiB,EAAE;AAC/D,UAAI,WAAWA,kBAAiB,EAAE;AAElC,UAAI;AACF,YAAI,gCAAgCA,kBAAiB,EAAE;AACvD,eAAO,EAAE,SAAS,OAAO,SAAS,kDAAkD;AAAA,MACtF,QAAQ;AACN,YAAI,kDAAkD;AAAA,MACxD;AAAA,IACF;AAEA,QAAI;AACF,UAAI,sCAAsC,UAAU,EAAE;AAAA,IACxD,QAAQ;AACN,UAAI,2BAA2B,UAAU,EAAE;AAAA,IAC7C;AACA,WAAO,EAAE,SAAS,MAAM,SAAS,6CAA6C;AAAA,EAChF,SAAS,KAAK;AACZ,QAAI;AACF,UAAI,gBAAgB,UAAU,EAAE;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU;AACjD,WAAO,EAAE,SAAS,OAAO,SAAS,uBAAuB,GAAG,GAAG;AAAA,EACjE;AACF;AAEO,SAAS,UAAgB;AAC9B,MAAI;AACF,aAAS,iBAAiB,EAAE,OAAO,SAAS,CAAC;AAC7C,aAAS,kCAAkC,EAAE,OAAO,SAAS,CAAC;AAAA,EAChE,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,cAAc,cAA4B;AACxD,MAAI;AACF,aAAS,yBAAyB;AAAA,MAChC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;AC9EA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAErB,IAAM,eAAe;AAEd,SAAS,eAAe,YAAoB,QAAgB,QAAyB;AAC1F,QAAM,eAAeA,MAAK,YAAY,cAAc,MAAM;AAE1D,MAAI,WAAW,YAAY,GAAG;AAC5B,QAAI,QAAQ;AACV,UAAI;AACF,QAAAD,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;AAEO,SAAS,eAAe,YAAoB,QAAsB;AACvE,QAAM,eAAeC,MAAK,YAAY,cAAc,MAAM;AAC1D,MAAI,CAAC,WAAW,YAAY,EAAG;AAC/B,MAAI;AACF,IAAAD,UAAS,wBAAwB,YAAY,aAAa;AAAA,MACxD,KAAK;AAAA,MACL,OAAO;AAAA,IACT,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;;;AC3CA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;;;ACWzB,eAAe,sBACb,OACA,MACA,eACe;AACf,QAAM,EAAE,QAAQ,IAAI,MAAM;AAC1B,QAAM,gBAA0B,CAAC;AAEjC,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,SAAS,QAAQ;AACzB,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,YAAY;AACpC,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;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,SAAK,WAAW,gBAAgB,cAAc,KAAK,MAAM,CAAC;AAAA,EAC5D;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,WAAW,CAAC,GAAG,aAAa,EAAE,CAAC;AAC7E,kBAAc,SAAS;AAAA,EACzB;AACF;AAEA,IAAM,oBAAoB;AAE1B,SAAS,kBACP,OACA,MACA,SACA,WAC8C;AAC9C,MAAI,eAAe;AACnB,MAAI,YAAY;AAEhB,MAAI,MAAM,YAAY,WAAW;AAC/B,UAAM,eAAe;AACrB,UAAM,eAAe,aAAa;AAClC,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,UAAM,UAAU,aAAa,UAAU;AAEvC,QAAI,kBAAkB,KAAK,OAAO,KAAK,aAAa,KAAQ;AAC1D,kBAAY;AAAA,IACd;AAGA,UAAM,kBAAkB,KAAK,YAAY,aAAa,YAAY;AAClE,mBAAe;AAGf,UAAM,EAAE,WAAW,IAAI;AACvB,QAAI,cAAc,OAAO,eAAe,UAAU;AAChD,WAAK,YAAY,cAAc,UAAU;AAAA,IAC3C;AAEA,SAAK,WAAW,UAAU,EAAE,MAAM,aAAa,SAAS,SAAS,iBAAiB,WAAW,CAAC;AAE9F,QAAI,kBAAkB,KAAK,QAAQ,WAAW,QAAQ,kBAAkB;AACtE,YAAM,YAAY,KAAK,YAAY;AACnC,WAAK,WAAW,cAAc;AAAA,QAC5B,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,QACnB,cAAc;AAAA,QACd,gBAAgB,KAAK,OAAO,SAAS,QAAQ,CAAC,CAAC,QAAQ,IAAI;AAAA,QAC3D,YAAY,UAAU,SAAS,IAAI,YAAY;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,UAAM,aAAa;AACnB,UAAM,WACJ,WAAW,OAAO,SAAS,IACvB,WAAW,OAAO,KAAK,IAAI,IAC3B,kBAAkB,WAAW,OAAO;AAE1C,QAAI,kBAAkB,KAAK,QAAQ,GAAG;AACpC,kBAAY;AAAA,IACd;AAEA,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,SAAS,SAAS,CAAC;AAAA,EAChE;AAEA,SAAO,EAAE,cAAc,UAAU;AACnC;AAEA,eAAe,gBACb,OACA,MACA,SACA,WACkB;AAClB,QAAM,SAAS,kBAAkB,OAAO,MAAM,SAAS,SAAS;AAChE,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,OAAO;AACL,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,OAAO;AAChB;AAEA,SAAS,qBAAqB,OAA0B,MAAuB;AAC7E,QAAM,EAAE,gBAAgB,IAAI;AAC5B,QAAM,SAAS,gBAAgB;AAE/B,MAAI,WAAW,YAAY;AACzB,UAAM,WAAW,gBAAgB,WAC7B,IAAI,KAAK,gBAAgB,QAAQ,EAAE,YAAY,IAC/C;AACJ,UAAM,UAAU,8BAA8B,gBAAgB,iBAAiB,SAAS,gBAAgB,QAAQ;AAChH,SAAK,WAAW,UAAU,EAAE,MAAM,SAAS,QAAQ,CAAC;AACpD,SAAK,KAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,QAAQ,CAAC;AAAA,EACxD,WAAW,WAAW,mBAAmB;AACvC,UAAM,cAAc,gBAAgB,cAChC,GAAG,KAAK,MAAM,gBAAgB,cAAc,GAAG,CAAC,MAChD;AACJ,UAAM,UAAU,uBAAuB,WAAW,uBAAuB,gBAAgB,iBAAiB,SAAS;AACnH,SAAK,WAAW,UAAU,EAAE,MAAM,YAAY,QAAQ,CAAC;AACvD,SAAK,KAAK,UAAU,QAAQ,EAAE,MAAM,YAAY,QAAQ,CAAC;AAAA,EAC3D;AACF;AAEA,eAAsB,cACpB,QACA,SACA,MACiC;AACjC,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,kBAAkB;AACtB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,QAAM,gBAAwC,CAAC;AAE/C,mBAAiB,SAAS,QAAQ;AAChC,QAAI,KAAK,UAAU,EAAG;AAEtB,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,UAAU;AACb,cAAM,cAAc;AACpB,YAAI,YAAY,YAAY,QAAQ;AAClC,cAAI,YAAY,cAAc,CAAC,iBAAiB;AAC9C,8BAAkB;AAClB,iBAAK,WAAW,eAAe,YAAY,UAAU;AACrD,oBAAQ,kBAAkB,YAAY;AAAA,UACxC;AACA,gBAAM,KAAK,UAAU,QAAQ;AAAA,YAC3B,MAAM;AAAA,YACN,SAAS,6BAA6B,YAAY,KAAK;AAAA,UACzD,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAAA,MAEA,KAAK,aAAa;AAChB,YAAI,CAAC,UAAU;AACb,qBAAW,MAAM,KAAK,WAAW,gBAAgB,GAAG,GAAG;AACvD,qBAAW;AAAA,QACb;AACA,cAAM,sBAAsB,OAA8B,MAAM,aAAa;AAC7E;AAAA,MACF;AAAA,MAEA,KAAK,UAAU;AACb,YAAI,UAAU;AACZ,eAAK,WAAW,eAAe;AAC/B,qBAAW;AAAA,QACb;AACA,oBAAY,MAAM,gBAAgB,OAA2B,MAAM,SAAS,SAAS;AACrF;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,6BAAqB,OAA4B,IAAI;AACrD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,SAAK,WAAW,eAAe;AAAA,EACjC;AAEA,SAAO,EAAE,UAAU;AACrB;;;AC9NA,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,OAMK;;;ACNP,IAAM,kBAAkB,oBAAI,IAAI,CAAC,cAAc,YAAY,aAAa,YAAY,CAAC;AAErF,SAAS,eAAe,OAAmC;AACzD,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;AAEA,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,uBACP,SACiD;AACjD,QAAM,eAAe,0BAA0B,QAAQ,WAAW;AAClE,MAAI,iBAAiB,GAAI,QAAO;AAEhC,QAAM,eACJ,CAAC,CAAC,QAAQ,eAAe,CAAC,CAAC,QAAQ,mBAAmB,gBAAgB,IAAI,QAAQ,UAAU,EAAE;AAChG,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,yBACP,MACA,SACe;AACf,QAAM,WAAW,uBAAuB,OAAO;AAC/C,MAAI,CAAC,QAAQ,mBAAmB,aAAa,QAAS,QAAO;AAE7D,QAAM,QAAkB,CAAC;AACzB,QAAM,eAAe,0BAA0B,QAAQ,WAAW;AAElE,MAAI,SAAS,MAAM;AACjB,UAAM,cAAc,QAAQ,YACzB,MAAM,eAAe,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAClC,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,MACrE;AAAA,IACF,OAAO;AACL,YAAM,KAAK,oEAAoE;AAAA,IACjF;AACA,UAAM;AAAA,MACJ;AAAA;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,aAAa,qBAAqB;AAC3C,UAAM,cAAc,QAAQ,YACzB,MAAM,eAAe,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAClC,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,MACA;AAAA,IACF;AACA,QAAI,QAAQ,aAAa;AACvB,YAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,IACxF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,cAAc,SAAgC;AACrD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,WAAW,QAAQ,KAAK,EAAE;AACrC,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK;AAAA;AAAA,EAAqB,QAAQ,WAAW,EAAE;AAAA,EACvD;AACA,MAAI,QAAQ,MAAM;AAChB,UAAM,KAAK;AAAA;AAAA,EAAc,QAAQ,IAAI,EAAE;AAAA,EACzC;AAEA,MAAI,QAAQ,SAAS,QAAQ,MAAM,SAAS,GAAG;AAC7C,UAAM,KAAK;AAAA,kBAAqB;AAChC,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,cAAM,KAAK;AAAA,MAAS,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG;AACtD,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,KAAK,OAAO;AACvB,cAAM,KAAK,KAAK;AAAA,MAClB,WAAW,CAAC,KAAK,SAAS;AACxB,cAAM,KAAK,OAAO,KAAK,QAAQ,OAAO,KAAK,QAAQ,MAAM,KAAK,WAAW,EAAE;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,GAAG;AACnD,UAAM,KAAK;AAAA,yBAA4B;AACvC,eAAW,OAAO,QAAQ,UAAU;AAClC,YAAM,OAAO,IAAI,YAAY,WAAW,WAAW;AACnD,YAAM,KAAK,MAAM,IAAI,OAAO,IAAI,IAAI,IAAI;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,UAAM,WAAW,QAAQ,YAAY,MAAM,GAAG;AAC9C,UAAM,KAAK;AAAA,uBAA0B;AACrC,eAAW,OAAO,UAAU;AAC1B,YAAM,SAAS,IAAI,YAAY,IAAI;AACnC,YAAM,KAAK,IAAI,MAAM,MAAM,IAAI,OAAO,EAAE;AACxC,UAAI,IAAI,OAAO,QAAQ;AACrB,mBAAW,QAAQ,IAAI,OAAO;AAC5B,gBAAM,UAAU,KAAK,WAAW,KAAK,eAAe,KAAK,QAAQ,CAAC,KAAK;AACvE,cAAI,KAAK,WAAW,KAAK,oBAAoB,SAAS;AACpD,kBAAM,KAAK,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,IAAI;AACtE,kBAAM,KAAK,KAAK;AAChB,kBAAM,KAAK,KAAK,OAAO;AACvB,kBAAM,KAAK,KAAK;AAAA,UAClB,WAAW,CAAC,KAAK,SAAS;AACxB,kBAAM;AAAA,cACJ,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,OAAO,KAAK,WAAW;AAAA,YAChF;AAAA,UACF,OAAO;AACL,kBAAM,KAAK,cAAc,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG,OAAO,IAAI;AAAA,UACxE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,MACA,SACA,UACU;AACV,QAAM,QAAkB,CAAC;AAAA,gBAAmB;AAC5C,QAAM,OAAO,SAAS;AAEtB,MAAI,aAAa,SAAS;AACxB,QAAI,QAAQ,QAAQ,cAAc;AAChC,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,MAAM;AACf,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA,mEAAmE,QAAQ,YAAY,4BAA4B,QAAQ,YAAY;AAAA,MACzI;AAAA,IACF;AAAA,EACF,WAAW,aAAa,iBAAiB;AACvC,QAAI,MAAM;AACR,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,aAAa;AACvB,cAAM,KAAK,6BAA6B,QAAQ,WAAW,2BAA2B;AAAA,MACxF;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,QAAI,MAAM;AACR,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,QACnE;AAAA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QACA,2BAA2B,QAAQ,YAAY;AAAA,QAC/C;AAAA,QACA;AAAA;AAAA,QACA,GAAG,YAAY,IAAI,CAAC,MAAM,IAAI,EAAE,YAAY,MAAM,MAAM,EAAE,OAAO,EAAE;AAAA,QACnE;AAAA;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,aAAa;AACvB,cAAM;AAAA,UACJ,6BAA6B,QAAQ,WAAW;AAAA,QAClD;AAAA,MACF,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,MAA8B,SAA8B;AAC7F,QAAM,kBAAkB,yBAAyB,MAAM,OAAO;AAC9D,MAAI,gBAAiB,QAAO;AAE5B,QAAM,WAAW,uBAAuB,OAAO;AAC/C,QAAM,OAAO,cAAc,OAAO;AAClC,QAAM,eAAe,kBAAkB,MAAM,SAAS,QAAQ;AAC9D,SAAO,CAAC,GAAG,MAAM,GAAG,YAAY,EAAE,KAAK,IAAI;AAC7C;AAEO,SAAS,kBACd,MACA,SACA,QACA,UACA,YAAuB,YACf;AACR,QAAM,OAAO,SAAS;AACtB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,UAAU;AAAA,IACd,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,QAAQ,cAAc;AAChC,YAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACjE,YAAQ,KAAK;AAAA,mBAAsB;AACnC,eAAW,MAAM,QAAQ,aAAa;AACpC,YAAM,OAAO,GAAG,cAAc,WAAM,GAAG,WAAW,KAAK;AACvD,cAAQ,KAAK,WAAW,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,IACzD;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,GAAG;AACrE,YAAQ,KAAK;AAAA,gBAAmB;AAChC,eAAW,MAAM,QAAQ,eAAe;AACtC,YAAM,OAAO,GAAG,OAAO,SAAS,GAAG,IAAI,KAAK;AAC5C,YAAM,KAAK,GAAG,eAAe,OAAO,mBAAmB,GAAG,WAAW,KAAK;AAC1E,cAAQ,KAAK,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG;AAAA,IAClD;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB,yDAAyD,QAAQ,KAAK;AAAA,IACtE,sDAAsD,OAAO,YAAY;AAAA,IACzE;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,OAAO,YAAY;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,OAAO,OAAO;AAEhB,QAAM,QAAQ,aACV,cACA,OACE,UACA;AAAA,IACE,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;AAEN,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;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACxXA,SAAS,0BAA0B;;;ACAnC,SAAS,YAAY;AACrB,SAAS,SAAS;AAKX,SAAS,iBAAiB,YAAgC,QAA2B;AAC1F,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACzF;AAAA,MACA,OAAO,EAAE,MAAM,MAAM;AACnB,YAAI;AACF,gBAAM,WAAW,MAAM,WAAW,kBAAkB,KAAK;AACzD,iBAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QACrD,QAAQ;AACN,iBAAO;AAAA,YACL,KAAK,UAAU;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,iCAAiC,EAAE;AAAA,MAClE,CAAC,EAAE,QAAQ,MAAM;AACf,mBAAW,gBAAgB,OAAO;AAClC,eAAO,QAAQ,QAAQ,WAAW,8BAA8B,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQ,EACL,KAAK,CAAC,cAAc,YAAY,UAAU,CAAC,EAC3C,SAAS,6BAA6B;AAAA,MAC3C;AAAA,MACA,CAAC,EAAE,OAAO,MAAM;AACd,mBAAW,aAAa,MAAM;AAC9B,eAAO,QAAQ,QAAQ,WAAW,0BAA0B,MAAM,GAAG,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,MAAM,MAAM,WAAW,iBAAiB;AAC9C,iBAAO,WAAW,IAAI,QAAQ,oBAAoB;AAAA,QACpD,QAAQ;AACN,iBAAO,WAAW,YAAY,OAAO,MAAM,kCAAkC;AAAA,QAC/E;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,YAAY,EAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MAC1E;AAAA,MACA,OAAO,EAAE,WAAW,MAAM;AACxB,YAAI;AACF,gBAAM,OAAO,MAAM,WAAW,UAAU,UAAU;AAClD,iBAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,QACjD,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACjF;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,QAAQ,MAAM,WAAW,eAAe;AAC9C,iBAAO,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,QAClD,QAAQ;AACN,iBAAO,WAAW,4BAA4B;AAAA,QAChD;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,yBAAyB,EAAE;AAAA,MACzD,OAAO,EAAE,OAAO,MAAM;AACpB,YAAI;AACF,gBAAM,OAAO,MAAM,WAAW,cAAc,MAAM;AAClD,iBAAO,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,QACjD,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACtF;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;;;ACjHA,SAAS,QAAAC,aAAY;AACrB,SAAS,KAAAC,UAAS;AAKX,SAAS,2BAA2B,aAAkD;AAC3F,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,UAAM,QAAQ,YAAY,IAAI,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,GAAG,IAAI,EAAE,EAAE,KAAK,IAAI;AACzE,WAAO,sBAAsB,KAAK;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,aACd,YACA,aACA;AACA,QAAM,gBAAgB,2BAA2B,WAAW;AAC5D,SAAO;AAAA,IACLC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAMC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,QAChE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MACxE;AAAA,MACA,OAAO,EAAE,MAAM,YAAY,MAAM;AAC/B,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,iBAAiB,EAAE,MAAM,YAAY,CAAC,CAAC;AACxE,iBAAO,WAAW,4BAA4B;AAAA,QAChD,QAAQ;AACN,iBAAO,WAAW,wBAAwB;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAOC,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QAC1C,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,QAC/D,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,QACtE,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,QACrE,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAC/D;AAAA,MACA,OAAO,WAAW;AAChB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,cAAc,MAAM;AACpD,iBAAO,WAAW,4BAA4B,OAAO,EAAE,EAAE;AAAA,QAC3D,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAWC,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,QACzD,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC3B,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,QACjC,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAC/D;AAAA,MACA,OAAO,EAAE,WAAW,GAAG,OAAO,MAAM;AAClC,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,cAAc,WAAW,MAAM,CAAC;AACjE,iBAAO,WAAW,kBAAkB;AAAA,QACtC,SAAS,OAAO;AACd,iBAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,WAAWC,GAAE,OAAO,EAAE,SAAS,0BAA0B,EAAE;AAAA,MAC7D,OAAO,EAAE,UAAU,MAAM;AACvB,YAAI;AACF,gBAAM,QAAQ,QAAQ,WAAW,cAAc,SAAS,CAAC;AACzD,iBAAO,WAAW,kBAAkB;AAAA,QACtC,SAAS,OAAO;AACd,iBAAO,WAAW,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,IACAD;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD,YAAY;AACV,YAAI;AACF,gBAAM,WAAW,MAAM,WAAW,aAAa;AAC/C,iBAAO,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QACrD,QAAQ;AACN,iBAAO,WAAW,0BAA0B;AAAA,QAC9C;AAAA,MACF;AAAA,MACA,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,IACxC;AAAA,EACF;AACF;;;ACzGA,SAAS,QAAAE,aAAY;AACrB,SAAS,KAAAC,UAAS;AAIX,SAAS,eAAe,YAAgC;AAC7D,SAAO;AAAA,IACLC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAOC,GAAE,OAAO,EAAE,SAAS,cAAc;AAAA,QACzC,MAAMA,GAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MACjE;AAAA,MACA,OAAO,EAAE,OAAO,KAAK,MAAM;AACzB,YAAI;AACF,gBAAM,SAAS,MAAM,WAAW,SAAS,EAAE,OAAO,KAAK,CAAC;AACxD,qBAAW,UAAU;AAAA,YACnB,MAAM;AAAA,YACN,KAAK,OAAO;AAAA,YACZ,QAAQ,OAAO;AAAA,UACjB,CAAC;AACD,iBAAO,WAAW,iBAAiB,OAAO,MAAM,aAAa,OAAO,GAAG,EAAE;AAAA,QAC3E,SAAS,OAAO;AACd,gBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,iBAAO,WAAW,kCAAkC,GAAG,EAAE;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AHvBO,SAAS,WAAW,MAA6D;AACtF,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AACtD;AAGO,SAAS,wBACd,YACA,QACA,SACA;AACA,QAAM,cAAc,iBAAiB,YAAY,MAAM;AACvD,QAAM,YACJ,OAAO,SAAS,OACZ,aAAa,YAAY,SAAS,WAAW,IAC7C,eAAe,UAAU;AAE/B,SAAO,mBAAmB;AAAA,IACxB,MAAM;AAAA,IACN,OAAO,CAAC,GAAG,aAAa,GAAG,SAAS;AAAA,EACtC,CAAC;AACH;;;AFLA,IAAMC,qBAAoB;AAC1B,IAAM,kBAAkB,CAAC,KAAQ,MAAS,MAAS,GAAO;AAC1D,IAAM,qBAAqB,oBAAI,IAAI,CAAC,SAAS,QAAQ,WAAW,CAAC;AACjE,IAAM,0BACJ;AAiBF,SAAS,gBACP,MAOA;AACA,QAAM,sBAAsB,IAAI,KAAK;AAErC,SAAO,OAAO,UAAU,UAAU;AAChC,UAAM,eAAe,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AACtE,UAAM,aAAa,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AAGpE,QAAI,gBAAgB,mBAAmB,IAAI,QAAQ,GAAG;AACpD,YAAM,WAAW,OAAO,MAAM,aAAa,MAAM,QAAQ,EAAE;AAC3D,UAAI,SAAS,SAAS,gBAAgB,GAAG;AACvC,eAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,MAClD;AACA,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,MACX;AAAA,IACF;AAGA,QAAI,cAAc,aAAa,QAAQ;AACrC,YAAM,MAAM,OAAO,MAAM,WAAW,EAAE;AACtC,UAAI,wBAAwB,KAAK,GAAG,GAAG;AACrC,eAAO;AAAA,UACL,UAAU;AAAA,UACV,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa,mBAAmB;AAClC,aAAO,EAAE,UAAU,SAAS,cAAc,MAAM;AAAA,IAClD;AAEA,UAAM,YAAY,MAAM;AAOxB,UAAM,YAAY,WAAW;AAC7B,SAAK,WAAW,WAAW,mBAAmB;AAC9C,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,KAAK,UAAU,KAAK;AAAA,IAC7B,CAAC;AAED,UAAM,gBAAgB,KAAK,WAAW,gBAAgB,WAAW,SAAS;AAC1E,UAAM,iBAAiB,IAAI,QAAc,CAACC,aAAY;AACpD,iBAAW,MAAMA,SAAQ,IAAI,GAAG,mBAAmB;AAAA,IACrD,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,eAAe,cAAc,CAAC;AAClE,SAAK,WAAW,WAAW,SAAS;AAEpC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SACE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,SAAS,cAAc,EAAE,WAAW,MAAM,WAAW,QAAQ,EAAE;AAAA,EACpF;AACF;AAEA,SAAS,kBAAkB,MAAiB,SAA+C;AACzF,QAAM,WAAW,QAAQ,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AACxE,QAAM,aAAa,KAAK,OAAO,SAAS,QAAQ,KAAK,eAAe;AACpE,QAAM,mBAAmB;AAAA,IACvB,KAAK,OAAO;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,aAAa,WAAW;AAAA,EAC1B;AACA,QAAM,cAAc,wBAAwB,KAAK,YAAY,KAAK,QAAQ,OAAO;AACjF,QAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAM,oBAAoB,QAAQ,CAAC,aAAa,CAAC,aAAa,YAAY,cAAc,IAAI,CAAC;AAC7F,QAAM,kBAAkB,CAAC,GAAI,SAAS,mBAAmB,CAAC,GAAI,GAAG,iBAAiB;AAClF,QAAM,iBAAkB,SAAS,kBAAkB,CAAC,QAAQ,SAAS;AAMrE,QAAM,QAA2D;AAAA,IAC/D,aAAa;AAAA,MACX;AAAA,QACE,OAAO;AAAA,UACL,OAAO,UAAmC;AACxC,gBAAI,MAAM,oBAAoB,eAAe;AAC3C,oBAAM,SACJ,OAAO,MAAM,kBAAkB,WAC3B,MAAM,cAAc,MAAM,GAAG,GAAG,IAChC,KAAK,UAAU,MAAM,aAAa,EAAE,MAAM,GAAG,GAAG;AACtD,mBAAK,WAAW,UAAU;AAAA,gBACxB,MAAM;AAAA,gBACN,MAAM,MAAM;AAAA,gBACZ;AAAA,gBACA,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AACA,mBAAO,EAAE,UAAU,KAAK;AAAA,UAC1B;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAuC;AAAA,IAC3C,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,aAAa,gBAAgB;AAAA,IAC7C,iCAAiC,CAAC;AAAA,IAClC,YAAY,gBAAgB,IAAI;AAAA,IAChC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,IACjE,YAAY,EAAE,UAAU,YAAY;AAAA,IACpC;AAAA,IACA,UAAU,SAAS;AAAA,IACnB,QAAQ,SAAS;AAAA,IACjB,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,cAAc,SAAS,gBAAgB;AAAA,IACvC,iBAAiB,gBAAgB,SAAS,IAAI,kBAAkB;AAAA,IAChE,yBAAyB,SAAS;AAAA,EACpC;AAEA,MAAI,YAAY;AACd,UAAM,cAAc,IAAI,IAAI,KAAK,OAAO,cAAc,EAAE;AACxD,gBAAY,UAAU;AAAA,MACpB,SAAS;AAAA,MACT,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,YAAY;AAAA,QACV,YAAY,CAAC,GAAG,KAAK,OAAO,YAAY,KAAK;AAAA,QAC7C,UAAU,CAAC,eAAe,eAAe,WAAW,WAAW;AAAA,QAC/D,WAAW,CAAC,WAAW,aAAa,oBAAoB;AAAA,MAC1D;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB,CAAC,aAAa,mBAAmB;AAAA,QACjD,yBAAyB;AAAA,QACzB,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,sBACP,YACA,SAC4B;AAC5B,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;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM,oBAAoB,KAAK,QAAQ,KAAK,KAAK,QAAQ;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,aAAW,QAAQ,YAAY;AAC7B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,YAAY,KAAK;AAAA,QACjB,MAAM,KAAK;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM,gBAAgB,KAAK,QAAQ,KAAK,KAAK,QAAQ;AAAA,IACvD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAsB,YACpB,MACA,SACA,iBACe;AACf,MAAI,KAAK,UAAU,EAAG;AAEtB,QAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAM,eAAe,QAAQ,KAAK,eAAe;AACjD,MAAI,cAAc;AAChB,SAAK,kBAAkB;AAAA,EACzB;AAEA,QAAM,UAAU,kBAAkB,MAAM,OAAO;AAC/C,QAAM,SAAS,QAAQ,mBAAmB;AAE1C,MAAI,iBAAiB;AACnB,UAAM,eACJ,OAAO,oBAAoB,WACvB,kBACA,gBACG,OAAO,CAAC,MAAuD,EAAE,SAAS,MAAM,EAChF,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AAElB,UAAM,iBACJ,OAAO,oBAAoB,WACvB,CAAC,IACD,gBAAgB;AAAA,MACd,CAAC,MAAwD,EAAE,SAAS;AAAA,IACtE;AAEN,UAAM,aAAa,OACf,GAAG,mBAAmB,KAAK,OAAO,MAAM,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAA8B,YAAY,KAC1F;AAEJ,QAAI;AACJ,QAAI,MAAM;AACR,eAAS,sBAAsB,YAAY,OAAO;AAClD,UAAI,eAAe,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;AACtD,eAAO,KAAK,GAAG,cAAc;AAAA,MAC/B;AAAA,IACF,WAAW,eAAe,SAAS,GAAG;AACpC,eAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,GAAG,GAAG,cAAc;AAAA,IACjE,OAAO;AACL,eAAS;AAAA,IACX;AAEA,UAAM,aAAa,MAAM;AAAA,MACvB,QAAQ,OAAO,WAAW,WAAW,SAAS,KAAK,kBAAkB,MAAM;AAAA,MAC3E,SAAS,EAAE,GAAG,SAAS,OAAO;AAAA,IAChC,CAAC;AACD,UAAM,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,EACvD,WAAW,cAAc;AACvB;AAAA,EACF,OAAO;AACL,UAAM,gBAAgB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAClE,UAAM,SAAS,sBAAsB,eAAe,OAAO;AAC3D,UAAM,aAAa,MAAM;AAAA,MACvB,QAAQ,KAAK,kBAAkB,MAAM;AAAA,MACrC,SAAS,EAAE,GAAG,SAAS,OAAO;AAAA,IAChC,CAAC;AACD,UAAM,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,EACvD;AAEA,MAAI,cAAc;AAChB,SAAK,aAAa;AAAA,EACpB;AACF;AAEA,eAAe,aACb,cACA,SACA,MACA,SACe;AACf,WAAS,UAAU,GAAG,WAAW,gBAAgB,QAAQ,WAAW;AAClE,QAAI,KAAK,UAAU,EAAG;AAEtB,UAAM,aACJ,YAAY,IACR,gBACC,MAAM;AACL,YAAM,cAAc;AAAA,QAClB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAAA,QAC5C;AAAA,MACF;AACA,aAAO,MAAM;AAAA,QACX,QAAQ,KAAK,kBAAkB,WAAW;AAAA,QAC1C,SAAS,EAAE,GAAG,SAAS,QAAQ,OAAU;AAAA,MAC3C,CAAC;AAAA,IACH,GAAG;AAET,QAAI;AACF,YAAM,EAAE,UAAU,IAAI,MAAM,cAAc,YAAY,SAAS,IAAI;AACnE,UAAI,CAAC,aAAa,KAAK,UAAU,EAAG;AAAA,IACtC,SAAS,OAAO;AACd,YAAM,iBACJ,iBAAiB,SAAS,MAAM,QAAQ,SAAS,uCAAuC;AAE1F,UAAI,kBAAkB,QAAQ,iBAAiB;AAC7C,gBAAQ,kBAAkB;AAC1B,aAAK,WAAW,eAAe,EAAE;AACjC,cAAM,cAAc;AAAA,UAClB,mBAAmB,KAAK,OAAO,MAAM,OAAO;AAAA,UAC5C;AAAA,QACF;AACA,cAAM,aAAa,MAAM;AAAA,UACvB,QAAQ,KAAK,kBAAkB,WAAW;AAAA,UAC1C,SAAS,EAAE,GAAG,SAAS,QAAQ,OAAU;AAAA,QAC3C,CAAC;AACD,eAAO,aAAa,YAAY,SAAS,MAAM,OAAO;AAAA,MACxD;AAEA,YAAM,aAAa,iBAAiB,SAASD,mBAAkB,KAAK,MAAM,OAAO;AACjF,UAAI,CAAC,WAAY,OAAM;AAAA,IACzB;AAEA,QAAI,WAAW,gBAAgB,QAAQ;AACrC,WAAK,WAAW;AAAA,QACd,6BAA6B,gBAAgB,MAAM;AAAA,MAErD;AACA;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,OAAO;AACvC,UAAM,WAAW,KAAK,MAAM,UAAU,GAAM;AAC5C,SAAK,WAAW;AAAA,MACd,sCAAsC,QAAQ,UAAU,WAAW,IAAI,MAAM,EAAE,gBAAgB,UAAU,CAAC,IAAI,gBAAgB,MAAM;AAAA,IACtI;AACA,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM;AAAA,MACN,SAAS,0BAA0B,QAAQ,MAAM,UAAU,CAAC,IAAI,gBAAgB,MAAM;AAAA,IACxF,CAAC;AACD,SAAK,WAAW,WAAW,mBAAmB;AAC9C,UAAM,KAAK,UAAU,eAAe,mBAAmB;AAEvD,UAAM,IAAI,QAAc,CAACC,aAAY;AACnC,YAAM,QAAQ,WAAWA,UAAS,OAAO;AACzC,YAAM,eAAe,YAAY,MAAM;AACrC,YAAI,KAAK,UAAU,GAAG;AACpB,uBAAa,KAAK;AAClB,wBAAc,YAAY;AAC1B,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF,GAAG,GAAI;AACP,iBAAW,MAAM,cAAc,YAAY,GAAG,UAAU,GAAG;AAAA,IAC7D,CAAC;AAED,SAAK,WAAW,WAAW,SAAS;AACpC,UAAM,KAAK,UAAU,eAAe,SAAS;AAAA,EAC/C;AACF;;;AMvZO,IAAM,cAAN,MAAkB;AAAA,EACf,oBAAoB;AAAA,EACpB,aAAa,oBAAI,IAA6B;AAAA;AAAA,EAGtD,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,SAAS,aAAa,UAAU,oBAAoB;AACpD,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAGd,IAAM,WAAN,MAAe;AAAA,EACZ,mBAAmB,oBAAI,IAAoB;AAAA,EAC3C,iBAAgC;AAAA,EAChC;AAAA,EACA;AAAA,EAER,YAAY,cAAsB,YAAgC;AAChE,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,mBAAmB,cAA4B;AAC7C,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,cAAwB;AAC9B,WAAO,CAACA,MAAK,QAAQ,GAAG,WAAW,OAAO,GAAGA,MAAK,KAAK,cAAc,WAAW,OAAO,CAAC;AAAA,EAC1F;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,WAAWA,MAAK,UAAU,IAAI;AACpC,kBAAM,OAAO,SAAS,QAAQ;AAC9B,iBAAK,iBAAiB,IAAI,UAAU,KAAK,OAAO;AAAA,UAClD,QAAQ;AACN;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAqB;AACnB,QAAI,KAAK,gBAAgB;AACvB,UAAI;AACF,cAAM,UAAU,aAAa,KAAK,gBAAgB,OAAO,EAAE,KAAK;AAChE,YAAI,SAAS;AACX,eAAK,WAAW,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAClD,gBAAM,WAAW,KAAK,eAAe,MAAM,GAAG,EAAE,IAAI;AACpD,eAAK,WAAW,gBAAgB,2BAA2B,QAAQ,qBAAqB;AAAA,QAC1F;AAAA,MACF,QAAQ;AAAA,MAER;AACA;AAAA,IACF;AAEA,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,WAAWA,MAAK,UAAU,IAAI;AACpC,YAAI;AACF,gBAAM,OAAO,SAAS,QAAQ;AAC9B,gBAAM,YAAY,KAAK,iBAAiB,IAAI,QAAQ;AACpD,gBAAM,QAAQ,cAAc,UAAa,KAAK,UAAU;AACxD,cAAI,UAAU,CAAC,UAAU,KAAK,UAAU,OAAO,QAAQ;AACrD,qBAAS,EAAE,MAAM,UAAU,OAAO,KAAK,QAAQ;AAAA,UACjD;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,WAAK,iBAAiB,OAAO;AAC7B,YAAM,UAAU,aAAa,OAAO,MAAM,OAAO,EAAE,KAAK;AACxD,UAAI,SAAS;AACX,aAAK,WAAW,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAClD,cAAM,WAAW,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI;AAC5C,aAAK,WAAW;AAAA,UACd,6BAA6B,QAAQ;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ATpEA,IAAM,wBAAwB;AAEvB,IAAM,cAAN,MAAM,aAAY;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA4B;AAAA,EAC5B,UAAU;AAAA,EACV,gBAA+D;AAAA,EAC/D,kBAAoC,CAAC;AAAA,EACrC,WAAqB,CAAC;AAAA,EACtB,iBAAwD;AAAA,EACxD,cAAkC;AAAA,EAClC;AAAA,EACA,cAAc,IAAI,YAAY;AAAA,EAC9B,iBAAiB;AAAA,EACjB,aAAwB;AAAA,EAChC,OAAwB,sBAAsB;AAAA,EAE9C,YAAY,QAA2B,WAAiC;AACtE,SAAK,SAAS;AACd,SAAK,aAAa,IAAI,mBAAmB,MAAM;AAC/C,SAAK,YAAY;AACjB,SAAK,WAAW,IAAI,SAAS,OAAO,cAAc,KAAK,UAAU;AAAA,EACnE;AAAA,EAEA,IAAI,QAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,SAAS,QAA0C;AAC/D,SAAK,SAAS;AACd,SAAK,WAAW,WAAW,MAAM;AACjC,UAAM,KAAK,UAAU,eAAe,MAAM;AAAA,EAC5C;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,iBAAiB,YAAY,MAAM;AACtC,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,WAAW,cAAc;AAAA,MAChC;AAAA,IACF,GAAG,qBAAqB;AAAA,EAC1B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,SAAS,YAAY;AAChC,UAAM,KAAK,WAAW,QAAQ;AAE9B,SAAK,WAAW,gBAAgB,MAAM,KAAK,KAAK,CAAC;AACjD,SAAK,WAAW;AAAA,MAAc,CAAC,YAC7B,KAAK,mBAAmB,QAAQ,SAAS,QAAQ,KAAK;AAAA,IACxD;AACA,SAAK,WAAW,aAAa,CAAC,SAAS,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAEvE,UAAM,KAAK,SAAS,WAAW;AAC/B,SAAK,WAAW,UAAU,EAAE,MAAM,aAAa,QAAQ,KAAK,OAAO,OAAO,CAAC;AAC3E,SAAK,eAAe;AAEpB,QAAI,KAAK,OAAO,SAAS,QAAQ,QAAQ,IAAI,eAAe,QAAQ;AAClE,YAAM,UAAU,MAAM,KAAK,aAAa;AACxC,UAAI,CAAC,SAAS;AACZ,aAAK,cAAc;AACnB,cAAM,KAAK,SAAS,OAAO;AAC3B,aAAK,WAAW,WAAW;AAC3B;AAAA,MACF;AAAA,IACF;AAEA,YAAQ;AAER,QACE,QAAQ,IAAI,0BAA0B,YACrC,KAAK,OAAO,SAAS,QAAQ,QAAQ,IAAI,0BAA0B,SACpE;AACA,UAAI;AACF,cAAM,eAAe,eAAe,KAAK,OAAO,cAAc,KAAK,OAAO,MAAM;AAChF,aAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,cAAc,aAAa;AAC3D,aAAK,SAAS,mBAAmB,YAAY;AAC7C,aAAK,iBAAiB;AACtB,aAAK,SAAS,KAAK,8BAA8B,YAAY,EAAE;AAAA,MACjE,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,aAAK,SAAS,KAAK,gEAAgE,GAAG,EAAE;AAAA,MAC1F;AAAA,IACF;AAEA,UAAM,KAAK,SAAS,kBAAkB;AACtC,QAAI;AACF,WAAK,cAAc,MAAM,KAAK,WAAW,iBAAiB;AAAA,IAC5D,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,WAAK,cAAc;AACnB,YAAM,KAAK,SAAS,OAAO;AAC3B,WAAK,WAAW,WAAW;AAC3B;AAAA,IACF;AAEA,SAAK,YAAY,mBAAmBC,YAAW;AAC/C,SAAK,qBAAqB;AAE1B,QAAI,QAAQ,IAAI,eAAe,QAAQ;AACrC,oBAAc,KAAK,OAAO,YAAY;AAAA,IACxC;AAEA,QAAI,QAAQ,IAAI,eAAe,UAAU,KAAK,YAAY,YAAY;AACpE,YAAM,SAAS;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,KAAK,YAAY;AAAA,QACjB,KAAK,YAAY;AAAA,MACnB;AACA,UAAI,OAAO,SAAS;AAClB,aAAK,SAAS,KAAK,cAAc,OAAO,OAAO,EAAE;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,kBAAkB,KAAK,YAAY,aAAa;AACxD,UAAI;AACF,cAAM,eAAe,eAAe,KAAK,OAAO,cAAc,KAAK,OAAO,MAAM;AAChF,aAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,cAAc,aAAa;AAC3D,aAAK,SAAS,mBAAmB,YAAY;AAC7C,aAAK,iBAAiB;AACtB,aAAK,SAAS,KAAK,iDAAiD,YAAY,EAAE;AAAA,MACpF,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,aAAK,SAAS,KAAK,gEAAgE,GAAG,EAAE;AAAA,MAC1F;AAAA,IACF;AAEA,QAAI,KAAK,kBAAkB,KAAK,YAAY,cAAc;AACxD,UAAI;AACF,cAAM,SAAS,KAAK,YAAY;AAChC,QAAAC,UAAS,oBAAoB,MAAM,oBAAoB,MAAM,IAAI;AAAA,UAC/D,KAAK,KAAK,OAAO;AAAA,UACjB,OAAO;AAAA,QACT,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAI,MAAM;AACR,YAAM,KAAK,SAAS,MAAM;AAAA,IAC5B,OAAO;AACL,YAAM,KAAK,SAAS,SAAS;AAC7B,YAAM,KAAK,aAAa,KAAK,WAAW;AACxC,UAAI,CAAC,KAAK,QAAS,OAAM,KAAK,SAAS,MAAM;AAAA,IAC/C;AAEA,UAAM,KAAK,YAAY;AAEvB,SAAK,cAAc;AACnB,UAAM,KAAK,SAAS,UAAU;AAC9B,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,MAAc,aACZ,SACA,UACe;AACf,QAAI;AACF,YAAM,YAAY,KAAK,YAAY,GAAG,SAAS,QAAQ;AAAA,IACzD,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;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAc,cAA6B;AACzC,QAAI,CAAC,KAAK,YAAa;AACvB,WAAO,CAAC,KAAK,SAAS;AACpB,UAAI,KAAK,WAAW,QAAQ;AAC1B,cAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAI,CAAC,IAAK;AACV,cAAM,KAAK,SAAS,SAAS;AAC7B,cAAM,KAAK,aAAa,KAAK,aAAa,GAAG;AAC7C,YAAI,CAAC,KAAK,WAAY,KAAK,WAAsB,QAAS,OAAM,KAAK,SAAS,MAAM;AAAA,MACtF,WAAW,KAAK,WAAW,SAAS;AAClC,cAAM,KAAK,SAAS,MAAM;AAAA,MAC5B,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAiC;AAC7C,UAAM,KAAK,SAAS,OAAO;AAE3B,UAAM,QAAQ,MAAM,iBAAiB,KAAK,OAAO,YAAY;AAC7D,QAAI,MAAM,SAAS,KAAK,QAAQ,IAAI,gBAAgB;AAClD,YAAM,aAAa,MAAM,IAAI,CAAC,MAAM,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG;AAC3D;AAAA,QACE,iCAAiC,UAAU,QAAQ,QAAQ,IAAI,cAAc;AAAA,QAC7E,KAAK,OAAO;AAAA,QACZ,MAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAChE,QAAI,CAAC,QAAQ;AACX,WAAK,WAAW,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACvD,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,KAAK,mBAAmB,MAAM;AACpC,YAAM,aAAyB;AAAA,QAC7B,MAAM;AAAA,QACN,aAAa,OAAO,eAAe;AAAA,MACrC;AACA,WAAK,WAAW,UAAU,UAAU;AACpC,YAAM,KAAK,UAAU,QAAQ,UAAU;AACvC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,WAAW,UAAU,EAAE,MAAM,eAAe,QAAQ,CAAC;AAC1D,YAAM,KAAK,UAAU,QAAQ,EAAE,MAAM,eAAe,QAAQ,CAAC;AAC7D,WAAK,WAAW;AAAA,QACd,6BAA6B,OAAO;AAAA;AAAA,MACtC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,IAAI,KAAK,YAAY,iBAAiB,KAAK,OAAO,iBAAiB,CAAC;AAC1E,UAAM,QAAQ,KAAK,YAAY,SAAS,KAAK,OAAO;AACpD,UAAM,WACJ,EAAE,UAAU,SAAS,YACjB,WAAY,EAAE,SAAuC,gBAAgB,GAAG,MACvE,EAAE,UAAU,QAAQ;AAC3B,UAAM,QAAQ;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK,OAAO,QAAQ,MAAM;AAAA,MAClC,UAAU,EAAE,UAAU,SAAS;AAAA,MAC/B,YAAY,QAAQ;AAAA,MACpB,cAAc,EAAE,gBAAgB,EAAE;AAAA,MAClC,YAAY,EAAE,YAAY,WAAW;AAAA,IACvC;AACA,QAAI,EAAE,OAAO,OAAQ,OAAM,KAAK,SAAS,EAAE,MAAM,KAAK,GAAG,CAAC,EAAE;AAC5D,QAAI,EAAE,iBAAiB,OAAQ,OAAM,KAAK,eAAe,EAAE,gBAAgB,KAAK,GAAG,CAAC,GAAG;AACvF,QAAI,EAAE,wBAAyB,OAAM,KAAK,kBAAkB;AAE5D,YAAQ,IAAI,oBAAoB,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EAEpD;AAAA,EAEQ,aAAa,MAAoB;AACvC,SAAK,SAAS,KAAK,IAAI;AACvB,QAAI,KAAK,SAAS,SAAS,aAAY,qBAAqB;AAC1D,WAAK,SAAS,OAAO,GAAG,KAAK,SAAS,SAAS,aAAY,mBAAmB;AAAA,IAChF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,QAAuC;AACtE,QAAI,OAAO,cAAc;AACvB,WAAK,aAAa,KAAK,OAAO,YAAY,EAAE;AAC5C,YAAM,gBAAgB,OAAO,cAAc,KAAK,OAAO,cAAc,CAAC,QAAQ,SAAS;AACrF,aAAK,WAAW,UAAU,EAAE,MAAM,gBAAgB,QAAQ,KAAK,CAAC;AAChE,mBAAW,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACnD,eAAK,aAAa,IAAI,MAAM,KAAK,IAAI,EAAE;AAAA,QACzC;AAAA,MACF,CAAC;AACD,WAAK,aAAa,UAAU;AAAA,IAC9B;AAEA,QAAI,OAAO,cAAc;AACvB,WAAK,aAAa,KAAK,OAAO,YAAY,kBAAkB;AAC5D,sBAAgB,OAAO,cAAc,KAAK,OAAO,cAAc,CAAC,QAAQ,SAAS;AAC/E,aAAK,WAAW,UAAU,EAAE,MAAM,wBAAwB,QAAQ,KAAK,CAAC;AAAA,MAC1E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBACN,SACA,OAQM;AASN,QAAI;AACJ,QAAI,OAAO,QAAQ;AACjB,YAAM,SAAyB,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAC/D,iBAAW,KAAK,OAAO;AACrB,YAAI,EAAE,WAAW,EAAE,oBAAoB,UAAU;AAC/C,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,UAAU,YAAY,EAAE,UAA4B,MAAM,EAAE,QAAQ;AAAA,UACtF,CAAC;AACD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,oBAAoB,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAAA,UACrD,CAAC;AAAA,QACH,WAAW,EAAE,WAAW,EAAE,oBAAoB,SAAS;AACrD,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,mBAAmB,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAAA;AAAA,EAAe,EAAE,OAAO;AAAA;AAAA,UAC5E,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM,mBAAmB,EAAE,QAAQ,KAAK,EAAE,QAAQ,gBAAgB,EAAE,WAAW;AAAA,UACjF,CAAC;AAAA,QACH;AAAA,MACF;AACA,uBAAiB;AAAA,IACnB,OAAO;AACL,uBAAiB;AAAA,IACnB;AAEA,UAAM,MAAsB;AAAA,MAC1B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,EAAE,MAAM,QAAiB,SAAS,eAAe;AAAA,MAC1D,oBAAoB;AAAA,IACtB;AAEA,QAAI,KAAK,eAAe;AACtB,YAAMC,WAAU,KAAK;AACrB,WAAK,gBAAgB;AACrB,MAAAA,SAAQ,GAAG;AAAA,IACb,OAAO;AACL,WAAK,gBAAgB,KAAK,GAAG;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,iBAAiD;AACvD,WAAO,IAAI,QAA+B,CAACA,aAAY;AACrD,YAAM,eAAe,YAAY,MAAM;AACrC,YAAI,KAAK,SAAS;AAChB,wBAAc,YAAY;AAC1B,eAAK,gBAAgB;AACrB,UAAAA,SAAQ,IAAI;AAAA,QACd;AAAA,MACF,GAAG,GAAI;AAEP,WAAK,gBAAgB,CAAC,QAA+B;AACnD,sBAAc,YAAY;AAC1B,QAAAA,SAAQ,GAAG;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,qBAAiE;AAC7E,QAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,YAAM,OAAO,KAAK,gBAAgB,MAAM;AACxC,YAAMC,WAAU,MAAM,QAAQ;AAC9B,UAAI,CAACA,SAAS,QAAO;AACrB,aAAOA;AAAA,IACT;AACA,UAAM,MAAM,MAAM,KAAK,eAAe;AACtC,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,UAAU,IAAI,QAAQ;AAC5B,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,kBACL,eAC+C;AAC/C,UAAM,kBAAkB,CAAC,aAAyD;AAAA,MAChF,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,EAAE,MAAM,QAAiB,QAAQ;AAAA,MAC1C,oBAAoB;AAAA,IACtB;AAEA,UAAM,gBAAgB,aAAa;AAEnC,WAAO,CAAC,KAAK,SAAS;AACpB,UAAI,KAAK,gBAAgB,SAAS,GAAG;AACnC,cAAM,OAAO,KAAK,gBAAgB,MAAM;AACxC,YAAI,KAAM,OAAM;AAChB;AAAA,MACF;AAEA,WAAK,WAAW,WAAW,mBAAmB;AAC9C,YAAM,KAAK,UAAU,eAAe,mBAAmB;AACvD,YAAM,MAAM,MAAM,KAAK,eAAe;AAEtC,UAAI,CAAC,IAAK;AACV,WAAK,WAAW,WAAW,SAAS;AACpC,YAAM,KAAK,UAAU,eAAe,SAAS;AAC7C,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,cAAyB;AAC/B,UAAM,gBAAgB,MAAiB,KAAK;AAC5C,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,IAAI,aAAwB;AAC1B,eAAO,cAAc;AAAA,MACvB;AAAA,MACA,WAAW,MAAM,KAAK;AAAA,MACtB,mBAAmB,CAAC,WAAmB,KAAK,kBAAkB,MAAM;AAAA,MACpE,mBAAmB,MAAM,KAAK,SAAS,kBAAkB;AAAA,MACzD,cAAc,MAAM,KAAK,SAAS,aAAa;AAAA,IACjD;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAuB;AAC9C,QAAI,KAAK,OAAO,SAAS,KAAM;AAC/B,SAAK,aAAa;AAClB,SAAK,WAAW,gBAAgB,IAAI;AACpC,SAAK,WAAW;AAAA,MACd,sBAAsB,IAAI,KAAK,SAAS,WAAW,6CAAwC,gCAA2B;AAAA,IACxH;AAAA,EACF;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc,IAAI;AACvB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AACF;;;AUxdA,SAAS,YAA+B;AACxC,SAAS,YAAAC,iBAAgB;AACzB,YAAY,UAAU;AACtB,SAAS,qBAAqB;;;ACH9B,SAAS,SAAAC,cAAuC;AAQhD,IAAM,iBAAiB;AAEvB,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,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;AAQA,eAAsB,yBACpB,SACA,YACA,YACe;AACf,aAAW,gBAAgB,MAAM;AAEjC,MAAI;AACF,QAAI,WAAgC;AACpC,QAAI;AACF,iBAAW,MAAM,WAAW,kBAAkB;AAAA,IAChD,QAAQ;AACN,cAAQ,IAAI,8DAA8D;AAAA,IAC5E;AAEA,QAAI,cAAoC,CAAC;AACzC,QAAI;AACF,oBAAc,MAAM,WAAW,iBAAiB,EAAE;AAAA,IACpD,QAAQ;AACN,cAAQ,IAAI,oEAAoE;AAAA,IAClF;AAEA,UAAM,QAAQ,UAAU,SAAS;AACjC,UAAM,WAAW,UAAU,iBAAiB,CAAC;AAC7C,UAAM,eAAeA,mBAAkB,YAAY,QAAQ;AAC3D,UAAM,SAAS,YAAY,SAAS,WAAW;AAE/C,UAAM,SAASD,OAAM;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA,KAAK;AAAA,QACL,gBAAgB;AAAA,QAChB,iCAAiC;AAAA,QACjC,OAAO,EAAE,MAAM,UAAmB,QAAQ,cAAuB;AAAA,QACjE,UAAW,SAAS,YAAmC;AAAA,QACvD,cAAe,SAAS,gBAAuC;AAAA,QAC/D,QAAQ,SAAS;AAAA,QACjB,UAAU,SAAS;AAAA,MAKrB;AAAA,IACF,CAAC;AAED,UAAM,gBAA0B,CAAC;AACjC,UAAM,gBAAmC,CAAC;AAC1C,QAAI,WAAW;AAEf,qBAAiB,SAAS,QAAQ;AAChC,UAAI,MAAM,SAAS,aAAa;AAC9B,YAAI,CAAC,UAAU;AACb,qBAAW,MAAM,WAAW,UAAU,EAAE,MAAM,qBAAqB,CAAC,GAAG,GAAG;AAC1E,qBAAW;AAAA,QACb;AAEA,cAAM,iBAAiB;AACvB,cAAM,EAAE,QAAQ,IAAI,eAAe;AAEnC,mBAAW,SAAS,SAAS;AAC3B,cAAI,MAAM,SAAS,QAAQ;AACzB,0BAAc,KAAK,MAAM,IAAI;AAAA,UAC/B,WAAW,MAAM,SAAS,YAAY;AACpC,kBAAM,WACJ,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK;AAC5E,0BAAc,KAAK;AAAA,cACjB,MAAM,MAAM;AAAA,cACZ,OAAO,SAAS,MAAM,GAAG,GAAM;AAAA,cAC/B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AACD,oBAAQ,IAAI,6BAA6B,MAAM,IAAI,EAAE;AAAA,UACvD;AAAA,QACF;AAEA,YAAI,cAAc,SAAS,GAAG;AAC5B,qBAAW,UAAU,EAAE,MAAM,kBAAkB,QAAQ,CAAC,GAAG,aAAa,EAAE,CAAC;AAC3E,wBAAc,SAAS;AAAA,QACzB;AAAA,MACF,WAAW,MAAM,SAAS,UAAU;AAClC,YAAI,UAAU;AACZ,qBAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClD,qBAAW;AAAA,QACb;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU;AACZ,iBAAW,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAAA,IACpD;AAEA,UAAM,eAAe,cAAc,KAAK,MAAM,EAAE,KAAK;AACrD,QAAI,cAAc;AAChB,YAAM,WAAW,gBAAgB,YAAY;AAAA,IAC/C;AAAA,EACF,SAAS,OAAO;AACd,YAAQ;AAAA,MACN;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC3C;AACA,QAAI;AACF,YAAM,WAAW;AAAA,QACf;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF,UAAE;AACA,eAAW,gBAAgB,MAAM;AAAA,EACnC;AACF;;;AD3KA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAiB,aAAQ,UAAU;AAezC,IAAME,yBAAwB;AAC9B,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAEjB,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,eAAe,oBAAI,IAAyB;AAAA,EAC5C,iBAAwD;AAAA,EACxD,WAAW;AAAA,EACX,mBAAwC;AAAA,EAEhD,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;AAAA,EACH;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,WAAW,QAAQ;AAE9B,SAAK,WAAW,iBAAiB,CAAC,eAAe;AAC/C,WAAK,KAAK,iBAAiB,UAAU;AAAA,IACvC,CAAC;AAED,SAAK,WAAW,WAAW,CAAC,SAAS;AACnC,WAAK,eAAe,KAAK,MAAM;AAAA,IACjC,CAAC;AAED,SAAK,WAAW,WAAW,MAAM;AAC/B,cAAQ,IAAI,uDAAuD;AACnE,WAAK,KAAK,KAAK;AAAA,IACjB,CAAC;AAED,SAAK,WAAW,cAAc,CAAC,QAAQ;AACrC,cAAQ,IAAI,gDAAgD;AAC5D,WAAK,yBAAyB,KAAK,KAAK,YAAY,KAAK,UAAU;AAAA,IACrE,CAAC;AAED,SAAK,iBAAiB,YAAY,MAAM;AACtC,WAAK,WAAW,cAAc;AAAA,IAChC,GAAGA,sBAAqB;AAExB,YAAQ,IAAI,6DAA6D;AAEzE,UAAM,IAAI,QAAc,CAACC,aAAY;AACnC,WAAK,mBAAmBA;AACxB,cAAQ,GAAG,WAAW,MAAM,KAAK,KAAK,KAAK,CAAC;AAC5C,cAAQ,GAAG,UAAU,MAAM,KAAK,KAAK,KAAK,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,iBAAiB,YAA2C;AACxE,UAAM,EAAE,QAAQ,WAAW,QAAQ,MAAM,QAAQ,WAAW,YAAY,IAAI;AAC5E,UAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AAEjC,QAAI,KAAK,aAAa,IAAI,MAAM,GAAG;AACjC,cAAQ,IAAI,yBAAyB,OAAO,4BAA4B;AACxE;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,QAAQ,gBAAgB;AAC5C,cAAQ;AAAA,QACN,2CAA2C,cAAc,6BAA6B,OAAO;AAAA,MAC/F;AACA,WAAK,WAAW,gBAAgB,QAAQ,wBAAwB;AAChE;AAAA,IACF;AAEA,QAAI;AACF,UAAI;AACF,QAAAC,UAAS,oBAAoB,EAAE,KAAK,KAAK,YAAY,OAAO,SAAS,CAAC;AAAA,MACxE,QAAQ;AACN,gBAAQ,IAAI,SAAS,OAAO,6BAA6B;AAAA,MAC3D;AAEA,UAAI;AACJ,YAAM,iBAAiB,gBAAgB;AACvC,UAAI,gBAAgB;AAClB,kBAAU,eAAe,KAAK,YAAY,QAAQ,SAAS;AAAA,MAC7D,OAAO;AACL,kBAAU,KAAK;AAAA,MACjB;AAEA,UAAI,UAAU,WAAW,WAAW;AAClC,YAAI;AACF,UAAAA,UAAS,gBAAgB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,QACtE,QAAQ;AACN,cAAI;AACF,YAAAA,UAAS,mBAAmB,MAAM,IAAI,EAAE,KAAK,SAAS,OAAO,SAAS,CAAC;AAAA,UACzE,QAAQ;AACN,oBAAQ,IAAI,SAAS,OAAO,wCAAwC,MAAM,EAAE;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAe,aAAQ,WAAW,QAAQ;AAEhD,YAAM,WAAW,EAAE,GAAG,QAAQ,IAAI;AAClC,aAAO,SAAS;AAChB,aAAO,SAAS;AAEhB,YAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;AAAA,QAC9B,KAAK;AAAA,UACH,GAAG;AAAA,UACH,kBAAkB;AAAA,UAClB,qBAAqB;AAAA,UACrB,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf,oBAAoB;AAAA,UACpB,uBAAuB;AAAA,QACzB;AAAA,QACA,KAAK;AAAA,QACL,OAAO,CAAC,QAAQ,QAAQ,QAAQ,KAAK;AAAA,MACvC,CAAC;AAED,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI;AAClD,mBAAW,QAAQ,OAAO;AACxB,kBAAQ,IAAI,SAAS,OAAO,KAAK,IAAI,EAAE;AAAA,QACzC;AAAA,MACF,CAAC;AACD,YAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,cAAM,QAAQ,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI;AAClD,mBAAW,QAAQ,OAAO;AACxB,kBAAQ,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE;AAAA,QAC3C;AAAA,MACF,CAAC;AAED,WAAK,aAAa,IAAI,QAAQ,EAAE,SAAS,OAAO,cAAc,SAAS,KAAK,CAAC;AAC7E,WAAK,WAAW,gBAAgB,MAAM;AAEtC,cAAQ,IAAI,iCAAiC,OAAO,OAAO,IAAI,YAAY,OAAO,EAAE;AAEpF,YAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,aAAK,aAAa,OAAO,MAAM;AAC/B,cAAM,SAAS,SAAS,IAAI,cAAc,oBAAoB,IAAI;AAClE,aAAK,WAAW,gBAAgB,QAAQ,MAAM;AAC9C,gBAAQ,IAAI,yBAAyB,OAAO,IAAI,MAAM,EAAE;AAExD,YAAI,SAAS,GAAG;AACd,cAAI;AACF,2BAAe,KAAK,YAAY,MAAM;AAAA,UACxC,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,yCAAyC,OAAO;AAAA,QAChD,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AACA,WAAK,WAAW;AAAA,QACd;AAAA,QACA,iBAAiB,iBAAiB,QAAQ,MAAM,UAAU,SAAS;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,QAAsB;AAC3C,UAAM,QAAQ,KAAK,aAAa,IAAI,MAAM;AAC1C,QAAI,CAAC,MAAO;AAEZ,UAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,YAAQ,IAAI,kCAAkC,OAAO,EAAE;AAEvD,UAAM,QAAQ,KAAK,SAAS;AAE5B,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,KAAK,aAAa,IAAI,MAAM,GAAG;AACjC,cAAM,QAAQ,KAAK,SAAS;AAAA,MAC9B;AAAA,IACF,GAAG,eAAe;AAElB,UAAM,QAAQ,GAAG,QAAQ,MAAM;AAC7B,mBAAa,KAAK;AAClB,UAAI;AACF,uBAAe,KAAK,YAAY,MAAM;AAAA,MACxC,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAEhB,YAAQ,IAAI,mCAAmC;AAE/C,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,WACC,IAAI,QAAc,CAACD,aAAY;AAC7B,cAAM,QAAQ,KAAK,aAAa,IAAI,MAAM;AAC1C,YAAI,CAAC,OAAO;AACV,UAAAA,SAAQ;AACR;AAAA,QACF;AACA,cAAM,QAAQ,GAAG,QAAQ,MAAM;AAC7B,UAAAA,SAAQ;AAAA,QACV,CAAC;AACD,aAAK,eAAe,MAAM;AAAA,MAC5B,CAAC;AAAA,IACL;AAEA,UAAM,QAAQ,KAAK;AAAA,MACjB,QAAQ,IAAI,YAAY;AAAA,MACxB,IAAI,QAAc,CAACA,aAAY,WAAWA,UAAS,GAAM,CAAC;AAAA,IAC5D,CAAC;AAED,SAAK,WAAW,WAAW;AAC3B,YAAQ,IAAI,oCAAoC;AAEhD,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AACF;;;AE7PA,IAAM,yBAAyB,KAAK,OAAO;AAC3C,IAAM,iBAAiB,KAAK,KAAK;AAU1B,IAAM,YAAN,MAAgB;AAAA,EACb,QAAQ,oBAAI,IAAwB;AAAA,EACpC,cAAc;AAAA,EACL;AAAA,EACA;AAAA,EAEjB,YAAY,eAAe,wBAAwB,QAAQ,gBAAgB;AACzE,SAAK,eAAe;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,IAAI,QAAmC;AACrC,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM;AACnC,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI,KAAK,IAAI,IAAI,MAAM,YAAY,KAAK,OAAO;AAC7C,WAAK,OAAO,MAAM;AAClB,aAAO;AAAA,IACT;AAEA,SAAK,MAAM,OAAO,MAAM;AACxB,SAAK,MAAM,IAAI,QAAQ,KAAK;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,QAAgB,SAAiB,UAAkB,UAAwB;AAC7E,QAAI,KAAK,MAAM,IAAI,MAAM,GAAG;AAC1B,WAAK,OAAO,MAAM;AAAA,IACpB;AAEA,UAAM,OAAO,QAAQ;AAErB,QAAI,OAAO,KAAK,aAAc;AAE9B,WAAO,KAAK,cAAc,OAAO,KAAK,gBAAgB,KAAK,MAAM,OAAO,GAAG;AACzE,YAAM,YAAY,KAAK,MAAM,KAAK,EAAE,KAAK,EAAE;AAC3C,UAAI,cAAc,QAAW;AAC3B,aAAK,OAAO,SAAS;AAAA,MACvB;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AACD,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,OAAO,QAAsB;AACnC,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM;AACnC,QAAI,OAAO;AACT,WAAK,eAAe,MAAM;AAC1B,WAAK,MAAM,OAAO,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AACjB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,IAAI,QAAsE;AACxE,WAAO;AAAA,MACL,SAAS,KAAK,MAAM;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AACF;","names":["resolve","io","resolve","resolve","DEVCONTAINER_PATH","execSync","join","randomUUID","execSync","tool","z","tool","z","tool","z","tool","z","API_ERROR_PATTERN","resolve","join","randomUUID","execSync","resolve","content","execSync","query","buildSystemPrompt","HEARTBEAT_INTERVAL_MS","resolve","execSync"]}