agents 0.21.0 → 0.23.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.
Files changed (258) hide show
  1. package/README.md +21 -1
  2. package/dist/{agent-tool-types-CzGGB-20.d.ts → agent-routing-DE5zmCQ8.d.ts} +1844 -1336
  3. package/dist/agent-routing.d.ts +14 -0
  4. package/dist/agent-routing.js +187 -0
  5. package/dist/agent-routing.js.map +1 -0
  6. package/dist/agent-tool-types.d.ts +26 -26
  7. package/dist/{agent-tools-zR2d5uij.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
  8. package/dist/agent-tools.d.ts +21 -21
  9. package/dist/agent-tools.js +2 -1
  10. package/dist/agent-tools.js.map +1 -1
  11. package/dist/browser/ai.js +6 -2
  12. package/dist/browser/ai.js.map +1 -1
  13. package/dist/browser/tanstack-ai.js.map +1 -1
  14. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  15. package/dist/callable-decorator.d.ts +18 -0
  16. package/dist/callable-decorator.js +71 -0
  17. package/dist/callable-decorator.js.map +1 -0
  18. package/dist/capability-BjSKYpzg.js +42 -0
  19. package/dist/capability-BjSKYpzg.js.map +1 -0
  20. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  21. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  22. package/dist/channels/ai-sdk.d.ts +46 -0
  23. package/dist/channels/ai-sdk.js +120 -0
  24. package/dist/channels/ai-sdk.js.map +1 -0
  25. package/dist/channels/email.d.ts +95 -0
  26. package/dist/channels/email.js +323 -0
  27. package/dist/channels/email.js.map +1 -0
  28. package/dist/channels/index.d.ts +233 -0
  29. package/dist/channels/index.js +608 -0
  30. package/dist/channels/index.js.map +1 -0
  31. package/dist/channels/slack.d.ts +140 -0
  32. package/dist/channels/slack.js +614 -0
  33. package/dist/channels/slack.js.map +1 -0
  34. package/dist/channels/tanstack-ai.d.ts +39 -0
  35. package/dist/channels/tanstack-ai.js +17 -0
  36. package/dist/channels/tanstack-ai.js.map +1 -0
  37. package/dist/channels/telegram.d.ts +106 -0
  38. package/dist/channels/telegram.js +427 -0
  39. package/dist/channels/telegram.js.map +1 -0
  40. package/dist/channels/voice.d.ts +45 -0
  41. package/dist/channels/voice.js +122 -0
  42. package/dist/channels/voice.js.map +1 -0
  43. package/dist/chat/index.d.ts +2328 -2015
  44. package/dist/chat/index.js +891 -521
  45. package/dist/chat/index.js.map +1 -1
  46. package/dist/chat/react.d.ts +14 -1
  47. package/dist/chat/react.js +82 -52
  48. package/dist/chat/react.js.map +1 -1
  49. package/dist/chat/transport.js +1 -1
  50. package/dist/chat-sdk/index.d.ts +7 -7
  51. package/dist/chat-sdk/index.js +1 -1
  52. package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
  53. package/dist/client-jagG8a9_.js.map +1 -0
  54. package/dist/client.d.ts +1 -1
  55. package/dist/client.js +1 -1
  56. package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
  57. package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
  58. package/dist/context/index.d.ts +216 -0
  59. package/dist/context/index.js +454 -0
  60. package/dist/context/index.js.map +1 -0
  61. package/dist/current-agent-Da_C9a3b.d.ts +266 -0
  62. package/dist/current-agent-DhoDkSnH.js +51 -0
  63. package/dist/current-agent-DhoDkSnH.js.map +1 -0
  64. package/dist/diagnostics-BzvaX2UT.js +45 -0
  65. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  66. package/dist/diagnostics-C4jcz3VK.js +360 -0
  67. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  68. package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
  69. package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
  70. package/dist/email-send.d.ts +15 -0
  71. package/dist/email-send.js +32 -0
  72. package/dist/email-send.js.map +1 -0
  73. package/dist/email.d.ts +14 -10
  74. package/dist/email.js.map +1 -1
  75. package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
  76. package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
  77. package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
  78. package/dist/index-BB0kqhIz.d.ts +101 -0
  79. package/dist/index-XDkuQ7zm.d.ts +89 -0
  80. package/dist/{index-BRnybD6X.d.ts → index-YSKgfgg9.d.ts} +21 -31
  81. package/dist/index.d.ts +113 -101
  82. package/dist/index.js +11 -7234
  83. package/dist/ingress-BfetZbMO.js +83 -0
  84. package/dist/ingress-BfetZbMO.js.map +1 -0
  85. package/dist/internal-CYlgHl1l.js +59 -0
  86. package/dist/internal-CYlgHl1l.js.map +1 -0
  87. package/dist/internal_context-BlxFEWfn.d.ts +19 -0
  88. package/dist/internal_context.d.ts +10 -4
  89. package/dist/internal_context.js +1 -10
  90. package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
  91. package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
  92. package/dist/invoker-CHMnoxIA.js.map +1 -0
  93. package/dist/lifecycle/index.d.ts +66 -0
  94. package/dist/lifecycle/index.js +4 -0
  95. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  96. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  97. package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
  98. package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
  99. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
  100. package/dist/mcp/client/index.d.ts +42 -0
  101. package/dist/mcp/{client.js → client/index.js} +1 -1
  102. package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
  103. package/dist/mcp/{x402.js → client/x402.js} +2 -2
  104. package/dist/mcp/client/x402.js.map +1 -0
  105. package/dist/mcp/index.d.ts +36 -36
  106. package/dist/mcp/index.js +14 -16
  107. package/dist/mcp/index.js.map +1 -1
  108. package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
  109. package/dist/mcp/{server.js → server/index.js} +1 -1
  110. package/dist/observability/ai/index.js +50 -35
  111. package/dist/observability/ai/index.js.map +1 -1
  112. package/dist/observability/index.d.ts +4 -4
  113. package/dist/observability/index.js +3 -50
  114. package/dist/observability/index.js.map +1 -1
  115. package/dist/{protocol-Dqc2MQxo.js → protocol-B0nh6KNf.js} +19 -21
  116. package/dist/protocol-B0nh6KNf.js.map +1 -0
  117. package/dist/react.d.ts +4 -4
  118. package/dist/react.js +1 -1
  119. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  120. package/dist/retries.d.ts +8 -6
  121. package/dist/retries.js +13 -1
  122. package/dist/retries.js.map +1 -1
  123. package/dist/routing/index.d.ts +137 -0
  124. package/dist/routing/index.js +244 -0
  125. package/dist/routing/index.js.map +1 -0
  126. package/dist/sanitize-D9TujEK8.js +79 -0
  127. package/dist/sanitize-D9TujEK8.js.map +1 -0
  128. package/dist/schedule.d.ts +25 -94
  129. package/dist/schedule.js +1 -98
  130. package/dist/schedule.js.map +1 -1
  131. package/dist/scheduler-DD9NdYbF.js +665 -0
  132. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  133. package/dist/scheduler-Dwh85ZGl.d.ts +223 -0
  134. package/dist/schedules/index.d.ts +22 -0
  135. package/dist/schedules/index.js +2 -0
  136. package/dist/schedules/parser.d.ts +79 -0
  137. package/dist/schedules/parser.js +103 -0
  138. package/dist/schedules/parser.js.map +1 -0
  139. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  140. package/dist/serializable.d.ts +1 -1
  141. package/dist/sessions/index.d.ts +441 -0
  142. package/dist/sessions/index.js +2063 -0
  143. package/dist/sessions/index.js.map +1 -0
  144. package/dist/skills/index.d.ts +99 -0
  145. package/dist/skills/index.js +254 -5
  146. package/dist/skills/index.js.map +1 -1
  147. package/dist/sql-error-CPY-GXyI.d.ts +12 -0
  148. package/dist/sql-error.d.ts +2 -0
  149. package/dist/sql-error.js +16 -0
  150. package/dist/sql-error.js.map +1 -0
  151. package/dist/src-DlSHshb2.js +6963 -0
  152. package/dist/src-DlSHshb2.js.map +1 -0
  153. package/dist/streams/index.d.ts +120 -0
  154. package/dist/streams/index.js +107 -0
  155. package/dist/streams/index.js.map +1 -0
  156. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  157. package/dist/streams-DZKgAj9b.js +709 -0
  158. package/dist/streams-DZKgAj9b.js.map +1 -0
  159. package/dist/sub-routing.d.ts +12 -12
  160. package/dist/surface-bZZJqBka.js +17 -0
  161. package/dist/surface-bZZJqBka.js.map +1 -0
  162. package/dist/tasks/index.d.ts +64 -0
  163. package/dist/tasks/index.js +2 -0
  164. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  165. package/dist/tasks-ylZgBjhj.js +1656 -0
  166. package/dist/tasks-ylZgBjhj.js.map +1 -0
  167. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  168. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  169. package/dist/text-stream-CpdiKrJB.js +272 -0
  170. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  171. package/dist/tokens-nHAKcN6M.js +52 -0
  172. package/dist/tokens-nHAKcN6M.js.map +1 -0
  173. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  174. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  175. package/dist/types-B7LojTe4.d.ts +202 -0
  176. package/dist/types-_Faxb570.d.ts +439 -0
  177. package/dist/voice/client.d.ts +226 -0
  178. package/dist/voice/client.js +932 -0
  179. package/dist/voice/client.js.map +1 -0
  180. package/dist/voice/errors.d.ts +43 -0
  181. package/dist/voice/errors.js +41 -0
  182. package/dist/voice/errors.js.map +1 -0
  183. package/dist/voice/index.d.ts +271 -0
  184. package/dist/voice/index.js +1812 -0
  185. package/dist/voice/index.js.map +1 -0
  186. package/dist/voice/react.d.ts +167 -0
  187. package/dist/voice/react.js +234 -0
  188. package/dist/voice/react.js.map +1 -0
  189. package/dist/voice/sfu.d.ts +71 -0
  190. package/dist/voice/sfu.js +157 -0
  191. package/dist/voice/sfu.js.map +1 -0
  192. package/dist/voice/text.d.ts +6 -0
  193. package/dist/voice/text.js +2 -0
  194. package/dist/voice/types.d.ts +58 -0
  195. package/dist/voice/types.js +18 -0
  196. package/dist/voice/types.js.map +1 -0
  197. package/dist/voice/workers-ai.d.ts +136 -0
  198. package/dist/voice/workers-ai.js +568 -0
  199. package/dist/voice/workers-ai.js.map +1 -0
  200. package/dist/websockets/index.d.ts +192 -0
  201. package/dist/websockets/index.js +2 -0
  202. package/dist/websockets-DUfRHPRq.js +502 -0
  203. package/dist/websockets-DUfRHPRq.js.map +1 -0
  204. package/dist/workflow-types.d.ts +25 -25
  205. package/dist/workflows.d.ts +22 -22
  206. package/dist/workflows.js +2 -1
  207. package/dist/workflows.js.map +1 -1
  208. package/dist/{ws-chat-transport-CIoOBbO7.js → ws-chat-transport-rWwta645.js} +152 -15
  209. package/dist/ws-chat-transport-rWwta645.js.map +1 -0
  210. package/docs/agent-class.md +29 -87
  211. package/docs/agent-tools.md +2 -1
  212. package/docs/channels.md +323 -0
  213. package/docs/chat-agents.md +19 -25
  214. package/docs/context.md +131 -0
  215. package/docs/durable-execution.md +1 -1
  216. package/docs/http-websockets.md +1 -11
  217. package/docs/human-in-the-loop.md +1 -1
  218. package/docs/index.md +16 -12
  219. package/docs/lifecycle.md +370 -0
  220. package/docs/long-running-agents.md +4 -6
  221. package/docs/mcp-client.md +55 -0
  222. package/docs/mcp-servers.md +5 -1
  223. package/docs/observability.md +11 -11
  224. package/docs/resumable-streaming.md +2 -2
  225. package/docs/routing.md +105 -0
  226. package/docs/scheduling.md +175 -15
  227. package/docs/server-driven-messages.md +1 -1
  228. package/docs/sessions.md +237 -871
  229. package/docs/streams.md +213 -0
  230. package/docs/sub-agents.md +185 -125
  231. package/docs/tasks.md +246 -0
  232. package/docs/voice.md +745 -0
  233. package/package.json +144 -33
  234. package/dist/cli/index.js +0 -26
  235. package/dist/cli/index.js.map +0 -1
  236. package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
  237. package/dist/client-zqKcsyFa.js.map +0 -1
  238. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  239. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  240. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  241. package/dist/experimental/memory/session/index.d.ts +0 -670
  242. package/dist/experimental/memory/session/index.js +0 -2374
  243. package/dist/experimental/memory/session/index.js.map +0 -1
  244. package/dist/experimental/memory/utils/index.d.ts +0 -96
  245. package/dist/experimental/memory/utils/index.js +0 -79
  246. package/dist/experimental/memory/utils/index.js.map +0 -1
  247. package/dist/handler-stateless-CIkKPETH.js.map +0 -1
  248. package/dist/index.js.map +0 -1
  249. package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
  250. package/dist/internal_context.js.map +0 -1
  251. package/dist/mcp/client.d.ts +0 -42
  252. package/dist/mcp/do-oauth-client-provider.js.map +0 -1
  253. package/dist/mcp/x402.js.map +0 -1
  254. package/dist/protocol-Dqc2MQxo.js.map +0 -1
  255. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  256. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
  257. package/dist/ws-chat-transport-CIoOBbO7.js.map +0 -1
  258. /package/dist/{cli/index.d.ts → index-BVVgDSdq.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-DlSHshb2.js","names":["bridge","agentContext","getCurrentLifecycleAgent","DynamicAgentsApi","subAgentRpcReplyContext","_parseSubAgentPath","workerExports"],"sources":["../src/dynamic-agents/bridges.ts","../src/dynamic-agents/identity.ts","../src/dynamic-agents/registry.ts","../src/dynamic-agents/dynamic-agents.ts","../src/dynamic-agents/api.ts","../src/observability/agent-span-attributes.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { RpcTarget } from \"cloudflare:workers\";\nimport type { Connection } from \"../lifecycle/durable-object-lifecycle\";\nimport type { RPCResponse, StreamingResponse } from \"../index\";\nimport type {\n RootFacetRpcSurface,\n DynamicAgentConnectionBridgeLike\n} from \"./types\";\n\n// ── Facet RPC reply bridging ─────────────────────────────────────────\n//\n// A `@callable` invoked on a facet must deliver its reply (including\n// streamed chunks) onto the RPC frame that carried the request into the\n// facet — not onto the root-owned native WebSocket directly. The ALS\n// below carries the per-invocation reply bridge; it MUST stay a single\n// module-level instance shared by the Agent host and this module, or\n// reply routing silently breaks.\n\nexport function isClosedWebSocketSendError(error: unknown): boolean {\n return (\n error instanceof TypeError &&\n error.message.includes(\"WebSocket send() after close\")\n );\n}\n\ntype RPCReplyTarget = {\n send(message: string | ArrayBuffer | ArrayBufferView): void | Promise<void>;\n};\n\ntype FacetRPCResponseDelivery = {\n sent: boolean;\n completion: Promise<void>;\n};\n\nexport type DynamicAgentRpcReplyInvocationContext = {\n bridge?: DynamicAgentConnectionBridge;\n};\n\nexport const dynamicAgentRpcReplyContext =\n new AsyncLocalStorage<DynamicAgentRpcReplyInvocationContext>();\n\nexport function sendFacetRpcResponseIfOpen(\n target: RPCReplyTarget,\n response: RPCResponse\n): FacetRPCResponseDelivery {\n try {\n const completion = Promise.resolve(\n target.send(JSON.stringify(response))\n ).catch((error: unknown) => {\n if (!isClosedWebSocketSendError(error)) {\n console.error(\"[Agent] Facet RPC response delivery failed:\", error);\n }\n });\n return { sent: true, completion };\n } catch (error) {\n if (isClosedWebSocketSendError(error)) {\n return { sent: false, completion: Promise.resolve() };\n }\n throw error;\n }\n}\n\ntype FacetStreamingResponseDeliveryState = {\n replyTarget: RPCReplyTarget;\n pending: Set<Promise<void>>;\n};\n\nconst facetStreamingResponseDeliveryStates = new WeakMap<\n StreamingResponse,\n FacetStreamingResponseDeliveryState\n>();\n\n/**\n * Mark a StreamingResponse as facet-bridged: its chunks are delivered to\n * `replyTarget` (the RPC frame that carried the request into the facet)\n * instead of the connection's native WebSocket.\n */\nexport function registerFacetStreamingDelivery(\n stream: StreamingResponse,\n replyTarget: RPCReplyTarget\n): void {\n facetStreamingResponseDeliveryStates.set(stream, {\n replyTarget,\n pending: new Set()\n });\n}\n\n/**\n * Deliver one streamed RPC response for a facet-bridged stream, tracking\n * its completion. Returns null when the stream is not facet-bridged (the\n * caller should send on the native connection instead).\n */\nexport function sendFacetStreamingResponse(\n stream: StreamingResponse,\n response: RPCResponse\n): boolean | null {\n const state = facetStreamingResponseDeliveryStates.get(stream);\n if (!state) return null;\n\n const delivery = sendFacetRpcResponseIfOpen(state.replyTarget, response);\n state.pending.add(delivery.completion);\n void delivery.completion.finally(() =>\n state.pending.delete(delivery.completion)\n );\n return delivery.sent;\n}\n\nexport async function waitForFacetStreamingResponseDeliveries(\n stream: StreamingResponse\n): Promise<void> {\n const state = facetStreamingResponseDeliveryStates.get(stream);\n if (!state) return;\n\n try {\n await Promise.all(state.pending);\n } finally {\n facetStreamingResponseDeliveryStates.delete(stream);\n }\n}\n\n/**\n * Parent-side bridge handed to a facet over RPC: wraps a live root-owned\n * `Connection` so the facet can send/close/setState on it, and carries\n * the root's broadcast entry point for facet-scoped broadcasts.\n */\nexport class DynamicAgentConnectionBridge\n extends RpcTarget\n implements DynamicAgentConnectionBridgeLike\n{\n #connection: Connection;\n #broadcast?: (\n ownerPath: ReadonlyArray<{ className: string; name: string }>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ) => void | Promise<void>;\n\n constructor(\n connection: Connection,\n broadcast?: (\n ownerPath: ReadonlyArray<{ className: string; name: string }>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ) => void | Promise<void>\n ) {\n super();\n this.#connection = connection;\n this.#broadcast = broadcast;\n }\n\n send(message: string | ArrayBuffer | ArrayBufferView): void {\n this.#connection.send(message);\n }\n\n close(code?: number, reason?: string): void {\n this.#connection.close(code, reason);\n }\n\n setState(state: unknown): unknown {\n return this.#connection.setState(state);\n }\n\n broadcast(\n ownerPath: ReadonlyArray<{ className: string; name: string }>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): void | Promise<void> {\n return this.#broadcast?.(ownerPath, message, without);\n }\n}\n\n/**\n * Facet-side bridge used after the originating RPC frame has completed:\n * routes connection operations back to the root over a fresh RPC call.\n */\nexport class RootDynamicAgentConnectionBridge implements DynamicAgentConnectionBridgeLike {\n #root: RootFacetRpcSurface;\n #connectionId: string;\n\n constructor(root: RootFacetRpcSurface, connectionId: string) {\n this.#root = root;\n this.#connectionId = connectionId;\n }\n\n send(message: string | ArrayBuffer | ArrayBufferView): Promise<void> {\n return this.#root._cf_sendToSubAgentConnection(this.#connectionId, message);\n }\n\n close(code?: number, reason?: string): Promise<void> {\n return this.#root._cf_closeSubAgentConnection(\n this.#connectionId,\n code,\n reason\n );\n }\n\n setState(state: unknown): Promise<unknown> {\n return this.#root._cf_setSubAgentConnectionState(this.#connectionId, state);\n }\n\n broadcast(\n ownerPath: ReadonlyArray<{ className: string; name: string }>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): Promise<void> {\n return this.#root._cf_broadcastToSubAgent(ownerPath, message, without);\n }\n}\n","import type { AgentPathStep } from \"../sub-routing\";\n\n// ── Facet identity versioning ────────────────────────────────────────\n//\n// These strings are stored in DO storage and embedded in facet identity\n// names — they are wire/storage-frozen and must never be renamed.\n\nexport const SUB_AGENT_IDENTITY_VERSION_LEGACY = \"legacy\";\nexport const SUB_AGENT_IDENTITY_VERSION_PATH_V2 = \"path-v2\";\nexport const SUB_AGENT_IDENTITY_PATH_V2_PREFIX = \"cf-agents:v2:\";\n\nexport type SubAgentIdentityVersion =\n | typeof SUB_AGENT_IDENTITY_VERSION_LEGACY\n | typeof SUB_AGENT_IDENTITY_VERSION_PATH_V2;\n\nexport async function sha256Hex(value: string): Promise<string> {\n const bytes = new TextEncoder().encode(value);\n const digest = await crypto.subtle.digest(\"SHA-256\", bytes);\n return [...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nexport function pathV2IdentityName(\n logicalName: string,\n digest: string\n): string {\n return `${SUB_AGENT_IDENTITY_PATH_V2_PREFIX}${encodeURIComponent(logicalName)}:${digest}`;\n}\n\nexport function logicalNameFromPathV2Identity(\n identityName: string\n): string | null {\n if (!identityName.startsWith(SUB_AGENT_IDENTITY_PATH_V2_PREFIX)) {\n return null;\n }\n const rest = identityName.slice(SUB_AGENT_IDENTITY_PATH_V2_PREFIX.length);\n const separator = rest.lastIndexOf(\":\");\n if (separator === -1) return null;\n\n try {\n return decodeURIComponent(rest.slice(0, separator));\n } catch {\n return null;\n }\n}\n\n/**\n * Validate that a stored `parentPath` has the expected shape. Used\n * when restoring from DO storage to guard against corrupted data.\n */\nexport function isValidParentPath(\n value: unknown\n): value is Array<{ className: string; name: string }> {\n if (!Array.isArray(value)) return false;\n return value.every(\n (entry) =>\n entry != null &&\n typeof entry === \"object\" &&\n typeof (entry as { className?: unknown }).className === \"string\" &&\n typeof (entry as { name?: unknown }).name === \"string\"\n );\n}\n\nexport function agentPathKey(\n path: ReadonlyArray<AgentPathStep> | null\n): string | null {\n if (!path) return null;\n return path\n .map(\n (step) =>\n `${encodeURIComponent(step.className)}:${encodeURIComponent(step.name)}`\n )\n .join(\"/\");\n}\n","import type { AgentPathStep } from \"../sub-routing\";\nimport {\n pathV2IdentityName,\n sha256Hex,\n SUB_AGENT_IDENTITY_VERSION_LEGACY,\n SUB_AGENT_IDENTITY_VERSION_PATH_V2,\n type SubAgentIdentityVersion\n} from \"./identity\";\n\n/**\n * SQL access the registry needs from its owning Agent: the tagged\n * template helper plus raw DDL execution (for additive column\n * migrations whose errors must be inspected).\n */\nexport type DynamicAgentRegistrySqlHost = {\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ): T[];\n execRawSql(sql: string): void;\n};\n\n/**\n * The parent-side registry of spawned dynamic agents (facets), stored\n * in the parent's own SQLite. Backs `hasSubAgent` / `listSubAgents`\n * and the identity-versioning decision (legacy bare-name facets vs\n * path-scoped v2 identities).\n *\n * Table and column names are storage-frozen — never rename them.\n */\nexport class DynamicAgentRegistry {\n #host: DynamicAgentRegistrySqlHost;\n #ready = false;\n\n constructor(host: DynamicAgentRegistrySqlHost) {\n this.#host = host;\n }\n\n #addColumnIfNotExists(sql: string): void {\n try {\n this.#host.execRawSql(sql);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n if (!message.toLowerCase().includes(\"duplicate column\")) {\n throw e;\n }\n }\n }\n\n ensure(): void {\n if (this.#ready) return;\n // This registry is lazy because older agents may never create sub-agents.\n // Keep its additive column migrations here instead of the global schema\n // gate so first sub-agent access upgrades legacy registry tables in place.\n this.#host.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_sub_agents (\n class TEXT NOT NULL,\n name TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n identity_version TEXT,\n identity_name TEXT,\n PRIMARY KEY (class, name)\n )\n `;\n this.#addColumnIfNotExists(\n \"ALTER TABLE cf_agents_sub_agents ADD COLUMN identity_version TEXT\"\n );\n this.#addColumnIfNotExists(\n \"ALTER TABLE cf_agents_sub_agents ADD COLUMN identity_name TEXT\"\n );\n this.#ready = true;\n }\n\n record(\n className: string,\n name: string,\n identity: { version: SubAgentIdentityVersion; name: string }\n ): void {\n this.ensure();\n this.#host.sql`\n INSERT OR IGNORE INTO cf_agents_sub_agents\n (class, name, created_at, identity_version, identity_name)\n VALUES\n (${className}, ${name}, ${Date.now()}, ${identity.version}, ${identity.name})\n `;\n }\n\n row(\n className: string,\n name: string\n ): {\n identity_version: string | null;\n identity_name: string | null;\n } | null {\n this.ensure();\n const rows = this.#host.sql<{\n identity_version: string | null;\n identity_name: string | null;\n }>`\n SELECT identity_version, identity_name\n FROM cf_agents_sub_agents\n WHERE class = ${className} AND name = ${name}\n LIMIT 1\n `;\n return rows[0] ?? null;\n }\n\n async identity(\n className: string,\n name: string,\n childPath: ReadonlyArray<AgentPathStep>\n ): Promise<{\n version: SubAgentIdentityVersion;\n name: string;\n existing: boolean;\n }> {\n const row = this.row(className, name);\n if (row) {\n if (\n row.identity_version === SUB_AGENT_IDENTITY_VERSION_PATH_V2 &&\n typeof row.identity_name === \"string\"\n ) {\n return {\n version: SUB_AGENT_IDENTITY_VERSION_PATH_V2,\n name: row.identity_name,\n existing: true\n };\n }\n return {\n version: SUB_AGENT_IDENTITY_VERSION_LEGACY,\n name,\n existing: true\n };\n }\n\n // Do not probe the legacy bare-name facet here. `ctx.facets.get()` is\n // create-on-access, so probing would create or wake legacy storage as a\n // side effect and could reintroduce old id collisions. Existing registry\n // rows remain the compatibility signal; new rows use path-v2.\n const digest = await sha256Hex(JSON.stringify(childPath));\n return {\n version: SUB_AGENT_IDENTITY_VERSION_PATH_V2,\n name: pathV2IdentityName(name, digest),\n existing: false\n };\n }\n\n forget(className: string, name: string): void {\n this.ensure();\n this.#host.sql`\n DELETE FROM cf_agents_sub_agents\n WHERE class = ${className} AND name = ${name}\n `;\n }\n\n has(className: string, name: string): boolean {\n this.ensure();\n const rows = this.#host.sql<{ n: number }>`\n SELECT COUNT(*) AS n FROM cf_agents_sub_agents\n WHERE class = ${className} AND name = ${name}\n `;\n return (rows[0]?.n ?? 0) > 0;\n }\n\n list(\n className?: string\n ): Array<{ className: string; name: string; createdAt: number }> {\n this.ensure();\n const rows = className\n ? this.#host.sql<{ class: string; name: string; created_at: number }>`\n SELECT class, name, created_at FROM cf_agents_sub_agents\n WHERE class = ${className}\n ORDER BY created_at ASC\n `\n : this.#host.sql<{ class: string; name: string; created_at: number }>`\n SELECT class, name, created_at FROM cf_agents_sub_agents\n ORDER BY created_at ASC\n `;\n return rows.map((r) => ({\n className: r.class,\n name: r.name,\n createdAt: r.created_at\n }));\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\nimport type {\n Connection,\n LifecycleRouteEnvelope,\n WSMessage\n} from \"../lifecycle/durable-object-lifecycle\";\nimport {\n LifecycleCapability,\n type LifecycleRouteAddress\n} from \"../lifecycle/capability\";\nimport {\n SUB_PREFIX,\n parseSubAgentPath,\n type AgentPathStep\n} from \"../sub-routing\";\nimport { getAgentByName } from \"../agent-routing\";\nimport { camelCaseToKebabCase, isInternalJsStubProp } from \"../utils\";\nimport type { Agent } from \"../index\";\nimport { agentPathKey, isValidParentPath } from \"./identity\";\nimport { DynamicAgentRegistry } from \"./registry\";\nimport {\n DynamicAgentConnectionBridge,\n RootDynamicAgentConnectionBridge,\n dynamicAgentRpcReplyContext,\n type DynamicAgentRpcReplyInvocationContext\n} from \"./bridges\";\nimport type { DynamicAgentHostPort } from \"./host\";\nimport type {\n DynamicAgentBridgeInvocationContext,\n DynamicAgentConnectionBridgeLike,\n DynamicAgentConnectionMeta,\n DynamicAgentConnectionOperationName,\n DynamicAgentPathInvokeEndpoint,\n DynamicAgentWebSocketEndpoint,\n FacetCapableCtx,\n FacetRunStorageRow,\n RootFacetRpcSurface,\n StoredDynamicAgentConnection\n} from \"./types\";\n\n/**\n * Internal key used to remember the outer `/sub/...` URL for a\n * WebSocket accepted by the parent on behalf of a child facet.\n * Hibernated events then wake the parent, which forwards frames to\n * the child over serializable RPC while keeping native WebSocket I/O\n * parent-owned.\n *\n * Storage-frozen — never rename.\n */\nexport const CF_SUB_AGENT_OUTER_URL_KEY = \"_cf_subAgentOuterUrl\";\nexport const CF_SUB_AGENT_TAGS_KEY = \"_cf_subAgentTags\";\n\n/** Wire-frozen internal header carrying the outer URL on WS upgrades. */\nexport const SUB_AGENT_OUTER_URL_HEADER = \"x-cf-agents-subagent-url\";\n\n/**\n * The facet-backed dynamic-agent machinery, extracted from the Agent\n * class. One instance per Agent, installed as a Lifecycle capability\n * (`capabilityId: \"dynamic-agents\"`); the host port documents exactly\n * which Agent internals it touches.\n *\n * The capability claims no runner hooks — four integration points are\n * deliberately wired directly through the Agent composition root\n * instead, because the runner's dispatch contract cannot express them:\n * the `/sub/` upgrade path rewrites the request and *continues* into\n * `lifecycle.fetch` (onRequest can only claim), forwarded WS frames run\n * inside the host's onMessage wrapper *after* the WebSockets capability\n * has claimed the wake, this module *implements* the lifecycle route\n * transport rather than consuming it, and facet-context restore has\n * load-bearing startup ordering inside the host's startup span.\n *\n * Nothing here renames any wire- or storage-visible identifier: the\n * `cf_agents_facet_runs` table, `_cf_*` RPC method names, and route\n * key formats are frozen.\n *\n * @internal\n */\nexport class DynamicAgentsInternal extends LifecycleCapability {\n #host: DynamicAgentHostPort;\n\n /** The parent-side registry of spawned dynamic agents. */\n readonly registry: DynamicAgentRegistry;\n\n /**\n * Root-owned keepAlive tokens held on behalf of descendant facets.\n * Facets cannot arm a physical alarm, so their keepAlive refs ride\n * on the root's heartbeat.\n */\n #facetKeepAliveTokens = new Set<string>();\n\n /** Per-frame bridge context while a forwarded WS event runs in a facet. */\n #bridgeContext = new AsyncLocalStorage<DynamicAgentBridgeInvocationContext>();\n\n /**\n * Facet-side virtual connections: real WebSockets owned by the ROOT\n * DO, mirrored here as `Connection`-shaped objects whose operations\n * route back through the live frame bridge or the root over RPC.\n */\n #virtualConnections = new Map<string, StoredDynamicAgentConnection>();\n\n /** Per-connection operation queues (send/setState/close ordering). */\n #connectionOperationTails = new Map<string, Promise<void>>();\n\n /** One-way barrier so facet broadcasts wait for older queued operations. */\n #broadcastOperationTail?: Promise<void>;\n\n constructor(host: DynamicAgentHostPort) {\n super(\"dynamic-agents\");\n this.#host = host;\n this.registry = new DynamicAgentRegistry({\n sql: host.sql.bind(host),\n execRawSql: (sql) => void host.ctx.storage.sql.exec(sql)\n });\n }\n\n runRowsForPrefix(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): FacetRunStorageRow[] {\n const rows = this.#host.sql<FacetRunStorageRow>`\n SELECT owner_path, owner_path_key, run_id, created_at\n FROM cf_agents_facet_runs\n `;\n return rows.filter((row) => {\n try {\n const rowOwnerPath = JSON.parse(row.owner_path) as AgentPathStep[];\n return this.#host._isSameAgentPathPrefix(ownerPath, rowOwnerPath);\n } catch {\n return false;\n }\n });\n }\n\n deleteRunRowsForPrefix(ownerPath: ReadonlyArray<AgentPathStep>): void {\n for (const row of this.runRowsForPrefix(ownerPath)) {\n this.#host.sql`\n DELETE FROM cf_agents_facet_runs\n WHERE owner_path_key = ${row.owner_path_key}\n AND run_id = ${row.run_id}\n `;\n }\n }\n\n lifecycleRouteAddress(): LifecycleRouteAddress | undefined {\n if (!this.#host._isFacet) return undefined;\n const key = agentPathKey(this.#host.selfPath);\n return key ? { key, data: JSON.stringify(this.#host.selfPath) } : undefined;\n }\n\n async routeLifecycleToRoot(\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n if (!this.#host._isFacet) return this.#host.lifecycle.route(envelope);\n return (await this.rootAlarmOwner())._cf_routeLifecycle(\n undefined,\n envelope\n );\n }\n\n async routeLifecycleToTarget(\n target: LifecycleRouteAddress,\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n let targetPath: AgentPathStep[];\n try {\n targetPath = JSON.parse(target.data) as AgentPathStep[];\n } catch {\n throw new Error(\"Lifecycle route target is not a valid Agent path\");\n }\n\n const selfPath = this.#host.selfPath;\n if (!this.#host._isSameAgentPathPrefix(selfPath, targetPath)) {\n throw new Error(\n `Lifecycle route does not descend from ${JSON.stringify(selfPath)}.`\n );\n }\n if (selfPath.length === targetPath.length) {\n return this.#host.lifecycle.route(envelope);\n }\n\n const next = targetPath[selfPath.length];\n if (!this.#host.hasSubAgent(next.className, next.name)) {\n const stalePath = targetPath.slice(0, selfPath.length + 1);\n if (this.#host._isFacet) {\n await (await this.rootAlarmOwner())._cf_cleanupFacetPrefix(stalePath);\n } else {\n await this.#host._cf_cleanupFacetPrefix(stalePath);\n }\n return false;\n }\n\n const child = await this.#host._cf_resolveSubAgent(\n next.className,\n next.name\n );\n return (\n child as unknown as {\n _cf_routeLifecycle(\n target: LifecycleRouteAddress,\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown>;\n }\n )._cf_routeLifecycle(target, envelope);\n }\n\n /** Body of the single native-RPC aperture for routed Lifecycle capabilities. */\n routeLifecycle(\n target: LifecycleRouteAddress | undefined,\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n return target\n ? this.routeLifecycleToTarget(target, envelope)\n : this.#host.lifecycle.route(envelope);\n }\n\n async rootAlarmOwner(): Promise<RootFacetRpcSurface> {\n const root = this.#host._parentPath[0];\n if (!root) {\n throw new Error(\"Facet routing requires a root parent.\");\n }\n\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n const binding = ctx.exports?.[root.className] as\n | DurableObjectNamespace\n | undefined;\n if (!binding) {\n throw new Error(\n `Unable to resolve root \"${root.className}\" for facet routing.`\n );\n }\n\n return (await getAgentByName<Cloudflare.Env, Agent>(\n binding as unknown as DurableObjectNamespace<Agent>,\n root.name\n )) as unknown as RootFacetRpcSurface;\n }\n\n rootResolvesToSelf(): boolean {\n const root = this.#host._parentPath[0];\n if (!root) return false;\n\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n const binding = ctx.exports?.[root.className] as\n | DurableObjectNamespace\n | undefined;\n if (!binding?.idFromName) return false;\n\n return binding.idFromName(root.name).equals(this.#host.ctx.id);\n }\n\n /**\n * Clean root-owned bookkeeping for a sub-tree of facets: bulk-cancel\n * schedules and routed Task wake mirrors under the owner-path prefix,\n * and delete root-side facet fiber recovery leases for the same sub-tree.\n */\n async cleanupPrefix(ownerPath: ReadonlyArray<AgentPathStep>): Promise<void> {\n const prefix = agentPathKey(ownerPath);\n if (prefix) {\n await this.#host.scheduler.__DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(\n prefix\n );\n await this.#host.tasks.__DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(\n prefix\n );\n }\n this.deleteRunRowsForPrefix(ownerPath);\n await this.#host._syncHostJobs();\n }\n\n /**\n * Acquire a root-owned keepAlive ref on behalf of a descendant facet.\n */\n async acquireKeepAlive(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<string> {\n const ownerPathKey = agentPathKey(ownerPath);\n const token = `${ownerPathKey ?? \"unknown\"}:${nanoid(9)}`;\n this.#facetKeepAliveTokens.add(token);\n this.#host._keepAliveRefs++;\n if (this.#host._keepAliveRefs === 1) {\n await this.#host._syncHostJobs();\n }\n return token;\n }\n\n /**\n * Release a root-owned keepAlive ref previously acquired for a facet.\n * Idempotent so disposer calls can safely race or run twice.\n */\n async releaseKeepAlive(token: string): Promise<void> {\n if (!this.#facetKeepAliveTokens.delete(token)) return;\n this.#host._keepAliveRefs = Math.max(0, this.#host._keepAliveRefs - 1);\n await this.#host._syncHostJobs();\n }\n\n /**\n * Register a facet's durable run row in the root-side index so root\n * alarm housekeeping can dispatch recovery checks into idle facets.\n */\n async registerRun(\n ownerPath: ReadonlyArray<AgentPathStep>,\n runId: string\n ): Promise<void> {\n const ownerPathJson = JSON.stringify(ownerPath);\n const ownerPathKey = agentPathKey(ownerPath);\n if (!ownerPathKey) {\n throw new Error(\"_cf_registerFacetRun requires a non-empty owner path.\");\n }\n this.#host.sql`\n INSERT OR REPLACE INTO cf_agents_facet_runs\n (owner_path, owner_path_key, run_id, created_at)\n VALUES\n (${ownerPathJson}, ${ownerPathKey}, ${runId}, ${Date.now()})\n `;\n await this.#host._syncHostJobs();\n }\n\n /**\n * Root-side scan for durable fibers owned by descendant facets.\n * `cf_agents_facet_runs` is only an index; actual snapshots and\n * recovery hooks live in each facet's own `cf_agents_runs` table.\n */\n async checkRunFibers(): Promise<void> {\n // Only the root owns the physical alarm and facet-run index.\n if (this.#host._parentPath.length > 0) return;\n\n const rows = this.#host.sql<FacetRunStorageRow>`\n SELECT owner_path, owner_path_key, run_id, created_at\n FROM cf_agents_facet_runs\n ORDER BY created_at ASC\n `;\n const firstRowByOwner = new Map<string, FacetRunStorageRow>();\n for (const row of rows) {\n if (!firstRowByOwner.has(row.owner_path_key)) {\n firstRowByOwner.set(row.owner_path_key, row);\n }\n }\n\n for (const row of firstRowByOwner.values()) {\n let ownerPath: AgentPathStep[];\n try {\n ownerPath = JSON.parse(row.owner_path) as AgentPathStep[];\n } catch (e) {\n console.warn(\n `[Agent] Corrupted facet fiber owner path for ${row.owner_path_key}; pruning stale lease.`,\n e\n );\n this.#host.sql`\n DELETE FROM cf_agents_facet_runs\n WHERE owner_path_key = ${row.owner_path_key}\n `;\n continue;\n }\n\n try {\n // Dispatch through the host so subclass overrides of the\n // `_cf_checkRunFibersForFacet` RPC entry point keep intercepting.\n const remaining =\n await this.#host._cf_checkRunFibersForFacet(ownerPath);\n if (remaining === 0) {\n this.#host.sql`\n DELETE FROM cf_agents_facet_runs\n WHERE owner_path_key = ${row.owner_path_key}\n `;\n }\n } catch (e) {\n // Keep the lease so a transient failure (e.g. facet init error)\n // gets retried on the next root heartbeat.\n console.error(\n `[Agent] Facet fiber recovery check failed for ${row.owner_path_key}:`,\n e\n );\n }\n }\n }\n\n /**\n * Dispatch a runFiber recovery check into the facet identified by\n * `ownerPath`. Returns the number of remaining local `cf_agents_runs`\n * rows on the target facet after recovery.\n */\n async checkRunFibersAtPath(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<number> {\n const selfPath = this.#host.selfPath;\n if (!this.#host._isSameAgentPathPrefix(selfPath, ownerPath)) {\n throw new Error(\n `Facet fiber owner path does not descend from ${JSON.stringify(selfPath)}.`\n );\n }\n\n if (selfPath.length === ownerPath.length) {\n await this.#host._checkRunFibers();\n const rows = this.#host.sql<{ count: number }>`\n SELECT COUNT(*) as count FROM cf_agents_runs\n `;\n return rows[0]?.count ?? 0;\n }\n\n const next = ownerPath[selfPath.length];\n if (!this.#host.hasSubAgent(next.className, next.name)) {\n // The facet was deleted or its registry was cleared. The root\n // should prune the root-side lease; there is no remaining child\n // storage to recover through the public registry path.\n return 0;\n }\n\n const stub = await this.resolve(next.className, next.name);\n const handle = stub as unknown as {\n _cf_checkRunFibersForFacet(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<number>;\n };\n return handle._cf_checkRunFibersForFacet(ownerPath);\n }\n\n /**\n * Invoke an RPC method on the host Agent or a descendant facet\n * identified by a root-first path. Used by AgentWorkflow to route\n * callbacks and `this.agent` calls back to the exact sub-agent that\n * started a workflow.\n */\n async invokeAgentPath(\n targetPath: ReadonlyArray<AgentPathStep>,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n await this.#host.__unsafe_ensureInitialized();\n\n const selfPath = this.#host.selfPath;\n if (!this.#host._isSameAgentPathPrefix(selfPath, targetPath)) {\n throw new Error(\n `Workflow origin path does not descend from ${JSON.stringify(selfPath)}.`\n );\n }\n\n if (selfPath.length === targetPath.length) {\n // Match real DO-stub RPC semantics: refuse JS-internal probes\n // (`constructor`, `toString`, symbol keys, thenable checks, …) and\n // anything inherited from `Object.prototype` so a facet-origin workflow\n // cannot reach a method surface a top-level workflow's stub would deny.\n // The framework's own `_workflow_*` / `_cf_*` RPC methods and any\n // user-defined Agent methods live on the subclass prototype, not\n // `Object.prototype`, so they remain callable.\n const target = this.#host as unknown as Record<string, unknown>;\n const fn = target[method];\n if (\n isInternalJsStubProp(method) ||\n method in Object.prototype ||\n typeof fn !== \"function\"\n ) {\n throw new Error(\n `Workflow origin method \"${method}\" is not callable on ${\n (this.#host as unknown as { constructor: { name: string } })\n .constructor.name\n }.`\n );\n }\n return await (fn as (...methodArgs: unknown[]) => unknown).apply(\n this.#host,\n args\n );\n }\n\n const next = targetPath[selfPath.length];\n if (!this.#host.hasSubAgent(next.className, next.name)) {\n throw new Error(\n `Workflow origin sub-agent ${next.className} \"${next.name}\" no longer exists.`\n );\n }\n\n const stub = await this.resolve(next.className, next.name);\n const handle = stub as unknown as {\n _cf_invokeAgentPath(\n path: ReadonlyArray<AgentPathStep>,\n method: string,\n args: unknown[]\n ): Promise<unknown>;\n };\n return await handle._cf_invokeAgentPath(targetPath, method, args);\n }\n\n /**\n * Recursively destroy a descendant facet identified by `targetPath`.\n * Walks down from `selfPath` until reaching the target's immediate\n * parent, where it cancels the target's parent-owned schedules (and\n * any descendants), removes the target from the registry, and calls\n * `ctx.facets.delete` to wipe the target's storage.\n */\n async destroyDescendant(\n targetPath: ReadonlyArray<AgentPathStep>\n ): Promise<void> {\n const selfPath = this.#host.selfPath;\n\n if (targetPath.length === 0) {\n throw new Error(\n \"_cf_destroyDescendantFacet: target path must not be empty.\"\n );\n }\n if (selfPath.length >= targetPath.length) {\n throw new Error(\n \"_cf_destroyDescendantFacet: target must be a strict descendant.\"\n );\n }\n if (!this.#host._isSameAgentPathPrefix(selfPath, targetPath)) {\n throw new Error(\n \"_cf_destroyDescendantFacet: target path does not descend from this agent.\"\n );\n }\n\n // The root owns every schedule row; cancel the target's prefix\n // upfront so we don't have to make an extra round trip back from\n // each intermediate hop.\n if (this.#host._parentPath.length === 0) {\n await this.#host._cf_cleanupFacetPrefix(targetPath);\n }\n\n if (selfPath.length === targetPath.length - 1) {\n // We are the immediate parent of the target — perform the local\n // facet teardown the same way `delete` does.\n const target = targetPath[targetPath.length - 1];\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n if (!ctx.facets) {\n throw new Error(\n \"destroy() (delegated from facet) is not supported in this runtime — \" +\n \"`ctx.facets` is unavailable. \" +\n \"Update to the latest `compatibility_date` in your wrangler.jsonc.\"\n );\n }\n try {\n ctx.facets.delete(`${target.className}\\0${target.name}`);\n } catch {\n // no-op — facet wasn't registered (already deleted / never spawned)\n }\n this.registry.forget(target.className, target.name);\n return;\n }\n\n // Recurse one step deeper.\n const next = targetPath[selfPath.length];\n if (!this.#host.hasSubAgent(next.className, next.name)) {\n // Already gone — schedules are cleared, nothing more to do.\n return;\n }\n const stub = await this.resolve(next.className, next.name);\n const handle = stub as unknown as {\n _cf_destroyDescendantFacet(\n targetPath: ReadonlyArray<AgentPathStep>\n ): Promise<void>;\n };\n await handle._cf_destroyDescendantFacet(targetPath);\n }\n\n /**\n * Shared facet resolution — takes a CamelCase class name string\n * (matching `ctx.exports`) rather than a class reference. Both\n * `subAgent(cls, name)` and `_cf_invokeSubAgent(className, ...)`\n * funnel through here so registry bookkeeping and the\n * `_cf_initAsFacet` handshake are consistent.\n */\n async resolve(className: string, name: string): Promise<unknown> {\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n if (!ctx.facets || !ctx.exports) {\n throw new Error(\n \"subAgent() is not supported in this runtime — \" +\n \"`ctx.facets` / `ctx.exports` are unavailable. \" +\n \"Update to the latest `compatibility_date` in your wrangler.jsonc.\"\n );\n }\n if (camelCaseToKebabCase(className) === SUB_PREFIX) {\n // Any class whose kebab-cased name equals the `sub` URL\n // separator would make `/agents/.../sub/sub/...` ambiguous.\n // `Sub`, `SUB`, and `Sub_` all kebab-case to `\"sub\"` — catch\n // them uniformly rather than listing each spelling.\n throw new Error(\n `Sub-agent class name \"${className}\" kebab-cases to \"${SUB_PREFIX}\", ` +\n `which collides with the reserved URL separator — rename the ` +\n `class (e.g. \"SubThing\" or \"Subtask\").`\n );\n }\n const Cls = ctx.exports[className];\n if (!Cls) {\n throw new Error(\n `Sub-agent class \"${className}\" not found in worker exports. ` +\n `Make sure the class is exported from your worker entry point ` +\n `and that the export name matches the class name.`\n );\n }\n if (name.includes(\"\\0\")) {\n // Null char is reserved for the facet composite key delimiter —\n // letting it through would corrupt the `${class}\\0${name}` key.\n throw new Error(\n `Sub-agent name contains null character (\\\\0), which is reserved.`\n );\n }\n // Composite key: class name + NUL + facet name, so two different\n // classes can share the same user-facing name.\n const facetKey = `${className}\\0${name}`;\n\n // Derive the child's ancestor chain: our own `parentPath` +\n // `{ class: this.constructor.name, name: this.name }`. Inductive\n // across recursive nesting.\n const childParentPath = this.#host.selfPath;\n const childPath = [...childParentPath, { className, name }];\n\n // For nested facets, the immediate parent is itself facet-only\n // and is not expected to expose namespace helpers. Use the root\n // supervisor namespace instead; path-v2 identities are scoped to\n // the full logical path while legacy rows continue using bare names.\n const rootClassName =\n this.#host._parentPath[0]?.className ??\n (this.#host as unknown as { constructor: { name: string } }).constructor\n .name;\n const rootNs = ctx.exports[rootClassName];\n if (!rootNs?.idFromName) {\n // Minification is the most common cause of this error in\n // production builds: aggressive bundlers rewrite class\n // identifiers to short ids, so `this.constructor.name`\n // becomes something like `_a` and the ctx.exports lookup\n // misses. Detect that case and append a hint, otherwise\n // the message is mysterious.\n //\n // Heuristic: optional leading underscore(s), then 1–3\n // lowercase letters/digits starting with a letter (e.g.\n // `_a`, `_ab`, `_a1`, `__a`). Real class names like\n // `MyAgent` or `_UnboundParent` start with an uppercase\n // letter and won't match.\n const looksMinified = /^_*[a-z][a-z0-9]{0,2}$/.test(rootClassName);\n const minificationHint = looksMinified\n ? ` The class name \"${rootClassName}\" looks minified — make sure your bundler preserves class names (e.g. esbuild's \\`keepNames: true\\`).`\n : \"\";\n throw new Error(\n `Sub-agent bootstrap requires the root agent class \"${rootClassName}\" to be available as a Durable Object namespace, but ctx.exports[\"${rootClassName}\"] is missing or doesn't expose idFromName.${minificationHint} Make sure the root agent class is exported under that class name and registered in your wrangler.jsonc durable_objects.bindings.`\n );\n }\n const identity = await this.registry.identity(className, name, childPath);\n const facetId = rootNs.idFromName(identity.name);\n const stub = ctx.facets.get(facetKey, () => ({\n class: Cls as DurableObjectClass,\n id: facetId\n }));\n\n // Record before initialization so a successfully-initialized facet is\n // not left without identity metadata if the parent is interrupted after\n // the child RPC returns. Roll back only rows this call created.\n //\n // A facet may start a workflow from onStart(); workflow callbacks route\n // through the parent registry and must be able to find this in-flight\n // child, so recording before the init RPC is also what lets those\n // callbacks resolve.\n this.registry.record(className, name, identity);\n\n // Initialize the child as a facet via a single RPC that runs\n // inside the child's isolate. Avoids the cross-DO I/O error that\n // the previous `stub.fetch(req)` path triggered by handing a\n // parent-owned Request across the isolate boundary.\n //\n // The parent may be inside a WebSocket/message request context here.\n // Clear native context handles before the child facet RPC so workerd\n // never sees parent-owned I/O attached to child initialization.\n try {\n await this.#host._runFacetInitInvocation(async () => {\n await (\n stub as unknown as {\n _cf_initAsFacet(\n name: string,\n parentPath: ReadonlyArray<{ className: string; name: string }>,\n identityName: string\n ): Promise<void>;\n }\n )._cf_initAsFacet(name, childParentPath, identity.name);\n });\n } catch (error) {\n if (!identity.existing) {\n this.registry.forget(className, name);\n }\n throw error;\n }\n\n return stub;\n }\n\n /**\n * Forcefully abort a running facet. Transitively aborts the child's\n * own children; storage is preserved.\n */\n abort(className: string, name: string, reason?: unknown): void {\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n if (!ctx.facets) {\n throw new Error(\n \"abort() is not supported in this runtime — \" +\n \"`ctx.facets` is unavailable. \" +\n \"Update to the latest `compatibility_date` in your wrangler.jsonc.\"\n );\n }\n const facetKey = `${className}\\0${name}`;\n ctx.facets.abort(facetKey, reason);\n }\n\n /**\n * Delete a facet: abort it if running, then permanently wipe its\n * storage. Transitively deletes the child's own children.\n */\n async delete(className: string, name: string): Promise<void> {\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n if (!ctx.facets) {\n throw new Error(\n \"delete() is not supported in this runtime — \" +\n \"`ctx.facets` is unavailable. \" +\n \"Update to the latest `compatibility_date` in your wrangler.jsonc.\"\n );\n }\n const facetKey = `${className}\\0${name}`;\n const childPath = [...this.#host.selfPath, { className, name }];\n if (this.#host._isFacet) {\n const root = await this.rootAlarmOwner();\n await root._cf_cleanupFacetPrefix(childPath);\n } else {\n await this.#host._cf_cleanupFacetPrefix(childPath);\n }\n\n // Idempotent: make `ctx.facets.delete` tolerant of missing keys.\n // workerd throws an opaque \"internal error\" when the key isn't\n // registered; swallow that so double-delete and\n // delete-never-spawned both succeed silently. The registry DELETE\n // is already idempotent.\n try {\n ctx.facets.delete(facetKey);\n } catch {\n // no-op — facet wasn't registered (already deleted / never spawned)\n }\n this.registry.forget(className, name);\n }\n\n // ── WebSocket forwarding + virtual connections ────────────────────────\n\n /** Drop all facet-side virtual connections (test/rehydration hook). */\n clearVirtualConnections(): void {\n this.#virtualConnections.clear();\n }\n\n /** Facet-side lookup of a virtual connection by id. */\n getVirtualConnection(id: string): Connection | undefined {\n const stored = this.#virtualConnections.get(id);\n if (!stored) return undefined;\n return this.createBridgeConnection(stored.meta);\n }\n\n /** Facet-side iteration over virtual connections, optionally by tag. */\n *getVirtualConnections(tag?: string): Iterable<Connection> {\n for (const stored of this.#virtualConnections.values()) {\n if (!tag || stored.meta.tags.includes(tag)) {\n yield this.createBridgeConnection(stored.meta);\n }\n }\n }\n\n activeBridge(\n connectionId?: string\n ): DynamicAgentConnectionBridgeLike | undefined {\n const context = this.#bridgeContext.getStore();\n if (connectionId !== undefined && context?.connectionId !== connectionId) {\n return undefined;\n }\n return context?.bridge;\n }\n\n /**\n * Route a virtual sub-agent connection operation through its live frame\n * bridge, or through the durable root Agent after that frame completes.\n * All operations share one per-connection queue. Facet broadcasts wait for\n * older queued operations; failures do not block later work.\n */\n routeConnectionOperation(\n connectionId: string,\n operationName: DynamicAgentConnectionOperationName,\n operation: (bridge: DynamicAgentConnectionBridgeLike) => unknown\n ): void {\n const activeBridge = this.activeBridge(connectionId);\n const previousConnectionOperation =\n this.#connectionOperationTails.get(connectionId);\n let pending: Promise<void>;\n if (activeBridge && !previousConnectionOperation) {\n try {\n pending = Promise.resolve(operation(activeBridge)).then(() => {});\n } catch (error) {\n pending = Promise.reject(error);\n }\n } else {\n pending = (previousConnectionOperation ?? Promise.resolve()).then(\n async () => {\n const root = await this.rootAlarmOwner();\n await operation(\n new RootDynamicAgentConnectionBridge(root, connectionId)\n );\n }\n );\n }\n const completion = pending.catch((error: unknown) => {\n this.#reportConnectionOperationFailure(\n connectionId,\n operationName,\n error\n );\n });\n\n this.#connectionOperationTails.set(connectionId, completion);\n this.#host.ctx.waitUntil(completion);\n void completion.then(() => {\n if (this.#connectionOperationTails.get(connectionId) === completion) {\n this.#connectionOperationTails.delete(connectionId);\n }\n });\n }\n\n /**\n * Route a facet broadcast after every older connection operation.\n *\n * This barrier is intentionally one-way: facet startup can broadcast before\n * a child connection has finished initializing its tags and protocol flags.\n * Making those later connection operations wait would let the next frame\n * observe stale root-owned metadata.\n */\n async routeBroadcast(\n ownerPath: ReadonlyArray<AgentPathStep>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[],\n upstreamBridge?: DynamicAgentConnectionBridgeLike\n ): Promise<void> {\n const activeBridge = upstreamBridge ?? this.activeBridge();\n const previousOperations = new Set([\n ...(this.#broadcastOperationTail ? [this.#broadcastOperationTail] : []),\n ...this.#connectionOperationTails.values()\n ]);\n let pending: Promise<void>;\n if (activeBridge && previousOperations.size === 0) {\n try {\n pending = Promise.resolve(\n activeBridge.broadcast(ownerPath, message, without)\n );\n } catch (error) {\n pending = Promise.reject(error);\n }\n } else {\n pending = Promise.all(previousOperations).then(async () => {\n const root = await this.rootAlarmOwner();\n await root._cf_broadcastToSubAgent(ownerPath, message, without);\n });\n }\n const completion = pending.catch((error: unknown) => {\n console.error(\"[Agent] Sub-agent broadcast operation failed:\", {\n operation: \"broadcast\",\n error\n });\n });\n\n this.#broadcastOperationTail = completion;\n this.#host.ctx.waitUntil(completion);\n void completion.then(() => {\n if (this.#broadcastOperationTail === completion) {\n this.#broadcastOperationTail = undefined;\n }\n });\n await completion;\n }\n\n #reportConnectionOperationFailure(\n connectionId: string,\n operation: DynamicAgentConnectionOperationName,\n error: unknown\n ): void {\n console.error(\"[Agent] Sub-agent connection operation failed:\", {\n connectionId,\n operation,\n error\n });\n }\n\n async broadcastToParent(\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): Promise<void> {\n await this.routeBroadcast(this.#host.selfPath, message, without);\n }\n\n async broadcastToPath(\n ownerPath: ReadonlyArray<AgentPathStep>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): Promise<void> {\n if (this.#host._isFacet) {\n await this.routeBroadcast(ownerPath, message, without);\n return;\n }\n\n for (const connection of this.#host._webSockets.getConnections()) {\n if (without?.includes(connection.id)) continue;\n const targetPath = this.connectionTargetPath(connection);\n if (!targetPath) continue;\n if (!this.isSameAgentPath(targetPath, ownerPath)) continue;\n connection.send(message);\n }\n }\n\n async connectionMetas(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<DynamicAgentConnectionMeta[]> {\n const metas: DynamicAgentConnectionMeta[] = [];\n for (const connection of this.#host._webSockets.getConnections()) {\n const meta = this.#connectionMetaForPath(connection, ownerPath);\n if (meta) metas.push(meta);\n }\n return metas;\n }\n\n async sendToConnection(\n connectionId: string,\n message: string | ArrayBuffer | ArrayBufferView\n ): Promise<void> {\n const connection = this.#host._webSockets.getConnection(connectionId);\n if (!connection || !this.connectionHasChildTarget(connection)) {\n return;\n }\n connection.send(message);\n }\n\n async closeConnection(\n connectionId: string,\n code?: number,\n reason?: string\n ): Promise<void> {\n const connection = this.#host._webSockets.getConnection(connectionId);\n if (!connection || !this.connectionHasChildTarget(connection)) {\n return;\n }\n connection.close(code, reason);\n }\n\n async setConnectionState(\n connectionId: string,\n state: unknown\n ): Promise<unknown> {\n const connection = this.#host._webSockets.getConnection(connectionId);\n if (!connection || !this.connectionHasChildTarget(connection)) {\n return null;\n }\n this.#host._ensureConnectionWrapped(connection);\n connection.setState(state);\n return this.getForwardedState(connection);\n }\n\n #connectionMetaForPath(\n connection: Connection,\n ownerPath: ReadonlyArray<AgentPathStep>\n ): DynamicAgentConnectionMeta | null {\n this.#host._ensureConnectionWrapped(connection);\n const outerUri = this.#host._unsafe_getConnectionFlag(\n connection,\n CF_SUB_AGENT_OUTER_URL_KEY\n );\n if (typeof outerUri !== \"string\") return null;\n\n const target = this.#pathFromOuterUri(outerUri, ownerPath);\n if (!target) return null;\n\n const raw = this.getRawConnectionState(connection);\n const rawTags =\n raw != null && typeof raw === \"object\"\n ? (raw as Record<string, unknown>)[CF_SUB_AGENT_TAGS_KEY]\n : undefined;\n const tags = Array.isArray(rawTags)\n ? rawTags.filter((tag): tag is string => typeof tag === \"string\")\n : [...connection.tags];\n return {\n id: connection.id,\n uri: target.uri,\n tags,\n state: this.getForwardedState(connection)\n };\n }\n\n connectionTargetPath(\n connection: Connection\n ): ReadonlyArray<AgentPathStep> | null {\n this.#host._ensureConnectionWrapped(connection);\n const outerUri = this.#host._unsafe_getConnectionFlag(\n connection,\n CF_SUB_AGENT_OUTER_URL_KEY\n );\n if (typeof outerUri !== \"string\") return null;\n\n return this.#pathFromOuterUri(outerUri)?.path ?? null;\n }\n\n #pathFromOuterUri(\n outerUri: string,\n stopAt?: ReadonlyArray<AgentPathStep>\n ): { path: ReadonlyArray<AgentPathStep>; uri: string } | null {\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n const knownClasses = ctx.exports ? Object.keys(ctx.exports) : undefined;\n const path: AgentPathStep[] = [...this.#host.selfPath];\n let currentUrl = outerUri;\n\n while (true) {\n const match = parseSubAgentPath(currentUrl, { knownClasses });\n if (!match) break;\n path.push({ className: match.childClass, name: match.childName });\n const rewritten = new URL(currentUrl);\n rewritten.pathname = match.remainingPath;\n currentUrl = rewritten.toString();\n if (stopAt && this.isSameAgentPath(path, stopAt)) {\n return { path, uri: currentUrl };\n }\n }\n\n if (path.length === this.#host.selfPath.length) return null;\n if (stopAt) return null;\n return { path, uri: currentUrl };\n }\n\n isSameAgentPath(\n a: ReadonlyArray<AgentPathStep>,\n b: ReadonlyArray<AgentPathStep>\n ): boolean {\n if (a.length !== b.length) return false;\n return a.every(\n (step, index) =>\n step.className === b[index]?.className && step.name === b[index]?.name\n );\n }\n\n connectionHasChildTarget(connection: Connection): boolean {\n this.#host._ensureConnectionWrapped(connection);\n return (\n typeof this.#host._unsafe_getConnectionFlag(\n connection,\n CF_SUB_AGENT_OUTER_URL_KEY\n ) === \"string\"\n );\n }\n\n connectionTargetsChild(connection: Connection): boolean {\n if (!connection.uri) return false;\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n return (\n parseSubAgentPath(connection.uri, {\n knownClasses: ctx.exports ? Object.keys(ctx.exports) : undefined\n }) !== null\n );\n }\n\n requestTargetsChild(request: Request): boolean {\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n return (\n parseSubAgentPath(request.url, {\n knownClasses: ctx.exports ? Object.keys(ctx.exports) : undefined\n }) !== null\n );\n }\n\n async forwardWebSocketConnect(\n connection: Connection,\n request: Request,\n options: { gate: boolean }\n ): Promise<boolean> {\n const routed = await this.#resolveConnection(connection, request, options);\n if (!routed) return false;\n\n await routed.child._cf_handleSubAgentWebSocketConnect(\n this.#createConnectionBridge(connection),\n routed.meta\n );\n return true;\n }\n\n #createConnectionBridge(\n connection: Connection\n ): DynamicAgentConnectionBridge {\n // A child-to-parent RPC callback starts a fresh async context. Capture the\n // upstream bridge explicitly while this forwarding frame is still active.\n const upstreamBroadcastBridge = this.#host._isFacet\n ? this.activeBridge(connection.id)\n : undefined;\n\n return new DynamicAgentConnectionBridge(\n connection,\n (ownerPath, message, without) => {\n if (upstreamBroadcastBridge) {\n return this.routeBroadcast(\n ownerPath,\n message,\n without,\n upstreamBroadcastBridge\n );\n }\n // Dispatch through the host so subclass overrides of the\n // `_cf_broadcastToSubAgent` RPC entry point keep intercepting.\n return this.#host._cf_broadcastToSubAgent(ownerPath, message, without);\n }\n );\n }\n\n async forwardWebSocketMessage(\n connection: Connection,\n message: WSMessage,\n replyBridge?: DynamicAgentConnectionBridge\n ): Promise<boolean> {\n const routed = await this.#resolveConnection(connection);\n if (!routed) return false;\n\n const bridge = this.#createConnectionBridge(connection);\n await routed.child._cf_handleSubAgentWebSocketMessage(\n message,\n bridge,\n routed.meta,\n replyBridge ?? bridge\n );\n return true;\n }\n\n async forwardWebSocketClose(\n connection: Connection,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<boolean> {\n const routed = await this.#resolveConnection(connection);\n if (!routed) return false;\n\n await routed.child._cf_handleSubAgentWebSocketClose(\n code,\n reason,\n wasClean,\n this.#createConnectionBridge(connection),\n routed.meta\n );\n return true;\n }\n\n async #resolveConnection(\n connection: Connection,\n request?: Request,\n options: { gate: boolean } = { gate: false }\n ): Promise<{\n child: DynamicAgentWebSocketEndpoint;\n meta: DynamicAgentConnectionMeta;\n } | null> {\n this.#host._ensureConnectionWrapped(connection);\n const outerUri = this.#host._unsafe_getConnectionFlag(\n connection,\n CF_SUB_AGENT_OUTER_URL_KEY\n );\n const uri = typeof outerUri === \"string\" ? outerUri : connection.uri;\n if (!uri) return null;\n\n const ctx = this.#host.ctx as unknown as Partial<FacetCapableCtx>;\n let match = parseSubAgentPath(uri, {\n knownClasses: ctx.exports ? Object.keys(ctx.exports) : undefined\n });\n if (!match) return null;\n if (\n this.#host._ParentClass.name === match.childClass &&\n this.#host.name === match.childName\n ) {\n const tailUri = new URL(uri);\n tailUri.pathname = match.remainingPath;\n match = parseSubAgentPath(tailUri.toString(), {\n knownClasses: ctx.exports ? Object.keys(ctx.exports) : undefined\n });\n if (!match) return null;\n }\n\n let forwardReq = request;\n if (request && options.gate) {\n const decision = await this.#host.onBeforeSubAgent(request, {\n className: match.childClass,\n name: match.childName\n });\n if (decision instanceof Response) {\n connection.close(1008, \"Sub-agent connection rejected\");\n return null;\n }\n forwardReq = decision instanceof Request ? decision : request;\n }\n\n const child = (await this.resolve(\n match.childClass,\n match.childName\n )) as DynamicAgentWebSocketEndpoint;\n\n const childUri = new URL(forwardReq?.url ?? uri);\n childUri.pathname = match.remainingPath;\n const raw = this.getRawConnectionState(connection);\n const rawTags =\n raw != null && typeof raw === \"object\"\n ? (raw as Record<string, unknown>)[CF_SUB_AGENT_TAGS_KEY]\n : undefined;\n const tags = Array.isArray(rawTags)\n ? rawTags.filter((tag): tag is string => typeof tag === \"string\")\n : [...connection.tags];\n\n return {\n child,\n meta: {\n id: connection.id,\n uri: childUri.toString(),\n tags,\n state: this.getForwardedState(connection),\n requestHeaders: forwardReq ? [...forwardReq.headers] : undefined\n }\n };\n }\n\n async handleWebSocketConnect(\n bridge: DynamicAgentConnectionBridge,\n meta: DynamicAgentConnectionMeta\n ): Promise<void> {\n await this.runWithBridge(bridge, meta.id, async () => {\n const connection = this.createBridgeConnection(meta);\n const request = new Request(meta.uri ?? \"http://placeholder/\", {\n headers: meta.requestHeaders\n });\n if (\n await this.forwardWebSocketConnect(connection, request, {\n gate: true\n })\n ) {\n return;\n }\n\n if (this.#host.shouldConnectionBeReadonly(connection, { request })) {\n this.#host.setConnectionReadonly(connection, true);\n }\n if (!this.#host.shouldSendProtocolMessages(connection, { request })) {\n this.#host._setConnectionNoProtocol(connection);\n }\n\n const childTags = await this.#host.getConnectionTags(connection, {\n request\n });\n (connection as unknown as { tags: string[] }).tags = [\n connection.id,\n ...childTags.filter((tag) => tag !== connection.id)\n ];\n this.storeVirtualConnection(connection);\n await this.#host.onConnect(connection, { request });\n this.storeVirtualConnection(connection);\n // Publish onConnect state to the root before the first client frame can\n // replace the virtual connection's state with root-owned metadata.\n await this.#connectionOperationTails.get(meta.id);\n });\n }\n\n async handleWebSocketMessage(\n message: WSMessage,\n bridge: DynamicAgentConnectionBridge,\n meta: DynamicAgentConnectionMeta,\n replyBridge: DynamicAgentConnectionBridge = bridge\n ): Promise<void> {\n const connection = this.createBridgeConnection(meta);\n this.storeVirtualConnection(connection);\n const replyContext: DynamicAgentRpcReplyInvocationContext = {\n bridge: replyBridge\n };\n try {\n await dynamicAgentRpcReplyContext.run(replyContext, () =>\n this.runWithBridge(bridge, meta.id, () =>\n this.#host.onMessage(connection, message)\n )\n );\n } finally {\n replyContext.bridge = undefined;\n }\n }\n\n async handleWebSocketClose(\n code: number,\n reason: string,\n wasClean: boolean,\n bridge: DynamicAgentConnectionBridge,\n meta: DynamicAgentConnectionMeta\n ): Promise<void> {\n const connection = this.createBridgeConnection(meta);\n this.storeVirtualConnection(connection);\n await this.runWithBridge(bridge, meta.id, () =>\n this.#host.onClose(connection, code, reason, wasClean)\n );\n this.#virtualConnections.delete(meta.id);\n }\n\n async runWithBridge<T>(\n bridge: DynamicAgentConnectionBridgeLike,\n connectionId: string,\n fn: () => Promise<T> | T\n ): Promise<T> {\n const context: DynamicAgentBridgeInvocationContext = {\n bridge,\n connectionId\n };\n try {\n return await this.#bridgeContext.run(context, fn);\n } finally {\n // Detached work inherits this context, but a forwarded RPC bridge is only\n // valid until its originating connect, message, or close call completes.\n context.bridge = undefined;\n }\n }\n\n createBridgeConnection(meta: DynamicAgentConnectionMeta): Connection {\n let stored = this.#virtualConnections.get(meta.id);\n if (stored) {\n stored.meta = meta;\n if (stored.connection) {\n (\n stored.connection as unknown as {\n uri: string | null;\n tags: string[];\n }\n ).uri = meta.uri;\n (\n stored.connection as unknown as {\n uri: string | null;\n tags: string[];\n }\n ).tags = meta.tags;\n return stored.connection;\n }\n } else {\n stored = { meta };\n this.#virtualConnections.set(meta.id, stored);\n }\n\n const owner = this;\n const getStored = () => this.#virtualConnections.get(meta.id) ?? stored;\n const updateStoredState = (nextState: unknown) => {\n const current = this.#virtualConnections.get(meta.id);\n if (current) {\n current.meta = { ...current.meta, state: nextState };\n }\n };\n\n const connection = {\n id: meta.id,\n uri: meta.uri,\n tags: meta.tags,\n get state() {\n return getStored().meta.state;\n },\n setState(next: unknown | ((prev: unknown) => unknown)) {\n const currentState = getStored().meta.state;\n const state = typeof next === \"function\" ? next(currentState) : next;\n updateStoredState(state);\n owner.routeConnectionOperation(meta.id, \"setState\", (bridge) =>\n bridge.setState(state)\n );\n return state;\n },\n send(message: string | ArrayBuffer | ArrayBufferView) {\n owner.routeConnectionOperation(meta.id, \"send\", (bridge) =>\n bridge.send(message)\n );\n },\n close(code?: number, reason?: string) {\n owner.routeConnectionOperation(meta.id, \"close\", (bridge) =>\n bridge.close(code, reason)\n );\n },\n addEventListener() {},\n removeEventListener() {}\n } as unknown as Connection;\n\n stored.connection = connection;\n this.#host._ensureConnectionWrapped(connection);\n return connection;\n }\n\n storeVirtualConnection(connection: Connection): void {\n this.#host._unsafe_setConnectionFlag(connection, CF_SUB_AGENT_TAGS_KEY, [\n ...connection.tags\n ]);\n const stored = this.#virtualConnections.get(connection.id);\n this.#virtualConnections.set(connection.id, {\n meta: {\n id: connection.id,\n uri: connection.uri,\n tags: [...connection.tags],\n state: this.getRawConnectionState(connection)\n },\n connection: stored?.connection ?? connection\n });\n }\n\n /**\n * Restore the facet identity persisted by `init` (wake after\n * hibernation), then best-effort hydrate the virtual connections\n * from the root's WebSocket state.\n */\n async restoreFacetContext(): Promise<void> {\n const isFacet =\n await this.#host.ctx.storage.get<boolean>(\"cf_agents_is_facet\");\n if (isFacet) this.#host._isFacet = true;\n\n const storedFacetName = await this.#host.ctx.storage.get<string>(\n \"cf_agents_facet_name\"\n );\n if (typeof storedFacetName === \"string\") {\n this.#host._facetName = storedFacetName;\n }\n\n const storedParentPath = await this.#host.ctx.storage.get<\n Array<{ className: string; name: string }>\n >(\"cf_agents_parent_path\");\n if (isValidParentPath(storedParentPath)) {\n this.#host._parentPath = storedParentPath;\n }\n\n try {\n await this.hydrateConnectionsFromRoot();\n } catch (error) {\n console.warn(\n \"[Agent] Unable to hydrate sub-agent WebSocket connections:\",\n error\n );\n }\n }\n\n async hydrateConnectionsFromRoot(): Promise<void> {\n if (!this.#host._isFacet || this.#host._parentPath.length === 0) return;\n\n if (this.rootResolvesToSelf()) {\n // The root stub would resolve back to this blocked Durable Object\n // during startup. The facet view cannot see root-owned hibernated\n // sockets locally, so preserve liveness and skip best-effort hydration.\n return;\n }\n\n const root = await this.rootAlarmOwner();\n const metas = await root._cf_subAgentConnectionMetas(this.#host.selfPath);\n for (const meta of metas) {\n this.#virtualConnections.set(meta.id, { meta });\n }\n }\n\n getRawConnectionState(connection: Connection): unknown {\n this.#host._ensureConnectionWrapped(connection);\n return this.#host._rawStateAccessors.get(connection)?.getRaw() ?? null;\n }\n\n getForwardedState(connection: Connection): unknown {\n const raw = this.getRawConnectionState(connection);\n if (raw == null || typeof raw !== \"object\") return raw;\n const { [CF_SUB_AGENT_OUTER_URL_KEY]: _, ...rest } = raw as Record<\n string,\n unknown\n >;\n return Object.keys(rest).length > 0 ? rest : null;\n }\n\n /**\n * Resolve the facet Fetcher for the match and forward the request to\n * it with `/sub/{class}/{name}` stripped.\n */\n async forward(\n req: Request,\n match: {\n childClass: string;\n childName: string;\n remainingPath: string;\n }\n ): Promise<Response> {\n let fetcher: { fetch(r: Request): Promise<Response> };\n try {\n fetcher = (await this.resolve(match.childClass, match.childName)) as {\n fetch(r: Request): Promise<Response>;\n };\n } catch (err) {\n // Keep the wire response terse: don't leak the parent's view of\n // exports or internal error text over HTTP. The full error is\n // still available to developers via worker logs / `console.error`.\n const message = err instanceof Error ? err.message : String(err);\n console.error(\"[agents] sub-agent route failed:\", message);\n if (/null character/i.test(message) || /reserved/i.test(message)) {\n return new Response(\"Bad Request\", { status: 400 });\n }\n return new Response(\"Not Found\", { status: 404 });\n }\n\n // Rewrite the URL to strip the /sub/{class}/{name} prefix. The\n // child's own fetch then processes either its own request (if\n // no further /sub/... remains) or recurses into its own child.\n const rewritten = new URL(req.url);\n rewritten.pathname = match.remainingPath;\n const forwardedHeaders = new Headers(req.headers);\n const forwardedInit: RequestInit = {\n method: req.method,\n headers: forwardedHeaders\n };\n if (req.headers.get(\"Upgrade\")?.toLowerCase() === \"websocket\") {\n forwardedHeaders.set(SUB_AGENT_OUTER_URL_HEADER, req.url);\n }\n // Hand the body through as a stream. Reading it here (e.g.\n // `await req.arrayBuffer()`) materialises the entire body in the\n // parent DO's isolate, ahead of any application-level intake limit,\n // and re-materialises it once per `/sub/` hop — see #2015.\n if (req.body && req.method !== \"GET\" && req.method !== \"HEAD\") {\n forwardedInit.body = req.body;\n }\n const forwarded = new Request(rewritten, forwardedInit);\n return fetcher.fetch(forwarded);\n }\n\n /**\n * Bridge used by `getSubAgentByName`: resolve the facet and dispatch\n * one RPC method. Stateless — no cached references.\n */\n async invoke(\n className: string,\n name: string,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n const stub = await this.resolve(className, name);\n return await this.invokeStubMethod(stub, className, method, args);\n }\n\n /**\n * Bridge used by `parentAgent()` when the requested parent is itself\n * a facet (and therefore has no top-level env namespace). The root\n * receives the full root-first target path, then each hop delegates\n * to the next facet using that facet's own `ctx.facets`.\n */\n async invokePath(\n path: ReadonlyArray<{ className: string; name: string }>,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n const [self, next, ...rest] = path;\n if (!self) {\n throw new Error(`Sub-agent path invocation requires a non-empty path.`);\n }\n\n const ownClassName = (\n this.#host as unknown as { constructor: { name: string } }\n ).constructor.name;\n if (self.className !== ownClassName || self.name !== this.#host.name) {\n throw new Error(\n `Sub-agent path invocation reached ${ownClassName}(\"${this.#host.name}\") ` +\n `but expected ${self.className}(\"${self.name}\").`\n );\n }\n\n if (!next) {\n return await this.invokeStubMethod(\n this.#host,\n ownClassName,\n method,\n args\n );\n }\n\n const child = await this.resolve(next.className, next.name);\n if (rest.length === 0) {\n return await this.invokeStubMethod(child, next.className, method, args);\n }\n\n const bridge = child as DynamicAgentPathInvokeEndpoint;\n return await bridge._cf_invokeSubAgentPath([next, ...rest], method, args);\n }\n\n async invokeStubMethod(\n stub: unknown,\n className: string,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n // Must call `handle[method](...)` in one expression — extracting\n // via `const fn = handle[method]; fn.apply(handle, args)` breaks\n // the workerd RpcProperty binding. (Confirmed by the spike.)\n const handle = stub as unknown as Record<\n string,\n (...a: unknown[]) => Promise<unknown>\n >;\n if (typeof handle[method] !== \"function\") {\n throw new Error(`Method \"${method}\" not found on ${className}.`);\n }\n return await handle[method](...args);\n }\n\n /**\n * Initialize the host agent as a facet in a single RPC. Runs entirely\n * inside the child's isolate, so every storage write and `onStart()`\n * I/O is owned by the child DO.\n */\n async init(\n name: string,\n parentPath: ReadonlyArray<{ className: string; name: string }> = [],\n identityName = name\n ): Promise<void> {\n const routedName = this.#host.lifecycle.name;\n if (routedName !== identityName) {\n throw new Error(\n `Facet bootstrap mismatch: expected routed identity \"${identityName}\" but got \"${routedName}\". ` +\n `This usually means the parent passed the wrong id to ctx.facets.get(). ` +\n `See _cf_resolveSubAgent.`\n );\n }\n\n this.#host._isFacet = true;\n this.#host._facetName = name;\n this.#host._parentPath = parentPath as AgentPathStep[];\n // Persist the agent-specific facet keys in parallel.\n await Promise.all([\n this.#host.ctx.storage.put(\"cf_agents_is_facet\", true),\n this.#host.ctx.storage.put(\"cf_agents_facet_name\", name),\n this.#host.ctx.storage.put(\"cf_agents_parent_path\", parentPath)\n ]);\n // Fire onStart() now since native RPC bypasses lifecycle fetch, which is the\n // entry point that normally triggers it. Protocol broadcasts during this\n // bootstrap window are safe: on a facet `getConnections()` returns only\n // virtual sub-agent connections and `broadcast()` routes to the parent\n // bridge, so neither touches the parent's own WebSocket handles (#1679).\n await this.#host.__unsafe_ensureInitialized();\n }\n\n /** Remove a completed facet fiber from the root-side index. */\n async unregisterRun(\n ownerPath: ReadonlyArray<AgentPathStep>,\n runId: string\n ): Promise<void> {\n const ownerPathKey = agentPathKey(ownerPath);\n this.#host.sql`\n DELETE FROM cf_agents_facet_runs\n WHERE owner_path_key IS ${ownerPathKey}\n AND run_id = ${runId}\n `;\n await this.#host._syncHostJobs();\n }\n}\n","import type { Agent } from \"../index\";\nimport type { DynamicAgentsInternal } from \"./dynamic-agents\";\nimport type { DynamicAgentClass, DynamicAgentStub } from \"./types\";\n\n/**\n * The public dynamic-agents capability surface, reached via\n * `this.dynamicAgents` on an Agent.\n *\n * A dynamic agent is a facet-backed child: it runs in its own isolate\n * with its own SQLite database, colocated with — and supervised by —\n * its parent Agent. Use dynamic agents for code whose class or\n * lifecycle the parent owns (dynamically-loaded/generated code,\n * per-run tool agents, sandboxed components). For independent peers\n * such as one-DO-per-chat, use `getAgentByName` instead.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class DynamicAgents {\n #internal: DynamicAgentsInternal;\n\n /** @internal Constructed by Agent; do not instantiate directly. */\n constructor(internal: DynamicAgentsInternal) {\n this.#internal = internal;\n }\n\n /**\n * Get (creating or waking if needed) the dynamic agent of the given\n * class and name, as a typed RPC stub. Idempotent — repeated calls\n * with the same class and name return the same child.\n *\n * @experimental\n */\n async get<T extends Agent>(\n cls: DynamicAgentClass<T>,\n name: string\n ): Promise<DynamicAgentStub<T>> {\n return (await this.#internal.resolve(\n cls.name,\n name\n )) as DynamicAgentStub<T>;\n }\n\n /**\n * Forcefully abort a running dynamic agent. The child stops\n * executing immediately and restarts on the next {@link get} call;\n * its storage is preserved. Transitively aborts the child's own\n * children. Pending RPC calls receive the reason as an error.\n *\n * @experimental\n */\n abort(cls: DynamicAgentClass, name: string, reason?: unknown): void {\n this.#internal.abort(cls.name, name, reason);\n }\n\n /**\n * Delete a dynamic agent: abort it if running, then permanently wipe\n * its storage. Transitively deletes the child's own children.\n *\n * @experimental\n */\n delete(cls: DynamicAgentClass, name: string): Promise<void> {\n return this.#internal.delete(cls.name, name);\n }\n\n /**\n * Whether this agent has previously spawned (and not deleted) a\n * dynamic agent of the given class and name. Backed by an\n * auto-maintained SQLite registry in the parent's storage.\n *\n * @experimental\n */\n has<T extends Agent>(cls: DynamicAgentClass<T>, name: string): boolean;\n has(className: string, name: string): boolean;\n has(classOrName: DynamicAgentClass | string, name: string): boolean {\n const className =\n typeof classOrName === \"string\" ? classOrName : classOrName.name;\n return this.#internal.registry.has(className, name);\n }\n\n /**\n * List known dynamic agents, optionally filtered by class. Reflects\n * the registry rows written by {@link get} and removed by\n * {@link delete}.\n *\n * @experimental\n */\n list<T extends Agent>(\n cls: DynamicAgentClass<T>\n ): Array<{ className: string; name: string; createdAt: number }>;\n list(\n className?: string\n ): Array<{ className: string; name: string; createdAt: number }>;\n list(\n classOrName?: DynamicAgentClass | string\n ): Array<{ className: string; name: string; createdAt: number }> {\n const className =\n typeof classOrName === \"string\" ? classOrName : classOrName?.name;\n return this.#internal.registry.list(className);\n }\n}\n","import type { TraceAttributes } from \"./tracing/tracer\";\n\nexport function agentSpanAttributes(input: {\n readonly agentClassName: string;\n readonly sessionId: string;\n readonly sessionName: string | undefined;\n}): TraceAttributes {\n return {\n // Compatibility representation of InstrumentationScope until the Workers\n // tracing API exposes native scope metadata.\n \"instrumentation_scope.name\": \"agents\",\n // Before bumping this telemetry schema version, notify Workers\n // Observability and any other downstream consumers.\n \"instrumentation_scope.version\": \"1\",\n \"cloudflare.agents.session.id\": input.sessionId,\n \"cloudflare.agents.session.name\": input.sessionName,\n \"gen_ai.agent.name\": input.agentClassName\n };\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type {\n Prompt,\n Resource,\n ServerCapabilities,\n SSEClientTransportOptions,\n Tool\n} from \"@modelcontextprotocol/client\";\nimport {\n __DO_NOT_USE_WILL_BREAK__agentContext as agentContext,\n type AgentContextStore,\n type AgentEmail\n} from \"./internal_context\";\nexport { __DO_NOT_USE_WILL_BREAK__agentContext } from \"./internal_context\";\n/**\n * @internal — This is an internal implementation detail shared with the Think\n * package so it can declare a turn's invocation boundary. Importing or relying\n * on this symbol **will** break your code in a future release.\n */\nexport { withInvocationScope as __DO_NOT_USE_WILL_BREAK__withInvocationScope } from \"./observability/tracing/tracer\";\nimport {\n parseSubAgentPath as _parseSubAgentPath,\n type AgentPathStep\n} from \"./sub-routing\";\nexport {\n buildAgentPath,\n buildAgentUrl,\n routeSubAgentRequest,\n getSubAgentByName,\n parseSubAgentPath,\n SUB_PREFIX\n} from \"./sub-routing\";\nexport type {\n AgentPathStep,\n BuildAgentPathOptions,\n SubAgentPathMatch\n} from \"./sub-routing\";\nimport {\n isClosedWebSocketSendError,\n registerFacetStreamingDelivery,\n sendFacetRpcResponseIfOpen,\n sendFacetStreamingResponse,\n DynamicAgentConnectionBridge as SubAgentConnectionBridge,\n dynamicAgentRpcReplyContext as subAgentRpcReplyContext,\n waitForFacetStreamingResponseDeliveries\n} from \"./dynamic-agents/bridges\";\nimport {\n CF_SUB_AGENT_OUTER_URL_KEY,\n CF_SUB_AGENT_TAGS_KEY,\n SUB_AGENT_OUTER_URL_HEADER\n} from \"./dynamic-agents/dynamic-agents\";\nimport { logicalNameFromPathV2Identity } from \"./dynamic-agents/identity\";\nimport { DynamicAgentsInternal } from \"./dynamic-agents/dynamic-agents\";\nimport { DynamicAgents as DynamicAgentsApi } from \"./dynamic-agents/api\";\nimport type { DynamicAgentHostPort } from \"./dynamic-agents/host\";\nimport type {\n FacetCapableCtx,\n RootFacetRpcSurface,\n DynamicAgentClass as SubAgentClass,\n DynamicAgentConnectionMeta as SubAgentConnectionMeta,\n DynamicAgentPathInvokeEndpoint as SubAgentPathInvokeEndpoint,\n DynamicAgentStub as SubAgentStub\n} from \"./dynamic-agents/types\";\nexport type {\n DynamicAgentClass,\n DynamicAgentStub,\n DynamicAgentClass as SubAgentClass,\n DynamicAgentStub as SubAgentStub\n} from \"./dynamic-agents/types\";\nimport { signAgentHeaders, type SendEmailOptions } from \"./email\";\nimport { sendAgentEmail } from \"./email-send\";\nexport type { EmailSendBinding, SendEmailOptions } from \"./email\";\nimport { nanoid } from \"nanoid\";\nimport { EmailMessage } from \"cloudflare:email\";\nimport {\n DurableObject,\n RpcTarget,\n exports as workerExports\n} from \"cloudflare:workers\";\nimport {\n type LifecycleJobContext,\n type MemoryLimitContext,\n type Connection,\n type ConnectionContext,\n Lifecycle,\n type LifecycleJobOutcome,\n setLifecycleEventSink,\n setLifecycleHostInvoker,\n setLifecycleRouteTransport,\n type LifecycleRouteEnvelope,\n type WSMessage\n} from \"./lifecycle/durable-object-lifecycle\";\nimport { abortWithoutAlarmRetry } from \"./lifecycle/abort\";\nimport type { LifecycleRouteAddress } from \"./lifecycle/capability\";\nimport {\n getCurrentAgent as getCurrentLifecycleAgent,\n type CurrentAgentContext\n} from \"./lifecycle/current-agent\";\nimport { getAgentByName, type AgentOptions } from \"./agent-routing\";\nimport { callablesFromDecorated, WebSockets } from \"./websockets\";\nexport {\n getAgentByName,\n routeAgentRequest,\n type AgentGetOptions,\n type AgentOptions,\n type RoutingRetryOptions\n} from \"./agent-routing\";\nimport { camelCaseToKebabCase, isInternalJsStubProp } from \"./utils\";\nexport { camelCaseToKebabCase } from \"./utils\";\nimport { SqlError } from \"./sql-error\";\nimport {\n type RetryOptions,\n tryN,\n isErrorRetryable,\n validateRetryOptions\n} from \"./retries\";\nexport {\n isDurableObjectCodeUpdateReset,\n isDurableObjectMemoryLimitReset,\n isDurableObjectStorageReset,\n isPlatformTransientError\n} from \"./retries\";\nimport { MCPClientManager, normalizeServerId } from \"./mcp/client\";\nimport type {\n WorkflowCallback,\n WorkflowTrackingRow,\n WorkflowStatus,\n RunWorkflowOptions,\n WorkflowEventPayload,\n WorkflowInfo,\n WorkflowQueryCriteria,\n WorkflowPage,\n AgentWorkflowOrigin\n} from \"./workflow-types\";\nimport { MCPConnectionState } from \"./mcp/client/connection\";\nimport {\n DurableObjectOAuthClientProvider,\n type AgentMcpOAuthProvider\n} from \"./mcp/client/do-oauth-client-provider\";\nimport type { McpClientOptions, TransportType } from \"./mcp/types\";\nimport {\n genericObservability,\n type Observability,\n type ObservabilityEvent\n} from \"./observability\";\nimport { agentSpanAttributes } from \"./observability/agent-span-attributes\";\nimport { tracer } from \"./observability/tracing/cloudflare\";\nimport {\n withInvocationScope,\n writeSpanAttributes,\n type InvocationScopeOptions,\n type TraceAttributes\n} from \"./observability/tracing/tracer\";\nimport { DisposableStore } from \"./core/events\";\nimport { MessageType } from \"./types\";\nimport { RPC_DO_PREFIX } from \"./mcp/rpc\";\nimport { ensureMcpServerTable } from \"./mcp/client/storage\";\nimport type { McpAgent } from \"./mcp\";\nimport { Scheduler, setSchedulerCallbackResolver } from \"./schedules/scheduler\";\nimport {\n Tasks,\n setTaskDefinitionResolver,\n setTaskRoutedMemoryLimitHandler\n} from \"./tasks/tasks\";\nimport type { TaskCallbacks, TaskHandlers } from \"./tasks/types\";\nimport type {\n Schedule,\n ScheduleCriteria,\n ScheduleOptions\n} from \"./schedules/types\";\nexport type {\n Schedule,\n ScheduleCriteria,\n ScheduleOptions\n} from \"./schedules/types\";\nexport {\n AGENT_TOOL_PROGRESS_PART,\n AGENT_TOOL_MILESTONE_PART\n} from \"./agent-tool-types\";\nimport {\n AGENT_TOOL_MILESTONE_PART,\n AGENT_TOOL_PROGRESS_PART\n} from \"./agent-tool-types\";\nimport type {\n AgentToolChildAdapter,\n AgentToolDisplayMetadata,\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolInterruptedReason,\n AgentToolLifecycleResult,\n AgentToolMilestone,\n AgentToolProgress,\n AgentToolProgressSnapshot,\n AgentToolRunInfo,\n AgentToolRunInspection,\n AgentToolRunStatus,\n AgentToolStoredChunk,\n ChatCapableAgentClass,\n DetachedAgentToolConfig,\n DetachedRunAgentToolResult,\n RunAgentToolOptions,\n RunAgentToolResult\n} from \"./agent-tool-types\";\n\nexport type {\n AgentToolChildAdapter,\n AgentToolDisplayMetadata,\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolFailure,\n AgentToolInterruptedReason,\n AgentToolLifecycleResult,\n AgentToolMilestone,\n AgentToolProgress,\n AgentToolProgressSnapshot,\n AgentToolRunInfo,\n AgentToolRunInspection,\n AgentToolRunPart,\n AgentToolRunState,\n AgentToolRunStatus,\n AgentToolStoredChunk,\n AgentToolTerminalStatus,\n ChatCapableAgentClass,\n DetachedAgentToolConfig,\n DetachedRunAgentToolResult,\n RunAgentToolOptions,\n RunAgentToolResult\n} from \"./agent-tool-types\";\n\nexport type {\n Connection,\n ConnectionContext,\n WSMessage\n} from \"./lifecycle/durable-object-lifecycle\";\nexport { MessageType } from \"./types\";\n\n/**\n * RPC request message from client\n */\nexport type RPCRequest = {\n type: \"rpc\";\n id: string;\n method: string;\n args: unknown[];\n};\n\n/**\n * State update message from client\n */\nexport type StateUpdateMessage = {\n type: MessageType.CF_AGENT_STATE;\n state: unknown;\n};\n\n/**\n * RPC response message to client\n */\nexport type RPCResponse = {\n type: MessageType.RPC;\n id: string;\n} & (\n | {\n success: true;\n result: unknown;\n done?: false;\n }\n | {\n success: true;\n result: unknown;\n done: true;\n }\n | {\n success: false;\n error: string;\n }\n);\n\n/**\n * Enters an agent invocation: the context every handler reads, plus the span\n * scope that stops invocation-bounded spans from outliving it. Scopes do not\n * nest, so the outermost live entry point owns the boundary — pass\n * `detached` for work that deliberately runs on past its caller.\n */\nfunction runInInvocation<T>(\n store: AgentContextStore,\n body: () => T,\n options?: InvocationScopeOptions\n): T {\n return agentContext.run(store, () => withInvocationScope(body, options));\n}\n\nfunction sendRpcResponseIfOpen(\n connection: Connection,\n response: RPCResponse\n): boolean {\n try {\n connection.send(JSON.stringify(response));\n return true;\n } catch (error) {\n if (isClosedWebSocketSendError(error)) return false;\n throw error;\n }\n}\n\n/**\n * Type guard for RPC request messages\n */\nfunction isRPCRequest(msg: unknown): msg is RPCRequest {\n return (\n typeof msg === \"object\" &&\n msg !== null &&\n \"type\" in msg &&\n msg.type === MessageType.RPC &&\n \"id\" in msg &&\n typeof msg.id === \"string\" &&\n \"method\" in msg &&\n typeof msg.method === \"string\" &&\n \"args\" in msg &&\n Array.isArray((msg as RPCRequest).args)\n );\n}\n\n/**\n * Type guard for state update messages\n */\nfunction isStateUpdateMessage(msg: unknown): msg is StateUpdateMessage {\n return (\n typeof msg === \"object\" &&\n msg !== null &&\n \"type\" in msg &&\n msg.type === MessageType.CF_AGENT_STATE &&\n \"state\" in msg\n );\n}\n\nexport {\n callable,\n unstable_callable,\n type CallableMetadata\n} from \"./callable-decorator\";\nimport {\n copyCallableMetadata,\n decoratedMethods,\n getCallableMetadata,\n isCallableMethod,\n type CallableMetadata\n} from \"./callable-decorator\";\n\nexport { SqlError } from \"./sql-error\";\n\nexport type QueueItem<T = string> = {\n id: string;\n payload: T;\n callback: keyof Agent<Cloudflare.Env>;\n created_at: number;\n retry?: RetryOptions;\n};\n\ntype AgentToolRunStorageRow = {\n run_id: string;\n parent_tool_call_id: string | null;\n agent_type: string;\n input_preview: string | null;\n status: AgentToolRunStatus;\n summary: string | null;\n output_json: string | null;\n error_message: string | null;\n interrupted_reason: string | null;\n child_still_running: number | null;\n display_metadata: string | null;\n display_order: number;\n started_at: number;\n completed_at: number | null;\n // Detached (\"background\") run bookkeeping (rfc-detached-agent-tools).\n detached: number;\n detached_on_finish: string | null;\n detached_notify_source?: string | null;\n detached_max_budget_at: number | null;\n finish_claimed_at: number | null;\n finish_delivered_at: number | null;\n give_up_claimed_at: number | null;\n give_up_delivered_at: number | null;\n detached_no_progress_budget_ms?: number | null;\n last_progress_at?: number | null;\n detached_on_milestones?: string | null;\n};\n\ntype DeferredAgentToolFinish = () => Promise<void>;\ntype DetachedReconcilePayload = { cadenceIndex?: number };\n\n/**\n * Context passed to the `runFiber` callback. Provides checkpoint\n * and identity for durable execution.\n */\nexport type FiberContext = {\n /** Unique identifier for this fiber execution. */\n id: string;\n /** Cooperative cancellation signal for managed fiber callers. */\n signal: AbortSignal;\n /** Checkpoint data during execution. Synchronous SQLite write. */\n stash(data: unknown): void;\n /** Currently null during execution; recovered snapshots are passed to onFiberRecovered(). */\n snapshot: unknown | null;\n};\n\nexport type FiberStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"aborted\"\n | \"interrupted\"\n | \"error\";\n\nexport type StartFiberOptions = {\n fiberId?: string;\n idempotencyKey?: string;\n metadata?: Record<string, unknown>;\n waitForCompletion?: boolean;\n};\n\nexport type FiberInspection = {\n fiberId: string;\n name: string;\n idempotencyKey?: string;\n status: FiberStatus;\n snapshot?: unknown;\n error?: string;\n metadata?: Record<string, unknown>;\n createdAt: number;\n startedAt?: number;\n settledAt?: number;\n};\n\nexport type StartFiberResult = FiberInspection & {\n accepted: boolean;\n};\n\nexport type FiberRecoveryResult =\n | {\n status: \"completed\";\n snapshot?: unknown;\n metadata?: Record<string, unknown>;\n }\n | {\n status: \"error\";\n error?: unknown;\n snapshot?: unknown;\n }\n | {\n status: \"aborted\";\n reason?: string;\n snapshot?: unknown;\n }\n | {\n status: \"interrupted\";\n reason?: string;\n snapshot?: unknown;\n };\n\nexport type ListFibersOptions = {\n status?: FiberStatus | FiberStatus[];\n name?: string;\n limit?: number;\n};\n\nexport type DeleteFibersOptions = {\n status?: FiberStatus | FiberStatus[];\n settledBefore?: Date;\n limit?: number;\n};\n\ntype FiberLedgerRow = {\n fiber_id: string;\n idempotency_key: string | null;\n name: string;\n status: FiberStatus;\n snapshot: string | null;\n metadata_json: string | null;\n error_message: string | null;\n created_at: number;\n started_at: number | null;\n completed_at: number | null;\n};\n\n/**\n * Context passed to the `onFiberRecovered` hook when an interrupted\n * fiber is detected after DO restart.\n */\nexport type FiberRecoveryContext = {\n /** Fiber ID. */\n id: string;\n /** Name passed to `runFiber`. */\n name: string;\n /** Status for managed fibers recovered through the retained ledger. */\n status?: FiberStatus;\n /** Idempotency key for managed fibers, if one was supplied. */\n idempotencyKey?: string;\n /** Metadata for managed fibers, if one was supplied. */\n metadata?: Record<string, unknown> | null;\n /** Last checkpoint data from `stash()`, or null if never stashed. */\n snapshot: unknown | null;\n /**\n * Epoch milliseconds when the fiber row was inserted (when `runFiber`\n * started). Use `Date.now() - createdAt` to gate stale recoveries.\n */\n createdAt: number;\n /** Why this recovery hook is running. */\n recoveryReason: \"interrupted\";\n [key: string]: unknown;\n};\n\nconst _fiberALS = new AsyncLocalStorage<{\n id: string;\n signal: AbortSignal;\n stash: (data: unknown) => void;\n}>();\n\ntype InternalFiberOptions = {\n signal?: AbortSignal;\n managed?: boolean;\n initialSnapshot?: unknown;\n wrapStash?: (data: unknown) => unknown;\n beforeRunCleanup?: (\n outcome: { ok: true } | { ok: false; error: unknown }\n ) => void;\n};\n\nexport type { TransportType } from \"./mcp/types\";\nexport type { RetryOptions } from \"./retries\";\nexport {\n normalizeServerId,\n MCP_SERVER_ID_MAX_LENGTH,\n type MCPAITool,\n type MCPAIToolSet\n} from \"./mcp/client\";\nexport {\n DurableObjectOAuthClientProvider,\n type AgentMcpOAuthProvider,\n /** @deprecated Use {@link AgentMcpOAuthProvider} instead. */\n type AgentsOAuthProvider\n} from \"./mcp/client/do-oauth-client-provider\";\n\n/**\n * MCP Server state update message from server -> Client\n */\nexport type MCPServerMessage = {\n type: MessageType.CF_AGENT_MCP_SERVERS;\n mcp: MCPServersState;\n};\n\nexport type MCPServersState = {\n servers: {\n [id: string]: MCPServer;\n };\n tools: (Tool & { serverId: string })[];\n prompts: (Prompt & { serverId: string })[];\n resources: (Resource & { serverId: string })[];\n};\n\nexport type MCPServer = {\n name: string;\n server_url: string;\n auth_url: string | null;\n // This state is specifically about the temporary process of getting a token (if needed).\n // Scope outside of that can't be relied upon because when the DO sleeps, there's no way\n // to communicate a change to a non-ready state.\n state: MCPConnectionState;\n /** May contain untrusted content from external OAuth providers. Escape appropriately for your output context. */\n error: string | null;\n instructions: string | null;\n capabilities: ServerCapabilities | null;\n};\n\n/**\n * Options for adding an MCP server\n */\nexport type AddMcpServerOptions = {\n /**\n * Optional caller-supplied stable server id. When provided, this id is used\n * for storage, restore, and tool-name namespacing instead of a generated\n * `nanoid`. The value is normalized via {@link normalizeServerId} — for\n * connector-style integrations this lets `addMcpServer` keep producing\n * keys like `tool_github_create_pull_request`.\n *\n * Throws if an existing server already uses the same (normalized) id but a\n * different name or url.\n */\n id?: string;\n /** OAuth callback host (auto-derived from request if omitted) */\n callbackHost?: string;\n /**\n * Custom callback URL path — bypasses the default `/agents/{class}/{name}/callback` construction.\n * Required when `sendIdentityOnConnect` is `false` to prevent leaking the instance name.\n * When set, the callback URL becomes `{callbackHost}/{callbackPath}`.\n * The developer must route this path to the agent instance via `getAgentByName`.\n * Should be a plain path (e.g., `/mcp-callback`) — do not include query strings or fragments.\n */\n callbackPath?: string;\n /** Agents routing prefix (default: \"agents\") */\n agentsPrefix?: string;\n /** MCP client options */\n client?: McpClientOptions;\n /** Transport options */\n transport?: {\n /** Custom headers for authentication (e.g., bearer tokens, CF Access) */\n headers?: HeadersInit;\n /** Transport type: \"sse\", \"streamable-http\", or \"auto\" (default) */\n type?: TransportType;\n /**\n * Compatibility escape hatch for a trusted legacy authorization server\n * whose RFC 8414 issuer does not match its metadata discovery URL.\n * Security-weakening; leave false unless the server is explicitly known.\n */\n skipIssuerMetadataValidation?: boolean;\n };\n /** Retry options for connection and reconnection attempts */\n retry?: RetryOptions;\n};\n\n/**\n * Options for adding an MCP server via RPC (Durable Object binding)\n */\nexport type AddRpcMcpServerOptions = {\n /**\n * Optional caller-supplied stable server id. When provided, this id is used\n * for storage, restore, and tool-name namespacing instead of a generated\n * `nanoid`. The value is normalized via {@link normalizeServerId}.\n *\n * Throws if an existing server already uses the same (normalized) id but a\n * different name or url.\n */\n id?: string;\n /** Props to pass to the McpAgent instance */\n props?: Record<string, unknown>;\n};\n\nconst DEFAULT_KEEP_ALIVE_INTERVAL_MS = 30_000;\nconst DEFAULT_AGENT_TOOL_RECOVERY_TIMEOUT_MS = 2_000;\nconst DEFAULT_AGENT_TOOL_RECOVERY_TOTAL_TIMEOUT_MS = 5_000;\n// Durable marker that this agent is condemned: written before teardown begins\n// (and by `_cf_scheduleDestroy`, which defers teardown to an alarm invocation\n// with its own execution budget, #1625). The final `deleteAll()` in `destroy()`\n// removes it, so \"marker present\" always means an unfinished teardown that the\n// next wake must complete instead of resuming normal work.\n//\n// Scope: the marker is only consulted on alarm-driven paths (`alarm()` and\n// `_syncHostJobs()`). It deliberately does NOT gate request entrypoints\n// (`onRequest`/`onMessage`/RPC) — a request that lands between scheduling and\n// the teardown alarm runs normally and `_ensureSchema()` recreates tables. For\n// the MCP session-DELETE use case this is benign: the session id is unique and\n// is never addressed again after DELETE, so no further request reaches a\n// condemned session DO before its teardown alarm fires.\nconst DESTROY_PENDING_KEY = \"cf_agents_destroy_pending\";\n\n// Stable ids for Agent-owned host jobs in the Lifecycle job queue.\nconst HOST_JOB_KEEP_ALIVE_ID = \"cf:keep-alive\";\nconst HOST_JOB_HOUSEKEEPING_ID = \"cf:housekeeping\";\nconst HOST_JOB_DESTROY_ID = \"cf:destroy\";\n// Delay before the deferred-teardown alarm fires (#1625). `_cf_scheduleDestroy`\n// is awaited by an HTTP handler (the MCP session-DELETE) that then returns its\n// response. The teardown alarm runs `destroy()`, which ends in\n// `ctx.abort(\"destroyed\")` — and an immediate (`Date.now()`) alarm fires and\n// aborts the isolate fast enough to race the still-in-flight RPC response,\n// surfacing to the caller as a 500 instead of the intended 204 (observed\n// against a real deployment; the local test runtime does not exhibit it). A\n// small delay lets the response flush before the abort. Teardown latency of a\n// second is irrelevant for an already-abandoned session.\nconst DESTROY_ALARM_DELAY_MS = 1_000;\n// Ceiling for the exponential backoff applied to the runFiber-recovery\n// follow-up alarm. A scan that makes NO forward progress (every pending orphan\n// row's recovery hook threw) but still has work pending backs off so a poison\n// fiber — or a `fiberRecoveryMaxAgeMs: 0` \"retain forever\" row whose hook keeps\n// throwing — does not wake the DO every `keepAliveIntervalMs` indefinitely (the\n// perpetual-heartbeat hazard #1707 guards against). A scan that DID make\n// progress (recovered ≥1 row, including a scan-deadline yield that drained\n// some) resets the backoff so legitimate multi-pass draining stays prompt.\nconst FIBER_RECOVERY_MAX_BACKOFF_MS = 5 * 60_000;\n// Cap the doubling exponent so `base * 2 ** n` never overflows before the\n// `FIBER_RECOVERY_MAX_BACKOFF_MS` clamp applies.\nconst FIBER_RECOVERY_BACKOFF_MAX_EXP = 20;\n// Re-attaching to a still-running child agent-tool run (parent recovery /\n// duplicate-runId re-issue) tails it to its REAL terminal result instead of\n// abandoning it as `interrupted` and re-running already-completed child work\n// (#1630). The budget is PROGRESS-KEYED, not a flat wall clock: it bounds how\n// long the parent waits with NO forward progress from the child, and resets\n// every time the child forwards a chunk. A child that keeps streaming toward\n// terminal is therefore never abandoned mid-flight (the previous flat 120s\n// budget abandoned healthy, still-advancing children); only a genuinely\n// silent/hung child seals `interrupted` after a full no-progress window.\nconst DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS = 120_000;\n// Optional hard wall-clock ceiling on a single re-attach. Defaults to NO cap,\n// mirroring chat-recovery's `maxRecoveryWork: Infinity` (#1672): the SDK does\n// not impose an implicit wall-clock bound on a child that keeps making forward\n// progress — a re-attached parent follows a healthy, still-streaming child for\n// as long as it advances, exactly as it would on the live (never-evicted) path.\n// A hung/silent child is already bounded by the progress-keyed no-progress\n// budget above, and a content-runaway is bounded uniformly (live AND recovery)\n// by the child's own `maxRecoveryWork` / `shouldKeepRecovering` — not by a\n// parent-only timer that would fire only after an eviction. Integrators that\n// want a hard wall-clock cap (and the `window-exceeded` child teardown it\n// triggers) can still set `agentToolReattachMaxWindowMs` to a finite value.\nconst DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS = Number.POSITIVE_INFINITY;\n// Absolute safety ceiling on a DETACHED (\"background\") agent-tool run\n// (rfc-detached-agent-tools). A detached run has no awaiting parent turn and no\n// live observer, so unlike the re-attach window above this defaults to a FINITE\n// value: an abandoned detached run otherwise holds a concurrency slot + live\n// facet forever with nobody to notice the leak. On expiry the parent gives up\n// watching (delivers the completion hook with `interrupted`/`budget-exceeded`)\n// and tears the child down. 24h is generous enough for video renders / large\n// batch jobs while still bounding a genuinely stuck run.\nconst DEFAULT_DETACHED_MAX_BUDGET_MS = 24 * 60 * 60 * 1000;\n// Resetting no-progress window for detached runs: once a child has emitted at\n// least one `reportProgress` signal, the parent gives up if it then goes silent\n// for this long (the window resets on every signal). A child that never signals\n// is bounded only by the absolute `detachedMaxBudgetMs` ceiling — we never give\n// up on a run merely for taking a long time, only for going silent after it\n// started reporting. Matches `rfc-chat-recovery-work-budget`.\nconst DEFAULT_DETACHED_NO_PROGRESS_BUDGET_MS = 60 * 60 * 1000;\n// How long a detached terminal-delivery claim is leased before another delivery\n// path (a backbone reconcile racing the warm fast path, or a re-delivery after\n// a crash mid-handler) may re-claim it. Guards against a double-fire on the\n// happy path while guaranteeing at-least-once delivery under failure.\nconst DETACHED_DELIVERY_LEASE_MS = 60_000;\n// Escalating cadence for the self-scheduling detached reconcile backbone. The\n// warm fast path makes the first entries near-moot; these bound worst-case\n// post-eviction latency while keeping steady-state alarm cost low. The schedule\n// cancels itself once no detached run remains outstanding.\nconst DETACHED_BACKBONE_CADENCE_S = [5, 15, 30, 120];\n// Detached runs hold a `maxConcurrentAgentTools` slot for their ENTIRE life and\n// have no observer to notice them piling up. With the default `Infinity` cap\n// that is a real leak footgun, so the framework emits an edge-triggered warning\n// when the live (non-terminal) detached count first crosses this threshold,\n// rather than silently accumulating. (A separate `maxConcurrentDetachedAgentTools`\n// cap is deferred until evidence shows the single cap conflates two budgets.)\nconst DETACHED_LIVE_COUNT_WARN_THRESHOLD = 50;\nconst DETACHED_RECONCILE_CALLBACK = \"_cfDetachedReconcileTick\";\n// Conventional method name a chat agent (Think / AIChatAgent) implements to\n// receive `detached: { notify: true }` completions. Resolved by name so the\n// base Agent stays decoupled from the chat layer.\nconst DETACHED_NOTIFY_CALLBACK = \"_cfDetachedNotifyFinish\";\ntype AgentToolRecoveryInspection =\n | {\n status: \"inspected\";\n adapter: AgentToolChildAdapter;\n inspection: AgentToolRunInspection | null;\n }\n | { status: \"failed\" }\n | { status: \"timed-out\" };\n\n/**\n * Schema version for the Agent's internal SQLite tables.\n * Bump this when adding new tables, columns, or migrations.\n * The constructor stores this as a row in cf_agents_state and checks it\n * on wake to skip DDL on established DOs.\n */\nconst CURRENT_SCHEMA_VERSION = 11;\n\nconst SCHEMA_VERSION_ROW_ID = \"cf_schema_version\";\nconst STATE_ROW_ID = \"cf_state_row_id\";\n// Legacy key — no longer written, but read for backward compatibility with\n// DOs that were created before the single-row state optimization.\nconst STATE_WAS_CHANGED = \"cf_state_was_changed\";\n\nconst DEFAULT_STATE = {} as unknown;\n\n/**\n * Internal key used to store the readonly flag in connection state.\n * Prefixed with _cf_ to avoid collision with user state keys.\n */\nconst CF_READONLY_KEY = \"_cf_readonly\";\n\n/**\n * Internal key used to store the no-protocol flag in connection state.\n * When set, protocol messages (identity, state sync, MCP servers) are not\n * sent to this connection — neither on connect nor via broadcasts.\n */\nconst CF_NO_PROTOCOL_KEY = \"_cf_no_protocol\";\n\n/**\n * Internal key used to store voice call state in connection state.\n * Used by the voice mixin to track whether a connection is in an active call.\n */\nconst CF_VOICE_IN_CALL_KEY = \"_cf_voiceInCall\";\n\n/**\n * The set of all internal keys stored in connection state that must be\n * hidden from user code and preserved across setState calls.\n */\nconst CF_INTERNAL_KEYS: ReadonlySet<string> = new Set([\n CF_READONLY_KEY,\n CF_NO_PROTOCOL_KEY,\n CF_VOICE_IN_CALL_KEY,\n CF_SUB_AGENT_OUTER_URL_KEY,\n CF_SUB_AGENT_TAGS_KEY\n]);\n\n/** Check if a raw connection state object contains any internal keys. */\nfunction rawHasInternalKeys(raw: Record<string, unknown>): boolean {\n for (const key of Object.keys(raw)) {\n if (CF_INTERNAL_KEYS.has(key)) return true;\n }\n return false;\n}\n\n/** Return a copy of `raw` with all internal keys removed, or null if no user keys remain. */\nfunction stripInternalKeys(\n raw: Record<string, unknown>\n): Record<string, unknown> | null {\n const result: Record<string, unknown> = {};\n let hasUserKeys = false;\n for (const key of Object.keys(raw)) {\n if (!CF_INTERNAL_KEYS.has(key)) {\n result[key] = raw[key];\n hasUserKeys = true;\n }\n }\n return hasUserKeys ? result : null;\n}\n\n/** Return a copy containing only the internal keys present in `raw`. */\nfunction extractInternalFlags(\n raw: Record<string, unknown>\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(raw)) {\n if (CF_INTERNAL_KEYS.has(key)) {\n result[key] = raw[key];\n }\n }\n return result;\n}\n\n/** Max length for error strings broadcast to clients. */\nconst MAX_ERROR_STRING_LENGTH = 500;\n\n/**\n * Sanitize an error string before broadcasting to clients.\n * MCP error strings may contain untrusted content from external OAuth\n * providers — truncate and strip control characters to limit XSS risk.\n */\n// Regex to match C0 control characters (except \\t, \\n, \\r) and DEL.\nconst CONTROL_CHAR_RE = new RegExp(\n // oxlint-disable-next-line no-control-regex -- intentionally matching control chars for sanitization\n \"[\\\\u0000-\\\\u0008\\\\u000B\\\\u000C\\\\u000E-\\\\u001F\\\\u007F]\",\n \"g\"\n);\n\nfunction sanitizeErrorString(error: string | null): string | null {\n if (error === null) return null;\n // Strip control characters (keep printable ASCII + common unicode)\n let sanitized = error.replace(CONTROL_CHAR_RE, \"\");\n if (sanitized.length > MAX_ERROR_STRING_LENGTH) {\n sanitized = sanitized.substring(0, MAX_ERROR_STRING_LENGTH) + \"...\";\n }\n return sanitized;\n}\n\n/**\n * Tracks which agent constructors have already emitted the onStateUpdate\n * deprecation warning, so it fires at most once per class.\n */\nconst _onStateUpdateWarnedClasses = new WeakSet<Function>();\n\n/**\n * Tracks which agent constructors have already emitted the\n * sendIdentityOnConnect deprecation warning, so it fires at most once per class.\n */\nconst _sendIdentityWarnedClasses = new WeakSet<Function>();\n\n/**\n * Default options for Agent configuration.\n * Child classes can override specific options without spreading.\n */\nexport const DEFAULT_AGENT_STATIC_OPTIONS = {\n /** Whether to send identity (name, agent) to clients on connect */\n sendIdentityOnConnect: true,\n /**\n * Timeout in seconds before a running interval schedule is considered \"hung\"\n * and force-reset. Increase this if you have callbacks that legitimately\n * take longer than 30 seconds.\n */\n hungScheduleTimeoutSeconds: 30,\n /**\n * Interval in milliseconds for keepAlive() alarm heartbeats.\n * Lower values mean faster recovery after eviction but more frequent alarms.\n */\n keepAliveIntervalMs: DEFAULT_KEEP_ALIVE_INTERVAL_MS,\n /** Default retry options for schedule(), queue(), and this.retry() */\n retry: {\n maxAttempts: 3,\n baseDelayMs: 100,\n maxDelayMs: 3000\n } satisfies Required<RetryOptions>,\n /** Timeout for internal framework fiber recovery hooks. */\n fiberRecoveryHookTimeoutMs: 10_000,\n /** Soft deadline for one interrupted-fiber recovery scan. */\n fiberRecoveryScanDeadlineMs: 10_000,\n /**\n * Maximum age of an unmanaged interrupted-fiber row before recovery gives\n * up. Bounds repeated retries of a `onFiberRecovered()` hook that keeps\n * throwing so a poison row cannot re-trigger forever across boots.\n */\n fiberRecoveryMaxAgeMs: 24 * 60 * 60 * 1000,\n /**\n * No-progress budget (ms) for re-attaching to a still-running agent-tool\n * child after a deploy / parent recovery (#1630). Bounds how long the parent\n * waits with NO forward progress from the child; it resets on every forwarded\n * chunk, so a child that keeps streaming is never abandoned mid-flight. Only a\n * genuinely silent/hung child seals `interrupted` after a full window. Raise\n * for children with long quiet stretches between outputs.\n */\n agentToolReattachNoProgressTimeoutMs:\n DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS,\n /**\n * Optional hard wall-clock ceiling (ms) on a single agent-tool re-attach\n * (#1630). Caps the total wait even as the no-progress budget re-arms across\n * stream-closes. Defaults to `Infinity` (no implicit cap), mirroring\n * chat-recovery's `maxRecoveryWork` (#1672): a healthy, still-advancing child\n * is followed for as long as it makes progress — a hung child is bounded by\n * the no-progress budget, and a content-runaway by the child's own\n * `maxRecoveryWork` / `shouldKeepRecovering`. Set a finite value to impose a\n * wall-clock cap (which also tears the child down on `window-exceeded`).\n */\n agentToolReattachMaxWindowMs: DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS,\n detachedMaxBudgetMs: DEFAULT_DETACHED_MAX_BUDGET_MS,\n detachedNoProgressBudgetMs: DEFAULT_DETACHED_NO_PROGRESS_BUDGET_MS,\n /**\n * Consecutive alarm invocations that may end in a Durable Object memory-limit\n * reset (the isolate exceeded its 128 MB limit) before the alarm-boundary\n * circuit breaker stops the platform's auto-retry loop and seals the looping\n * work (#1825). A small budget tolerates a genuinely transient memory spike;\n * a deterministic OOM (the work's footprint, not the platform, is the cause)\n * is bounded here regardless of whether the in-DO recovery budgets could run.\n */\n maxAlarmMemoryLimitStrikes: 3\n};\n\n/**\n * Fully resolved agent options — all fields are defined with concrete values.\n */\ninterface ResolvedAgentOptions {\n sendIdentityOnConnect: boolean;\n hungScheduleTimeoutSeconds: number;\n keepAliveIntervalMs: number;\n retry: Required<RetryOptions>;\n fiberRecoveryHookTimeoutMs: number;\n fiberRecoveryScanDeadlineMs: number;\n fiberRecoveryMaxAgeMs: number;\n agentToolReattachNoProgressTimeoutMs: number;\n agentToolReattachMaxWindowMs: number;\n detachedMaxBudgetMs: number;\n detachedNoProgressBudgetMs: number;\n maxAlarmMemoryLimitStrikes: number;\n}\n\n/**\n * Configuration options for the Agent.\n * Override in subclasses via `static options`.\n * All fields are optional - defaults are applied at runtime.\n */\nexport interface AgentStaticOptions {\n sendIdentityOnConnect?: boolean;\n hungScheduleTimeoutSeconds?: number;\n /**\n * Interval in milliseconds for keepAlive() alarm heartbeats.\n * Default: 30000 (30 seconds). Lower values mean faster recovery\n * after eviction but more frequent alarms.\n */\n keepAliveIntervalMs?: number;\n /** Default retry options for schedule(), queue(), and this.retry(). */\n retry?: RetryOptions;\n /**\n * Timeout in milliseconds for internal framework fiber recovery hooks.\n * User-defined `onFiberRecovered()` hooks are not timed out by default.\n */\n fiberRecoveryHookTimeoutMs?: number;\n /** Soft deadline in milliseconds for one interrupted-fiber recovery scan. */\n fiberRecoveryScanDeadlineMs?: number;\n /**\n * Maximum age in milliseconds of an unmanaged interrupted-fiber row before\n * recovery stops retrying a repeatedly-throwing `onFiberRecovered()` hook\n * and discards the row (emitting `fiber:recovery:skipped` with reason\n * `max_age_exceeded`). Defaults to 24h.\n *\n * Set to `0` to retain rows indefinitely. NOTE: with `0`, a hook that keeps\n * throwing is retried forever — the recovery alarm backs off exponentially\n * (capped at 5 minutes) so it is not a busy-loop, but the Durable Object\n * stays warm (never idle-evicts) for as long as the un-recoverable row\n * exists. Prefer a finite age unless you intend to inspect/clear such rows\n * yourself.\n */\n fiberRecoveryMaxAgeMs?: number;\n /**\n * No-progress budget in milliseconds for re-attaching to a still-running\n * agent-tool child after a deploy / parent recovery (#1630). Resets on every\n * forwarded chunk, so a steadily-streaming child is never abandoned; only a\n * genuinely silent child seals `interrupted` after a full window.\n * Default: 120000 (2 minutes). Set to `0` to skip waiting (collect only an\n * already-terminal child). Set to `Infinity` to never seal on no-progress —\n * a silent-but-alive child is then followed until its stream closes (or the\n * `agentToolReattachMaxWindowMs` ceiling fires), mirroring that knob's\n * \"Infinity = off\" convention.\n */\n agentToolReattachNoProgressTimeoutMs?: number;\n /**\n * Optional hard wall-clock ceiling in milliseconds on a single agent-tool\n * re-attach (#1630). Caps the total wait even as the no-progress budget\n * re-arms across stream-closes. Default: `Infinity` (no implicit cap),\n * mirroring chat-recovery's `maxRecoveryWork` (#1672) — a healthy,\n * still-advancing child is followed for as long as it makes progress, exactly\n * as on the live (never-evicted) path. Set a finite value to impose a\n * wall-clock cap (which also tears the child down on `window-exceeded`); `0`\n * also disables the ceiling.\n */\n agentToolReattachMaxWindowMs?: number;\n /**\n * Absolute safety ceiling in milliseconds for a DETACHED (\"background\")\n * agent-tool run dispatched via `runAgentTool(cls, { detached: ... })`\n * (rfc-detached-agent-tools). A detached run has no awaiting parent turn, so\n * on expiry the parent gives up watching — delivers the completion hook with\n * `interrupted` / `budget-exceeded` and tears the child down — rather than\n * holding a concurrency slot + live facet forever. Unlike the re-attach\n * window this defaults to a FINITE value (24h) precisely because an abandoned\n * detached run has no observer to notice the leak. Override per-run via\n * `detached: { maxBudgetMs }`.\n */\n detachedMaxBudgetMs?: number;\n /**\n * Resetting no-progress window in milliseconds for a DETACHED agent-tool run\n * (rfc-detached-agent-tools §progress). Once the child has emitted at least\n * one `reportProgress` signal, the parent gives up if the run then goes\n * silent for this long; the window resets on every subsequent signal. A child\n * that never reports progress is bounded only by `detachedMaxBudgetMs` — we\n * never give up on a run merely for taking a long time, only for going silent\n * after it began reporting. Default: 1h. Set `0`/`Infinity` to disable (rely\n * on the absolute ceiling only). Override per-run via\n * `detached: { noProgressBudgetMs }`.\n */\n detachedNoProgressBudgetMs?: number;\n /**\n * Consecutive alarm invocations that may end in a Durable Object memory-limit\n * reset (the isolate exceeded its 128 MB limit) before the alarm-boundary\n * circuit breaker stops the platform's auto-retry loop and seals the looping\n * recovery work (#1825). Default: 3. Set to `0` to seal on the first such\n * reset. This is the universal backstop for the case where the in-DO recovery\n * budgets (`chatRecovery.maxOomRetries` / `maxRecoveryWork`) can't engage\n * because the OOM bypasses them — e.g. it is thrown before the budget code\n * runs, or its own writes also OOM. The boundary handler runs at the outermost\n * alarm frame, after the heavy turn has unwound and GC has reclaimed its\n * footprint, so its small seal/purge writes can land where mid-turn writes\n * could not.\n */\n maxAlarmMemoryLimitStrikes?: number;\n}\n\n/**\n * Parse the raw `retry_options` TEXT column from a SQLite row into a\n * typed `RetryOptions` object, or `undefined` if not set.\n */\nfunction parseRetryOptions(\n row: Record<string, unknown>\n): RetryOptions | undefined {\n const raw = row.retry_options;\n if (typeof raw !== \"string\") return undefined;\n return JSON.parse(raw) as RetryOptions;\n}\n\n/**\n * Resolve per-task retry options against class-level defaults and call\n * `tryN`. This is the retry-execution path for queue flush; Scheduler owns\n * its own copy for schedule callbacks.\n */\nfunction resolveRetryConfig(\n taskRetry: RetryOptions | undefined,\n defaults: Required<RetryOptions>\n): { maxAttempts: number; baseDelayMs: number; maxDelayMs: number } {\n return {\n maxAttempts: taskRetry?.maxAttempts ?? defaults.maxAttempts,\n baseDelayMs: taskRetry?.baseDelayMs ?? defaults.baseDelayMs,\n maxDelayMs: taskRetry?.maxDelayMs ?? defaults.maxDelayMs\n };\n}\n\n// `isDurableObjectCodeUpdateReset` / `isPlatformTransientError` live in\n// ./retries and remain re-exported from the package root so higher layers\n// classify platform failures with the same matcher instead of drifting copies.\n\n/** Compatibility alias for the lifecycle-owned current Agent accessor. */\nexport const getCurrentAgent = getCurrentLifecycleAgent as <\n T extends DurableObject = Agent<Cloudflare.Env>\n>() => CurrentAgentContext<T, AgentEmail>;\n\n/**\n * Restore Agent context when a public method is entered outside a Lifecycle\n * hook, notably through native Durable Object RPC or cross-Agent re-entry.\n * Lifecycle already owns context for its capability and semantic user hooks.\n */\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- generic callable constraint\nfunction withAgentContext<T extends (...args: any[]) => any>(\n method: T\n): (\n this: Agent<Cloudflare.Env, unknown>,\n ...args: Parameters<T>\n) => ReturnType<T> {\n return function (...args: Parameters<T>): ReturnType<T> {\n const { agent } = getCurrentAgent();\n\n if (agent === this) {\n // already wrapped, so we can just call the method\n return method.apply(this, args);\n }\n // Crossing to a different Agent must not carry native I/O handles\n // from the previous request/WebSocket/email turn into the new DO.\n return runInInvocation(\n {\n agent: this,\n connection: undefined,\n request: undefined,\n email: undefined\n },\n () => {\n return method.apply(this, args);\n }\n );\n };\n}\n\n/**\n * Extract string keys from Env where the value is a Workflow binding.\n */\ntype WorkflowBinding<E> = {\n [K in keyof E & string]: E[K] extends Workflow ? K : never;\n}[keyof E & string];\n\n/**\n * Type for workflow name parameter.\n * When Env has typed Workflow bindings, provides autocomplete for those keys.\n * Also accepts any string for dynamic use cases and compatibility.\n * The `string & {}` trick preserves autocomplete while allowing any string.\n */\ntype WorkflowName<E> = WorkflowBinding<E> | (string & {});\n\n/**\n * Base class for creating Agent implementations\n * @template Env Environment type containing bindings\n * @template State State type to store within the Agent\n */\nexport class Agent<\n Env extends Cloudflare.Env = Cloudflare.Env,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>\n> extends DurableObject<Env> {\n /**\n * Runtime lifecycle and reusable durable capabilities for this Agent.\n *\n * @experimental The API surface may change before stabilizing.\n */\n readonly lifecycle = Lifecycle.install<Env, Props>(this, {\n maxAlarmMemoryLimitStrikes: this._resolvedOptions.maxAlarmMemoryLimitStrikes\n });\n\n /**\n * WebSocket connection subsystem. Constructed as a field initializer\n * so it exists before the constructor installs it; the handler arrows\n * defer to `this.*`, so they always hit the framework-wrapped hooks.\n * Those wrappers still open their own invocation scope even though\n * the capability's dispatch already entered one via the host invoker\n * — the inner wrap is kept because the wrapped hooks are also invoked\n * from paths that do not pass through the capability (facet bridging,\n * direct calls).\n */\n private readonly _webSockets = new WebSockets({\n handlers: {\n onConnect: (connection, ctx) => this.onConnect(connection, ctx),\n onMessage: (connection, message) => this.onMessage(connection, message),\n onClose: (connection, code, reason, wasClean) =>\n this.onClose(connection, code, reason, wasClean),\n onError: (connection, error) => this.onError(connection, error)\n },\n // Agent's callable interface comes from its existing public\n // surface — @callable()-decorated methods — served here over the\n // Cap'n Web endpoint and, natively, over the legacy JSON RPC\n // protocol: one interface on every wire, no new Agent members.\n // Capability hosts pass an RpcTarget directly instead.\n callables: callablesFromDecorated(this),\n getConnectionTags: (connection, ctx) =>\n this.getConnectionTags(connection, ctx)\n });\n\n /** Run user initialization after lifecycle components have started. */\n onStart(_props?: Props): void | Promise<void> {}\n\n /** Handle an HTTP request not claimed by a lifecycle component. */\n onRequest(_request: Request): Response | Promise<Response> {\n return new Response(\"Not implemented\", { status: 404 });\n }\n\n /** Handle a newly accepted hibernating WebSocket connection. */\n onConnect(\n _connection: Connection,\n _context: ConnectionContext\n ): void | Promise<void> {}\n\n /** Handle a message from a hibernating WebSocket connection. */\n onMessage(\n _connection: Connection,\n _message: WSMessage\n ): void | Promise<void> {}\n\n /** Handle a hibernating WebSocket connection closing. */\n onClose(\n _connection: Connection,\n _code: number,\n _reason: string,\n _wasClean: boolean\n ): void | Promise<void> {}\n\n /** Return tags persisted with a hibernating WebSocket connection. */\n getConnectionTags(\n _connection: Connection,\n _context: ConnectionContext\n ): string[] | Promise<string[]> {\n return [];\n }\n\n /** @internal Ensure lifecycle startup before a native RPC implementation. */\n async __unsafe_ensureInitialized(props?: Props): Promise<void> {\n await this.lifecycle.start(props);\n }\n\n private _state = DEFAULT_STATE as State;\n private _disposables = new DisposableStore();\n private _destroyed = false;\n\n /**\n * Stores raw state accessors for wrapped connections.\n * Used by internal flag methods (readonly, no-protocol) to read/write\n * _cf_-prefixed keys without going through the user-facing state/setState.\n */\n private _rawStateAccessors = new WeakMap<\n Connection,\n {\n getRaw: () => Record<string, unknown> | null;\n setRaw: (state: unknown) => unknown;\n }\n >();\n\n /**\n * Cached persistence-hook dispatch mode, computed once in the constructor.\n * - \"new\" → call onStateChanged\n * - \"old\" → call onStateUpdate (deprecated)\n * - \"none\" → neither hook is overridden, skip entirely\n */\n private _persistenceHookMode: \"new\" | \"old\" | \"none\" = \"none\";\n\n /** True when this agent runs as a facet (sub-agent) inside a parent. */\n private _isFacet = false;\n\n private _protocolBroadcastExcludeIds = new Set<string>();\n\n /**\n * User-facing facet name. For legacy facets this is the same as\n * `ctx.id.name`; path-scoped facets use an internal routing id and\n * keep the logical name here instead.\n * @internal\n */\n private _facetName?: string;\n\n /**\n * Ancestor chain, root-first. Empty for top-level DOs; populated at\n * facet init time from the parent's own `selfPath`. Exposed publicly\n * via the `parentPath` getter.\n * @internal\n */\n private _parentPath: ReadonlyArray<AgentPathStep> = [];\n\n /** Warn-once guard: `chatRecovery` reassigned during onStart() (too late for wake recovery). */\n private _warnedChatRecoveryInOnStart = false;\n\n /**\n * Number of active keepAlive() callers. When > 0, `_syncHostJobs()`\n * caps the next alarm at `keepAliveIntervalMs` so the DO stays alive.\n * Purely in-memory — lost on eviction, which is correct because the\n * in-memory work keepAlive was protecting is also lost.\n * @internal\n */\n _keepAliveRefs = 0;\n\n /** @internal The extracted dynamic-agent (facet) machinery. */\n private _dynamicAgentsInstance: DynamicAgentsInternal | undefined;\n\n /** @internal */\n private get _dynamicAgents(): DynamicAgentsInternal {\n this._dynamicAgentsInstance ??= new DynamicAgentsInternal(\n this as unknown as DynamicAgentHostPort\n );\n return this._dynamicAgentsInstance;\n }\n\n /** @internal */\n private _dynamicAgentsApi: DynamicAgentsApi | undefined;\n\n /**\n * The dynamic-agents capability: facet-backed child agents that run\n * in their own isolate with their own SQLite database, colocated\n * with — and supervised by — this agent.\n *\n * Use dynamic agents for code whose class or lifecycle this agent\n * owns: dynamically-loaded or AI-generated code, per-run tool\n * agents, sandboxed components. For independent peers (for example\n * one Durable Object per chat), use `getAgentByName` instead.\n *\n * ```ts\n * const child = await this.dynamicAgents.get(Researcher, id);\n * await child.doWork();\n * this.dynamicAgents.abort(Researcher, id, reason);\n * await this.dynamicAgents.delete(Researcher, id);\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\n get dynamicAgents(): DynamicAgentsApi {\n this._dynamicAgentsApi ??= new DynamicAgentsApi(this._dynamicAgents);\n return this._dynamicAgentsApi;\n }\n\n /** @internal In-memory set of fiber IDs running in this process. */\n private _runFiberActiveFibers = new Set<string>();\n /** @internal In-memory abort controllers for managed running fibers. */\n private _managedFiberAbortControllers = new Map<string, AbortController>();\n /** @internal In-memory executions for callers that want to await accepted work. */\n private _managedFiberExecutions = new Map<string, Promise<void>>();\n /** @internal In-memory waiters for managed fibers reaching terminal ledger state. */\n private _managedFiberTerminalWaiters = new Map<string, Set<() => void>>();\n /** @internal Prevents re-entrant recovery from overlapping alarm ticks. */\n private _runFiberRecoveryInProgress = false;\n /**\n * @internal Consecutive runFiber-recovery scans that made NO forward progress\n * while work was still pending. Drives the exponential backoff of the\n * recovery follow-up alarm so a repeatedly-throwing recovery hook does not\n * busy-loop the DO. Reset to 0 whenever a scan recovers anything.\n */\n private _recoveryNoProgressScans = 0;\n /** @internal Single-flight background recovery for parent agent-tool rows. */\n private _agentToolRunRecoveryPromise: Promise<void> | undefined;\n /** @internal Serializes detached-backbone arming against concurrent dispatch. */\n private _detachedBackboneArming: Promise<void> = Promise.resolve();\n /** @internal Edge-trigger latch for the live-detached-count warning. */\n private _detachedLiveCountWarned = false;\n\n private _ParentClass: typeof Agent<Env, State> =\n Object.getPrototypeOf(this).constructor;\n\n /**\n * Durable scheduling capability installed into this Agent's Lifecycle.\n *\n * @experimental The API surface may change before stabilizing. Agent's\n * schedule()/scheduleEvery()/getScheduleById()/listSchedules()/\n * cancelSchedule() methods are the stable surface.\n */\n readonly scheduler: Scheduler;\n\n /**\n * Durable replayable execution capability installed into this Agent's\n * Lifecycle. Declare definitions on the overridable\n * {@link taskDefinitions} property and start runs with\n * `this.tasks.run(name, input, options)`.\n *\n * @experimental The API surface may change before stabilizing.\n */\n readonly tasks: Tasks;\n\n /**\n * Named Task definitions for this Agent, resolved lazily on every\n * dispatch. Declare as a field so the map is rebuilt on every Durable\n * Object wake — that is what lets in-flight runs resolve their persisted\n * definition names after a restart:\n *\n * ```ts\n * readonly taskDefinitions = {\n * \"build-report@v1\": async (input: ReportInput, step: TaskStep) => {\n * // ...\n * }\n * } satisfies TaskHandlers;\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\n declare readonly taskDefinitions?: TaskHandlers;\n\n readonly mcp: MCPClientManager;\n\n /**\n * Initial state for the Agent\n * Override to provide default state values\n */\n initialState: State = DEFAULT_STATE as State;\n\n /**\n * Stable key for Workers AI session affinity (prefix-cache optimization).\n *\n * Uses the Durable Object ID, which is globally unique across all agent\n * classes and stable for the lifetime of the instance. Pass this value as\n * the `sessionAffinity` option when creating a Workers AI model so that\n * requests from the same agent instance are routed to the same backend\n * replica, improving KV-prefix-cache hit rates across conversation turns.\n *\n * @example\n * ```typescript\n * const workersai = createWorkersAI({ binding: this.env.AI });\n * const model = workersai(\"@cf/meta/llama-3.3-70b-instruct-fp8-fast\", {\n * sessionAffinity: this.sessionAffinity,\n * });\n * ```\n */\n get sessionAffinity(): string {\n return this.ctx.id.toString();\n }\n\n /**\n * Current state of the Agent\n */\n get state(): State {\n if (this._state !== DEFAULT_STATE) {\n // state was previously set, and populated internal state\n return this._state;\n }\n // looks like this is the first time the state is being accessed\n // check if the state was set in a previous life\n const result = this.sql<{ state: State | undefined }>`\n SELECT state FROM cf_agents_state WHERE id = ${STATE_ROW_ID}\n `;\n\n // Row existence is the signal that state was previously set.\n // This handles all values including falsy ones (null, 0, false, \"\").\n if (result.length > 0) {\n const state = result[0].state as string;\n\n try {\n this._state = JSON.parse(state);\n } catch (e) {\n console.error(\n \"Failed to parse stored state, falling back to initialState:\",\n e\n );\n if (this.initialState !== DEFAULT_STATE) {\n this._state = this.initialState;\n // Persist the fixed state to prevent future parse errors\n this._setStateInternal(this.initialState);\n } else {\n // No initialState defined - clear corrupted data to prevent infinite retry loop\n this.sql`DELETE FROM cf_agents_state WHERE id = ${STATE_ROW_ID}`;\n return undefined as State;\n }\n }\n return this._state;\n }\n\n // ok, this is the first time the state is being accessed\n // and the state was not set in a previous life\n // so we need to set the initial state (if provided)\n if (this.initialState === DEFAULT_STATE) {\n // no initial state provided, so we return undefined\n return undefined as State;\n }\n // initial state provided, so we set the state,\n // update db and return the initial state\n this._setStateInternal(this.initialState);\n return this.initialState;\n }\n\n /**\n * Agent configuration options.\n * Override in subclasses - only specify what you want to change.\n * @example\n * class SecureAgent extends Agent {\n * static options = { sendIdentityOnConnect: false };\n * }\n */\n static options: AgentStaticOptions = {};\n\n /**\n * Resolved options (merges defaults with subclass overrides).\n * Cached after first access — static options never change during the\n * lifetime of a Durable Object instance.\n */\n private _cachedOptions?: ResolvedAgentOptions;\n private get _resolvedOptions(): ResolvedAgentOptions {\n if (this._cachedOptions) return this._cachedOptions;\n const ctor = this.constructor as typeof Agent;\n const userRetry = ctor.options?.retry;\n this._cachedOptions = {\n sendIdentityOnConnect:\n ctor.options?.sendIdentityOnConnect ??\n DEFAULT_AGENT_STATIC_OPTIONS.sendIdentityOnConnect,\n hungScheduleTimeoutSeconds:\n ctor.options?.hungScheduleTimeoutSeconds ??\n DEFAULT_AGENT_STATIC_OPTIONS.hungScheduleTimeoutSeconds,\n keepAliveIntervalMs:\n ctor.options?.keepAliveIntervalMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.keepAliveIntervalMs,\n retry: {\n maxAttempts:\n userRetry?.maxAttempts ??\n DEFAULT_AGENT_STATIC_OPTIONS.retry.maxAttempts,\n baseDelayMs:\n userRetry?.baseDelayMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.retry.baseDelayMs,\n maxDelayMs:\n userRetry?.maxDelayMs ?? DEFAULT_AGENT_STATIC_OPTIONS.retry.maxDelayMs\n },\n fiberRecoveryHookTimeoutMs:\n ctor.options?.fiberRecoveryHookTimeoutMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryHookTimeoutMs,\n fiberRecoveryScanDeadlineMs:\n ctor.options?.fiberRecoveryScanDeadlineMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryScanDeadlineMs,\n fiberRecoveryMaxAgeMs:\n ctor.options?.fiberRecoveryMaxAgeMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryMaxAgeMs,\n agentToolReattachNoProgressTimeoutMs:\n ctor.options?.agentToolReattachNoProgressTimeoutMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.agentToolReattachNoProgressTimeoutMs,\n agentToolReattachMaxWindowMs:\n ctor.options?.agentToolReattachMaxWindowMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.agentToolReattachMaxWindowMs,\n detachedMaxBudgetMs:\n ctor.options?.detachedMaxBudgetMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.detachedMaxBudgetMs,\n detachedNoProgressBudgetMs:\n ctor.options?.detachedNoProgressBudgetMs ??\n DEFAULT_AGENT_STATIC_OPTIONS.detachedNoProgressBudgetMs,\n maxAlarmMemoryLimitStrikes:\n ctor.options?.maxAlarmMemoryLimitStrikes ??\n DEFAULT_AGENT_STATIC_OPTIONS.maxAlarmMemoryLimitStrikes\n };\n return this._cachedOptions;\n }\n\n /**\n * The observability implementation to use for the Agent\n */\n observability?: Observability = genericObservability;\n\n /**\n * Emit an observability event with auto-generated timestamp.\n * @internal\n */\n protected _emit(\n type: ObservabilityEvent[\"type\"],\n payload: Record<string, unknown> = {}\n ): void {\n this.observability?.emit({\n type,\n agent: this._ParentClass.name,\n name: this.name,\n payload,\n timestamp: Date.now()\n } as ObservabilityEvent);\n }\n\n /** Run SDK work under a stable parent for platform child spans. */\n private _withAgentSpan<T>(\n operation: string,\n storagePhase: string,\n attributes: TraceAttributes,\n run: (update: (attributes: TraceAttributes) => void) => Promise<T>\n ): Promise<T>;\n private _withAgentSpan<T>(\n operation: string,\n storagePhase: string,\n attributes: TraceAttributes,\n run: (update: (attributes: TraceAttributes) => void) => T\n ): T;\n private _withAgentSpan<T>(\n operation: string,\n storagePhase: string,\n attributes: TraceAttributes,\n run: (update: (attributes: TraceAttributes) => void) => T | Promise<T>\n ): T | Promise<T> {\n // The instance name is not always readable during construction: facets\n // restore it after construction and unnamed DOs receive it later.\n let agentId: string | undefined;\n try {\n agentId = this.name;\n } catch {\n agentId = undefined;\n }\n\n return tracer.withSpan(\n operation,\n {\n ...agentSpanAttributes({\n agentClassName: this._ParentClass.name,\n sessionId: this.ctx.id.toString(),\n sessionName: agentId\n }),\n \"cloudflare.agents.operation.name\": operation,\n \"cloudflare.agents.storage.grouped\": true,\n \"cloudflare.agents.storage.system\": \"durable_object\",\n \"cloudflare.agents.storage.phase\": storagePhase,\n ...attributes\n },\n (span) =>\n run((finishAttributes) => writeSpanAttributes(span, finishAttributes)),\n agentContext.getStore()?.connection === undefined\n ? undefined\n : { boundToInvocation: true }\n );\n }\n\n /**\n * Execute SQL queries against the Agent's database\n * @template T Type of the returned rows\n * @param strings SQL query template strings\n * @param values Values to be inserted into the query\n * @returns Array of query results\n */\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n let query = \"\";\n try {\n // Construct the SQL query with placeholders\n query = strings.reduce(\n (acc, str, i) => acc + str + (i < values.length ? \"?\" : \"\"),\n \"\"\n );\n\n // Execute the SQL query with the provided values\n return [...this.ctx.storage.sql.exec(query, ...values)] as T[];\n } catch (e) {\n throw new SqlError(query, e);\n }\n }\n private _schemaInitialization:\n | {\n previousVersion: number;\n currentVersion: number;\n migrated: boolean;\n }\n | undefined;\n\n /**\n * Create all internal tables and run migrations if needed.\n * Called by the constructor on every wake. Idempotent — skips DDL when\n * the stored schema version matches CURRENT_SCHEMA_VERSION.\n *\n * Protected so that test agents can re-run the real migration path\n * after manipulating DB state (since ctx.abort() is unavailable in\n * local dev and the constructor only runs once per DO instance).\n */\n protected _ensureSchema(): void {\n // Schema version gating: skip all DDL on established DOs whose schema\n // is already up-to-date. We always create cf_agents_state first (cheap\n // idempotent DDL) and store the version as a row inside it.\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_state (\n id TEXT PRIMARY KEY NOT NULL,\n state TEXT\n )\n `;\n\n const versionRow = this.sql<{ state: string | null }>`\n SELECT state FROM cf_agents_state WHERE id = ${SCHEMA_VERSION_ROW_ID}\n `;\n const schemaVersion =\n versionRow.length > 0 ? Number(versionRow[0].state) : 0;\n\n if (schemaVersion < CURRENT_SCHEMA_VERSION) {\n ensureMcpServerTable(this.ctx.storage);\n\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_queues (\n id TEXT PRIMARY KEY NOT NULL,\n payload TEXT,\n callback TEXT,\n created_at INTEGER DEFAULT (unixepoch())\n )\n `;\n\n // Migration: add queue retry options for existing agents.\n // Schedule schema and migrations are owned by Scheduler.\n const addColumnIfNotExists = (sql: string) => {\n try {\n this.ctx.storage.sql.exec(sql);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n if (!message.toLowerCase().includes(\"duplicate column\")) {\n throw error;\n }\n }\n };\n\n addColumnIfNotExists(\n \"ALTER TABLE cf_agents_queues ADD COLUMN retry_options TEXT\"\n );\n\n // Workflow tracking table for Agent-Workflow integration\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_workflows (\n id TEXT PRIMARY KEY NOT NULL,\n workflow_id TEXT NOT NULL UNIQUE,\n workflow_name TEXT NOT NULL,\n status TEXT NOT NULL CHECK(status IN (\n 'queued', 'running', 'paused', 'errored',\n 'terminated', 'complete', 'waiting',\n 'waitingForPause', 'unknown'\n )),\n metadata TEXT,\n error_name TEXT,\n error_message TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n updated_at INTEGER NOT NULL DEFAULT (unixepoch()),\n completed_at INTEGER\n )\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_workflows_status ON cf_agents_workflows(status)\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_workflows_name ON cf_agents_workflows(workflow_name)\n `;\n\n // Clean up legacy STATE_WAS_CHANGED rows from the single-row state optimization\n this.ctx.storage.sql.exec(\n \"DELETE FROM cf_agents_state WHERE id = ?\",\n STATE_WAS_CHANGED\n );\n\n // v3: durable fibers table for runFiber\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_runs (\n id TEXT PRIMARY KEY NOT NULL,\n name TEXT NOT NULL,\n snapshot TEXT,\n created_at INTEGER NOT NULL\n )\n `;\n\n // v5: root-side index of descendant facet fibers. The fiber's\n // authoritative row stays in the facet's own cf_agents_runs table;\n // this table only lets the root alarm owner know which facets need\n // recovery checks while they are idle.\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_facet_runs (\n owner_path TEXT NOT NULL,\n owner_path_key TEXT NOT NULL,\n run_id TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n PRIMARY KEY (owner_path_key, run_id)\n )\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_facet_runs_owner_path_key\n ON cf_agents_facet_runs(owner_path_key)\n `;\n\n // v8: managed fiber job ledger for idempotent acceptance,\n // inspection, cancellation, and terminal cleanup.\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agents_fibers (\n fiber_id TEXT PRIMARY KEY,\n idempotency_key TEXT UNIQUE,\n name TEXT NOT NULL,\n status TEXT NOT NULL,\n snapshot TEXT,\n metadata_json TEXT,\n error_message TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER\n )\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_fibers_status_created\n ON cf_agents_fibers(status, created_at, fiber_id)\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_fibers_name_status_created\n ON cf_agents_fibers(name, status, created_at, fiber_id)\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_fibers_status_completed\n ON cf_agents_fibers(status, completed_at, created_at)\n `;\n\n this.sql`\n CREATE TABLE IF NOT EXISTS cf_agent_tool_runs (\n run_id TEXT PRIMARY KEY,\n parent_tool_call_id TEXT,\n agent_type TEXT NOT NULL,\n input_preview TEXT,\n input_redacted INTEGER NOT NULL DEFAULT 1,\n status TEXT NOT NULL,\n summary TEXT,\n output_json TEXT,\n error_message TEXT,\n interrupted_reason TEXT,\n child_still_running INTEGER,\n display_metadata TEXT,\n display_order INTEGER NOT NULL DEFAULT 0,\n started_at INTEGER NOT NULL,\n completed_at INTEGER\n )\n `;\n\n this.sql`\n CREATE INDEX IF NOT EXISTS idx_agent_tool_runs_parent_tool_call_id\n ON cf_agent_tool_runs(parent_tool_call_id, display_order)\n `;\n\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN output_json TEXT\"\n );\n // #1630 follow-up: persist the typed interrupted cause so it survives a\n // reconnect replay (otherwise live clients see `reason`/`childStillRunning`\n // but reconnecting clients replay them as `undefined`).\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN interrupted_reason TEXT\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN child_still_running INTEGER\"\n );\n // Detached (\"background\") runs (rfc-detached-agent-tools). `detached`\n // marks a run dispatched without an awaiting parent turn;\n // `detached_on_finish` is the parent METHOD NAME to call on terminal\n // (durable, eviction-surviving — like a `schedule` callback);\n // `detached_notify_source` is a caller-controlled chat metadata source for\n // the `notify` sugar; `detached_max_budget_at` is the absolute give-up\n // deadline. The four ledger columns implement a two-slot (finish /\n // give-up) claim+lease so delivery is exactly-once on the happy path and\n // at-least-once under failure — give-up and finish are INDEPENDENT slots\n // so a premature give-up can never dedupe a child's real late completion\n // away (the production incident in #1752).\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached INTEGER NOT NULL DEFAULT 0\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached_on_finish TEXT\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached_notify_source TEXT\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached_max_budget_at INTEGER\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN finish_claimed_at INTEGER\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN finish_delivered_at INTEGER\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN give_up_claimed_at INTEGER\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN give_up_delivered_at INTEGER\"\n );\n // Detached progress (rfc-detached-agent-tools §progress). The resetting\n // no-progress window DURATION (not an absolute deadline — it floats with\n // the child's latest signal) and the parent's last-observed signal time.\n // The backbone reconcile reads the child's authoritative `progress.at`\n // via `inspectAgentToolRun`; this cached value is a best-effort liveness\n // hint observed off the warm tail so a still-warm parent does not have to\n // inspect on every tick.\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached_no_progress_budget_ms INTEGER\"\n );\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN last_progress_at INTEGER\"\n );\n // Chat-host `detached: { onMilestones }` convenience (4b): JSON\n // `{ names, mode }` — the milestone names that inject an idempotent chat\n // notification when reached, and whether to \"react\" (model turn) or\n // \"narrate\" (synthetic assistant line). Persisted so the cold backbone\n // reconcile can deliver them after eviction, not only the warm tail.\n addColumnIfNotExists(\n \"ALTER TABLE cf_agent_tool_runs ADD COLUMN detached_on_milestones TEXT\"\n );\n\n // Mark schema as up-to-date\n this.sql`\n INSERT OR REPLACE INTO cf_agents_state (id, state)\n VALUES (${SCHEMA_VERSION_ROW_ID}, ${String(CURRENT_SCHEMA_VERSION)})\n `;\n }\n\n this._schemaInitialization = {\n previousVersion: schemaVersion,\n currentVersion: CURRENT_SCHEMA_VERSION,\n migrated: schemaVersion < CURRENT_SCHEMA_VERSION\n };\n }\n\n constructor(ctx: AgentContext, env: Env) {\n super(ctx, env);\n\n const routeHost = this;\n setLifecycleRouteTransport(this.lifecycle, {\n get source() {\n return routeHost._lifecycleRouteAddress();\n },\n toRoot: (envelope) => this._routeLifecycleToRoot(envelope),\n to: (target, envelope) => this._routeLifecycleToTarget(target, envelope)\n });\n setLifecycleEventSink(this.lifecycle, (event) => {\n const payload =\n event.payload !== null &&\n typeof event.payload === \"object\" &&\n !Array.isArray(event.payload)\n ? (event.payload as Record<string, unknown>)\n : { value: event.payload };\n // Lifecycle events are open-ended; Agent's installed capabilities emit\n // event names represented by the observability union.\n this._emit(event.type as ObservabilityEvent[\"type\"], payload);\n });\n\n // Capability-run user callbacks (scheduled callbacks today, future\n // capability callbacks tomorrow) enter through Agent's invocation\n // boundary so they get the same tracing span scope as every other Agent\n // entry point.\n // Connection-scoped callbacks (e.g. from a WebSockets capability)\n // carry their live connection/request in the scope.\n setLifecycleHostInvoker(this.lifecycle, (run, scope) =>\n runInInvocation(\n {\n agent: this,\n connection: scope?.connection,\n request: scope?.request,\n email: undefined\n },\n run\n )\n );\n\n this.scheduler = new Scheduler({\n retry: this._resolvedOptions.retry,\n hungScheduleTimeoutSeconds:\n this._resolvedOptions.hungScheduleTimeoutSeconds,\n onError: (error: unknown) =>\n runInInvocation(\n {\n agent: this,\n connection: undefined,\n request: undefined,\n email: undefined\n },\n () => this.onError(error)\n )\n });\n\n // Agent's historical name-based scheduling API: names outside the\n // (empty) registered map resolve to methods on this Agent. The resolved\n // handler still runs inside the Lifecycle host boundary, so it gets the\n // tracing invocation scope installed above.\n setSchedulerCallbackResolver(this.scheduler, (name) => {\n const method = this[name as keyof this];\n if (typeof method !== \"function\") return undefined;\n return (payload, schedule) =>\n (\n method as (payload: unknown, schedule: Schedule<unknown>) => unknown\n ).call(this, payload, schedule);\n });\n\n this.tasks = new Tasks({\n onError: (error) => this.onError(error)\n });\n\n // Twin bridge for a routed Task run: the physical alarm lives on the\n // root, but the run's storage and this hook live on the owning dynamic\n // agent, whose own Lifecycle never observes the root's alarm directly.\n setTaskRoutedMemoryLimitHandler(this.tasks, (context) => {\n const hook = (\n this as unknown as {\n onAlarmMemoryLimit?: (value: typeof context) => void | Promise<void>;\n }\n ).onAlarmMemoryLimit;\n return hook?.call(this, context);\n });\n\n // Framework-internal reserved (`__cf`-prefixed) definitions — chat\n // turns, chat recovery, messenger replies — register eagerly through\n // `this.tasks.register()` from each host subclass's own constructor\n // (AIChatAgent, Think), which runs after `this.tasks` exists here.\n // What remains for Agent to bridge is only the end user's own\n // overridable `taskDefinitions` field, which cannot be read yet: a\n // further-downstream subclass's field initializer runs only after\n // every constructor body up this chain (this one included) returns.\n // The resolver stays lazy for exactly that reason; nothing else needs\n // it any more.\n setTaskDefinitionResolver(\n this.tasks,\n (name) =>\n this.taskDefinitions?.[name] as TaskCallbacks[string] | undefined\n );\n\n this.mcp = this._withAgentSpan(\n \"agent_initialization\",\n \"initialization\",\n {},\n (update) => {\n if (!wrappedClasses.has(this.constructor)) {\n // Auto-wrap custom methods with agent context\n this._autoWrapCustomMethods();\n wrappedClasses.add(this.constructor);\n }\n\n this._withAgentSpan(\n \"initialize_agent_storage\",\n \"initialization\",\n {},\n (updateStorage) => {\n this._ensureSchema();\n const schemaAttributes = {\n \"cloudflare.agents.schema.version.previous\":\n this._schemaInitialization?.previousVersion,\n \"cloudflare.agents.schema.version.current\":\n this._schemaInitialization?.currentVersion,\n \"cloudflare.agents.schema.migrated\":\n this._schemaInitialization?.migrated\n };\n updateStorage(schemaAttributes);\n update(schemaAttributes);\n }\n );\n\n // Initialize MCPClientManager AFTER tables are created.\n return new MCPClientManager(this._ParentClass.name, \"0.0.1\", {\n env: this.env,\n createAuthProvider: (callbackUrl) =>\n this.createMcpOAuthProvider(callbackUrl)\n });\n }\n );\n\n // Agent's WebSocket connections ride the WebSockets capability —\n // Lifecycle itself no longer models connections. The handlers call\n // through `this.*` so they always hit the framework-wrapped hooks.\n this.lifecycle\n .use(this.scheduler)\n .use(this.mcp)\n .use(this._webSockets, { fallback: true })\n .use(this.tasks)\n // Registered for capability identity/services; its hot paths are\n // wired directly (see the DynamicAgentsInternal class doc).\n .use(this._dynamicAgents);\n\n // MCP starts before Agent restores facet routing state. Defer its initial\n // publication until broadcasts can be routed to the correct owner.\n let mcpBroadcastReady = false;\n this._disposables.add(\n this.mcp.onServerStateChanged(() => {\n if (mcpBroadcastReady) this.broadcastMcpServers();\n })\n );\n\n // Emit MCP observability events\n this._disposables.add(\n this.mcp.onObservabilityEvent((event) => {\n this.observability?.emit({\n ...event,\n agent: this._ParentClass.name,\n name: this.name\n });\n })\n );\n // Compute persistence-hook dispatch mode once.\n // Throws immediately if both hooks are overridden on the same class.\n {\n const proto = Object.getPrototypeOf(this);\n const hasOwnNew = Object.prototype.hasOwnProperty.call(\n proto,\n \"onStateChanged\"\n );\n const hasOwnOld = Object.prototype.hasOwnProperty.call(\n proto,\n \"onStateUpdate\"\n );\n\n if (hasOwnNew && hasOwnOld) {\n throw new Error(\n `[Agent] Cannot override both onStateChanged and onStateUpdate. ` +\n `Remove onStateUpdate — it has been renamed to onStateChanged.`\n );\n }\n\n if (hasOwnOld) {\n const ctor = this.constructor;\n if (!_onStateUpdateWarnedClasses.has(ctor)) {\n _onStateUpdateWarnedClasses.add(ctor);\n console.warn(\n `[Agent] onStateUpdate is deprecated. Rename to onStateChanged — the behavior is identical.`\n );\n }\n }\n\n const base = Agent.prototype;\n if (proto.onStateChanged !== base.onStateChanged) {\n this._persistenceHookMode = \"new\";\n } else if (proto.onStateUpdate !== base.onStateUpdate) {\n this._persistenceHookMode = \"old\";\n }\n // default \"none\" already set in field initializer\n }\n\n const _onAlarm = this.onAlarm.bind(this);\n this.onAlarm = async () => {\n if (this._destroyed) return;\n await _onAlarm();\n if (this._destroyed) return;\n await this._onAlarmHousekeeping();\n // Housekeeping scans change fiber/facet/keep-alive state; refresh the\n // host jobs that guarantee their wakes before Lifecycle re-arms.\n if (this._destroyed) return;\n await this._syncHostJobs();\n };\n\n const _onRequest = this.onRequest.bind(this);\n this.onRequest = (request: Request) => {\n return runInInvocation(\n { agent: this, connection: undefined, request, email: undefined },\n () => this._tryCatch(() => _onRequest(request))\n );\n };\n\n const _onMessage = this.onMessage.bind(this);\n this.onMessage = async (connection: Connection, message: WSMessage) => {\n const replyBridge = subAgentRpcReplyContext.getStore()?.bridge;\n // Lifecycle establishes the root socket context before entering this\n // wrapper. Do not carry root-owned native I/O into the facet RPC.\n if (\n await agentContext.exit(() =>\n this._cf_forwardSubAgentWebSocketMessage(\n connection,\n message,\n replyBridge\n )\n )\n ) {\n return;\n }\n this._ensureConnectionWrapped(connection);\n return runInInvocation(\n { agent: this, connection, request: undefined, email: undefined },\n async () => {\n if (typeof message !== \"string\") {\n return this._tryCatch(() => _onMessage(connection, message));\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch (_e) {\n // silently fail and let the onMessage handler handle it\n return this._tryCatch(() => _onMessage(connection, message));\n }\n\n if (isStateUpdateMessage(parsed)) {\n // Check if connection is readonly\n if (this.isConnectionReadonly(connection)) {\n // Send error response back to the connection\n connection.send(\n JSON.stringify({\n type: MessageType.CF_AGENT_STATE_ERROR,\n error: \"Connection is readonly\"\n })\n );\n return;\n }\n try {\n this._setStateInternal(parsed.state as State, connection);\n } catch (e) {\n // validateStateChange (or another sync error) rejected the update.\n // Log the full error server-side, send a generic message to the client.\n console.error(\"[Agent] State update rejected:\", e);\n connection.send(\n JSON.stringify({\n type: MessageType.CF_AGENT_STATE_ERROR,\n error: \"State update rejected\"\n })\n );\n }\n return;\n }\n\n if (isRPCRequest(parsed)) {\n try {\n const { id, method, args } = parsed;\n\n // Check if method exists and is callable\n const methodFn = this[method as keyof this];\n if (typeof methodFn !== \"function\") {\n throw new Error(`Method ${method} does not exist`);\n }\n\n if (!this._isCallable(method)) {\n throw new Error(`Method ${method} is not callable`);\n }\n\n const metadata = getCallableMetadata(methodFn as Function);\n\n // For streaming methods, pass a StreamingResponse object\n if (metadata?.streaming) {\n const stream = new StreamingResponse(connection, id);\n if (replyBridge) {\n registerFacetStreamingDelivery(stream, replyBridge);\n }\n\n this._emit(\"rpc\", { method, streaming: true });\n\n try {\n await methodFn.apply(this, [stream, ...args]);\n } catch (err) {\n console.error(`Error in streaming method \"${method}\":`, err);\n this._emit(\"rpc:error\", {\n method,\n error: err instanceof Error ? err.message : String(err)\n });\n // Auto-close stream with error if method throws before closing\n if (!stream.isClosed) {\n stream.error(\n err instanceof Error ? err.message : String(err)\n );\n }\n }\n await waitForFacetStreamingResponseDeliveries(stream);\n return;\n }\n\n // For regular methods, execute and send response\n const result = await methodFn.apply(this, args);\n\n this._emit(\"rpc\", { method, streaming: metadata?.streaming });\n\n const response: RPCResponse = {\n done: true,\n id,\n result,\n success: true,\n type: MessageType.RPC\n };\n if (replyBridge) {\n await sendFacetRpcResponseIfOpen(replyBridge, response)\n .completion;\n } else {\n sendRpcResponseIfOpen(connection, response);\n }\n } catch (e) {\n const response: RPCResponse = {\n error:\n e instanceof Error ? e.message : \"Unknown error occurred\",\n id: parsed.id,\n success: false,\n type: MessageType.RPC\n };\n if (replyBridge) {\n await sendFacetRpcResponseIfOpen(replyBridge, response)\n .completion;\n } else {\n sendRpcResponseIfOpen(connection, response);\n }\n\n console.error(\"RPC error:\", e);\n this._emit(\"rpc:error\", {\n method: parsed.method,\n error: e instanceof Error ? e.message : String(e)\n });\n }\n return;\n }\n\n return this._tryCatch(() => _onMessage(connection, message));\n }\n );\n };\n\n const _onConnect = this.onConnect.bind(this);\n this.onConnect = async (connection: Connection, ctx: ConnectionContext) => {\n this._ensureConnectionWrapped(connection);\n const subAgentOuterUrl = ctx.request.headers.get(\n SUB_AGENT_OUTER_URL_HEADER\n );\n if (subAgentOuterUrl) {\n this._unsafe_setConnectionFlag(\n connection,\n CF_SUB_AGENT_OUTER_URL_KEY,\n subAgentOuterUrl\n );\n }\n // Lifecycle establishes the root socket/request context before entering\n // this wrapper. Do not carry root-owned native I/O into the facet RPC.\n if (\n await agentContext.exit(() =>\n this._cf_forwardSubAgentWebSocketConnect(connection, ctx.request, {\n gate: false\n })\n )\n ) {\n return;\n }\n // TODO: This is a hack to ensure the state is sent after the connection is established\n // must fix this\n return runInInvocation(\n { agent: this, connection, request: ctx.request, email: undefined },\n async () => {\n // Check if connection should be readonly before sending any messages\n // so that the flag is set before the client can respond\n if (this.shouldConnectionBeReadonly(connection, ctx)) {\n this.setConnectionReadonly(connection, true);\n }\n\n // Check if protocol messages should be suppressed for this\n // connection. When disabled, no identity/state/MCP text frames\n // are sent — useful for binary-only clients (e.g. MQTT devices).\n if (this.shouldSendProtocolMessages(connection, ctx)) {\n // Send agent identity first so client knows which instance it's connected to\n // Can be disabled via static options for security-sensitive instance names\n if (this._resolvedOptions.sendIdentityOnConnect) {\n const ctor = this.constructor as typeof Agent;\n if (\n ctor.options?.sendIdentityOnConnect === undefined &&\n !_sendIdentityWarnedClasses.has(ctor) &&\n // Facets are always addressed via `/sub/{class}/{name}`\n // in the OUTER client URL, even though the request the\n // facet itself receives has that segment stripped by\n // `_cf_forwardToFacet`. The sendIdentityOnConnect\n // concern (name only reachable via identity push) does\n // not apply — skip the warning entirely for facets.\n !this._isFacet\n ) {\n // Only warn when using custom routing — with default routing\n // the name is already visible in the URL path (/agents/{class}/{name})\n // so sendIdentityOnConnect leaks no additional information.\n const urlPath = new URL(ctx.request.url).pathname;\n if (!urlPath.includes(this.name)) {\n _sendIdentityWarnedClasses.add(ctor);\n console.warn(\n `[Agent] ${ctor.name}: sending instance name \"${this.name}\" to clients ` +\n `via sendIdentityOnConnect (the name is not visible in the URL with ` +\n `custom routing). If this name is sensitive, add ` +\n `\\`static options = { sendIdentityOnConnect: false }\\` to opt out. ` +\n `Set it to true to silence this message.`\n );\n }\n }\n connection.send(\n JSON.stringify({\n name: this.name,\n agent: camelCaseToKebabCase(this._ParentClass.name),\n type: MessageType.CF_AGENT_IDENTITY\n })\n );\n }\n\n const wasExcludedFromStateInitBroadcast =\n this._protocolBroadcastExcludeIds.has(connection.id);\n let currentState: State | undefined;\n this._protocolBroadcastExcludeIds.add(connection.id);\n try {\n currentState = this.state;\n } finally {\n if (!wasExcludedFromStateInitBroadcast) {\n this._protocolBroadcastExcludeIds.delete(connection.id);\n }\n }\n\n if (currentState !== undefined) {\n connection.send(\n JSON.stringify({\n state: currentState,\n type: MessageType.CF_AGENT_STATE\n })\n );\n }\n\n connection.send(\n JSON.stringify({\n mcp: this.getMcpServers(),\n type: MessageType.CF_AGENT_MCP_SERVERS\n })\n );\n } else {\n this._setConnectionNoProtocol(connection);\n }\n\n this._emit(\"connect\", { connectionId: connection.id });\n await this._replayAgentToolRuns(connection);\n return this._tryCatch(() => _onConnect(connection, ctx));\n }\n );\n };\n\n const _onClose = this.onClose.bind(this);\n this.onClose = async (\n connection: Connection,\n code: number,\n reason: string,\n wasClean: boolean\n ) => {\n // Lifecycle establishes the root socket context before entering this\n // wrapper. Do not carry root-owned native I/O into the facet RPC.\n if (\n await agentContext.exit(() =>\n this._cf_forwardSubAgentWebSocketClose(\n connection,\n code,\n reason,\n wasClean\n )\n )\n ) {\n return;\n }\n return runInInvocation(\n { agent: this, connection, request: undefined, email: undefined },\n () => {\n this._emit(\"disconnect\", {\n connectionId: connection.id,\n code,\n reason\n });\n return _onClose(connection, code, reason, wasClean);\n }\n );\n };\n\n const _onStart = this.onStart.bind(this);\n const startAgent = async (\n props: Props | undefined,\n update: (attributes: TraceAttributes) => void\n ) => {\n return runInInvocation(\n {\n agent: this,\n connection: undefined,\n request: undefined,\n email: undefined\n },\n async () => {\n await this._restoreAgentFacetContext();\n\n await this._tryCatch(async () => {\n mcpBroadcastReady = true;\n this.broadcastMcpServers();\n\n const startupAgentToolRunIds = await this._withAgentSpan(\n \"recover_agent_work\",\n \"startup\",\n {},\n async () => {\n this._checkOrphanedWorkflows();\n await this._checkRunFibers();\n // Interrupted Task runs (including chat turns) recover via\n // the Lifecycle job queue: their mirror jobs are overdue and\n // re-fire on the post-startup alarm derivation.\n return this._agentToolRunRecoveryRunIds();\n }\n );\n update({\n \"cloudflare.agents.start.facet\": this._isFacet,\n \"cloudflare.agents.recovery.agent_tools.count\":\n startupAgentToolRunIds.length\n });\n\n // Chat recovery (above, in `_checkRunFibers`) evaluates its budgets\n // — and may seal an interrupted turn, firing `onExhausted` — BEFORE\n // the user's onStart runs. So a `chatRecovery` config produced\n // inside onStart is applied too late for the recovery that matters.\n // Snapshot the reference (subclasses like Think / AIChatAgent expose\n // `chatRecovery`; plain Agents leave it undefined) so we can warn if\n // onStart swaps in a custom config object below.\n const chatRecoveryBefore = (this as { chatRecovery?: unknown })\n .chatRecovery;\n\n const result = await this._withAgentSpan(\n \"run_user_on_start\",\n \"startup\",\n {},\n () => _onStart(props)\n );\n\n const chatRecoveryAfter = (this as { chatRecovery?: unknown })\n .chatRecovery;\n // Warn when onStart swaps in any recognized recovery config. A\n // custom config is applied too late for this wake, while a legacy\n // `false` value no longer disables durable recovery.\n const chatRecoveryAfterMatters =\n typeof chatRecoveryAfter === \"boolean\" ||\n (typeof chatRecoveryAfter === \"object\" &&\n chatRecoveryAfter !== null);\n if (\n !this._warnedChatRecoveryInOnStart &&\n chatRecoveryBefore !== chatRecoveryAfter &&\n chatRecoveryAfterMatters\n ) {\n this._warnedChatRecoveryInOnStart = true;\n console.warn(\n \"[Agent] `chatRecovery` was assigned during onStart(). Chat \" +\n \"recovery evaluates its budgets (and may seal an interrupted \" +\n \"turn, firing onExhausted) on wake BEFORE onStart() runs, so a \" +\n \"config set here is applied too late and the built-in defaults \" +\n \"are used for the recovery that matters. Assign `chatRecovery` \" +\n \"as a class field or in the constructor instead.\"\n );\n }\n\n this._scheduleAgentToolRunRecovery({\n runIds: startupAgentToolRunIds\n });\n\n // Push-based host jobs replace the pull-based alarm contribution:\n // re-sync them on every wake so orphaned fiber/facet recovery\n // state left by a dead process re-arms its housekeeping wake.\n await this._syncHostJobs();\n return result;\n });\n }\n );\n };\n this.onStart = (props?: Props) =>\n this._withAgentSpan(\"agent_start\", \"startup\", {}, (update) =>\n startAgent(props, update)\n );\n }\n\n private async _restoreAgentFacetContext(): Promise<void> {\n await this._withAgentSpan(\"restore_agent_state\", \"startup\", {}, () =>\n this._dynamicAgents.restoreFacetContext()\n );\n }\n\n /**\n * Check for workflows referencing unknown bindings and warn with migration suggestion.\n */\n private _checkOrphanedWorkflows(): void {\n // Get distinct workflow names with counts by active/completed status\n const distinctNames = this.sql<{\n workflow_name: string;\n total: number;\n active: number;\n completed: number;\n }>`\n SELECT \n workflow_name,\n COUNT(*) as total,\n SUM(CASE WHEN status NOT IN ('complete', 'errored', 'terminated') THEN 1 ELSE 0 END) as active,\n SUM(CASE WHEN status IN ('complete', 'errored', 'terminated') THEN 1 ELSE 0 END) as completed\n FROM cf_agents_workflows \n GROUP BY workflow_name\n `;\n\n const orphaned = distinctNames.filter(\n (row) => !this._findWorkflowBindingByName(row.workflow_name)\n );\n\n if (orphaned.length > 0) {\n const currentBindings = this._getWorkflowBindingNames();\n for (const {\n workflow_name: oldName,\n total,\n active,\n completed\n } of orphaned) {\n const suggestion =\n currentBindings.length === 1\n ? `this.migrateWorkflowBinding('${oldName}', '${currentBindings[0]}')`\n : `this.migrateWorkflowBinding('${oldName}', '<NEW_BINDING_NAME>')`;\n const breakdown =\n active > 0 && completed > 0\n ? ` (${active} active, ${completed} completed)`\n : active > 0\n ? ` (${active} active)`\n : ` (${completed} completed)`;\n console.warn(\n `[Agent] Found ${total} workflow(s) referencing unknown binding '${oldName}'${breakdown}. ` +\n `If you renamed the binding, call: ${suggestion}`\n );\n }\n }\n }\n\n /**\n * Broadcast a protocol message only to connections that have protocol\n * messages enabled. Connections where shouldSendProtocolMessages returned\n * false are excluded automatically.\n * @param msg The JSON-encoded protocol message\n * @param excludeIds Additional connection IDs to exclude (e.g. the source)\n */\n private _broadcastProtocol(msg: string, excludeIds: string[] = []) {\n const exclude = [...excludeIds, ...this._protocolBroadcastExcludeIds];\n for (const conn of this.getConnections()) {\n if (!this.isConnectionProtocolEnabled(conn)) {\n exclude.push(conn.id);\n }\n }\n this.broadcast(msg, exclude);\n }\n\n private _setStateInternal(\n nextState: State,\n source: Connection | \"server\" = \"server\"\n ): void {\n // Validation/gating hook (sync only)\n this.validateStateChange(nextState, source);\n\n // Persist state — row existence in cf_agents_state is the signal that\n // state was set (no separate wasChanged flag needed).\n this._state = nextState;\n this.sql`\n INSERT OR REPLACE INTO cf_agents_state (id, state)\n VALUES (${STATE_ROW_ID}, ${JSON.stringify(nextState)})\n `;\n\n // Broadcast state to protocol-enabled connections, excluding the source\n this._broadcastProtocol(\n JSON.stringify({\n state: nextState,\n type: MessageType.CF_AGENT_STATE\n }),\n source !== \"server\" ? [source.id] : []\n );\n\n // Notification hook (non-gating). Run after broadcast and do not block.\n // Use waitUntil for reliability after the handler returns.\n const { connection, request, email } = agentContext.getStore() || {};\n this.ctx.waitUntil(\n (async () => {\n try {\n await runInInvocation(\n { agent: this, connection, request, email },\n async () => {\n this._emit(\"state:update\");\n await this._callStatePersistenceHook(nextState, source);\n },\n // Runs past the handler that set the state, on waitUntil's own\n // extension of the invocation.\n { detached: true }\n );\n } catch (e) {\n // onStateChanged/onStateUpdate errors should not affect state or broadcasts\n try {\n await this.onError(e);\n } catch {\n // swallow\n }\n }\n })()\n );\n }\n\n /**\n * Update the Agent's state\n * @param state New state to set\n * @throws Error if called from a readonly connection context\n */\n setState(state: State): void {\n // Check if the current context has a readonly connection\n const store = agentContext.getStore();\n if (store?.connection && this.isConnectionReadonly(store.connection)) {\n throw new Error(\"Connection is readonly\");\n }\n this._setStateInternal(state, \"server\");\n }\n\n /**\n * Wraps connection.state and connection.setState so that internal\n * _cf_-prefixed flags (readonly, no-protocol) are hidden from user code\n * and cannot be accidentally overwritten.\n *\n * Idempotent — safe to call multiple times on the same connection.\n * After hibernation, the _rawStateAccessors WeakMap is empty but the\n * connection's state getter still reads from the persisted WebSocket\n * attachment. Calling this method re-captures the raw getter so that\n * predicate methods (isConnectionReadonly, isConnectionProtocolEnabled)\n * work correctly post-hibernation.\n */\n private _ensureConnectionWrapped(connection: Connection) {\n if (this._rawStateAccessors.has(connection)) return;\n\n // Hibernating lifecycle connections expose attachment-backed state as a\n // configurable accessor. Virtual facet connections use a data property,\n // so retain both projections below.\n const descriptor = Object.getOwnPropertyDescriptor(connection, \"state\");\n\n let getRaw: () => Record<string, unknown> | null;\n let setRaw: (state: unknown) => unknown;\n\n if (descriptor?.get) {\n // Accessor property — bind the original getter directly.\n // The getter reads from the serialized WebSocket attachment, so it\n // always returns the latest value even after setState updates it.\n getRaw = descriptor.get.bind(connection) as () => Record<\n string,\n unknown\n > | null;\n setRaw = connection.setState.bind(connection);\n } else {\n // Data property — track raw state in a closure variable.\n // Reading `connection.state` after our override would call our filtered\n // getter (circular), so we snapshot the value here and keep it in sync.\n let rawState = (connection.state ?? null) as Record<\n string,\n unknown\n > | null;\n getRaw = () => rawState;\n setRaw = (state: unknown) => {\n rawState = state as Record<string, unknown> | null;\n return rawState;\n };\n }\n\n this._rawStateAccessors.set(connection, { getRaw, setRaw });\n\n // Override state getter to hide all internal _cf_ flags from user code\n Object.defineProperty(connection, \"state\", {\n configurable: true,\n enumerable: true,\n get() {\n const raw = getRaw();\n if (raw != null && typeof raw === \"object\" && rawHasInternalKeys(raw)) {\n return stripInternalKeys(raw);\n }\n return raw;\n }\n });\n\n // Override setState to preserve internal flags when user sets state\n Object.defineProperty(connection, \"setState\", {\n configurable: true,\n writable: true,\n value(stateOrFn: unknown | ((prev: unknown) => unknown)) {\n const raw = getRaw();\n const flags =\n raw != null && typeof raw === \"object\"\n ? extractInternalFlags(raw as Record<string, unknown>)\n : {};\n const hasFlags = Object.keys(flags).length > 0;\n\n let newUserState: unknown;\n if (typeof stateOrFn === \"function\") {\n // Pass only the user-visible state (without internal flags) to the callback\n const userVisible = hasFlags\n ? stripInternalKeys(raw as Record<string, unknown>)\n : raw;\n newUserState = (stateOrFn as (prev: unknown) => unknown)(userVisible);\n } else {\n newUserState = stateOrFn;\n }\n\n // Merge back internal flags if any were set\n if (hasFlags) {\n if (newUserState != null && typeof newUserState === \"object\") {\n return setRaw({\n ...(newUserState as Record<string, unknown>),\n ...flags\n });\n }\n // User set null — store just the flags\n return setRaw(flags);\n }\n return setRaw(newUserState);\n }\n });\n }\n\n /**\n * Mark a connection as readonly or readwrite\n * @param connection The connection to mark\n * @param readonly Whether the connection should be readonly (default: true)\n */\n setConnectionReadonly(connection: Connection, readonly = true) {\n this._ensureConnectionWrapped(connection);\n const accessors = this._rawStateAccessors.get(connection)!;\n const raw = (accessors.getRaw() as Record<string, unknown> | null) ?? {};\n if (readonly) {\n accessors.setRaw({ ...raw, [CF_READONLY_KEY]: true });\n } else {\n // Remove the key entirely instead of storing false — avoids dead keys\n // accumulating in the connection attachment.\n const { [CF_READONLY_KEY]: _, ...rest } = raw;\n accessors.setRaw(Object.keys(rest).length > 0 ? rest : null);\n }\n }\n\n /**\n * Check if a connection is marked as readonly.\n *\n * Safe to call after hibernation — re-wraps the connection if the\n * in-memory accessor cache was cleared.\n * @param connection The connection to check\n * @returns True if the connection is readonly\n */\n isConnectionReadonly(connection: Connection): boolean {\n this._ensureConnectionWrapped(connection);\n const raw = this._rawStateAccessors.get(connection)!.getRaw() as Record<\n string,\n unknown\n > | null;\n return !!raw?.[CF_READONLY_KEY];\n }\n\n /**\n * ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️\n *\n * Read an internal `_cf_`-prefixed flag from the raw connection state,\n * bypassing the user-facing state wrapper that strips internal keys.\n *\n * This exists for framework mixins (e.g. voice) that need to persist\n * flags in the connection attachment across hibernation. Application\n * code should use `connection.state` and `connection.setState()` instead.\n *\n * @internal\n */\n _unsafe_getConnectionFlag(connection: Connection, key: string): unknown {\n this._ensureConnectionWrapped(connection);\n const raw = this._rawStateAccessors.get(connection)!.getRaw() as Record<\n string,\n unknown\n > | null;\n return raw?.[key];\n }\n\n /**\n * ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️\n *\n * Write an internal `_cf_`-prefixed flag to the raw connection state,\n * bypassing the user-facing state wrapper. The key must be registered\n * in `CF_INTERNAL_KEYS` so it is preserved across user `setState` calls\n * and hidden from `connection.state`.\n *\n * @internal\n */\n _unsafe_setConnectionFlag(\n connection: Connection,\n key: string,\n value: unknown\n ): void {\n this._ensureConnectionWrapped(connection);\n const accessors = this._rawStateAccessors.get(connection)!;\n const raw = (accessors.getRaw() as Record<string, unknown> | null) ?? {};\n if (value === undefined) {\n const { [key]: _, ...rest } = raw;\n accessors.setRaw(Object.keys(rest).length > 0 ? rest : null);\n } else {\n accessors.setRaw({ ...raw, [key]: value });\n }\n }\n\n /**\n * Override this method to determine if a connection should be readonly on connect\n * @param _connection The connection that is being established\n * @param _ctx Connection context\n * @returns True if the connection should be readonly\n */\n shouldConnectionBeReadonly(\n _connection: Connection,\n _ctx: ConnectionContext\n ): boolean {\n return false;\n }\n\n /**\n * Override this method to control whether protocol messages are sent to a\n * connection. Protocol messages include identity (CF_AGENT_IDENTITY), state\n * sync (CF_AGENT_STATE), and MCP server lists (CF_AGENT_MCP_SERVERS).\n *\n * When this returns `false` for a connection, that connection will not\n * receive any protocol text frames — neither on connect nor via broadcasts.\n * This is useful for binary-only clients (e.g. MQTT devices) that cannot\n * handle JSON text frames.\n *\n * The connection can still send and receive regular messages, use RPC, and\n * participate in all non-protocol communication.\n *\n * @param _connection The connection that is being established\n * @param _ctx Connection context (includes the upgrade request)\n * @returns True if protocol messages should be sent (default), false to suppress them\n */\n shouldSendProtocolMessages(\n _connection: Connection,\n _ctx: ConnectionContext\n ): boolean {\n return true;\n }\n\n /**\n * Check if a connection has protocol messages enabled.\n * Protocol messages include identity, state sync, and MCP server lists.\n *\n * Safe to call after hibernation — re-wraps the connection if the\n * in-memory accessor cache was cleared.\n * @param connection The connection to check\n * @returns True if the connection receives protocol messages\n */\n isConnectionProtocolEnabled(connection: Connection): boolean {\n this._ensureConnectionWrapped(connection);\n const raw = this._rawStateAccessors.get(connection)!.getRaw() as Record<\n string,\n unknown\n > | null;\n return !raw?.[CF_NO_PROTOCOL_KEY];\n }\n\n /**\n * Mark a connection as having protocol messages disabled.\n * Called internally when shouldSendProtocolMessages returns false.\n */\n private _setConnectionNoProtocol(connection: Connection) {\n this._ensureConnectionWrapped(connection);\n const accessors = this._rawStateAccessors.get(connection)!;\n const raw = (accessors.getRaw() as Record<string, unknown> | null) ?? {};\n accessors.setRaw({ ...raw, [CF_NO_PROTOCOL_KEY]: true });\n }\n\n /**\n * Called before the Agent's state is persisted and broadcast.\n * Override to validate or reject an update by throwing an error.\n *\n * IMPORTANT: This hook must be synchronous.\n */\n // oxlint-disable-next-line eslint(no-unused-vars) -- params used by subclass overrides\n validateStateChange(_nextState: State, _source: Connection | \"server\") {\n // override this to validate state updates\n }\n\n /**\n * Called after the Agent's state has been persisted and broadcast to all clients.\n * This is a notification hook — errors here are routed to onError and do not\n * affect state persistence or client broadcasts.\n *\n * @param state Updated state\n * @param source Source of the state update (\"server\" or a client connection)\n */\n // oxlint-disable-next-line eslint(no-unused-vars) -- params used by subclass overrides\n onStateChanged(_state: State | undefined, _source: Connection | \"server\") {\n // override this to handle state updates after persist + broadcast\n }\n\n /**\n * @deprecated Renamed to `onStateChanged` — the behavior is identical.\n * `onStateUpdate` will be removed in the next major version.\n *\n * Called after the Agent's state has been persisted and broadcast to all clients.\n * This is a server-side notification hook. For the client-side state callback,\n * see the `onStateUpdate` option in `useAgent` / `AgentClient`.\n *\n * @param state Updated state\n * @param source Source of the state update (\"server\" or a client connection)\n */\n // oxlint-disable-next-line eslint(no-unused-vars) -- params used by subclass overrides\n onStateUpdate(_state: State | undefined, _source: Connection | \"server\") {\n // override this to handle state updates (deprecated — use onStateChanged)\n }\n\n /**\n * Dispatch to the appropriate persistence hook based on the mode\n * cached in the constructor. No prototype walks at call time.\n */\n private async _callStatePersistenceHook(\n state: State | undefined,\n source: Connection | \"server\"\n ): Promise<void> {\n switch (this._persistenceHookMode) {\n case \"new\":\n await this.onStateChanged(state, source);\n break;\n case \"old\":\n await this.onStateUpdate(state, source);\n break;\n // \"none\": neither hook overridden — skip\n }\n }\n\n /**\n * Called when the Agent receives an email via routeAgentEmail()\n * Override this method to handle incoming emails\n * @param payload Internal wire format — plain data + RpcTarget bridge\n */\n async _onEmail(payload: {\n from: string;\n to: string;\n headers: Headers;\n rawSize: number;\n _secureRouted?: boolean;\n _bridge: EmailBridge;\n }) {\n // nb: we use this roundabout way of getting to onEmail\n // because of https://github.com/cloudflare/workerd/issues/4499\n\n // Reconstruct the AgentEmail interface from the payload so the\n // user's onEmail handler sees the same API as before\n const email: AgentEmail = {\n from: payload.from,\n to: payload.to,\n headers: payload.headers,\n rawSize: payload.rawSize,\n _secureRouted: payload._secureRouted,\n getRaw: () => payload._bridge.getRaw(),\n setReject: (reason: string) => payload._bridge.setReject(reason),\n forward: (rcptTo: string, headers?: Headers) =>\n payload._bridge.forward(rcptTo, headers),\n reply: (options: { from: string; to: string; raw: string }) =>\n payload._bridge.reply(options)\n };\n\n return runInInvocation(\n { agent: this, connection: undefined, request: undefined, email },\n async () => {\n this._emit(\"email:receive\", {\n from: email.from,\n to: email.to,\n subject: email.headers.get(\"subject\") ?? undefined\n });\n if (\"onEmail\" in this && typeof this.onEmail === \"function\") {\n return this._tryCatch(() =>\n (this.onEmail as (email: AgentEmail) => Promise<void>)(email)\n );\n } else {\n console.log(\"Received email from:\", email.from, \"to:\", email.to);\n console.log(\"Subject:\", email.headers.get(\"subject\"));\n console.log(\n \"Implement onEmail(email: AgentEmail): Promise<void> in your agent to process emails\"\n );\n }\n }\n );\n }\n\n /**\n * Reply to an email\n * @param email The email to reply to\n * @param options Options for the reply\n * @param options.secret Secret for signing agent headers (enables secure reply routing).\n * Required if the email was routed via createSecureReplyEmailResolver.\n * Pass explicit `null` to opt-out of signing (not recommended for secure routing).\n * @returns void\n */\n async replyToEmail(\n email: AgentEmail,\n options: {\n fromName: string;\n subject?: string | undefined;\n body: string;\n contentType?: string;\n headers?: Record<string, string>;\n secret?: string | null;\n }\n ): Promise<void> {\n return this._tryCatch(async () => {\n // Enforce signing for emails routed via createSecureReplyEmailResolver\n if (email._secureRouted && options.secret === undefined) {\n throw new Error(\n \"This email was routed via createSecureReplyEmailResolver. \" +\n \"You must pass a secret to replyToEmail() to sign replies, \" +\n \"or pass explicit null to opt-out (not recommended).\"\n );\n }\n\n const agentName = camelCaseToKebabCase(this._ParentClass.name);\n const agentId = this.name;\n\n const { createMimeMessage } = await import(\"mimetext\");\n const msg = createMimeMessage();\n msg.setSender({ addr: email.to, name: options.fromName });\n msg.setRecipient(email.from);\n msg.setSubject(\n options.subject || `Re: ${email.headers.get(\"subject\")}` || \"No subject\"\n );\n msg.addMessage({\n contentType: options.contentType || \"text/plain\",\n data: options.body\n });\n\n const domain = email.from.split(\"@\")[1];\n const messageId = `<${agentId}@${domain}>`;\n msg.setHeader(\"In-Reply-To\", email.headers.get(\"Message-ID\")!);\n msg.setHeader(\"Message-ID\", messageId);\n msg.setHeader(\"X-Agent-Name\", agentName);\n msg.setHeader(\"X-Agent-ID\", agentId);\n\n // Sign headers if secret is provided (enables secure reply routing)\n if (typeof options.secret === \"string\") {\n const signedHeaders = await signAgentHeaders(\n options.secret,\n agentName,\n agentId\n );\n msg.setHeader(\"X-Agent-Sig\", signedHeaders[\"X-Agent-Sig\"]);\n msg.setHeader(\"X-Agent-Sig-Ts\", signedHeaders[\"X-Agent-Sig-Ts\"]);\n }\n\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n msg.setHeader(key, value);\n }\n }\n await email.reply({\n from: email.to,\n raw: msg.asRaw(),\n to: email.from\n });\n\n // Emit after the send succeeds — from/to are swapped because\n // this is a reply: the agent (email.to) is now the sender.\n const rawSubject = email.headers.get(\"subject\");\n this._emit(\"email:reply\", {\n from: email.to,\n to: email.from,\n subject:\n options.subject ?? (rawSubject ? `Re: ${rawSubject}` : undefined)\n });\n });\n }\n\n /**\n * Send an outbound email via an Email Service binding.\n *\n * Automatically injects agent routing headers (X-Agent-Name, X-Agent-ID).\n * When `secret` is provided, signs headers with HMAC-SHA256 so that replies\n * can be routed back to this agent instance via createSecureReplyEmailResolver.\n *\n * @param options.binding The send_email binding (e.g. this.env.EMAIL)\n * @param options.to Recipient address(es)\n * @param options.from Sender address or {email, name} object\n * @param options.subject Email subject line\n * @param options.text Plain text body (at least one of text/html required)\n * @param options.html HTML body (at least one of text/html required)\n * @param options.replyTo Reply-to address\n * @param options.cc CC recipient(s)\n * @param options.bcc BCC recipient(s)\n * @param options.inReplyTo Message-ID of the email this is replying to (for threading)\n * @param options.headers Additional custom headers\n * @param options.secret Secret for signing agent routing headers\n * @returns The messageId from Email Service\n */\n async sendEmail(options: SendEmailOptions): Promise<EmailSendResult> {\n return this._tryCatch(async () => {\n const result = await sendAgentEmail(options, {\n agentName: camelCaseToKebabCase(this._ParentClass.name),\n agentId: this.name\n });\n\n const fromAddr =\n typeof options.from === \"string\" ? options.from : options.from.email;\n this._emit(\"email:send\", {\n from: fromAddr,\n to: options.to,\n subject: options.subject\n });\n\n return result;\n });\n }\n\n private async _tryCatch<T>(fn: () => T | Promise<T>) {\n try {\n return await fn();\n } catch (e) {\n throw this.onError(e);\n }\n }\n\n /**\n * Wrap public subclass methods that may be entered outside Lifecycle, such as\n * native Durable Object RPC. Lifecycle hooks already have Agent context.\n */\n private _autoWrapCustomMethods() {\n // Agent.prototype traversal also covers the DurableObject base class.\n const basePrototypes = [Agent.prototype];\n const baseMethods = new Set<string>();\n for (const baseProto of basePrototypes) {\n let proto = baseProto;\n while (proto && proto !== Object.prototype) {\n const methodNames = Object.getOwnPropertyNames(proto);\n for (const methodName of methodNames) {\n baseMethods.add(methodName);\n }\n proto = Object.getPrototypeOf(proto);\n }\n }\n // Get all methods from the current instance's prototype chain\n let proto = Object.getPrototypeOf(this);\n let depth = 0;\n while (proto && proto !== Object.prototype && depth < 10) {\n const methodNames = Object.getOwnPropertyNames(proto);\n for (const methodName of methodNames) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);\n\n // Skip if it's a private method, a base method, a getter, or not a function,\n if (\n baseMethods.has(methodName) ||\n methodName.startsWith(\"_\") ||\n !descriptor ||\n !!descriptor.get ||\n typeof descriptor.value !== \"function\"\n ) {\n continue;\n }\n\n // Now, methodName is confirmed to be a custom method/function\n // Wrap the custom method with context\n /* oxlint-disable @typescript-eslint/no-explicit-any -- dynamic method wrapping requires any */\n const wrappedFunction = withAgentContext(\n this[methodName as keyof this] as (...args: any[]) => any\n ) as any;\n /* oxlint-enable @typescript-eslint/no-explicit-any */\n\n // if the method is callable, copy the metadata from the original method\n if (this._isCallable(methodName)) {\n copyCallableMetadata(\n this[methodName as keyof this] as Function,\n wrappedFunction\n );\n }\n\n // set the wrapped function on the prototype\n this.constructor.prototype[methodName as keyof this] = wrappedFunction;\n }\n\n proto = Object.getPrototypeOf(proto);\n depth++;\n }\n }\n\n onError(connection: Connection, error: unknown): void | Promise<void>;\n onError(error: unknown): void | Promise<void>;\n onError(connectionOrError: Connection | unknown, error?: unknown) {\n let theError: unknown;\n if (connectionOrError && error) {\n theError = error;\n // this is a websocket connection error\n console.error(\n \"Error on websocket connection:\",\n (connectionOrError as Connection).id,\n theError\n );\n console.error(\n \"Override onError(connection, error) to handle websocket connection errors\"\n );\n } else {\n theError = connectionOrError;\n // this is a server error\n console.error(\"Error on server:\", theError);\n console.error(\"Override onError(error) to handle server errors\");\n }\n throw theError;\n }\n\n /**\n * Render content (not implemented in base class)\n */\n render() {\n throw new Error(\"Not implemented\");\n }\n\n /**\n * Retry an async operation with exponential backoff and jitter.\n * Retries on all errors by default. Use `shouldRetry` to bail early on non-retryable errors.\n *\n * @param fn The async function to retry. Receives the current attempt number (1-indexed).\n * @param options Retry configuration.\n * @param options.maxAttempts Maximum number of attempts (including the first). Falls back to static options, then 3.\n * @param options.baseDelayMs Base delay in ms for exponential backoff. Falls back to static options, then 100.\n * @param options.maxDelayMs Maximum delay cap in ms. Falls back to static options, then 3000.\n * @param options.shouldRetry Predicate called with the error and next attempt number. Return false to stop retrying immediately. Default: retry all errors.\n * @returns The result of fn on success.\n * @throws The last error if all attempts fail or shouldRetry returns false.\n */\n async retry<T>(\n fn: (attempt: number) => Promise<T>,\n options?: RetryOptions & {\n /** Return false to stop retrying a specific error. Receives the error and the next attempt number. Default: retry all errors. */\n shouldRetry?: (err: unknown, nextAttempt: number) => boolean;\n }\n ): Promise<T> {\n const defaults = this._resolvedOptions.retry;\n if (options) {\n validateRetryOptions(options, defaults);\n }\n return tryN(options?.maxAttempts ?? defaults.maxAttempts, fn, {\n baseDelayMs: options?.baseDelayMs ?? defaults.baseDelayMs,\n maxDelayMs: options?.maxDelayMs ?? defaults.maxDelayMs,\n shouldRetry: options?.shouldRetry\n });\n }\n\n /**\n * Queue a task to be executed in the future\n * @param callback Name of the method to call\n * @param payload Payload to pass to the callback\n * @param options Options for the queued task\n * @param options.retry Retry options for the callback execution\n * @returns The ID of the queued task\n */\n async queue<T = unknown>(\n callback: keyof this,\n payload: T,\n options?: { retry?: RetryOptions }\n ): Promise<string> {\n const id = nanoid(9);\n if (typeof callback !== \"string\") {\n throw new Error(\"Callback must be a string\");\n }\n\n if (typeof this[callback] !== \"function\") {\n throw new Error(`this.${callback} is not a function`);\n }\n\n if (options?.retry) {\n validateRetryOptions(options.retry, this._resolvedOptions.retry);\n }\n\n const retryJson = options?.retry ? JSON.stringify(options.retry) : null;\n\n this.sql`\n INSERT OR REPLACE INTO cf_agents_queues (id, payload, callback, retry_options)\n VALUES (${id}, ${JSON.stringify(payload)}, ${callback}, ${retryJson})\n `;\n\n this._emit(\"queue:create\", { callback: callback as string, id });\n\n void this._flushQueue().catch((e) => {\n console.error(\"Error flushing queue:\", e);\n });\n\n return id;\n }\n\n private _flushingQueue = false;\n\n private async _flushQueue() {\n if (this._flushingQueue) {\n return;\n }\n this._flushingQueue = true;\n try {\n while (true) {\n const result = this.sql<QueueItem<string>>`\n SELECT * FROM cf_agents_queues\n ORDER BY created_at ASC\n `;\n\n if (!result || result.length === 0) {\n break;\n }\n\n for (const row of result || []) {\n const callback = this[row.callback as keyof Agent<Env>];\n if (!callback) {\n console.error(`callback ${row.callback} not found`);\n await this.dequeue(row.id);\n continue;\n }\n const { connection, request, email } = agentContext.getStore() || {};\n await runInInvocation(\n {\n agent: this,\n connection,\n request,\n email\n },\n async () => {\n const retryOpts = parseRetryOptions(\n row as unknown as Record<string, unknown>\n );\n const { maxAttempts, baseDelayMs, maxDelayMs } =\n resolveRetryConfig(retryOpts, this._resolvedOptions.retry);\n const parsedPayload = JSON.parse(row.payload as string);\n try {\n await tryN(\n maxAttempts,\n async (attempt) => {\n if (attempt > 1) {\n this._emit(\"queue:retry\", {\n callback: row.callback,\n id: row.id,\n attempt,\n maxAttempts\n });\n }\n await (\n callback as (\n payload: unknown,\n queueItem: QueueItem<string>\n ) => Promise<void>\n ).bind(this)(parsedPayload, row);\n },\n { baseDelayMs, maxDelayMs }\n );\n } catch (e) {\n console.error(\n `queue callback \"${row.callback}\" failed after ${maxAttempts} attempts`,\n e\n );\n this._emit(\"queue:error\", {\n callback: row.callback,\n id: row.id,\n error: e instanceof Error ? e.message : String(e),\n attempts: maxAttempts\n });\n try {\n await this.onError(e);\n } catch {\n // swallow onError errors\n }\n } finally {\n this.dequeue(row.id);\n }\n },\n // The drain loop is started with `void` and routinely outlives the\n // handler that enqueued the item.\n { detached: true }\n );\n }\n }\n } finally {\n this._flushingQueue = false;\n }\n }\n\n /**\n * Dequeue a task by ID\n * @param id ID of the task to dequeue\n */\n dequeue(id: string) {\n this.sql`DELETE FROM cf_agents_queues WHERE id = ${id}`;\n }\n\n /**\n * Dequeue all tasks\n */\n dequeueAll() {\n this.sql`DELETE FROM cf_agents_queues`;\n }\n\n /**\n * Dequeue all tasks by callback\n * @param callback Name of the callback to dequeue\n */\n dequeueAllByCallback(callback: string) {\n this.sql`DELETE FROM cf_agents_queues WHERE callback = ${callback}`;\n }\n\n /**\n * Get a queued task by ID\n * @param id ID of the task to get\n * @returns The task or undefined if not found\n */\n getQueue(id: string): QueueItem<string> | undefined {\n const result = this.sql<QueueItem<string>>`\n SELECT * FROM cf_agents_queues WHERE id = ${id}\n `;\n if (!result || result.length === 0) return undefined;\n const row = result[0];\n return {\n ...row,\n payload: JSON.parse(row.payload as unknown as string),\n retry: parseRetryOptions(row as unknown as Record<string, unknown>)\n };\n }\n\n /**\n * Get all queues by key and value\n * @param key Key to filter by\n * @param value Value to filter by\n * @returns Array of matching QueueItem objects\n */\n getQueues(key: string, value: string): QueueItem<string>[] {\n const result = this.sql<QueueItem<string>>`\n SELECT * FROM cf_agents_queues\n `;\n return result\n .filter(\n (row) => JSON.parse(row.payload as unknown as string)[key] === value\n )\n .map((row) => ({\n ...row,\n payload: JSON.parse(row.payload as unknown as string),\n retry: parseRetryOptions(row as unknown as Record<string, unknown>)\n }));\n }\n\n private _lifecycleRouteAddress(): LifecycleRouteAddress | undefined {\n return this._dynamicAgents.lifecycleRouteAddress();\n }\n\n private _routeLifecycleToRoot(\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n return this._dynamicAgents.routeLifecycleToRoot(envelope);\n }\n\n private _routeLifecycleToTarget(\n target: LifecycleRouteAddress,\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n return this._dynamicAgents.routeLifecycleToTarget(target, envelope);\n }\n\n /** Single native-RPC aperture for routed Lifecycle capabilities. */\n _cf_routeLifecycle(\n target: LifecycleRouteAddress | undefined,\n envelope: LifecycleRouteEnvelope\n ): Promise<unknown> {\n return this._dynamicAgents.routeLifecycle(target, envelope);\n }\n\n private _rootAlarmOwner(): Promise<RootFacetRpcSurface> {\n return this._dynamicAgents.rootAlarmOwner();\n }\n\n // ── Scheduling (delegates to agents/schedules) ─────────────────────────\n\n /**\n * Clean root-owned bookkeeping for a sub-tree of facets. This\n * bulk-cancels schedules whose `owner_path` starts with the given\n * prefix and deletes root-side facet fiber recovery leases for the\n * same sub-tree. Used by `deleteSubAgent` and recursive facet\n * destroy. Emits `schedule:cancel` on this agent (the alarm-owning\n * root) for each schedule row removed — the facets being torn down\n * may not be alive to receive the events themselves.\n * @internal\n */\n async _cf_cleanupFacetPrefix(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<void> {\n await this._dynamicAgents.cleanupPrefix(ownerPath);\n }\n\n /**\n * Acquire a root-owned keepAlive ref on behalf of a descendant facet.\n * Facets run in separate colocated isolates but cannot set their own\n * physical alarm, so this lets facet work use the root alarm heartbeat.\n * @internal\n */\n _cf_acquireFacetKeepAlive(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<string> {\n return this._dynamicAgents.acquireKeepAlive(ownerPath);\n }\n\n /**\n * Release a root-owned keepAlive ref previously acquired for a facet.\n * Idempotent so disposer calls can safely race or run twice.\n * @internal\n */\n _cf_releaseFacetKeepAlive(token: string): Promise<void> {\n return this._dynamicAgents.releaseKeepAlive(token);\n }\n\n /**\n * Register a facet's durable run row in the root-side index so root\n * alarm housekeeping can dispatch recovery checks into idle facets.\n * The facet remains authoritative for snapshots and recovery hooks.\n * @internal\n */\n _cf_registerFacetRun(\n ownerPath: ReadonlyArray<AgentPathStep>,\n runId: string\n ): Promise<void> {\n return this._dynamicAgents.registerRun(ownerPath, runId);\n }\n\n /**\n * Remove a completed facet fiber from the root-side index.\n * @internal\n */\n _cf_unregisterFacetRun(\n ownerPath: ReadonlyArray<AgentPathStep>,\n runId: string\n ): Promise<void> {\n return this._dynamicAgents.unregisterRun(ownerPath, runId);\n }\n\n /**\n * Schedule a task to be executed in the future\n *\n * Cron schedules are **idempotent by default** — calling `schedule(\"0 * * * *\", \"tick\")`\n * multiple times with the same callback, cron expression, and payload returns\n * the existing schedule instead of creating a duplicate. Set `idempotent: false`\n * to override this.\n *\n * For delayed and scheduled (Date) types, set `idempotent: true` to opt in\n * to the same dedup behavior (matched on callback + payload). This is useful\n * when calling `schedule()` in `onStart()` to avoid accumulating duplicate\n * rows across Durable Object restarts.\n *\n * @template T Type of the payload data\n * @param when When to execute the task (Date, seconds delay, or cron expression)\n * @param callback Name of the method to call\n * @param payload Data to pass to the callback\n * @param options Options for the scheduled task\n * @param options.retry Retry options for the callback execution\n * @param options.idempotent Dedup by callback+payload. Defaults to `true` for cron, `false` otherwise.\n * @returns Schedule object representing the scheduled task\n */\n schedule<T = string>(\n when: Date | string | number,\n callback: keyof this,\n payload?: T,\n options?: ScheduleOptions\n ): Promise<Schedule<T>> {\n // SAFETY: Agent's historical generic promises Schedule<T>; the untyped\n // scheduler default carries Schedule<unknown> for name-based calls.\n return this.scheduler.set(\n when,\n callback as string,\n payload,\n options\n ) as Promise<Schedule<T>>;\n }\n\n /**\n * Schedule a task to run repeatedly at a fixed interval.\n *\n * This method is **idempotent** — calling it multiple times with the same\n * `callback`, `intervalSeconds`, and `payload` returns the existing schedule\n * instead of creating a duplicate. A different interval or payload is\n * treated as a distinct schedule and creates a new row.\n *\n * This makes it safe to call in `onStart()`, which runs on every Durable\n * Object wake:\n *\n * ```ts\n * async onStart() {\n * // Only one schedule is created, no matter how many times the DO wakes\n * await this.scheduleEvery(30, \"tick\");\n * }\n * ```\n *\n * @template T Type of the payload data\n * @param intervalSeconds Number of seconds between executions\n * @param callback Name of the method to call\n * @param payload Data to pass to the callback\n * @param options Options for the scheduled task\n * @param options.retry Retry options for the callback execution\n * @returns Schedule object representing the scheduled task\n */\n scheduleEvery<T = string>(\n intervalSeconds: number,\n callback: keyof this,\n payload?: T,\n options?: { retry?: RetryOptions; _idempotent?: boolean }\n ): Promise<Schedule<T>> {\n // SAFETY: Agent's historical generic promises Schedule<T>; the untyped\n // scheduler default carries Schedule<unknown> for name-based calls.\n return this.scheduler.every(intervalSeconds, callback as string, payload, {\n retry: options?.retry,\n idempotent: options?._idempotent\n }) as Promise<Schedule<T>>;\n }\n\n /**\n * Get a scheduled task by ID\n * @template T Type of the payload data\n * @param id ID of the scheduled task\n * @returns The Schedule object or undefined if not found\n * @deprecated Use {@link getScheduleById}. This synchronous API cannot cross\n * Durable Object boundaries and throws inside sub-agents.\n */\n getSchedule<T = string>(id: string): Schedule<T> | undefined {\n return this.scheduler.__DO_NOT_USE_WILL_REMOVE__getSchedule<T>(id);\n }\n\n /**\n * Get a scheduled task by ID.\n *\n * Unlike the deprecated synchronous {@link getSchedule}, this works inside\n * sub-agents by delegating to the top-level parent that owns the alarm.\n *\n * @param id ID of the scheduled task\n * @returns The Schedule object or undefined if not found\n */\n getScheduleById(id: string): Promise<Schedule<unknown> | undefined> {\n return this.scheduler.get(id);\n }\n\n /**\n * Get scheduled tasks matching the given criteria\n * @template T Type of the payload data\n * @param criteria Criteria to filter schedules\n * @returns Array of matching Schedule objects\n * @deprecated Use {@link listSchedules}. This synchronous API cannot cross\n * Durable Object boundaries and throws inside sub-agents.\n */\n getSchedules<T = string>(criteria: ScheduleCriteria = {}): Schedule<T>[] {\n return this.scheduler.__DO_NOT_USE_WILL_REMOVE__getSchedules<T>(criteria);\n }\n\n /**\n * List scheduled tasks matching the given criteria.\n *\n * Unlike the deprecated synchronous {@link getSchedules}, this works inside\n * sub-agents by delegating to the top-level parent that owns the alarm.\n *\n * @param criteria Criteria to filter schedules\n * @returns Array of matching Schedule objects\n */\n listSchedules(criteria: ScheduleCriteria = {}): Promise<Schedule<unknown>[]> {\n return this.scheduler.list(criteria);\n }\n\n /**\n * Cancel a scheduled task.\n *\n * Schedules are isolated by owner: a top-level agent's\n * `cancelSchedule(id)` only matches its own schedules, and a\n * sub-agent's `cancelSchedule(id)` only matches schedules it\n * created. To clear every schedule under a sub-agent (and its\n * descendants), call `parent.deleteSubAgent(Cls, name)` from the\n * parent — that bulk-cleans root-owned bookkeeping via\n * {@link _cf_cleanupFacetPrefix}.\n *\n * @param id ID of the task to cancel\n * @returns true if the task was cancelled, false if the task was not found\n */\n cancelSchedule(id: string): Promise<boolean> {\n return this.scheduler.cancel(id);\n }\n\n /**\n * Keep the Durable Object alive via alarm heartbeats.\n * Returns a disposer function that stops the heartbeat when called.\n *\n * Use this when you have long-running work and need to prevent the\n * DO from going idle (eviction after ~70-140s of inactivity).\n * The heartbeat fires every `keepAliveIntervalMs` (default 30s) via the\n * alarm system, without creating schedule rows or emitting observability\n * events. Configure via `static options = { keepAliveIntervalMs: 5000 }`.\n *\n * In facets, delegates the physical heartbeat to the root parent\n * because facets do not have independent alarm slots.\n *\n * @example\n * ```ts\n * const dispose = await this.keepAlive();\n * try {\n * // ... long-running work ...\n * } finally {\n * dispose();\n * }\n * ```\n */\n async keepAlive(): Promise<() => void> {\n if (this._isFacet) {\n const root = await this._rootAlarmOwner();\n const token = await root._cf_acquireFacetKeepAlive(this.selfPath);\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n const release = root._cf_releaseFacetKeepAlive(token).catch((e) => {\n console.error(\"[Agent] Failed to release facet keepAlive:\", e);\n });\n this.ctx.waitUntil(release);\n };\n }\n\n this._keepAliveRefs++;\n\n if (this._keepAliveRefs === 1) {\n await this._syncHostJobs();\n }\n\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n this._keepAliveRefs = Math.max(0, this._keepAliveRefs - 1);\n // When the last lease is released, recompute the alarm from persistent\n // state so a short-lived keepAlive does not leave a stale\n // `now + keepAliveIntervalMs` heartbeat armed. The dispose contract is\n // synchronous, so fire-and-forget the async reschedule via waitUntil\n // (mirrors `_cf_releaseFacetKeepAlive`).\n if (this._keepAliveRefs === 0) {\n this.ctx.waitUntil(\n this._syncHostJobs().catch((e) => {\n console.error(\n \"[Agent] Failed to reschedule alarm after keepAlive dispose:\",\n e\n );\n })\n );\n }\n };\n }\n\n /**\n * Run an async function while keeping the Durable Object alive.\n * The heartbeat is automatically stopped when the function completes\n * (whether it succeeds or throws).\n *\n * This is the recommended way to use keepAlive — it guarantees cleanup\n * so you cannot forget to dispose the heartbeat.\n *\n * @example\n * ```ts\n * const result = await this.keepAliveWhile(async () => {\n * const data = await longRunningComputation();\n * return data;\n * });\n * ```\n */\n async keepAliveWhile<T>(fn: () => Promise<T>): Promise<T> {\n const dispose = await this.keepAlive();\n try {\n return await fn();\n } finally {\n dispose();\n }\n }\n\n // ── Managed fibers: idempotent durable jobs ────────────────────────\n\n private _isTerminalFiberStatus(status: FiberStatus): boolean {\n return (\n status === \"completed\" ||\n status === \"aborted\" ||\n status === \"interrupted\" ||\n status === \"error\"\n );\n }\n\n private _notifyManagedFiberTerminal(fiberId: string): void {\n const row = this._readFiber(fiberId);\n if (row && !this._isTerminalFiberStatus(row.status)) {\n return;\n }\n\n const waiters = this._managedFiberTerminalWaiters.get(fiberId);\n if (!waiters) {\n return;\n }\n\n this._managedFiberTerminalWaiters.delete(fiberId);\n for (const resolve of waiters) {\n resolve();\n }\n }\n\n private _waitForManagedFiberTerminal(fiberId: string): Promise<void> {\n const row = this._readFiber(fiberId);\n if (!row || this._isTerminalFiberStatus(row.status)) {\n return Promise.resolve();\n }\n\n return new Promise<void>((resolve) => {\n let waiters = this._managedFiberTerminalWaiters.get(fiberId);\n if (!waiters) {\n waiters = new Set();\n this._managedFiberTerminalWaiters.set(fiberId, waiters);\n }\n waiters.add(resolve);\n });\n }\n\n private _normalizeFiberStatusFilter(\n status?: FiberStatus | FiberStatus[]\n ): Set<FiberStatus> | null {\n if (!status) return null;\n return new Set(Array.isArray(status) ? status : [status]);\n }\n\n private _parseFiberJsonObject(\n value: string | null\n ): Record<string, unknown> | null {\n if (value === null) return null;\n try {\n const parsed = JSON.parse(value) as unknown;\n if (\n parsed !== null &&\n typeof parsed === \"object\" &&\n !Array.isArray(parsed)\n ) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Invalid metadata should not prevent inspection.\n }\n return null;\n }\n\n private _parseFiberSnapshot(value: string | null): unknown | undefined {\n if (value === null) return undefined;\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return undefined;\n }\n }\n\n private _fiberErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n }\n\n private _stringifyFiberSnapshot(snapshot: unknown): string | null {\n return snapshot === undefined ? null : JSON.stringify(snapshot);\n }\n\n private _fiberRecoveryErrorMessage(\n result: FiberRecoveryResult\n ): string | null {\n if (result.status === \"error\") {\n return result.error === undefined\n ? null\n : this._fiberErrorMessage(result.error);\n }\n if (result.status === \"aborted\" || result.status === \"interrupted\") {\n return result.reason ?? null;\n }\n return null;\n }\n\n private _applyManagedFiberRecoveryResult(\n fiberId: string,\n result: FiberRecoveryResult\n ): void {\n const completedAt = Date.now();\n const snapshot = this._stringifyFiberSnapshot(result.snapshot);\n const errorMessage = this._fiberRecoveryErrorMessage(result);\n const metadata =\n result.status === \"completed\" && result.metadata !== undefined\n ? JSON.stringify(result.metadata)\n : undefined;\n\n if (metadata !== undefined) {\n this.sql`\n UPDATE cf_agents_fibers\n SET status = ${result.status},\n snapshot = COALESCE(${snapshot}, snapshot),\n metadata_json = ${metadata},\n error_message = ${errorMessage},\n completed_at = ${completedAt}\n WHERE fiber_id = ${fiberId}\n AND status = 'interrupted'\n `;\n this._notifyManagedFiberTerminal(fiberId);\n return;\n }\n\n this.sql`\n UPDATE cf_agents_fibers\n SET status = ${result.status},\n snapshot = COALESCE(${snapshot}, snapshot),\n error_message = ${errorMessage},\n completed_at = ${completedAt}\n WHERE fiber_id = ${fiberId}\n AND status = 'interrupted'\n `;\n this._notifyManagedFiberTerminal(fiberId);\n }\n\n private _settleManagedFiberExecution(\n fiberId: string,\n outcome: { ok: true } | { ok: false; error: unknown },\n signal: AbortSignal\n ): void {\n const completedAt = Date.now();\n if (outcome.ok) {\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'completed', completed_at = ${completedAt}\n WHERE fiber_id = ${fiberId} AND status = 'running'\n `;\n this._notifyManagedFiberTerminal(fiberId);\n return;\n }\n\n const message = this._fiberErrorMessage(outcome.error);\n const status: FiberStatus = signal.aborted ? \"aborted\" : \"error\";\n this.sql`\n UPDATE cf_agents_fibers\n SET status = ${status},\n error_message = ${message},\n completed_at = ${completedAt}\n WHERE fiber_id = ${fiberId} AND status = 'running'\n `;\n this._notifyManagedFiberTerminal(fiberId);\n }\n\n private _parseFiberRecoverySnapshot(\n fiberId: string,\n snapshotText: string | null\n ): unknown | null {\n if (!snapshotText) return null;\n try {\n return JSON.parse(snapshotText) as unknown;\n } catch {\n console.warn(\n `[Agent] Corrupted snapshot for fiber ${fiberId}, treating as null`\n );\n return null;\n }\n }\n\n private _fiberRecoveryPayload(\n ctx: FiberRecoveryContext,\n managedRow: FiberLedgerRow | null,\n startedAt?: number\n ): Record<string, unknown> {\n return {\n fiberId: ctx.id,\n fiberName: ctx.name,\n managed: managedRow !== null,\n recoveryReason: ctx.recoveryReason,\n elapsedMs: startedAt === undefined ? undefined : Date.now() - startedAt\n };\n }\n\n private async _withFiberRecoveryTimeout<T>(\n ctx: FiberRecoveryContext,\n operation: () => Promise<T>\n ): Promise<T> {\n const timeoutMs = this._resolvedOptions.fiberRecoveryHookTimeoutMs;\n if (timeoutMs <= 0) return operation();\n\n // Note: this bounds how long we WAIT for the operation, but does not\n // cancel it — `operation` keeps running after the timeout rejects. It is\n // applied to internal framework recovery only, which is idempotent and\n // safe to abandon mid-flight.\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation(),\n new Promise<T>((_, reject) => {\n timer = setTimeout(() => {\n reject(\n new Error(\n `Fiber recovery hook timed out after ${timeoutMs}ms for \"${ctx.name}\" (${ctx.id})`\n )\n );\n }, timeoutMs);\n })\n ]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n private _recordFiberRecoveryFailure(\n ctx: FiberRecoveryContext,\n managedRow: FiberLedgerRow | null,\n error: unknown,\n startedAt: number,\n reason = \"handler_error\"\n ): void {\n const errorMessage = this._fiberErrorMessage(error);\n const completedAt = Date.now();\n if (managedRow) {\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'error',\n error_message = ${errorMessage},\n completed_at = ${completedAt}\n WHERE fiber_id = ${ctx.id}\n AND status = 'interrupted'\n `;\n this._notifyManagedFiberTerminal(ctx.id);\n }\n this._emit(\"fiber:recovery:failed\", {\n ...this._fiberRecoveryPayload(ctx, managedRow, startedAt),\n error: errorMessage,\n reason\n });\n }\n\n private async _runFiberRecoveryHook(\n ctx: FiberRecoveryContext,\n managedRow: FiberLedgerRow | null\n ): Promise<boolean> {\n const startedAt = Date.now();\n this._emit(\n \"fiber:recovery:attempt\",\n this._fiberRecoveryPayload(ctx, managedRow)\n );\n try {\n const handled = await this._withFiberRecoveryTimeout(ctx, () =>\n this._handleInternalFiberRecovery(ctx)\n );\n if (!handled) {\n const recoveryResult = await this.onFiberRecovered(ctx);\n if (managedRow && recoveryResult) {\n this._applyManagedFiberRecoveryResult(ctx.id, recoveryResult);\n }\n }\n this._emit(\"fiber:recovery:handled\", {\n ...this._fiberRecoveryPayload(ctx, managedRow, startedAt),\n status: handled ? \"internal\" : managedRow ? \"managed\" : \"user\"\n });\n return true;\n } catch (e) {\n this._recordFiberRecoveryFailure(ctx, managedRow, e, startedAt);\n console.error(\n `[Agent] Fiber recovery failed for \"${ctx.name}\" (${ctx.id}):`,\n e\n );\n return false;\n }\n }\n\n private _fiberInspectionFromRow(row: FiberLedgerRow): FiberInspection {\n const snapshot = this._parseFiberSnapshot(row.snapshot);\n const inspection: FiberInspection = {\n fiberId: row.fiber_id,\n name: row.name,\n status: row.status,\n createdAt: row.created_at\n };\n\n if (row.idempotency_key !== null) {\n inspection.idempotencyKey = row.idempotency_key;\n }\n if (snapshot !== undefined) {\n inspection.snapshot = snapshot;\n }\n if (row.error_message !== null) {\n inspection.error = row.error_message;\n }\n const metadata = this._parseFiberJsonObject(row.metadata_json);\n if (metadata !== null) {\n inspection.metadata = metadata;\n }\n if (row.started_at !== null) {\n inspection.startedAt = row.started_at;\n }\n if (row.completed_at !== null) {\n inspection.settledAt = row.completed_at;\n }\n\n return inspection;\n }\n\n private async _waitForManagedFiber(\n fiberId: string\n ): Promise<FiberInspection | null> {\n const row = this._readFiber(fiberId);\n if (!row || this._isTerminalFiberStatus(row.status)) {\n return row ? this._fiberInspectionFromRow(row) : null;\n }\n\n if (this._managedFiberExecutions.has(fiberId)) {\n await this._waitForManagedFiberTerminal(fiberId);\n return this.inspectFiber(fiberId);\n }\n\n await this._checkRunFibers();\n await this._waitForManagedFiberTerminal(fiberId);\n return this.inspectFiber(fiberId);\n }\n\n private _readFiber(fiberId: string): FiberLedgerRow | null {\n const rows = this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE fiber_id = ${fiberId}\n LIMIT 1\n `;\n return rows[0] ?? null;\n }\n\n private _readFiberByKey(idempotencyKey: string): FiberLedgerRow | null {\n const rows = this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE idempotency_key = ${idempotencyKey}\n LIMIT 1\n `;\n return rows[0] ?? null;\n }\n\n private _listFiberRows(options?: ListFibersOptions): FiberLedgerRow[] {\n const limit = Math.min(Math.max(options?.limit ?? 50, 1), 100);\n const statuses = this._normalizeFiberStatusFilter(options?.status);\n if (statuses) {\n return [...statuses]\n .flatMap((status) =>\n this._listFiberRowsByStatus(status, limit, options?.name)\n )\n .sort((a, b) =>\n b.created_at === a.created_at\n ? b.fiber_id.localeCompare(a.fiber_id)\n : b.created_at - a.created_at\n )\n .slice(0, limit);\n }\n\n if (options?.name) {\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE name = ${options.name}\n ORDER BY created_at DESC, fiber_id DESC\n LIMIT ${limit}\n `;\n }\n\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n ORDER BY created_at DESC, fiber_id DESC\n LIMIT ${limit}\n `;\n }\n\n private _listFiberRowsByStatus(\n status: FiberStatus,\n limit: number,\n name?: string\n ): FiberLedgerRow[] {\n if (name) {\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE status = ${status} AND name = ${name}\n ORDER BY created_at DESC, fiber_id DESC\n LIMIT ${limit}\n `;\n }\n\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE status = ${status}\n ORDER BY created_at DESC, fiber_id DESC\n LIMIT ${limit}\n `;\n }\n\n async inspectFiber(fiberId: string): Promise<FiberInspection | null> {\n const row = this._readFiber(fiberId);\n return row ? this._fiberInspectionFromRow(row) : null;\n }\n\n async inspectFiberByKey(\n idempotencyKey: string\n ): Promise<FiberInspection | null> {\n const row = this._readFiberByKey(idempotencyKey);\n return row ? this._fiberInspectionFromRow(row) : null;\n }\n\n async listFibers(options?: ListFibersOptions): Promise<FiberInspection[]> {\n return this._listFiberRows(options).map((row) =>\n this._fiberInspectionFromRow(row)\n );\n }\n\n async cancelFiber(fiberId: string, reason?: string): Promise<boolean> {\n const row = this._readFiber(fiberId);\n if (!row || this._isTerminalFiberStatus(row.status)) {\n return false;\n }\n\n const now = Date.now();\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'aborted',\n error_message = ${reason ?? null},\n completed_at = ${now}\n WHERE fiber_id = ${fiberId}\n AND status IN ('pending', 'running')\n `;\n this._managedFiberAbortControllers.get(fiberId)?.abort(reason);\n this._notifyManagedFiberTerminal(fiberId);\n return true;\n }\n\n async cancelFiberByKey(\n idempotencyKey: string,\n reason?: string\n ): Promise<boolean> {\n const row = this._readFiberByKey(idempotencyKey);\n return row ? this.cancelFiber(row.fiber_id, reason) : false;\n }\n\n async resolveFiber(\n fiberId: string,\n result: FiberRecoveryResult\n ): Promise<boolean> {\n const row = this._readFiber(fiberId);\n if (!row || row.status !== \"interrupted\") {\n return false;\n }\n\n this._applyManagedFiberRecoveryResult(fiberId, result);\n return true;\n }\n\n async deleteFibers(options?: DeleteFibersOptions): Promise<number> {\n const statuses =\n this._normalizeFiberStatusFilter(options?.status) ??\n new Set<FiberStatus>([\"completed\", \"aborted\", \"error\"]);\n const terminalStatuses = [...statuses].filter((status) =>\n this._isTerminalFiberStatus(status)\n );\n if (terminalStatuses.length === 0) {\n return 0;\n }\n\n const limit = Math.min(Math.max(options?.limit ?? 100, 1), 500);\n const settledBefore = options?.settledBefore?.getTime();\n const rows = terminalStatuses\n .flatMap((status) =>\n this._listTerminalFiberRowsForDelete(status, limit, settledBefore)\n )\n .sort((a, b) =>\n a.completed_at === b.completed_at\n ? a.created_at - b.created_at\n : (a.completed_at ?? 0) - (b.completed_at ?? 0)\n )\n .slice(0, limit);\n\n for (const row of rows) {\n this.sql`\n DELETE FROM cf_agents_fibers\n WHERE fiber_id = ${row.fiber_id}\n AND status IN ('completed', 'aborted', 'interrupted', 'error')\n `;\n }\n\n return rows.length;\n }\n\n private _listTerminalFiberRowsForDelete(\n status: FiberStatus,\n limit: number,\n settledBefore?: number\n ): FiberLedgerRow[] {\n if (settledBefore !== undefined) {\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE status = ${status}\n AND completed_at IS NOT NULL\n AND completed_at < ${settledBefore}\n ORDER BY completed_at ASC, created_at ASC\n LIMIT ${limit}\n `;\n }\n\n return this.sql<FiberLedgerRow>`\n SELECT fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at\n FROM cf_agents_fibers\n WHERE status = ${status}\n ORDER BY completed_at ASC, created_at ASC\n LIMIT ${limit}\n `;\n }\n\n // ── Legacy fibers: durable execution (see agents/tasks for the new engine) ──\n\n /**\n * Run a function as a durable fiber. The fiber is registered in SQLite\n * before execution, checkpointable during execution via `ctx.stash()`,\n * and recoverable after eviction via `onFiberRecovered`.\n *\n * - Row created in `cf_agents_runs` at start, deleted on completion\n * - `keepAlive()` held for the duration — prevents idle eviction\n * - Inline (await result) or fire-and-forget (`void this.runFiber(...)`)\n *\n * @param name Informational name for debugging and recovery filtering\n * @param fn Async function to execute. Receives a FiberContext with stash/snapshot.\n * @returns The return value of fn\n */\n async runFiber<T>(\n name: string,\n fn: (ctx: FiberContext) => Promise<T>\n ): Promise<T> {\n return this._runFiberInternal(nanoid(), name, fn);\n }\n\n /**\n * Internal framework entry point for fibers that need to compose their own\n * recovery metadata with user checkpoint data while preserving the public\n * `this.stash()` behavior.\n *\n * This deliberately stays protected/internal rather than becoming a public\n * `runFiber()` option until the durable execution API needs this generality.\n * @internal\n */\n protected async _runFiberWithStashWrapper<T>(\n name: string,\n fn: (ctx: FiberContext) => Promise<T>,\n options: Pick<InternalFiberOptions, \"initialSnapshot\" | \"wrapStash\">\n ): Promise<T> {\n return this._runFiberInternal(nanoid(), name, fn, options);\n }\n\n async startFiber(\n name: string,\n fn: (ctx: FiberContext) => Promise<void>,\n options?: StartFiberOptions\n ): Promise<StartFiberResult> {\n const fiberId = options?.fiberId ?? nanoid();\n const idempotencyKey = options?.idempotencyKey;\n if (options?.fiberId !== undefined && options.fiberId.trim() === \"\") {\n throw new Error(\"fiberId must not be blank\");\n }\n if (\n options?.idempotencyKey !== undefined &&\n options.idempotencyKey.trim() === \"\"\n ) {\n throw new Error(\"idempotencyKey must not be blank\");\n }\n const existingById = this._readFiber(fiberId);\n const existingByKey = idempotencyKey\n ? this._readFiberByKey(idempotencyKey)\n : null;\n\n if (\n existingById &&\n existingByKey &&\n existingById.fiber_id !== existingByKey.fiber_id\n ) {\n throw new Error(\"fiberId and idempotencyKey refer to different fibers\");\n }\n if (\n existingByKey &&\n options?.fiberId &&\n existingByKey.fiber_id !== fiberId\n ) {\n throw new Error(\"fiberId and idempotencyKey refer to different fibers\");\n }\n\n const existing = existingById ?? existingByKey;\n if (existing) {\n if (\n options?.waitForCompletion &&\n !this._isTerminalFiberStatus(existing.status)\n ) {\n const waited = await this._waitForManagedFiber(existing.fiber_id);\n if (waited) {\n return {\n ...waited,\n accepted: false\n };\n }\n throw new Error(`Fiber ${existing.fiber_id} no longer exists`);\n }\n return {\n ...this._fiberInspectionFromRow(existing),\n accepted: false\n };\n }\n\n const now = Date.now();\n this.sql`\n INSERT INTO cf_agents_fibers\n (fiber_id, idempotency_key, name, status, snapshot, metadata_json,\n error_message, created_at, started_at, completed_at)\n VALUES\n (${fiberId}, ${idempotencyKey ?? null}, ${name}, 'pending', NULL,\n ${options?.metadata ? JSON.stringify(options.metadata) : null}, NULL,\n ${now}, NULL, NULL)\n `;\n\n const row = this._readFiber(fiberId);\n if (!row) {\n throw new Error(`Failed to create fiber ${fiberId}`);\n }\n\n const execution = this._executeManagedFiber(fiberId, name, fn)\n .catch((error) => {\n console.error(\n `[Agent] Managed fiber \"${name}\" (${fiberId}) failed:`,\n error\n );\n })\n .finally(() => {\n if (this._managedFiberExecutions.get(fiberId) === execution) {\n this._managedFiberExecutions.delete(fiberId);\n }\n });\n this._managedFiberExecutions.set(fiberId, execution);\n\n if (options?.waitForCompletion) {\n const completed = await this._waitForManagedFiber(fiberId);\n if (!completed) {\n throw new Error(`Fiber ${fiberId} no longer exists`);\n }\n return {\n ...completed,\n accepted: true\n };\n }\n\n return {\n ...this._fiberInspectionFromRow(row),\n accepted: true\n };\n }\n\n private async _executeManagedFiber(\n fiberId: string,\n name: string,\n fn: (ctx: FiberContext) => Promise<void>\n ): Promise<void> {\n const row = this._readFiber(fiberId);\n if (!row || row.status !== \"pending\") {\n return;\n }\n\n const controller = new AbortController();\n this._managedFiberAbortControllers.set(fiberId, controller);\n const now = Date.now();\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'running', started_at = ${now}\n WHERE fiber_id = ${fiberId} AND status = 'pending'\n `;\n\n const updated = this._readFiber(fiberId);\n if (!updated || updated.status !== \"running\") {\n this._managedFiberAbortControllers.delete(fiberId);\n return;\n }\n\n let settled = false;\n try {\n await this._runFiberInternal(fiberId, name, fn, {\n signal: controller.signal,\n managed: true,\n beforeRunCleanup: (outcome) => {\n settled = true;\n this._settleManagedFiberExecution(\n fiberId,\n outcome,\n controller.signal\n );\n }\n });\n } catch (error) {\n if (!settled) {\n this._settleManagedFiberExecution(\n fiberId,\n { ok: false, error },\n controller.signal\n );\n }\n } finally {\n this._managedFiberAbortControllers.delete(fiberId);\n }\n }\n\n private async _runFiberInternal<T>(\n id: string,\n name: string,\n fn: (ctx: FiberContext) => Promise<T>,\n options?: InternalFiberOptions\n ): Promise<T> {\n const signal = options?.signal ?? new AbortController().signal;\n this._withAgentSpan(\n \"initialize_fiber\",\n \"fiber\",\n {\n \"cloudflare.agents.fiber.id\": id,\n \"cloudflare.agents.fiber.name\": name\n },\n () => {\n this.sql`\n INSERT INTO cf_agents_runs (id, name, snapshot, created_at)\n VALUES (${id}, ${name}, NULL, ${Date.now()})\n `;\n }\n );\n const startedAt = Date.now();\n this._emit(\"fiber:run:started\", {\n fiberId: id,\n fiberName: name,\n managed: options?.managed === true\n });\n this._runFiberActiveFibers.add(id);\n\n const writeSnapshot = (data: unknown) => {\n const snapshot = JSON.stringify(data);\n this._withAgentSpan(\n \"persist_fiber_snapshot\",\n \"fiber\",\n {\n \"cloudflare.agents.fiber.id\": id,\n \"cloudflare.agents.fiber.name\": name\n },\n () => {\n this.sql`\n UPDATE cf_agents_runs SET snapshot = ${snapshot}\n WHERE id = ${id}\n `;\n if (options?.managed) {\n this.sql`\n UPDATE cf_agents_fibers SET snapshot = ${snapshot}\n WHERE fiber_id = ${id}\n `;\n }\n }\n );\n };\n\n let root: RootFacetRpcSurface | undefined;\n let registeredFacetRun = false;\n let dispose: () => void = () => {};\n try {\n if (\"initialSnapshot\" in (options ?? {})) {\n writeSnapshot(options?.initialSnapshot);\n }\n\n if (this._isFacet) {\n root = await this._rootAlarmOwner();\n await root._cf_registerFacetRun(this.selfPath, id);\n registeredFacetRun = true;\n }\n\n dispose = await this.keepAlive();\n const stash = (data: unknown) => {\n writeSnapshot(options?.wrapStash ? options.wrapStash(data) : data);\n };\n\n try {\n const result = await _fiberALS.run({ id, signal, stash }, () =>\n fn({ id, signal, stash, snapshot: null })\n );\n options?.beforeRunCleanup?.({ ok: true });\n this._emit(\"fiber:run:completed\", {\n fiberId: id,\n fiberName: name,\n managed: options?.managed === true,\n elapsedMs: Date.now() - startedAt\n });\n return result;\n } catch (error) {\n options?.beforeRunCleanup?.({ ok: false, error });\n this._emit(\"fiber:run:failed\", {\n fiberId: id,\n fiberName: name,\n managed: options?.managed === true,\n error: this._fiberErrorMessage(error),\n elapsedMs: Date.now() - startedAt\n });\n throw error;\n }\n } finally {\n this._runFiberActiveFibers.delete(id);\n this._withAgentSpan(\n \"finalize_fiber\",\n \"fiber\",\n {\n \"cloudflare.agents.fiber.id\": id,\n \"cloudflare.agents.fiber.name\": name\n },\n () => {\n this.sql`DELETE FROM cf_agents_runs WHERE id = ${id}`;\n }\n );\n dispose();\n if (root && registeredFacetRun) {\n try {\n await root._cf_unregisterFacetRun(this.selfPath, id);\n } catch (e) {\n // Leave the root-side lease behind if cleanup fails; root\n // housekeeping will re-enter the facet and prune stale rows\n // once it observes that this fiber row no longer exists.\n console.error(\"[Agent] Failed to unregister facet fiber:\", e);\n }\n }\n }\n }\n\n /**\n * Checkpoint data for the currently executing fiber.\n * Uses AsyncLocalStorage to identify the correct fiber,\n * so it works correctly even with concurrent fibers.\n *\n * Throws if called outside a `runFiber` callback.\n */\n stash(data: unknown): void {\n const ctx = _fiberALS.getStore();\n if (!ctx) {\n throw new Error(\"stash() called outside a fiber\");\n }\n ctx.stash(data);\n }\n\n /**\n * Run `fn` inside the fiber stash context so `this.stash()` keeps working\n * for turns executing on the `tasks` capability exactly as it does inside\n * legacy `runFiber()` closures.\n * @internal\n */\n protected _withFiberStash<T>(\n context: {\n id: string;\n signal: AbortSignal;\n stash: (data: unknown) => void;\n },\n fn: () => Promise<T>\n ): Promise<T> {\n return _fiberALS.run(context, fn);\n }\n\n /**\n * Called when an interrupted fiber is detected after restart.\n * Override to implement recovery (re-invoke work, notify clients, etc.).\n *\n * Internal framework fibers are filtered by `_handleInternalFiberRecovery`\n * before this hook runs — users only see their own fibers.\n *\n * Default: logs a warning.\n */\n async onFiberRecovered(\n // oxlint-disable-next-line @typescript-eslint/no-unused-vars -- overridable hook\n _ctx: FiberRecoveryContext\n ): Promise<void | FiberRecoveryResult> {\n console.warn(\n `[Agent] Fiber \"${_ctx.name}\" (${_ctx.id}) was interrupted. ` +\n \"Override onFiberRecovered to handle recovery.\"\n );\n }\n\n /**\n * Override point for subclasses to handle internal (framework) fibers\n * before the user's recovery hook fires. Return `true` if handled.\n * @internal\n */\n protected async _handleInternalFiberRecovery(\n // oxlint-disable-next-line @typescript-eslint/no-unused-vars -- override point\n _ctx: FiberRecoveryContext\n ): Promise<boolean> {\n return false;\n }\n\n /** @internal Detect fibers left by a dead process (runFiber system). */\n private async _checkRunFibers(): Promise<void> {\n if (this._runFiberRecoveryInProgress) return;\n this._runFiberRecoveryInProgress = true;\n const scanStartedAt = Date.now();\n const scanDeadlineMs = this._resolvedOptions.fiberRecoveryScanDeadlineMs;\n const fiberRecoveryMaxAgeMs = this._resolvedOptions.fiberRecoveryMaxAgeMs;\n // Forward progress this scan = at least one fiber was resolved (orphan row\n // deleted via recovery/age-out/managed-terminal, or a ledger-only managed\n // fiber finalized). Drives the recovery-alarm backoff in `_syncHostJobs`.\n let madeProgress = false;\n\n try {\n const rows = this.sql<{\n id: string;\n name: string;\n snapshot: string | null;\n created_at: number;\n }>`SELECT id, name, snapshot, created_at FROM cf_agents_runs`;\n\n for (const row of rows) {\n if (scanDeadlineMs > 0 && Date.now() - scanStartedAt > scanDeadlineMs) {\n this._emit(\"fiber:recovery:skipped\", {\n fiberId: row.id,\n fiberName: row.name,\n reason: \"scan_deadline_exceeded\",\n elapsedMs: Date.now() - scanStartedAt\n });\n break;\n }\n if (this._runFiberActiveFibers.has(row.id)) continue;\n\n const snapshot = this._parseFiberRecoverySnapshot(row.id, row.snapshot);\n const ctx: FiberRecoveryContext = {\n id: row.id,\n name: row.name,\n snapshot,\n createdAt: row.created_at,\n recoveryReason: \"interrupted\"\n };\n\n const managedRow = this._readFiber(row.id);\n this._emit(\"fiber:recovery:detected\", {\n ...this._fiberRecoveryPayload(ctx, managedRow),\n elapsedMs: Date.now() - row.created_at\n });\n this._emit(\"fiber:run:interrupted\", {\n fiberId: row.id,\n fiberName: row.name,\n managed: managedRow !== null,\n recoveryReason: \"interrupted\",\n elapsedMs: Date.now() - row.created_at\n });\n if (managedRow) {\n if (this._isTerminalFiberStatus(managedRow.status)) {\n this.sql`DELETE FROM cf_agents_runs WHERE id = ${row.id}`;\n madeProgress = true;\n this._notifyManagedFiberTerminal(row.id);\n continue;\n }\n\n const completedAt = Date.now();\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'interrupted',\n snapshot = ${row.snapshot},\n completed_at = ${completedAt}\n WHERE fiber_id = ${row.id}\n AND status IN ('pending', 'running')\n `;\n ctx.idempotencyKey = managedRow.idempotency_key ?? undefined;\n ctx.metadata = this._parseFiberJsonObject(managedRow.metadata_json);\n ctx.status = \"interrupted\";\n }\n\n const recovered = await this._runFiberRecoveryHook(ctx, managedRow);\n // Managed rows are always cleaned up (their ledger row records the\n // terminal status). Unmanaged rows are retained when recovery fails so\n // a later scan can retry — but only until they exceed the max age, at\n // which point a repeatedly-throwing hook would otherwise loop forever.\n const tooOld =\n fiberRecoveryMaxAgeMs > 0 &&\n Date.now() - row.created_at > fiberRecoveryMaxAgeMs;\n if (recovered || managedRow || tooOld) {\n if (!recovered && !managedRow && tooOld) {\n this._emit(\"fiber:recovery:skipped\", {\n fiberId: row.id,\n fiberName: row.name,\n reason: \"max_age_exceeded\",\n elapsedMs: Date.now() - row.created_at\n });\n }\n this.sql`DELETE FROM cf_agents_runs WHERE id = ${row.id}`;\n madeProgress = true;\n }\n if (managedRow) {\n this._notifyManagedFiberTerminal(row.id);\n }\n }\n\n const ledgerOnlyRows = this.sql<FiberLedgerRow>`\n SELECT f.fiber_id, f.idempotency_key, f.name, f.status, f.snapshot,\n f.metadata_json, f.error_message, f.created_at, f.started_at,\n f.completed_at\n FROM cf_agents_fibers f\n LEFT JOIN cf_agents_runs r ON r.id = f.fiber_id\n WHERE f.status IN ('pending', 'running')\n AND r.id IS NULL\n `;\n\n for (const row of ledgerOnlyRows) {\n if (scanDeadlineMs > 0 && Date.now() - scanStartedAt > scanDeadlineMs) {\n this._emit(\"fiber:recovery:skipped\", {\n fiberId: row.fiber_id,\n fiberName: row.name,\n reason: \"scan_deadline_exceeded\",\n elapsedMs: Date.now() - scanStartedAt,\n managed: true\n });\n break;\n }\n if (this._runFiberActiveFibers.has(row.fiber_id)) continue;\n\n const snapshot = this._parseFiberRecoverySnapshot(\n row.fiber_id,\n row.snapshot\n );\n const completedAt = Date.now();\n this.sql`\n UPDATE cf_agents_fibers\n SET status = 'interrupted',\n completed_at = ${completedAt}\n WHERE fiber_id = ${row.fiber_id}\n AND status IN ('pending', 'running')\n `;\n\n const ctx: FiberRecoveryContext = {\n id: row.fiber_id,\n name: row.name,\n snapshot,\n createdAt: row.created_at,\n idempotencyKey: row.idempotency_key ?? undefined,\n metadata: this._parseFiberJsonObject(row.metadata_json),\n status: \"interrupted\",\n recoveryReason: \"interrupted\"\n };\n this._emit(\"fiber:recovery:detected\", {\n ...this._fiberRecoveryPayload(ctx, row),\n elapsedMs: Date.now() - row.created_at\n });\n this._emit(\"fiber:run:interrupted\", {\n fiberId: row.fiber_id,\n fiberName: row.name,\n managed: true,\n recoveryReason: \"interrupted\",\n elapsedMs: Date.now() - row.created_at\n });\n\n await this._runFiberRecoveryHook(ctx, row);\n // A ledger-only fiber is finalized this pass regardless of hook outcome\n // (its ledger row is marked terminal and waiters are notified), so it\n // will not be pending next scan — that is forward progress.\n madeProgress = true;\n this._notifyManagedFiberTerminal(row.fiber_id);\n }\n } finally {\n this._runFiberRecoveryInProgress = false;\n // Update the recovery-alarm backoff streak: reset on any forward progress,\n // otherwise grow it only while work is still pending (a repeatedly-failing\n // poison hook). `_syncHostJobs` reads this to space out retries.\n if (madeProgress) {\n this._recoveryNoProgressScans = 0;\n } else {\n this._recoveryNoProgressScans = this._hasPendingFiberRecovery()\n ? this._recoveryNoProgressScans + 1\n : 0;\n }\n }\n }\n\n /** @internal */\n async _onAlarmHousekeeping(): Promise<void> {\n await this._checkRunFibers();\n await this._checkFacetRunFibers();\n }\n\n private _isSameAgentPathPrefix(\n prefix: ReadonlyArray<AgentPathStep>,\n path: ReadonlyArray<AgentPathStep>\n ): boolean {\n if (prefix.length > path.length) return false;\n return prefix.every(\n (step, index) =>\n step.className === path[index].className &&\n step.name === path[index].name\n );\n }\n\n /**\n * Root-side scan for durable fibers owned by descendant facets.\n * `cf_agents_facet_runs` is only an index; actual snapshots and\n * recovery hooks live in each facet's own `cf_agents_runs` table.\n * @internal\n */\n private _checkFacetRunFibers(): Promise<void> {\n return this._dynamicAgents.checkRunFibers();\n }\n\n /**\n * Dispatch a runFiber recovery check into the facet identified by\n * `ownerPath`. Returns the number of remaining local `cf_agents_runs`\n * rows on the target facet after recovery.\n * @internal\n */\n _cf_checkRunFibersForFacet(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<number> {\n return this._dynamicAgents.checkRunFibersAtPath(ownerPath);\n }\n\n /**\n * Invoke an RPC method on this Agent or a descendant facet identified\n * by a root-first path. Used by AgentWorkflow to route callbacks and\n * `this.agent` calls back to the exact sub-agent that started a workflow.\n * @internal\n */\n _cf_invokeAgentPath(\n targetPath: ReadonlyArray<AgentPathStep>,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n return this._dynamicAgents.invokeAgentPath(targetPath, method, args);\n }\n\n /**\n * Recursively destroy a descendant facet identified by\n * `targetPath`. Walks down from `selfPath` until reaching the\n * target's immediate parent, where it cancels the target's\n * parent-owned schedules (and any descendants), removes the\n * target from the registry, and calls `ctx.facets.delete` to\n * wipe the target's storage.\n *\n * Called by a facet's own `destroy()` (via the root) so that\n * `this.destroy()` inside a sub-agent results in the same\n * cleanup as `parent.deleteSubAgent(Cls, name)` from the parent.\n * @internal\n */\n _cf_destroyDescendantFacet(\n targetPath: ReadonlyArray<AgentPathStep>\n ): Promise<void> {\n return this._dynamicAgents.destroyDescendant(targetPath);\n }\n\n /**\n * Whether any runFiber recovery work is still outstanding: orphaned\n * `cf_agents_runs` rows left by a dead process (excluding fibers currently\n * executing in memory, which already hold a keepAlive ref) or managed\n * ledger fibers stuck in a non-terminal state with no live run row.\n *\n * Used by `_syncHostJobs` to arm a follow-up alarm so multi-pass\n * recovery (e.g. after a scan-deadline yield, or while retrying a throwing\n * recovery hook) resumes instead of starving.\n * @internal\n */\n private _hasPendingFiberRecovery(): boolean {\n const runRows = this.sql<{ id: string }>`\n SELECT id FROM cf_agents_runs\n `;\n for (const row of runRows) {\n if (!this._runFiberActiveFibers.has(row.id)) return true;\n }\n\n const ledgerOnly = this.sql<{ count: number }>`\n SELECT COUNT(*) AS count\n FROM cf_agents_fibers f\n LEFT JOIN cf_agents_runs r ON r.id = f.fiber_id\n WHERE f.status IN ('pending', 'running')\n AND r.id IS NULL\n `;\n return (ledgerOnly[0]?.count ?? 0) > 0;\n }\n\n /**\n * Synchronize Agent-owned host jobs with current durable state.\n *\n * Replaces the old pull-based `getNextAlarm()` contribution: keep-alive\n * refs hold a `cf:keep-alive` job, and fiber-recovery / facet-run state\n * holds a `cf:housekeeping` job. Every state change that used to trigger\n * an alarm recalculation now re-pushes or cancels these jobs; queue\n * mutations re-arm the physical alarm automatically.\n * @internal\n */\n private async _syncHostJobs(): Promise<void> {\n if (this._destroyed) return;\n await this._withAgentSpan(\"schedule_agent_alarm\", \"alarm\", {}, async () => {\n const work = this.lifecycle.jobs;\n const nowMs = Date.now();\n\n // A pending destroy (#1625) must keep its wake armed and exclusive\n // through any re-sync — including markers written by a pre-job-queue\n // release — so a keepAlive-holding agent cannot delay its own\n // condemnation. The durable marker stays authoritative; the job is\n // re-derived from it.\n const pendingDestroy = await this._pendingDestroyAlarm();\n if (pendingDestroy !== null) {\n await work.push({\n id: HOST_JOB_DESTROY_ID,\n fn: \"destroy\",\n time: pendingDestroy,\n exclusive: true\n });\n return;\n }\n if (work.get(HOST_JOB_DESTROY_ID)) {\n await work.cancel(HOST_JOB_DESTROY_ID);\n }\n\n if (this._keepAliveRefs > 0) {\n await work.push({\n id: HOST_JOB_KEEP_ALIVE_ID,\n fn: \"keepAlive\",\n time: nowMs + this._resolvedOptions.keepAliveIntervalMs\n });\n } else if (work.get(HOST_JOB_KEEP_ALIVE_ID)) {\n await work.cancel(HOST_JOB_KEEP_ALIVE_ID);\n }\n\n const housekeepingAt = this._nextHousekeepingWakeMs(nowMs);\n if (housekeepingAt !== null) {\n await work.push({\n id: HOST_JOB_HOUSEKEEPING_ID,\n fn: \"housekeeping\",\n time: housekeepingAt\n });\n } else if (work.get(HOST_JOB_HOUSEKEEPING_ID)) {\n await work.cancel(HOST_JOB_HOUSEKEEPING_ID);\n }\n });\n }\n\n /**\n * The next wake fiber-recovery or facet-run housekeeping needs, or `null`\n * when neither has pending durable state.\n */\n private _nextHousekeepingWakeMs(nowMs: number): number | null {\n let nextTimeMs: number | null = null;\n\n if (this._hasPendingFiberRecovery()) {\n const base = this._resolvedOptions.keepAliveIntervalMs;\n const exp = Math.min(\n this._recoveryNoProgressScans,\n FIBER_RECOVERY_BACKOFF_MAX_EXP\n );\n const recoveryDelayMs = Math.min(\n FIBER_RECOVERY_MAX_BACKOFF_MS,\n base * 2 ** exp\n );\n nextTimeMs = nowMs + recoveryDelayMs;\n }\n\n const facetRuns = this.sql<{ count: number }>`\n SELECT COUNT(*) as count FROM cf_agents_facet_runs\n `;\n if ((facetRuns[0]?.count ?? 0) > 0) {\n const facetRecoveryMs = nowMs + this._resolvedOptions.keepAliveIntervalMs;\n nextTimeMs =\n nextTimeMs === null\n ? facetRecoveryMs\n : Math.min(nextTimeMs, facetRecoveryMs);\n }\n\n return nextTimeMs;\n }\n\n /** Lifecycle alarm callback; Agent housekeeping runs after user alarm work. */\n onAlarm(): void {}\n\n /**\n * Drive one Agent-owned host job from the Lifecycle queue.\n * @internal Dispatched by Lifecycle's alarm event loop; extensions add\n * job fns through {@link _onHostJob}.\n */\n onJob(\n context: LifecycleJobContext\n ): LifecycleJobOutcome | void | Promise<LifecycleJobOutcome | void> {\n return this._onHostJob(context.job.fn, context);\n }\n\n /**\n * @internal Dispatch one host job fn. Agent extensions (Think) override\n * this to add fns and delegate unknown ones to `super`.\n */\n protected _onHostJob(\n fn: string,\n _context: LifecycleJobContext\n ): LifecycleJobOutcome | void | Promise<LifecycleJobOutcome | void> {\n switch (fn) {\n case \"keepAlive\":\n // This job's only purpose is guaranteeing wakes while refs are\n // held; housekeeping itself runs on every alarm via the onAlarm\n // wrapper.\n return this._keepAliveRefs > 0\n ? {\n rescheduleAt:\n Date.now() + this._resolvedOptions.keepAliveIntervalMs\n }\n : undefined;\n case \"housekeeping\": {\n const next = this._nextHousekeepingWakeMs(Date.now());\n return next === null ? undefined : { rescheduleAt: next };\n }\n case \"destroy\":\n // The alarm preamble consumes pending destroys before the event\n // loop runs; a surviving job is stale.\n return undefined;\n default:\n console.warn(`Unknown Agent host job fn ${JSON.stringify(fn)}`);\n return undefined;\n }\n }\n\n /**\n * Apply host policy after the alarm memory-limit breaker records a strike.\n *\n * New chat hosts override this hook directly. The sealed-only fallback keeps\n * `agents` 0.23 compatible with already-published chat packages whose peer\n * ranges accept it but which implement only the former\n * `_cf_sealMemoryLimitedRecovery` template method. Queue membership remains\n * job-row policy; this invokes terminalization only and can be removed once\n * old chat releases no longer accept the current `agents` range.\n *\n * @internal\n */\n protected async onAlarmMemoryLimit(\n context: MemoryLimitContext\n ): Promise<void> {\n if (!context.sealed) return;\n const legacySeal = (\n this as unknown as {\n _cf_sealMemoryLimitedRecovery?: () => void | Promise<void>;\n }\n )._cf_sealMemoryLimitedRecovery;\n await legacySeal?.call(this);\n }\n\n /**\n * Run Lifecycle's alarm event loop after the pending-destroy preamble.\n *\n * The alarm memory-limit circuit breaker (#1825) lives inside\n * `Lifecycle.alarm()`; capabilities and hosts opt into extra domain\n * policy via their `onMemoryLimit` / `onAlarmMemoryLimit` hooks and the\n * `recoveryLoop` schedule option.\n *\n * @remarks Use `this.schedule()` for named Agent callbacks. Reusable durable\n * work belongs in a capability that pushes jobs and implements `onJob()`.\n */\n async alarm() {\n // A pending destroy (#1625) pre-empts everything — including lifecycle\n // startup, which would re-initialize user state on a\n // condemned agent. This is both the landing point for the deferred\n // teardown scheduled by `_cf_scheduleDestroy` (which arms an immediate\n // alarm precisely so teardown runs here, with this invocation's full\n // execution budget) and the convergence point for a destroy that a\n // previous invocation started but couldn't finish.\n if (await this._hasPendingDestroy()) {\n await this.destroy();\n return;\n }\n\n await this.lifecycle.alarm();\n }\n\n // ── Sub-agent routing (external addressability for facets) ──────────────\n\n /**\n * Intercept incoming HTTP/WS requests whose URL contains a\n * `/sub/{child-class}/{child-name}` marker and forward them to\n * the facet. The `onBeforeSubAgent` hook fires first (authorize,\n * mutate, or short-circuit). If the hook doesn't return a\n * Response, the framework resolves the facet and hands the\n * request off.\n *\n * The parent owns an upgraded WebSocket for its lifetime. Subsequent\n * frames wake the root parent, which forwards them to the child over\n * RPC and routes replies back to the native socket.\n *\n * @experimental The API surface may change before stabilizing.\n */\n async fetch(request: Request): Promise<Response> {\n const ctx = this.ctx as unknown as Partial<FacetCapableCtx>;\n const match = _parseSubAgentPath(request.url, {\n knownClasses: ctx.exports ? Object.keys(ctx.exports) : undefined\n });\n\n if (!match) {\n return this.lifecycle.fetch(request);\n }\n\n // Hook runs in the parent's isolate before any facet work.\n const decision = await this.onBeforeSubAgent(request, {\n className: match.childClass,\n name: match.childName\n });\n if (decision instanceof Response) return decision;\n const forwardReq = decision instanceof Request ? decision : request;\n\n if (request.headers.get(\"Upgrade\")?.toLowerCase() === \"websocket\") {\n const acceptHeaders = new Headers(forwardReq.headers);\n const routedUrl = new URL(forwardReq.url);\n routedUrl.pathname = new URL(request.url).pathname;\n acceptHeaders.set(SUB_AGENT_OUTER_URL_HEADER, routedUrl.toString());\n return this.lifecycle.fetch(\n new Request(forwardReq, { headers: acceptHeaders })\n );\n }\n\n return this._cf_forwardToFacet(forwardReq, match);\n }\n\n broadcast(\n msg: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): void {\n if (this._isFacet) {\n void this._dynamicAgents.broadcastToParent(msg, without);\n return;\n }\n\n for (const connection of this._webSockets.getConnections()) {\n if (without?.includes(connection.id)) continue;\n if (this._dynamicAgents.connectionHasChildTarget(connection)) continue;\n connection.send(msg);\n }\n }\n\n getConnection<TState = unknown>(id: string): Connection<TState> | undefined {\n if (this._isFacet) {\n // Do not read lifecycle-owned root connections from a facet — that\n // resolves to the host/root DO's hibernatable sockets and reading them\n // from the facet's I/O context throws a cross-DO Native I/O error. See\n // issue #1677. Only virtual (bridged) connections are visible here.\n return this._dynamicAgents.getVirtualConnection(id) as\n | Connection<TState>\n | undefined;\n }\n\n const connection = this._webSockets.getConnection<TState>(id);\n if (\n !connection ||\n this._dynamicAgents.connectionHasChildTarget(connection)\n ) {\n return undefined;\n }\n return connection;\n }\n\n *getConnections<TState = unknown>(\n tag?: string\n ): Iterable<Connection<TState>> {\n if (this._isFacet) {\n // A facet's client connections are all virtual — they are real\n // WebSockets owned by the ROOT DO and bridged in. We must NOT fall\n // through to `this._webSockets.getConnections()` here: on a facet that resolves to\n // the host/root DO's hibernatable sockets, and reading their attachments\n // from the facet's I/O context throws\n // \"Cannot perform I/O on behalf of a different Durable Object (Native)\".\n // See issue #1677.\n yield* this._dynamicAgents.getVirtualConnections(tag) as Iterable<\n Connection<TState>\n >;\n return;\n }\n\n for (const connection of this._webSockets.getConnections<TState>(tag)) {\n if (this._dynamicAgents.connectionHasChildTarget(connection)) continue;\n yield connection;\n }\n }\n\n async _cf_broadcastToSubAgent(\n ownerPath: ReadonlyArray<AgentPathStep>,\n message: string | ArrayBuffer | ArrayBufferView,\n without?: string[]\n ): Promise<void> {\n await this._dynamicAgents.broadcastToPath(ownerPath, message, without);\n }\n\n _cf_subAgentConnectionMetas(\n ownerPath: ReadonlyArray<AgentPathStep>\n ): Promise<SubAgentConnectionMeta[]> {\n return this._dynamicAgents.connectionMetas(ownerPath);\n }\n\n _cf_sendToSubAgentConnection(\n connectionId: string,\n message: string | ArrayBuffer | ArrayBufferView\n ): Promise<void> {\n return this._dynamicAgents.sendToConnection(connectionId, message);\n }\n\n _cf_closeSubAgentConnection(\n connectionId: string,\n code?: number,\n reason?: string\n ): Promise<void> {\n return this._dynamicAgents.closeConnection(connectionId, code, reason);\n }\n\n _cf_setSubAgentConnectionState(\n connectionId: string,\n state: unknown\n ): Promise<unknown> {\n return this._dynamicAgents.setConnectionState(connectionId, state);\n }\n\n protected _cf_connectionTargetsSubAgent(connection: Connection): boolean {\n return this._dynamicAgents.connectionTargetsChild(connection);\n }\n\n /**\n * Returns true when the current request is addressed to a child facet of\n * this agent rather than to this agent itself.\n *\n * Chat-style subclasses wrap `onConnect` before the base Agent forwarding\n * wrapper runs, so they need a request-level check to avoid sending their\n * own protocol frames on sockets that are about to be forwarded to a child.\n */\n protected _cf_requestTargetsSubAgent(request: Request): boolean {\n return this._dynamicAgents.requestTargetsChild(request);\n }\n\n private _cf_forwardSubAgentWebSocketConnect(\n connection: Connection,\n request: Request,\n options: { gate: boolean }\n ): Promise<boolean> {\n return this._dynamicAgents.forwardWebSocketConnect(\n connection,\n request,\n options\n );\n }\n\n private _cf_forwardSubAgentWebSocketMessage(\n connection: Connection,\n message: WSMessage,\n replyBridge?: SubAgentConnectionBridge\n ): Promise<boolean> {\n return this._dynamicAgents.forwardWebSocketMessage(\n connection,\n message,\n replyBridge\n );\n }\n\n private _cf_forwardSubAgentWebSocketClose(\n connection: Connection,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<boolean> {\n return this._dynamicAgents.forwardWebSocketClose(\n connection,\n code,\n reason,\n wasClean\n );\n }\n\n _cf_handleSubAgentWebSocketConnect(\n bridge: SubAgentConnectionBridge,\n meta: SubAgentConnectionMeta\n ): Promise<void> {\n return this._dynamicAgents.handleWebSocketConnect(bridge, meta);\n }\n\n _cf_handleSubAgentWebSocketMessage(\n message: WSMessage,\n bridge: SubAgentConnectionBridge,\n meta: SubAgentConnectionMeta,\n replyBridge: SubAgentConnectionBridge = bridge\n ): Promise<void> {\n return this._dynamicAgents.handleWebSocketMessage(\n message,\n bridge,\n meta,\n replyBridge\n );\n }\n\n _cf_handleSubAgentWebSocketClose(\n code: number,\n reason: string,\n wasClean: boolean,\n bridge: SubAgentConnectionBridge,\n meta: SubAgentConnectionMeta\n ): Promise<void> {\n return this._dynamicAgents.handleWebSocketClose(\n code,\n reason,\n wasClean,\n bridge,\n meta\n );\n }\n\n protected _cf_hydrateSubAgentConnectionsFromRoot(): Promise<void> {\n return this._dynamicAgents.hydrateConnectionsFromRoot();\n }\n\n /**\n * Parent-side middleware hook. Fires before a request is\n * forwarded into a facet sub-agent. Mirrors `onBeforeConnect` /\n * `onBeforeRequest`.\n *\n * - return `void` (default) → forward the original request\n * - return `Request` → forward this (modified) request\n * - return `Response` → return this response to the\n * client; do not wake the child\n *\n * Default implementation: return void (permissive).\n *\n * The hook receives the **original** request with its URL intact —\n * including the `/sub/{class}/{name}` segment. The routing\n * decision for which facet to wake is fixed at parse time, so if\n * you return a modified `Request`, its headers, body, method, and\n * query string flow through to the child, but the **pathname**\n * the child sees is always the tail after `/sub/{class}/{name}`.\n * Customize via headers/body rather than URL-rewriting.\n *\n * WebSocket upgrade requests flow through this hook the same way as\n * plain HTTP. If you return a mutated `Request`, make sure it still\n * carries the original `Upgrade: websocket` and `Sec-WebSocket-*`\n * headers — the simplest safe recipe is to clone the incoming\n * request's headers (via `new Headers(req.headers)`) and only add\n * or replace entries, rather than constructing a fresh `Headers`\n * object from scratch.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @example\n * ```ts\n * class Inbox extends Agent {\n * override async onBeforeSubAgent(req, { className, name }) {\n * // Strict registry gate\n * if (!this.dynamicAgents.has(className, name)) {\n * return new Response(\"Not found\", { status: 404 });\n * }\n * }\n * }\n * ```\n */\n async onBeforeSubAgent(\n // oxlint-disable-next-line eslint(no-unused-vars) -- subclass override\n _request: Request,\n // oxlint-disable-next-line eslint(no-unused-vars) -- subclass override\n _child: { className: string; name: string }\n ): Promise<Request | Response | void> {\n return undefined;\n }\n\n /**\n * Resolve the facet Fetcher for the match and forward the\n * request to it with `/sub/{class}/{name}` stripped.\n *\n * @internal\n */\n private _cf_forwardToFacet(\n req: Request,\n match: {\n childClass: string;\n childName: string;\n remainingPath: string;\n }\n ): Promise<Response> {\n return this._dynamicAgents.forward(req, match);\n }\n\n /**\n * Bridge method used by `getSubAgentByName`. Resolves the facet\n * on each call (idempotent via `subAgent`) and dispatches one\n * RPC method. Stateless — no cached references.\n *\n * @internal\n */\n _cf_invokeSubAgent(\n className: string,\n name: string,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n return this._dynamicAgents.invoke(className, name, method, args);\n }\n\n /**\n * Bridge method used by `parentAgent()` when the requested parent is\n * itself a facet (and therefore has no top-level env namespace).\n * The root receives the full root-first target path, then each hop\n * delegates to the next facet using that facet's own `ctx.facets`.\n *\n * @internal\n */\n _cf_invokeSubAgentPath(\n path: ReadonlyArray<{ className: string; name: string }>,\n method: string,\n args: unknown[]\n ): Promise<unknown> {\n return this._dynamicAgents.invokePath(path, method, args);\n }\n\n // ── Sub-agent (facet) management ────────────────────────────────────────\n\n /**\n * Initialize this agent as a facet in a single RPC.\n *\n * Runs entirely inside the child's isolate, so every storage write\n * and `onStart()` I/O is owned by the child DO. This replaces the\n * previous \"construct a Request in the parent DO and `stub.fetch()`\n * it on the child\" handshake, whose native I/O was tied to the\n * parent and triggered \"Cannot perform I/O on behalf of a different\n * Durable Object\" on the child.\n *\n * We set `_isFacet` eagerly (before `__unsafe_ensureInitialized`\n * runs `onStart()`) so any code that legitimately branches on it\n * — e.g. skipping parent-owned alarms in schedule guards — sees\n * the flag during the first `onStart()` run. Protocol broadcasts are\n * suppressed only during this bootstrap window; afterward, facets can\n * broadcast to their own WebSocket clients reached via sub-agent\n * routing.\n *\n * The facet's logical name is persisted separately from its routing id.\n * Legacy facets used the logical name directly as `ctx.id.name`; newer\n * facets can use path-scoped routing ids while preserving `this.name`.\n *\n * @internal Called by {@link subAgent}.\n */\n _cf_initAsFacet(\n name: string,\n parentPath: ReadonlyArray<{ className: string; name: string }> = [],\n identityName = name\n ): Promise<void> {\n return this._dynamicAgents.init(name, parentPath, identityName);\n }\n\n get name(): string {\n const routedName = this.lifecycle.name;\n return (\n this._facetName ?? logicalNameFromPathV2Identity(routedName) ?? routedName\n );\n }\n\n /**\n * Ancestor chain for this agent, root-first. Empty for top-level\n * DOs. Populated at facet init time; survives hibernation.\n *\n * @example\n * ```ts\n * class Chat extends Agent {\n * onStart() {\n * console.log(\"chat started under:\", this.parentPath);\n * // → [{ className: \"Tenant\", name: \"acme\" }, { className: \"Inbox\", name: \"alice\" }]\n * }\n * }\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\n get parentPath(): ReadonlyArray<AgentPathStep> {\n return this._parentPath;\n }\n\n /**\n * Ancestor chain + self, root-first. Convenient for logging.\n *\n * @experimental The API surface may change before stabilizing.\n */\n get selfPath(): ReadonlyArray<AgentPathStep> {\n return [\n ...this._parentPath,\n {\n className: (this.constructor as { name: string }).name,\n name: this.name\n }\n ];\n }\n\n /**\n * Resolve a typed parent stub for this facet's **immediate** parent\n * agent.\n *\n * Symmetric with `subAgent(Cls, name)`: while `subAgent` opens a\n * stub from parent to child, `parentAgent` opens one from child\n * to parent. Pass the direct parent's class reference — the\n * framework verifies it matches the last entry of\n * `this.parentPath` at runtime. If the parent is a top-level\n * Durable Object, the framework returns the normal namespace stub.\n * If the parent is itself a facet, the framework returns a bridge\n * proxy that routes method calls through the root/supervisor and\n * then down the recorded facet path.\n *\n * `this.parentPath` is root-first, so the direct parent is the\n * **last** entry: `this.parentPath.at(-1)`. For grandparents and\n * further ancestors, iterate `this.parentPath` and use\n * `getAgentByName(env.X, this.parentPath[i].name)` directly.\n *\n * For top-level parents, the framework first checks `env[Cls.name]`,\n * then falls back to the Worker `exports` object. This supports\n * custom binding names as long as the parent class is exported under\n * its class name.\n *\n * Facet-parent stubs route normal HTTP `.fetch()` calls through the\n * same root bridge as RPC methods. WebSocket upgrade requests are\n * not supported yet because WebSocket handles cannot be serialized\n * over RPC.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @throws If this agent is not a facet (no parent).\n * @throws If `Cls.name` doesn't match the recorded direct-parent\n * class (guards against accidentally reaching the wrong\n * DO, especially in nested Root → Mid → Leaf chains).\n * @throws If no namespace is found for a top-level parent, or no\n * root namespace is available for a facet parent bridge.\n *\n * @example\n * ```ts\n * class Chat extends AIChatAgent<Env> {\n * async onChatMessage(...) {\n * const inbox = await this.parentAgent(Inbox);\n * const memory = await inbox.getSharedMemory(\"facts\");\n * // ...\n * }\n * }\n * ```\n */\n async parentAgent<T extends Agent>(\n cls: SubAgentClass<T>\n ): Promise<DurableObjectStub<T>> {\n // `_parentPath` is root-first, so the *direct* parent is the\n // last entry. Destructuring with `[parent] = ...` would grab the\n // root ancestor instead — wrong for any chain deeper than one\n // level and silently routes to the wrong DO if the root and the\n // direct parent happen to be the same class.\n const parent = this._parentPath[this._parentPath.length - 1];\n if (!parent) {\n throw new Error(\n `parentAgent(): ${this.constructor.name} is not a facet — ` +\n `only sub-agents (spawned via \\`subAgent()\\`) have a parent.`\n );\n }\n if (cls.name !== parent.className) {\n throw new Error(\n `parentAgent(${cls.name}): this facet's recorded parent class ` +\n `is \"${parent.className}\", not \"${cls.name}\". Pass the class ` +\n `whose constructor actually spawned this facet.`\n );\n }\n if (this._parentPath.length > 1) {\n return await this._cf_parentAgentFacetProxy<T>(\n cls.name,\n this._parentPath\n );\n }\n\n const binding = this._cf_getTopLevelNamespaceByClassName<T>(cls.name);\n if (!binding) {\n throw new Error(\n `parentAgent(${cls.name}): no top-level namespace for \"${cls.name}\" ` +\n `was found in env or worker exports. Make sure the parent class is ` +\n `exported under that class name and registered as a Durable Object binding.`\n );\n }\n return await getAgentByName<Cloudflare.Env, T>(binding, parent.name);\n }\n\n private _cf_getTopLevelNamespaceByClassName<T extends Agent>(\n className: string\n ): DurableObjectNamespace<T> | undefined {\n // Prefer explicit env bindings; fall back to worker exports so\n // custom binding names still work when the class is exported under\n // its constructor name.\n return (\n this._cf_asDurableObjectNamespace<T>(\n (this.env as Record<string, unknown>)[className]\n ) ??\n this._cf_asDurableObjectNamespace<T>(\n (workerExports as Record<string, unknown>)[className]\n )\n );\n }\n\n private _cf_asDurableObjectNamespace<T extends Agent>(\n candidate: unknown\n ): DurableObjectNamespace<T> | undefined {\n const binding = candidate as DurableObjectNamespace<T> | undefined;\n return binding?.idFromName ? binding : undefined;\n }\n\n private async _cf_parentAgentFacetProxy<T extends Agent>(\n className: string,\n parentPath: ReadonlyArray<{ className: string; name: string }>\n ): Promise<DurableObjectStub<T>> {\n const [root] = parentPath;\n if (!root) {\n throw new Error(`parentAgent(${className}): parent path is empty.`);\n }\n\n const rootBinding = this._cf_getTopLevelNamespaceByClassName<Agent>(\n root.className\n );\n if (!rootBinding) {\n throw new Error(\n `parentAgent(${className}): direct parent is a facet, but no ` +\n `top-level root namespace \"${root.className}\" was found in env ` +\n `or worker exports to bridge the call.`\n );\n }\n\n const rootStubPromise = getAgentByName<Cloudflare.Env, Agent>(\n rootBinding,\n root.name\n );\n const targetPath = parentPath.map((step) => ({ ...step }));\n const invokeBridge = async (method: string, args: unknown[]) => {\n const rootStub = await rootStubPromise;\n const bridge = rootStub as unknown as SubAgentPathInvokeEndpoint;\n return await bridge._cf_invokeSubAgentPath(targetPath, method, args);\n };\n const owner = this;\n return new Proxy(\n {},\n {\n get(_target, prop) {\n if (isInternalJsStubProp(prop)) return undefined;\n if (typeof prop !== \"string\") return undefined;\n if (prop === \"fetch\") {\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n if (owner._cf_isWebSocketUpgradeRequest(input, init)) {\n throw new Error(\n `parentAgent(${className}).fetch() does not support WebSocket upgrade requests yet. ` +\n `Use externally routed sub-agent URLs for WebSocket connections.`\n );\n }\n\n return await invokeBridge(prop, [input, init]);\n };\n }\n return async (...args: unknown[]) => {\n return await invokeBridge(prop, args);\n };\n }\n }\n ) as DurableObjectStub<T>;\n }\n\n private _cf_isWebSocketUpgradeRequest(\n input: RequestInfo | URL,\n init?: RequestInit\n ): boolean {\n const initHeaders = init?.headers ? new Headers(init.headers) : undefined;\n const requestHeaders =\n input instanceof Request ? new Headers(input.headers) : undefined;\n return (\n initHeaders?.get(\"Upgrade\")?.toLowerCase() === \"websocket\" ||\n requestHeaders?.get(\"Upgrade\")?.toLowerCase() === \"websocket\"\n );\n }\n\n /**\n * Get or create a named sub-agent — a child Durable Object (facet)\n * with its own isolated SQLite storage running on the same machine.\n *\n * The child class must extend `Agent` and be exported from the worker\n * entry point. The first call for a given name triggers the child's\n * `onStart()`. Subsequent calls return the existing instance.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @param cls The Agent subclass (must be exported from the worker)\n * @param name Unique name for this child instance\n * @returns A typed RPC stub for calling methods on the child\n *\n * @example\n * ```typescript\n * const searcher = await this.subAgent(SearchAgent, \"main-search\");\n * const results = await searcher.search(\"cloudflare agents\");\n * ```\n *\n * @deprecated Use {@link Agent.dynamicAgents | this.dynamicAgents.get()} instead.\n */\n async subAgent<T extends Agent>(\n cls: SubAgentClass<T>,\n name: string\n ): Promise<SubAgentStub<T>> {\n return this.dynamicAgents.get(cls, name);\n }\n\n /** Maximum number of non-terminal agent-tool runs this parent may own at once. */\n maxConcurrentAgentTools = Infinity;\n\n async onAgentToolStart(_run: AgentToolRunInfo): Promise<void> {}\n\n async onAgentToolFinish(\n _run: AgentToolRunInfo,\n _result: AgentToolLifecycleResult\n ): Promise<void> {}\n\n /**\n * Parent hook fired (best-effort) whenever a child agent-tool run emits a\n * `reportProgress` signal that is forwarded through this parent's tail. Use it\n * to meter / steer / surface progress server-side. Fires for both awaited and\n * detached runs; it is NOT durable — after eviction a detached run's latest\n * snapshot is read from `inspectAgentToolRun().progress` on reconcile instead.\n */\n async onProgress(\n _run: AgentToolRunInfo,\n _progress: AgentToolProgressSnapshot\n ): Promise<void> {}\n\n /**\n * Emit an ephemeral progress signal from a sub-agent that is currently running\n * as an agent tool. Rides the child's active turn stream as a transient\n * `data-agent-progress` part (re-broadcast to the parent's clients + surfaced\n * in `useAgentToolEvents`) and persists a latest-wins snapshot for recovery /\n * inspection. A no-op (with a dev warning) on the base `Agent`, which has no\n * streaming turn — overridden by chat hosts (`@cloudflare/think`,\n * `AIChatAgent`). See `design/rfc-detached-agent-tools.md`.\n */\n async reportProgress<T = unknown>(\n _progress: AgentToolProgress<T>,\n _options?: { persist?: boolean }\n ): Promise<void> {\n console.warn(\n \"[agents] reportProgress() is only supported on chat agents (@cloudflare/think, AIChatAgent) running as an agent tool; ignoring on base Agent.\"\n );\n }\n\n async runAgentTool<Input = unknown>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input> & {\n detached: true | DetachedAgentToolConfig;\n }\n ): Promise<DetachedRunAgentToolResult>;\n async runAgentTool<Input = unknown, Output = unknown>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input>\n ): Promise<RunAgentToolResult<Output>>;\n async runAgentTool<Input = unknown, Output = unknown>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input>\n ): Promise<RunAgentToolResult<Output> | DetachedRunAgentToolResult> {\n const runId = options.runId ?? nanoid(12);\n const agentType = cls.name;\n const detached = this._parseDetachedOption(options.detached);\n\n const existing = this._readAgentToolRun(runId);\n if (existing) {\n // Detached re-dispatch (e.g. chat recovery re-running the dispatching\n // turn) is idempotent by runId: re-arm the durable backbone for a still\n // non-terminal run and hand back the live handle instead of re-tailing or\n // spawning fresh work. A run that already reached terminal simply returns\n // a running-shaped handle — its delivery already happened (or is owned by\n // the ledger).\n if (detached) {\n if (!this._isAgentToolRowHardTerminal(existing.status)) {\n await this._armDetachedBackbone();\n }\n return { runId, agentType, status: \"running\" };\n }\n // HARD terminals (completed/error/aborted) are returned as-is. `interrupted`\n // is a SOFT terminal — recovery gave up once, but the child may have\n // reached its real terminal since — so it falls through to the re-attach\n // path below (which can repair the row), exactly like a non-terminal run.\n if (\n existing.status === \"completed\" ||\n existing.status === \"error\" ||\n existing.status === \"aborted\"\n ) {\n if (existing.status === \"completed\" && existing.output_json == null) {\n try {\n const child = await this.subAgent(\n cls as SubAgentClass<Agent>,\n runId\n );\n const adapter = this._asAgentToolChildAdapter<Input, Output>(child);\n const inspection = await adapter.inspectAgentToolRun(runId);\n if (inspection?.status === \"completed\") {\n const result = this._terminalResultFromInspection<Output>(\n agentType,\n inspection\n );\n this._updateAgentToolTerminal(\n runId,\n result,\n inspection.completedAt\n );\n return result;\n }\n } catch {\n // Fall back to the retained parent row.\n }\n }\n return this._resultFromAgentToolRow<Output>(existing);\n }\n // Non-terminal or soft-terminal (`interrupted`) runId: the child may still\n // be in flight or may have reached terminal since we gave up (typically a\n // re-issue after parent recovery re-runs the same turn with a stable\n // runId — the documented \"correct pattern\"). Re-attach to the live child\n // and tail it to terminal instead of abandoning it as `interrupted` and\n // letting the model re-run already-completed child work (#1630). Falls\n // back to replay+interrupt when there is no tail adapter or the bounded\n // budget is exhausted.\n let reattachReason: AgentToolInterruptedReason | undefined;\n let childTornDown = false;\n try {\n const child = await this.subAgent(cls as SubAgentClass<Agent>, runId);\n const adapter = this._asAgentToolChildAdapter<Input, Output>(child);\n const reattach = await this._reattachAgentToolRunToTerminal<Output>(\n adapter,\n existing,\n 1,\n this._resolvedOptions.agentToolReattachNoProgressTimeoutMs,\n this._resolvedOptions.agentToolReattachMaxWindowMs\n );\n if (reattach.result) {\n await this._finishAgentToolRun(\n this._agentToolRunInfoFromRow(existing),\n reattach.result,\n { sequence: reattach.sequence, completedAt: reattach.completedAt }\n );\n return reattach.result;\n }\n reattachReason = reattach.reason;\n // The parent has genuinely given up re-attaching to this live child —\n // tear it down so it stops consuming a fiber / keep-alive (#1630).\n childTornDown = await this._teardownGivenUpAgentToolChild(\n adapter,\n runId,\n reattach.reason\n );\n } catch {\n // Fall through to the honest interrupted state below.\n }\n return await this._replayAndInterruptAgentToolRun<Output>(\n existing,\n this._interruptedMessageForReason(reattachReason),\n { reason: reattachReason, childStillRunning: !childTornDown }\n );\n }\n\n const displayOrder = options.displayOrder ?? 0;\n const inputPreview =\n options.inputPreview ?? this._defaultAgentToolPreview(options.input);\n const displayJson =\n options.display !== undefined ? JSON.stringify(options.display) : null;\n const inputPreviewJson =\n inputPreview !== undefined ? JSON.stringify(inputPreview) : null;\n const startedAt = Date.now();\n\n if (this._activeAgentToolRunCount() >= this.maxConcurrentAgentTools) {\n const error = `maxConcurrentAgentTools (${this.maxConcurrentAgentTools}) exceeded`;\n this.sql`\n INSERT INTO cf_agent_tool_runs (\n run_id, parent_tool_call_id, agent_type, input_preview,\n input_redacted, status, error_message, display_metadata,\n display_order, started_at, completed_at\n ) VALUES (\n ${runId}, ${options.parentToolCallId ?? null}, ${agentType},\n ${inputPreviewJson}, 1, 'error', ${error}, ${displayJson},\n ${displayOrder}, ${startedAt}, ${Date.now()}\n )\n `;\n this._broadcastAgentToolEvent(options.parentToolCallId, 0, {\n kind: \"started\",\n runId,\n agentType,\n inputPreview,\n order: displayOrder,\n display: options.display\n });\n this._broadcastAgentToolEvent(options.parentToolCallId, 1, {\n kind: \"error\",\n runId,\n error\n });\n return { runId, agentType, status: \"error\", error };\n }\n\n const detachedMaxBudgetAt = detached\n ? startedAt +\n (detached.maxBudgetMs ?? this._resolvedOptions.detachedMaxBudgetMs)\n : null;\n const detachedNoProgressBudgetMs = detached\n ? (detached.noProgressBudgetMs ??\n this._resolvedOptions.detachedNoProgressBudgetMs)\n : null;\n const detachedOnMilestonesJson = detached?.onMilestones\n ? JSON.stringify(detached.onMilestones)\n : null;\n this.sql`\n INSERT INTO cf_agent_tool_runs (\n run_id, parent_tool_call_id, agent_type, input_preview,\n input_redacted, status, display_metadata, display_order, started_at,\n detached, detached_on_finish, detached_notify_source,\n detached_max_budget_at, detached_no_progress_budget_ms,\n detached_on_milestones\n ) VALUES (\n ${runId}, ${options.parentToolCallId ?? null}, ${agentType},\n ${inputPreviewJson}, 1, 'starting', ${displayJson}, ${displayOrder},\n ${startedAt}, ${detached ? 1 : 0}, ${detached?.onFinishName ?? null},\n ${detached?.notifySource ?? null}, ${detachedMaxBudgetAt},\n ${detachedNoProgressBudgetMs}, ${detachedOnMilestonesJson}\n )\n `;\n\n const runInfo: AgentToolRunInfo = {\n runId,\n parentToolCallId: options.parentToolCallId,\n agentType,\n inputPreview,\n status: \"starting\",\n display: options.display,\n ...(detached?.notifySource !== undefined\n ? { notifySource: detached.notifySource }\n : {}),\n displayOrder,\n startedAt\n };\n await this.onAgentToolStart(runInfo);\n this._broadcastAgentToolEvent(options.parentToolCallId, 0, {\n kind: \"started\",\n runId,\n agentType,\n inputPreview,\n order: displayOrder,\n display: options.display\n });\n\n const child = await this.subAgent(cls as SubAgentClass<Agent>, runId);\n const adapter = this._asAgentToolChildAdapter<Input, Output>(child);\n const childStart = await adapter.startAgentToolRun(options.input, {\n runId\n });\n this._markAgentToolRunning(runId);\n\n if (detached) {\n // The child must OUTLIVE the dispatching turn, so a detached run never\n // inherits `options.signal` (which aborts when this turn ends). Cancel a\n // detached run explicitly with `cancelAgentTool(runId)`.\n if (options.signal) {\n console.warn(\n `[agents] runAgentTool: \\`signal\\` is ignored for a detached run (${runId}); a detached child must outlive the spawning turn. Use cancelAgentTool(runId) to cancel it.`\n );\n }\n // Arm the durable backbone first so eviction between here and the fast\n // path still finalizes the run, then kick the warm fast path that tails\n // the child to terminal and delivers with low latency while alive.\n await this._armDetachedBackbone({ resetCadence: true });\n // Surface runaway accumulation: detached runs hold a slot for their whole\n // life with no observer to notice a leak.\n this._maybeWarnDetachedLiveCount();\n this.ctx.waitUntil(\n this._detachedFastPath<Input, Output>(runInfo, cls, runId)\n );\n return { runId, agentType, status: \"running\" };\n }\n\n let sequence = 1;\n let parentAbortListener: (() => void) | undefined;\n if (options.signal) {\n if (options.signal.aborted) {\n await adapter.cancelAgentToolRun(runId, options.signal.reason);\n const reason =\n options.signal.reason instanceof Error\n ? options.signal.reason.message\n : String(options.signal.reason ?? \"cancelled\");\n const result: RunAgentToolResult<Output> = {\n runId,\n agentType,\n status: \"aborted\",\n error: reason\n };\n await this._finishAgentToolRun(runInfo, result, { sequence });\n return result;\n } else {\n parentAbortListener = () => {\n void adapter.cancelAgentToolRun(runId, options.signal?.reason);\n };\n options.signal.addEventListener(\"abort\", parentAbortListener, {\n once: true\n });\n }\n }\n\n try {\n if (adapter.tailAgentToolRun) {\n const stream = await adapter.tailAgentToolRun(runId, {\n afterSequence: -1\n });\n sequence = (\n await this._forwardAgentToolStream(\n stream,\n options.parentToolCallId,\n runId,\n sequence,\n options.signal\n )\n ).next;\n } else {\n const chunks = await adapter.getAgentToolChunks(runId);\n sequence = this._broadcastAgentToolChunks(\n options.parentToolCallId,\n runId,\n chunks,\n sequence\n );\n }\n\n if (options.signal?.aborted) {\n await adapter.cancelAgentToolRun(runId, options.signal.reason);\n const reason =\n options.signal.reason instanceof Error\n ? options.signal.reason.message\n : String(options.signal.reason ?? \"cancelled\");\n const result: RunAgentToolResult<Output> = {\n runId,\n agentType,\n status: \"aborted\",\n error: reason\n };\n await this._finishAgentToolRun(runInfo, result, { sequence });\n return result;\n }\n\n const inspection =\n (await adapter.inspectAgentToolRun(runId)) ?? childStart;\n const result = this._terminalResultFromInspection<Output>(\n agentType,\n inspection\n );\n await this._finishAgentToolRun(runInfo, result, {\n sequence,\n completedAt: inspection.completedAt\n });\n return result;\n } catch (error) {\n if (options.signal?.aborted) {\n await adapter.cancelAgentToolRun(runId, options.signal.reason);\n const reason =\n options.signal.reason instanceof Error\n ? options.signal.reason.message\n : String(options.signal.reason ?? \"cancelled\");\n const result: RunAgentToolResult<Output> = {\n runId,\n agentType,\n status: \"aborted\",\n error: reason\n };\n await this._finishAgentToolRun(runInfo, result, { sequence });\n return result;\n }\n const message = error instanceof Error ? error.message : String(error);\n const result: RunAgentToolResult<Output> = {\n runId,\n agentType,\n status: \"error\",\n error: message\n };\n await this._finishAgentToolRun(runInfo, result, { sequence });\n return result;\n } finally {\n if (parentAbortListener && options.signal) {\n options.signal.removeEventListener(\"abort\", parentAbortListener);\n }\n }\n }\n\n /**\n * Cancel an agent-tool run by id. Idempotent: cancelling an already-terminal\n * run is a no-op. Detached runs deliver through the guarded ledger so a wired\n * `onFinish` fires once with `status: \"aborted\"`; awaited runs leave terminal\n * observation to the awaiting/recovery path, avoiding duplicate finish hooks.\n */\n async cancelAgentTool(runId: string, reason?: unknown): Promise<void> {\n const row = this._readAgentToolRun(runId);\n if (!row) return;\n if (this._isAgentToolRowHardTerminal(row.status)) return;\n const isDetached = row.detached === 1;\n const message =\n reason instanceof Error\n ? reason.message\n : String(reason ?? \"cancelled by parent\");\n try {\n const child = await this._cf_resolveSubAgent(row.agent_type, runId);\n const adapter = this._asAgentToolChildAdapter(child);\n await adapter.cancelAgentToolRun(runId, reason);\n } catch {\n // Best-effort child teardown; we still record the aborted terminal so the\n // detached parent stops watching and any wired callback fires.\n }\n if (!isDetached) return;\n await this._deliverDetachedTerminal(runId, \"finish\", {\n runId,\n agentType: row.agent_type,\n status: \"aborted\",\n error: message\n });\n }\n\n /**\n * Parse + validate the `detached` option. Returns `null` for a non-detached\n * run, or the normalized config (with the validated `onFinish` method name)\n * for a detached one. Throws if `onFinish` does not name a method on this\n * agent — closures cannot survive Durable Object eviction, so the durable\n * hook is referenced by method name (the same contract as `schedule`).\n */\n private _parseDetachedOption(detached: RunAgentToolOptions[\"detached\"]): {\n onFinishName?: string;\n maxBudgetMs?: number;\n noProgressBudgetMs?: number;\n notifySource?: string;\n onMilestones?: { names: string[]; mode: \"react\" | \"narrate\" };\n } | null {\n if (!detached) return null;\n if (detached === true) return {};\n let onFinishName = detached.onFinish as string | undefined;\n const notifySource =\n typeof detached.notify === \"object\" ? detached.notify.source : undefined;\n if (onFinishName !== undefined) {\n const callback = (this as unknown as Record<string, unknown>)[\n onFinishName\n ];\n if (typeof callback !== \"function\") {\n throw new Error(\n `runAgentTool: detached.onFinish \"${onFinishName}\" is not a method on ${this.constructor.name}. ` +\n 'Pass the NAME of a method (e.g. \"onImportDone\"), not a closure — ' +\n \"closures cannot be rehydrated after the Durable Object is evicted.\"\n );\n }\n } else if (detached.notify) {\n // `notify` sugar: auto-target the chat-agent notify hook if present.\n // A no-op on a base Agent that does not implement it.\n const notifyHook = (this as unknown as Record<string, unknown>)[\n DETACHED_NOTIFY_CALLBACK\n ];\n if (typeof notifyHook === \"function\") {\n onFinishName = DETACHED_NOTIFY_CALLBACK;\n }\n }\n return {\n ...(onFinishName !== undefined ? { onFinishName } : {}),\n ...(notifySource !== undefined ? { notifySource } : {}),\n ...(detached.maxBudgetMs !== undefined\n ? { maxBudgetMs: detached.maxBudgetMs }\n : {}),\n ...(detached.noProgressBudgetMs !== undefined\n ? { noProgressBudgetMs: detached.noProgressBudgetMs }\n : {}),\n ...(() => {\n const raw = detached.onMilestones;\n if (!raw) return {};\n const names = Array.isArray(raw) ? raw : raw.names;\n if (!Array.isArray(names) || names.length === 0) return {};\n const mode: \"react\" | \"narrate\" = Array.isArray(raw)\n ? \"narrate\"\n : (raw.mode ?? \"narrate\");\n return { onMilestones: { names, mode } };\n })()\n };\n }\n\n private _isAgentToolRowHardTerminal(status: AgentToolRunStatus): boolean {\n return status === \"completed\" || status === \"error\" || status === \"aborted\";\n }\n\n private _hasOutstandingDetachedRuns(): boolean {\n const rows = this.sql<{ n: number }>`\n SELECT COUNT(*) AS n FROM cf_agent_tool_runs\n WHERE detached = 1 AND finish_delivered_at IS NULL\n `;\n return (rows[0]?.n ?? 0) > 0;\n }\n\n /** Detached runs still holding a concurrency slot (non-terminal). */\n private _liveDetachedRunCount(): number {\n const rows = this.sql<{ n: number }>`\n SELECT COUNT(*) AS n FROM cf_agent_tool_runs\n WHERE detached = 1 AND status IN ('starting', 'running')\n `;\n return rows[0]?.n ?? 0;\n }\n\n /**\n * Edge-triggered warning when live detached runs cross\n * `DETACHED_LIVE_COUNT_WARN_THRESHOLD`. Fires once on the up-crossing and\n * re-arms only after the count falls back below the threshold, so a parent\n * accumulating long-lived background runs surfaces a signal without spamming.\n */\n private _maybeWarnDetachedLiveCount(): void {\n const liveCount = this._liveDetachedRunCount();\n if (liveCount < DETACHED_LIVE_COUNT_WARN_THRESHOLD) {\n this._detachedLiveCountWarned = false;\n return;\n }\n if (this._detachedLiveCountWarned) return;\n this._detachedLiveCountWarned = true;\n this._emit(\"agent_tool:detached:live_count_warning\", {\n liveCount,\n threshold: DETACHED_LIVE_COUNT_WARN_THRESHOLD\n });\n console.warn(\n `[agents] ${liveCount} detached agent-tool runs are live on this agent (threshold ${DETACHED_LIVE_COUNT_WARN_THRESHOLD}). Detached runs hold a concurrency slot until they finish — make sure they are completing or being cancelled, or lower \\`maxConcurrentAgentTools\\`.`\n );\n }\n\n /**\n * Warm fast path for a detached run: tail the child to terminal (so the\n * parent re-broadcasts its live stream to clients) and deliver the completion\n * with low latency while the isolate stays alive. Best-effort — the durable\n * `_cfDetachedReconcileTick` backbone is the guarantee; anything this misses\n * (eviction, a child that has not yet reached terminal) the backbone collects.\n */\n private async _detachedFastPath<Input, Output>(\n runInfo: AgentToolRunInfo,\n cls: ChatCapableAgentClass,\n runId: string\n ): Promise<void> {\n try {\n const child = await this.subAgent(cls as SubAgentClass<Agent>, runId);\n const adapter = this._asAgentToolChildAdapter<Input, Output>(child);\n let sequence = 1;\n if (adapter.tailAgentToolRun) {\n const stream = await adapter.tailAgentToolRun(runId, {\n afterSequence: -1\n });\n sequence = (\n await this._forwardAgentToolStream(\n stream,\n runInfo.parentToolCallId,\n runId,\n sequence,\n undefined\n )\n ).next;\n }\n const inspection = await adapter.inspectAgentToolRun(runId);\n if (\n inspection &&\n this._isAgentToolRowHardTerminal(\n inspection.status as AgentToolRunStatus\n )\n ) {\n const result = this._terminalResultFromInspection<Output>(\n runInfo.agentType,\n inspection\n );\n await this._deliverDetachedTerminal(\n runId,\n \"finish\",\n result,\n { sequence, serialize: true },\n inspection.completedAt\n );\n }\n } catch {\n // Leave it to the backbone reconcile.\n }\n }\n\n /**\n * Single delivery funnel for a detached terminal. Both the warm fast path and\n * the durable backbone route through here, with INDEPENDENT ledger slots for\n * `finish` (the real terminal) vs `give_up` (budget exhausted). Each slot is\n * delivered at-least-once via a claim + lease:\n *\n * - Concurrent double-fire is prevented by the guarded CAS claim (RETURNING\n * yields the row only to the winner).\n * - A crash after the side effect but before `*_delivered_at` is written lets\n * the lease expire so a later reconcile re-delivers — hence handlers must be\n * idempotent.\n * - Two slots, not one, because `interrupted` is SOFT: a give-up followed by a\n * real completion is legitimate, and a single shared \"delivered\" bit would\n * dedupe the child's real late result away (the #1752 production incident).\n */\n private async _deliverDetachedTerminal<Output>(\n runId: string,\n kind: \"finish\" | \"give_up\",\n result: RunAgentToolResult<Output>,\n options?: { sequence?: number; serialize?: boolean },\n completedAt = Date.now()\n ): Promise<void> {\n const now = Date.now();\n const leaseFloor = now - DETACHED_DELIVERY_LEASE_MS;\n // Guarded CAS claim. `rowsWritten` (changes()) is the affected-row count, so\n // exactly one concurrent caller observes 1 and proceeds; everyone else (a\n // racing path, or a re-delivery within the lease) observes 0 and bails.\n const claimQuery =\n kind === \"finish\"\n ? `UPDATE cf_agent_tool_runs\n SET finish_claimed_at = ?\n WHERE run_id = ?\n AND finish_delivered_at IS NULL\n AND (finish_claimed_at IS NULL OR finish_claimed_at < ?)`\n : `UPDATE cf_agent_tool_runs\n SET give_up_claimed_at = ?\n WHERE run_id = ?\n AND give_up_delivered_at IS NULL\n AND (give_up_claimed_at IS NULL OR give_up_claimed_at < ?)`;\n const claimed = this.ctx.storage.sql.exec(\n claimQuery,\n now,\n runId,\n leaseFloor\n ).rowsWritten;\n if (claimed === 0) return;\n\n const row = this._readAgentToolRun(runId);\n if (!row) return;\n\n this._updateAgentToolTerminal(runId, result, completedAt);\n // Always project the terminal onto the parent's `agent-tool-event` stream so\n // a background-runs tray flips to its final state live. The backbone/fast\n // path supply a tail sequence; other paths (e.g. an explicit\n // `cancelAgentTool`, or a budget give-up) get a synthetic latest-wins\n // sequence — the client reducer keys terminal status off the event kind, not\n // the sequence, so a monotonic value is not required.\n this._broadcastAgentToolTerminal(\n row.parent_tool_call_id ?? undefined,\n options?.sequence ?? Date.now(),\n result\n );\n\n const runInfo = this._agentToolRunInfoFromRow(\n row,\n result.status,\n completedAt\n );\n const lifecycle: AgentToolLifecycleResult = {\n status: result.status,\n ...(result.summary !== undefined ? { summary: result.summary } : {}),\n ...(result.error !== undefined ? { error: result.error } : {}),\n ...(result.reason !== undefined ? { reason: result.reason } : {}),\n ...(result.childStillRunning !== undefined\n ? { childStillRunning: result.childStillRunning }\n : {})\n };\n\n const invoke = async () => {\n // Global metering hook fires for detached runs too (cost accounting\n // parity with the awaited path).\n try {\n await this.onAgentToolFinish(runInfo, lifecycle);\n } catch (error) {\n await this._safeRunOnError(error);\n }\n // Targeted, durable per-run callback (method name persisted on the row).\n const callbackName = row.detached_on_finish;\n if (callbackName) {\n const callback = (this as unknown as Record<string, unknown>)[\n callbackName\n ];\n if (typeof callback === \"function\") {\n try {\n await (\n callback as (\n run: AgentToolRunInfo,\n res: AgentToolLifecycleResult\n ) => Promise<void>\n ).bind(this)(runInfo, lifecycle);\n } catch (error) {\n this._emit(\"agent_tool:detached:delivery_failed\", {\n runId,\n kind,\n status: result.status,\n callback: callbackName,\n error: error instanceof Error ? error.message : String(error)\n });\n await this._safeRunOnError(error);\n throw error;\n }\n }\n }\n };\n\n // Delivery can fire from a scheduled alarm or the warm fast path (no ambient\n // turn). `_runDetachedDelivery` establishes `agentContext` so a handler that\n // calls runAgentTool / setState / submitMessages works, and — in chat-layer\n // subclasses — serializes the delivery against the host turn queue when\n // `serialize` is set, so a state-mutating `onFinish` never interleaves with\n // an active LLM turn (RFC §\"run inside a turn\"). An explicit cancel runs\n // inline (it is already inside its caller's context).\n await this._runDetachedDelivery(invoke, { serialize: options?.serialize });\n\n // Mark delivered only AFTER the handler resolves. A crash before this point\n // leaves the lease to expire and a later reconcile to re-deliver.\n if (kind === \"finish\") {\n this.sql`\n UPDATE cf_agent_tool_runs\n SET finish_delivered_at = ${Date.now()}\n WHERE run_id = ${runId}\n `;\n } else {\n this.sql`\n UPDATE cf_agent_tool_runs\n SET give_up_delivered_at = ${Date.now()}\n WHERE run_id = ${runId}\n `;\n }\n }\n\n private async _safeRunOnError(error: unknown): Promise<void> {\n try {\n await this.onError(error);\n } catch {\n // Delivery hooks are best-effort; a failing onError must not wedge the\n // ledger or other detached runs.\n }\n }\n\n /**\n * Run a detached terminal delivery (the `onAgentToolFinish` + per-run\n * `onFinish` callbacks) in an appropriate execution context. The base `Agent`\n * has no turn queue, so it only establishes `agentContext` — a handler that\n * calls `runAgentTool` / `setState` therefore works regardless of where the\n * delivery fired from.\n *\n * Chat-layer subclasses (`@cloudflare/think`, `@cloudflare/ai-chat`) override\n * this to additionally serialize delivery against their turn queue when\n * `serialize` is set: a fast-path push or backbone tick can land mid-turn, and\n * a state-mutating `onFinish` running concurrently with an active LLM turn is a\n * data race. The fast path and backbone never run synchronously inside a turn\n * (they fire from `waitUntil` / a scheduled alarm), so enqueuing them on the\n * turn queue is deadlock-free. An explicit `cancelAgentTool` runs with\n * `serialize` unset because it may be called from inside the very turn that\n * triggers it, where enqueuing would self-deadlock.\n */\n protected async _runDetachedDelivery(\n invoke: () => Promise<void>,\n _options?: { serialize?: boolean }\n ): Promise<void> {\n if (agentContext.getStore()?.agent) {\n await invoke();\n return;\n }\n await runInInvocation(\n {\n agent: this,\n connection: undefined,\n request: undefined,\n email: undefined\n },\n invoke,\n { detached: true }\n );\n }\n\n /**\n * Arm the self-scheduling detached reconcile backbone. Existing schedules are\n * reused for recovery/startup calls, but a fresh detached dispatch resets the\n * pending cadence to the fast end so new work is noticed promptly.\n */\n private async _armDetachedBackbone(options?: {\n resetCadence?: boolean;\n }): Promise<void> {\n // Serialize arming within the isolate. `_armDetachedBackboneInner` is a\n // read-modify-write over the schedule rows (list → cancel duplicates →\n // create one); concurrent dispatches (e.g. a fan-out of detached\n // `runAgentTool`s in one turn) could otherwise each observe zero schedules\n // and create their own, leaving several redundant backbones ticking.\n const run = this._detachedBackboneArming.then(() =>\n this._armDetachedBackboneInner(options)\n );\n // Keep the mutex chain alive even if one arm rejects.\n this._detachedBackboneArming = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n\n private async _armDetachedBackboneInner(options?: {\n resetCadence?: boolean;\n }): Promise<void> {\n const schedules = await this.listSchedules();\n const armed = schedules.filter(\n (schedule) => schedule.callback === DETACHED_RECONCILE_CALLBACK\n );\n // Collapse any accidental duplicates down to a single backbone even when no\n // cadence reset was requested.\n if (armed.length > 0 && !options?.resetCadence) {\n for (const schedule of armed.slice(1)) {\n await this.cancelSchedule(schedule.id);\n }\n return;\n }\n for (const schedule of armed) {\n await this.cancelSchedule(schedule.id);\n }\n await this.schedule(\n DETACHED_BACKBONE_CADENCE_S[0],\n DETACHED_RECONCILE_CALLBACK as keyof this,\n { cadenceIndex: 0 } satisfies DetachedReconcilePayload,\n // Armed during startup recovery; the explicit choice keeps the\n // non-idempotent-startup-schedule warning for user code only.\n { idempotent: true }\n );\n }\n\n /**\n * Durable backbone for detached runs. Runs on a self-rescheduling alarm:\n * collects any detached run that has reached terminal but was not yet\n * delivered (e.g. the parent was evicted before the fast path landed), gives\n * up on any run past its absolute budget (tearing the child down), and\n * reschedules itself while any detached run remains undelivered — cancelling\n * itself once everything has settled (zero steady-state cost).\n */\n async _cfDetachedReconcileTick(\n payload?: DetachedReconcilePayload\n ): Promise<void> {\n const rows = this.sql<AgentToolRunStorageRow>`\n SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,\n summary, output_json, error_message, interrupted_reason,\n child_still_running, display_metadata, display_order,\n started_at, completed_at, detached, detached_on_finish,\n detached_notify_source, detached_max_budget_at,\n detached_no_progress_budget_ms, last_progress_at,\n detached_on_milestones,\n finish_claimed_at, finish_delivered_at, give_up_claimed_at,\n give_up_delivered_at\n FROM cf_agent_tool_runs\n WHERE detached = 1 AND finish_delivered_at IS NULL\n ORDER BY started_at ASC\n `;\n\n for (const row of rows) {\n const runId = row.run_id;\n let inspection: AgentToolRunInspection | null = null;\n try {\n const child = await this._cf_resolveSubAgent(row.agent_type, runId);\n const adapter = this._asAgentToolChildAdapter(child);\n inspection = await adapter.inspectAgentToolRun(runId);\n } catch {\n // Treat an unreachable child like a null inspection: keep waiting within\n // budget rather than sealing (a single failure is not proof it is gone).\n }\n\n // Deliver any configured milestone notifications the warm tail missed\n // (e.g. the parent was evicted when the milestone landed). Idempotent:\n // `_deliverDetachedMilestone` keys on (runId, name), so re-delivering an\n // already-notified milestone is a no-op. Runs regardless of terminal\n // state — a milestone reached just before completion still notifies.\n if (inspection?.milestones && row.detached_on_milestones) {\n const milestoneRunInfo = this._agentToolRunInfoFromRow(row);\n for (const milestone of inspection.milestones) {\n this._maybeDeliverDetachedMilestone(row, milestoneRunInfo, milestone);\n }\n }\n\n if (\n inspection &&\n this._isAgentToolRowHardTerminal(\n inspection.status as AgentToolRunStatus\n )\n ) {\n const result = this._terminalResultFromInspection(\n row.agent_type,\n inspection\n );\n await this._deliverDetachedTerminal(\n runId,\n \"finish\",\n result,\n { sequence: Date.now(), serialize: true },\n inspection.completedAt\n );\n continue;\n }\n\n // Still non-terminal. Give up only once (the give_up slot guards\n // re-delivery), on whichever bound trips first:\n // - the absolute `detached_max_budget_at` ceiling (taking too long), or\n // - the resetting no-progress window: once the child has reported at\n // least one signal and then goes silent past the window. A child that\n // has never reported has no signal time and is bounded ONLY by the\n // absolute ceiling — never given up on merely for being slow.\n const now = Date.now();\n const budgetAt = row.detached_max_budget_at;\n // ANY signal resets the window — ephemeral progress OR a durable milestone\n // (milestones bump the child's signal clock but leave `progress` unset, so\n // a milestone-only child must still count as alive). After eviction the\n // child's inspect is authoritative; `last_progress_at` is the warm-tail\n // cache fallback.\n const latestMilestone = inspection?.milestones?.length\n ? inspection.milestones[inspection.milestones.length - 1].at\n : undefined;\n const signalTimes = [\n inspection?.progress?.at,\n latestMilestone,\n row.last_progress_at\n ].filter((t): t is number => typeof t === \"number\");\n const lastSignalAt =\n signalTimes.length > 0 ? Math.max(...signalTimes) : undefined;\n const noProgressBudgetMs = row.detached_no_progress_budget_ms;\n const overAbsolute = budgetAt !== null && now >= budgetAt;\n const overNoProgress =\n typeof noProgressBudgetMs === \"number\" &&\n noProgressBudgetMs > 0 &&\n Number.isFinite(noProgressBudgetMs) &&\n typeof lastSignalAt === \"number\" &&\n now - lastSignalAt >= noProgressBudgetMs;\n if (\n (overAbsolute || overNoProgress) &&\n row.give_up_delivered_at === null\n ) {\n let childTornDown = false;\n try {\n const child = await this._cf_resolveSubAgent(row.agent_type, runId);\n const adapter = this._asAgentToolChildAdapter(child);\n await adapter.cancelAgentToolRun(\n runId,\n overAbsolute\n ? \"detached budget exceeded\"\n : \"detached run went silent past its no-progress window\"\n );\n childTornDown = true;\n } catch {\n // Could not confirm teardown; the child may complete anyway and the\n // finish slot (still open) will deliver the real result.\n }\n await this._deliverDetachedTerminal(\n runId,\n \"give_up\",\n {\n runId,\n agentType: row.agent_type,\n status: \"interrupted\",\n error: overAbsolute\n ? \"detached run exceeded its budget before completing\"\n : \"detached run went silent past its no-progress window\",\n reason: overAbsolute ? \"budget-exceeded\" : \"no-progress\",\n childStillRunning: !childTornDown\n },\n { serialize: true }\n );\n }\n }\n\n // Reschedule while anything remains undelivered; otherwise let the backbone\n // go quiet (the schedule is one-shot and is not recreated here).\n if (this._hasOutstandingDetachedRuns()) {\n const currentIndex =\n typeof payload?.cadenceIndex === \"number\" ? payload.cadenceIndex : 0;\n const nextIndex = Math.min(\n currentIndex + 1,\n DETACHED_BACKBONE_CADENCE_S.length - 1\n );\n await this.schedule(\n DETACHED_BACKBONE_CADENCE_S[nextIndex],\n DETACHED_RECONCILE_CALLBACK as keyof this,\n { cadenceIndex: nextIndex } satisfies DetachedReconcilePayload\n );\n }\n }\n\n hasAgentToolRun<T extends Agent>(\n cls: SubAgentClass<T>,\n runId: string\n ): boolean;\n hasAgentToolRun(agentType: string, runId: string): boolean;\n hasAgentToolRun(classOrName: SubAgentClass | string, runId: string): boolean {\n const agentType =\n typeof classOrName === \"string\" ? classOrName : classOrName.name;\n const rows = this.sql<{ n: number }>`\n SELECT COUNT(*) AS n FROM cf_agent_tool_runs\n WHERE run_id = ${runId} AND agent_type = ${agentType}\n `;\n return (rows[0]?.n ?? 0) > 0;\n }\n\n async clearAgentToolRuns(options?: {\n olderThan?: number;\n status?: AgentToolRunStatus[];\n }): Promise<void> {\n const rows = this.sql<{\n run_id: string;\n agent_type: string;\n status: string;\n }>`\n SELECT run_id, agent_type, status FROM cf_agent_tool_runs\n ORDER BY started_at ASC\n `;\n const statusFilter = options?.status\n ? new Set<string>(options.status)\n : null;\n const retained = rows.filter((row) => {\n if (statusFilter && !statusFilter.has(row.status)) return false;\n if (options?.olderThan !== undefined) {\n const full = this._readAgentToolRun(row.run_id);\n if (!full || full.started_at >= options.olderThan) return false;\n }\n return true;\n });\n\n for (const row of retained) {\n try {\n const cls = this._agentToolClassByName(row.agent_type);\n if (row.status === \"starting\" || row.status === \"running\") {\n const child = await this.subAgent(cls, row.run_id);\n const adapter = this._asAgentToolChildAdapter(child);\n await adapter.cancelAgentToolRun(\n row.run_id,\n \"clearing agent tool run\"\n );\n }\n await this.deleteSubAgent(cls, row.run_id);\n } catch {\n // Cleanup is intentionally idempotent.\n }\n this.sql`\n DELETE FROM cf_agent_tool_runs WHERE run_id = ${row.run_id}\n `;\n }\n }\n\n private _isAgentToolTerminal(status: string): boolean {\n return (\n status === \"completed\" ||\n status === \"error\" ||\n status === \"aborted\" ||\n status === \"interrupted\"\n );\n }\n\n private _activeAgentToolRunCount(): number {\n const rows = this.sql<{ n: number }>`\n SELECT COUNT(*) AS n FROM cf_agent_tool_runs\n WHERE status IN ('starting', 'running')\n `;\n return rows[0]?.n ?? 0;\n }\n\n private _defaultAgentToolPreview(input: unknown): unknown {\n if (typeof input === \"string\") return input.slice(0, 500);\n if (input === null || input === undefined) return input;\n try {\n const json = JSON.stringify(input);\n return json.length > 500 ? `${json.slice(0, 497)}...` : json;\n } catch {\n return String(input).slice(0, 500);\n }\n }\n\n private _readAgentToolRun(runId: string): AgentToolRunStorageRow | null {\n const rows = this.sql<AgentToolRunStorageRow>`\n SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,\n summary, output_json, error_message, interrupted_reason,\n child_still_running, display_metadata, display_order,\n started_at, completed_at, detached, detached_on_finish,\n detached_notify_source, detached_max_budget_at,\n finish_claimed_at, finish_delivered_at, give_up_claimed_at,\n give_up_delivered_at\n FROM cf_agent_tool_runs\n WHERE run_id = ${runId}\n LIMIT 1\n `;\n return rows[0] ?? null;\n }\n\n /**\n * Reconstruct the typed interrupted cause (`reason` / `childStillRunning`,\n * #1630 follow-up) from a stored row so a row→result/event rebuild — e.g. a\n * reconnect replay — carries the same fields a live client saw. Only\n * `interrupted` rows store a cause; everything else yields `{}` (the columns\n * are cleared whenever a row settles to a hard terminal).\n */\n private _agentToolInterruptedExtrasFromRow(row: {\n status: AgentToolRunStatus;\n interrupted_reason: string | null;\n child_still_running: number | null;\n }): { reason?: AgentToolInterruptedReason; childStillRunning?: boolean } {\n if (row.status !== \"interrupted\") return {};\n return {\n ...(row.interrupted_reason !== null\n ? { reason: row.interrupted_reason as AgentToolInterruptedReason }\n : {}),\n ...(row.child_still_running !== null\n ? { childStillRunning: row.child_still_running !== 0 }\n : {})\n };\n }\n\n private _resultFromAgentToolRow<Output>(\n row: AgentToolRunStorageRow\n ): RunAgentToolResult<Output> {\n const output = this._parseAgentToolJson(row.output_json) as\n | Output\n | undefined;\n return {\n runId: row.run_id,\n agentType: row.agent_type,\n status: row.status as RunAgentToolResult<Output>[\"status\"],\n ...(output !== undefined ? { output } : {}),\n ...(row.summary !== null ? { summary: row.summary } : {}),\n ...(row.error_message !== null ? { error: row.error_message } : {}),\n ...this._agentToolInterruptedExtrasFromRow(row)\n };\n }\n\n private _agentToolRunInfoFromRow(\n row: AgentToolRunStorageRow,\n status: AgentToolRunStatus = row.status,\n completedAt = row.completed_at ?? undefined\n ): AgentToolRunInfo {\n return {\n runId: row.run_id,\n parentToolCallId: row.parent_tool_call_id ?? undefined,\n agentType: row.agent_type,\n inputPreview: this._parseAgentToolJson(row.input_preview),\n status,\n display: this._parseAgentToolJson(row.display_metadata) as\n | AgentToolDisplayMetadata\n | undefined,\n ...(row.detached_notify_source != null\n ? { notifySource: row.detached_notify_source }\n : {}),\n displayOrder: row.display_order,\n startedAt: row.started_at,\n completedAt\n };\n }\n\n private _terminalResultFromInspection<Output>(\n agentType: string,\n inspection: AgentToolRunInspection<Output>\n ): RunAgentToolResult<Output> {\n if (inspection.status === \"completed\") {\n return {\n runId: inspection.runId,\n agentType,\n status: \"completed\",\n output: inspection.output,\n summary: inspection.summary\n };\n }\n if (inspection.status === \"aborted\") {\n return {\n runId: inspection.runId,\n agentType,\n status: \"aborted\",\n error: inspection.error\n };\n }\n return {\n runId: inspection.runId,\n agentType,\n status: \"error\",\n error: inspection.error ?? \"Agent tool run failed\"\n };\n }\n\n private async _finishAgentToolRun<Output>(\n run: AgentToolRunInfo,\n result: RunAgentToolResult<Output>,\n options?: {\n sequence?: number;\n completedAt?: number;\n deferFinishHook?: boolean;\n }\n ): Promise<DeferredAgentToolFinish | undefined> {\n const completedAt = options?.completedAt ?? Date.now();\n this._updateAgentToolTerminal(run.runId, result, completedAt);\n if (options?.sequence !== undefined) {\n this._broadcastAgentToolTerminal(\n run.parentToolCallId,\n options.sequence,\n result\n );\n }\n const finish = () =>\n this.onAgentToolFinish(\n { ...run, status: result.status, completedAt },\n result\n );\n if (options?.deferFinishHook) return finish;\n await finish();\n return undefined;\n }\n\n private async _runDeferredAgentToolFinishHooks(\n hooks: DeferredAgentToolFinish[]\n ): Promise<void> {\n for (const hook of hooks) {\n try {\n await hook();\n } catch (error) {\n try {\n await this.onError(error);\n } catch {\n // Recovery hooks are best-effort; one failed mirror write should not\n // prevent the agent from starting or other recovered runs finalizing.\n }\n }\n }\n }\n\n private _updateAgentToolTerminal<Output>(\n runId: string,\n result: RunAgentToolResult<Output>,\n completedAt = Date.now()\n ): void {\n // `interrupted` is a SOFT terminal — recovery gave up collecting, but the\n // child (a durable facet) may still reach its real terminal. So it is NOT\n // in the guard below: a later child completion (via a re-issue's re-attach,\n // #1630) can repair an `interrupted` row to `completed`/`error`. The three\n // HARD terminals are never overwritten.\n // Persist the typed interrupted cause (#1630 follow-up) so a reconnect\n // replay reconstructs the same `reason` / `childStillRunning` a live client\n // saw. Written unconditionally so repairing an `interrupted` row to a hard\n // terminal (e.g. a re-attach that finally collects `completed`) CLEARS the\n // stale cause rather than leaving it dangling.\n const childStillRunning =\n result.childStillRunning === undefined\n ? null\n : result.childStillRunning\n ? 1\n : 0;\n this.sql`\n UPDATE cf_agent_tool_runs\n SET status = ${result.status},\n summary = ${result.summary ?? null},\n output_json = ${this._stringifyAgentToolOutput(result.output)},\n error_message = ${result.error ?? null},\n interrupted_reason = ${result.reason ?? null},\n child_still_running = ${childStillRunning},\n completed_at = ${completedAt}\n WHERE run_id = ${runId}\n AND status NOT IN ('completed', 'error', 'aborted')\n `;\n if (result.status === \"completed\" && result.output !== undefined) {\n this.sql`\n UPDATE cf_agent_tool_runs\n SET output_json = COALESCE(output_json, ${this._stringifyAgentToolOutput(result.output)}),\n summary = COALESCE(summary, ${result.summary ?? null})\n WHERE run_id = ${runId} AND status = 'completed'\n `;\n }\n }\n\n private _markAgentToolRunning(runId: string): void {\n this.sql`\n UPDATE cf_agent_tool_runs\n SET status = 'running'\n WHERE run_id = ${runId} AND status = 'starting'\n `;\n }\n\n private _parseAgentToolJson(value: string | null): unknown {\n if (value === null) return undefined;\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n\n private _stringifyAgentToolOutput(output: unknown): string | null {\n if (output === undefined) return null;\n const json = JSON.stringify(output);\n return json === undefined ? null : json;\n }\n\n private _broadcastAgentToolEvent(\n parentToolCallId: string | undefined,\n sequence: number,\n event: AgentToolEvent,\n replay?: true,\n connection?: Connection\n ): void {\n const message: AgentToolEventMessage = {\n type: \"agent-tool-event\",\n parentToolCallId,\n sequence,\n event,\n ...(replay ? { replay } : {})\n };\n const body = JSON.stringify(message);\n if (connection) {\n connection.send(body);\n } else {\n this.broadcast(body);\n }\n }\n\n private _broadcastAgentToolChunks(\n parentToolCallId: string | undefined,\n runId: string,\n chunks: AgentToolStoredChunk[],\n sequence: number,\n replay?: true,\n connection?: Connection\n ): number {\n let next = sequence;\n for (const chunk of chunks) {\n this._broadcastAgentToolEvent(\n parentToolCallId,\n next++,\n { kind: \"chunk\", runId, body: chunk.body },\n replay,\n connection\n );\n }\n return next;\n }\n\n private async _broadcastAgentToolStoredChunks(\n row: Pick<\n AgentToolRunStorageRow,\n \"run_id\" | \"agent_type\" | \"parent_tool_call_id\"\n >,\n sequence: number,\n replay?: true,\n connection?: Connection\n ): Promise<number> {\n const child = await this._cf_resolveSubAgent(row.agent_type, row.run_id);\n const adapter = this._asAgentToolChildAdapter(child);\n return this._broadcastAgentToolStoredChunksFromAdapter(\n adapter,\n row,\n sequence,\n replay,\n connection\n );\n }\n\n private async _broadcastAgentToolStoredChunksFromAdapter(\n adapter: AgentToolChildAdapter,\n row: Pick<AgentToolRunStorageRow, \"run_id\" | \"parent_tool_call_id\">,\n sequence: number,\n replay?: true,\n connection?: Connection,\n timeoutMs?: number\n ): Promise<number> {\n const chunks = await this._getAgentToolChunksForRecovery(\n adapter,\n row.run_id,\n timeoutMs\n );\n if (!chunks) return sequence;\n return this._broadcastAgentToolChunks(\n row.parent_tool_call_id ?? undefined,\n row.run_id,\n chunks,\n sequence,\n replay,\n connection\n );\n }\n\n private async _forwardAgentToolStream(\n stream: ReadableStream<AgentToolStoredChunk>,\n parentToolCallId: string | undefined,\n runId: string,\n sequence: number,\n signal?: AbortSignal,\n idleTimeoutMs?: number\n ): Promise<{ next: number; ended: \"done\" | \"idle\" | \"aborted\" }> {\n let next = sequence;\n if (signal?.aborted) return { next, ended: \"aborted\" };\n // How the forward loop ended, so the re-attach caller can re-arm ONLY on a\n // clean stream-close (`done`) and never abandon a fresh reader per idle\n // cycle: `idle` = a full no-progress window elapsed (stalled), `aborted` =\n // the caller's ceiling signal fired.\n let ended: \"done\" | \"idle\" | \"aborted\" = \"done\";\n const reader = (\n stream as ReadableStream<AgentToolStoredChunk | Uint8Array>\n ).getReader();\n const decoder = new TextDecoder();\n let bufferedBytes = \"\";\n let aborted = false;\n let resolveAbort: (() => void) | undefined;\n const abortPromise = new Promise<void>((resolve) => {\n resolveAbort = resolve;\n });\n let abortListener: (() => void) | undefined;\n if (signal) {\n abortListener = () => resolveAbort?.();\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n // Optional no-progress (idle) budget: a re-attach passes this so a child\n // that keeps forwarding chunks is never cut off mid-flight. The timer is\n // (re-)armed on every forwarded chunk and only fires after a full window of\n // silence. When `idleTimeoutMs` is undefined (the live run path) OR\n // non-finite (`Infinity` = \"never seal on no-progress\") the idle promise\n // never resolves, so the forward loop ends only on a clean stream-close or\n // the caller's ceiling signal — never on silence.\n const idleEnabled =\n typeof idleTimeoutMs === \"number\" &&\n idleTimeoutMs > 0 &&\n Number.isFinite(idleTimeoutMs);\n let resolveIdle: (() => void) | undefined;\n let idleTimer: ReturnType<typeof setTimeout> | undefined;\n const idlePromise = new Promise<void>((resolve) => {\n resolveIdle = resolve;\n });\n const armIdle = () => {\n if (!idleEnabled) return;\n if (idleTimer !== undefined) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => resolveIdle?.(), idleTimeoutMs);\n };\n // N9: track whether any chunk was forwarded since the last progress hook so\n // a parent that is merely orchestrating a child still records forward\n // progress for its OWN recovery budget — but ONLY when the child actually\n // produces output (a silent/hung child forwards nothing → no credit → the\n // parent still exhausts on its own no-progress timer).\n let forwardedSinceProgress = false;\n try {\n const forwardChunk = (chunk: AgentToolStoredChunk) => {\n this._broadcastAgentToolEvent(parentToolCallId, next++, {\n kind: \"chunk\",\n runId,\n body: chunk.body\n });\n // A reserved `data-agent-progress` frame fires the parent `onProgress`\n // hook + refreshes the cached liveness timestamp. Best-effort: never\n // let a progress observation break the forward loop.\n this._observeForwardedProgress(runId, chunk.body);\n forwardedSinceProgress = true;\n // Forward progress resets the no-progress budget.\n armIdle();\n };\n const forwardLine = (line: string) => {\n try {\n const chunk = JSON.parse(line) as Partial<AgentToolStoredChunk>;\n if (typeof chunk.body === \"string\") {\n forwardChunk(chunk as AgentToolStoredChunk);\n }\n } catch {\n // Skip malformed stream frames; the child remains authoritative for\n // final run status and durable chunk replay.\n }\n };\n const flushBufferedBytes = (final = false) => {\n while (true) {\n const newline = bufferedBytes.indexOf(\"\\n\");\n if (newline === -1) break;\n const line = bufferedBytes.slice(0, newline).trim();\n bufferedBytes = bufferedBytes.slice(newline + 1);\n if (line.length > 0) {\n forwardLine(line);\n }\n }\n if (final && bufferedBytes.trim().length > 0) {\n forwardLine(bufferedBytes);\n bufferedBytes = \"\";\n }\n };\n // Arm the idle budget up front so a child that never emits anything still\n // ends the wait after one no-progress window.\n armIdle();\n while (true) {\n // Pre-attach a catch so that if the abort wins the race below, a later\n // rejection of this read (e.g. the child closing / DO RPC surfacing\n // \"Stream was cancelled\") never bubbles up as an unhandled rejection.\n const readPromise = reader.read();\n readPromise.catch(() => {});\n const raced = await Promise.race([\n readPromise.then((result) => ({ kind: \"read\" as const, result })),\n abortPromise.then(() => ({ kind: \"abort\" as const })),\n idlePromise.then(() => ({ kind: \"idle\" as const }))\n ]);\n if (raced.kind === \"abort\" || raced.kind === \"idle\") {\n // Both leave the pending read in place — we never cancel a live child\n // facet stream (see the note below). The caller distinguishes a\n // no-progress stall from terminal via a follow-up inspect.\n aborted = true;\n ended = raced.kind === \"idle\" ? \"idle\" : \"aborted\";\n break;\n }\n const { done, value } = raced.result;\n if (done) {\n bufferedBytes += decoder.decode();\n flushBufferedBytes(true);\n break;\n }\n if (value instanceof Uint8Array) {\n bufferedBytes += decoder.decode(value, { stream: true });\n flushBufferedBytes();\n } else {\n forwardChunk(value);\n }\n if (forwardedSinceProgress) {\n forwardedSinceProgress = false;\n // Credit the parent's recovery progress for forwarding child output\n // (no-op in the base Agent; chat-recovery subclasses override). Kept\n // off the hot per-chunk path — runs once per read iteration and is\n // throttled inside the override. Best-effort: progress crediting is\n // advisory, so a bump failure must never break the child stream the\n // user is watching.\n try {\n await this._onAgentToolStreamProgress();\n } catch {\n // Ignore and keep forwarding; the next iteration tries again.\n }\n }\n }\n } finally {\n if (idleTimer !== undefined) clearTimeout(idleTimer);\n if (abortListener && signal) {\n signal.removeEventListener(\"abort\", abortListener);\n }\n if (!aborted) {\n try {\n reader.releaseLock();\n } catch {\n // A concurrently-cancelled reader can't release; safe to ignore.\n }\n }\n // When `aborted` (re-attach budget expired with a read still pending) we\n // deliberately do NOT cancel the reader: cancelling a remote child-facet\n // RPC stream surfaces a \"Stream was cancelled\" rejection from the RPC pump\n // that can't be reliably swallowed (verified). Instead we abandon the\n // pre-caught read — it resolves harmlessly when the child reaches terminal\n // and the adapter's tail fires its registered closer, releasing the reader\n // + stream. That makes the hold BOUNDED by the child's own recovery\n // (its turn is sealed within the chat-recovery ceiling), never unbounded.\n // The re-attach loop re-arms only on `ended === \"done\"`, so at most ONE\n // such read is ever left pending per re-attach (no per-cycle leak).\n }\n return { next, ended };\n }\n\n /**\n * Hook invoked by `_forwardAgentToolStream` after a child produces output that\n * was forwarded to the parent's connections. Forwarding a sub-agent's stream\n * is genuine forward progress for the *parent* turn (the parent is\n * orchestrating the child), so chat-recovery subclasses (Think / AIChatAgent)\n * override this to advance their recovery progress marker.\n *\n * Without it, a parent whose turn merely `await`s a sub-agent banks zero\n * progress of its own, so under deploy churn the parent's no-progress recovery\n * window exhausts and abandons the turn as `interrupted` — even though the\n * child is healthily streaming and ultimately completes (observed in the\n * `deploy-churn --mode subagent` harness: `attempt 6/6, stable_timeout,\n * progress: 1`).\n *\n * Called ONLY after at least one chunk was actually forwarded — never merely\n * because a child is attached — so a silent / hung child still lets the parent\n * exhaust on its own timer. The base Agent has no recovery budget, so this is\n * a no-op; subclasses should throttle the (durable) bump since this can be\n * called repeatedly while a child streams.\n */\n protected async _onAgentToolStreamProgress(): Promise<void> {}\n\n /**\n * Best-effort observation of a forwarded child chunk: if it is a reserved\n * `data-agent-progress` frame, refresh the cached liveness timestamp on the\n * run row (a hint for a still-warm parent) and fire the public `onProgress`\n * hook. Never throws into the forward loop — the child's own persisted\n * snapshot (read via `inspectAgentToolRun`) remains authoritative for the\n * resetting no-progress budget after eviction.\n */\n private _observeForwardedProgress(runId: string, body: string): void {\n let parsed:\n | {\n type?: unknown;\n data?: AgentToolProgress & {\n name?: string;\n sequence?: number;\n at?: number;\n };\n }\n | undefined;\n try {\n parsed = JSON.parse(body);\n } catch {\n return;\n }\n if (!parsed) return;\n const isMilestone = parsed.type === AGENT_TOOL_MILESTONE_PART;\n if (parsed.type !== AGENT_TOOL_PROGRESS_PART && !isMilestone) return;\n const data = parsed.data ?? {};\n const at = Date.now();\n const snapshot: AgentToolProgressSnapshot = {\n ...(typeof data.fraction === \"number\" ? { fraction: data.fraction } : {}),\n ...(typeof data.message === \"string\" ? { message: data.message } : {}),\n ...(typeof data.phase === \"string\" ? { phase: data.phase } : {}),\n ...(isMilestone && typeof data.name === \"string\"\n ? { milestone: data.name }\n : {}),\n ...(data.data !== undefined ? { data: data.data } : {}),\n at\n };\n const row = this._readAgentToolRun(runId);\n if (!row) return;\n // The cached liveness timestamp only feeds the DETACHED no-progress budget;\n // skip the write for awaited runs (the `onProgress` hook still fires below).\n if (row.detached) {\n try {\n this.sql`\n UPDATE cf_agent_tool_runs SET last_progress_at = ${at}\n WHERE run_id = ${runId}\n `;\n } catch {\n // Row may have settled / been pruned; the hook still fires below.\n }\n }\n const runInfo = this._agentToolRunInfoFromRow(row);\n void Promise.resolve(this.onProgress(runInfo, snapshot)).catch((error) => {\n console.error(\n `[agents] onProgress hook threw for run ${runId}:`,\n error instanceof Error ? error.message : String(error)\n );\n });\n // Chat-host `detached: { onMilestones }` convenience: when a CONFIGURED\n // milestone lands on the warm path, deliver its idempotent notification.\n // The cold backbone reconcile delivers the same set after eviction; the\n // idempotency key makes the two paths converge to at-most-once.\n if (isMilestone && typeof data.name === \"string\") {\n this._maybeDeliverDetachedMilestone(row, runInfo, {\n name: data.name,\n sequence: typeof data.sequence === \"number\" ? data.sequence : 0,\n at: typeof data.at === \"number\" ? data.at : at,\n ...(data.data !== undefined ? { data: data.data } : {})\n });\n }\n }\n\n /**\n * Deliver a milestone notification IF this run opted into it via\n * `detached: { onMilestones }` and the milestone name is in that set. Routes\n * to the overridable `_deliverDetachedMilestone` seam (a no-op on the base\n * `Agent`; chat hosts inject an idempotent synthetic chat message).\n */\n private _maybeDeliverDetachedMilestone(\n row: AgentToolRunStorageRow,\n runInfo: AgentToolRunInfo,\n milestone: AgentToolMilestone\n ): void {\n // Stored as `{ names, mode }`; tolerate a bare-array legacy/manual value.\n const configured = this._parseAgentToolJson(\n row.detached_on_milestones ?? null\n ) as\n | string[]\n | { names?: string[]; mode?: \"react\" | \"narrate\" }\n | undefined;\n const names = Array.isArray(configured) ? configured : configured?.names;\n const mode = Array.isArray(configured)\n ? \"narrate\"\n : (configured?.mode ?? \"narrate\");\n if (!Array.isArray(names) || !names.includes(milestone.name)) {\n return;\n }\n void Promise.resolve(\n this._deliverDetachedMilestone(runInfo, milestone, mode)\n ).catch((error) => {\n console.error(\n `[agents] detached milestone delivery threw for run ${runInfo.runId} (${milestone.name}):`,\n error instanceof Error ? error.message : String(error)\n );\n });\n }\n\n /**\n * Overridable seam for the `detached: { onMilestones }` convenience. The base\n * `Agent` has no chat surface, so this is a no-op; chat hosts\n * (`@cloudflare/think`, `AIChatAgent`) override it to submit an idempotent\n * synthetic message keyed on `(runId, milestone.name)`. Called from both the\n * warm tail and the backbone reconcile, so it MUST be idempotent.\n */\n protected async _deliverDetachedMilestone(\n _run: AgentToolRunInfo,\n _milestone: AgentToolMilestone,\n _mode: \"react\" | \"narrate\"\n ): Promise<void> {}\n\n private _broadcastAgentToolTerminal<Output>(\n parentToolCallId: string | undefined,\n sequence: number,\n result: RunAgentToolResult<Output>,\n replay?: true,\n connection?: Connection\n ): void {\n if (result.status === \"completed\") {\n this._broadcastAgentToolEvent(\n parentToolCallId,\n sequence,\n {\n kind: \"finished\",\n runId: result.runId,\n summary: result.summary ?? \"\"\n },\n replay,\n connection\n );\n } else if (result.status === \"aborted\") {\n this._broadcastAgentToolEvent(\n parentToolCallId,\n sequence,\n { kind: \"aborted\", runId: result.runId, reason: result.error },\n replay,\n connection\n );\n } else if (result.status === \"interrupted\") {\n this._broadcastAgentToolEvent(\n parentToolCallId,\n sequence,\n {\n kind: \"interrupted\",\n runId: result.runId,\n error: result.error ?? \"Agent tool run was interrupted\",\n ...(result.reason !== undefined ? { reason: result.reason } : {}),\n ...(result.childStillRunning !== undefined\n ? { childStillRunning: result.childStillRunning }\n : {})\n },\n replay,\n connection\n );\n } else {\n this._broadcastAgentToolEvent(\n parentToolCallId,\n sequence,\n {\n kind: \"error\",\n runId: result.runId,\n error: result.error ?? \"Agent tool run failed\"\n },\n replay,\n connection\n );\n }\n }\n\n private _asAgentToolChildAdapter<Input = unknown, Output = unknown>(\n child: unknown\n ): AgentToolChildAdapter<Input, Output> {\n const candidate = child as Partial<AgentToolChildAdapter<Input, Output>>;\n if (\n typeof candidate.startAgentToolRun !== \"function\" ||\n typeof candidate.cancelAgentToolRun !== \"function\" ||\n typeof candidate.inspectAgentToolRun !== \"function\" ||\n typeof candidate.getAgentToolChunks !== \"function\"\n ) {\n throw new Error(\n \"Agent tool child must implement the framework agent-tool adapter. Use a @cloudflare/think Think subclass or an AIChatAgent subclass.\"\n );\n }\n return candidate as AgentToolChildAdapter<Input, Output>;\n }\n\n private _agentToolClassByName(className: string): SubAgentClass<Agent> {\n const ctx = this.ctx as unknown as Partial<FacetCapableCtx>;\n const cls = ctx.exports?.[className];\n if (!cls) {\n throw new Error(`Agent tool class \"${className}\" is not exported.`);\n }\n return cls as unknown as SubAgentClass<Agent>;\n }\n\n private async _replayAndInterruptAgentToolRun<Output>(\n row: AgentToolRunStorageRow,\n message: string,\n extra?: { reason?: AgentToolInterruptedReason; childStillRunning?: boolean }\n ): Promise<RunAgentToolResult<Output>> {\n let sequence = 1;\n try {\n sequence = await this._broadcastAgentToolStoredChunks(row, sequence);\n } catch {\n // Interruption is still the honest parent state if replay fails.\n }\n const result: RunAgentToolResult<Output> = {\n runId: row.run_id,\n agentType: row.agent_type,\n status: \"interrupted\",\n error: message,\n ...(extra?.reason !== undefined ? { reason: extra.reason } : {}),\n ...(extra?.childStillRunning !== undefined\n ? { childStillRunning: extra.childStillRunning }\n : {})\n };\n await this._finishAgentToolRun(this._agentToolRunInfoFromRow(row), result, {\n sequence\n });\n return result;\n }\n\n /**\n * Human-readable prose for an `interrupted` seal. Kept in sync with\n * {@link AgentToolInterruptedReason}; callers branch on the typed `reason`\n * field, not this string.\n */\n private _interruptedMessageForReason(\n reason: AgentToolInterruptedReason | undefined\n ): string {\n switch (reason) {\n case \"no-progress\":\n return \"Agent tool run was still running but made no forward progress within the re-attach no-progress budget; the parent gave up.\";\n case \"window-exceeded\":\n return \"Agent tool run did not reach a terminal result within the maximum re-attach window; the parent gave up.\";\n case \"not-tailable\":\n return \"Agent tool run was still running, but live-tail reattachment is not supported in this runtime.\";\n case \"inspect-timeout\":\n return \"Agent tool run inspection timed out during parent recovery.\";\n case \"inspect-failed\":\n return \"Agent tool run could not be inspected during parent recovery.\";\n case \"recovery-deadline\":\n return \"Agent tool run recovery deadline exceeded.\";\n default:\n return \"Agent tool run was still running and did not reach a terminal result.\";\n }\n }\n\n /**\n * Tear down a child agent-tool run the parent has genuinely given up on\n * (#1630 follow-up). Teardown is scoped to `window-exceeded` ONLY — the hard\n * ceiling, where the child has had its full recovery window and is therefore\n * truly exhausted, so cancelling it reclaims its fiber / keep-alive. Every\n * other give-up is deliberately left repairable: `no-progress` seals stay\n * SOFT (`interrupted`, `childStillRunning: true`) so a re-issue can still\n * re-attach and collect the child if it self-heals — tearing those down would\n * defeat the repair-on-re-issue path and convert a retryable interrupt into a\n * non-retryable `aborted`. Reasons where the child's state is unknown\n * (`inspect-*`, `recovery-deadline`, `not-tailable`) are also left alone.\n * Returns whether the child was torn down (so the caller reports\n * `childStillRunning: false`).\n */\n private async _teardownGivenUpAgentToolChild(\n adapter: AgentToolChildAdapter,\n runId: string,\n reason: AgentToolInterruptedReason | undefined\n ): Promise<boolean> {\n if (reason !== \"window-exceeded\") return false;\n try {\n await adapter.cancelAgentToolRun(\n runId,\n `agent tool run given up by parent recovery: ${reason}`\n );\n return true;\n } catch {\n // Best-effort: a failed teardown just means the child may still be alive.\n return false;\n }\n }\n\n /**\n * Re-attach to a still-running child agent-tool run and tail it to its real\n * terminal result, instead of abandoning it as `interrupted` (#1630). The\n * child is a separate facet with its own `chatRecovery`, so resolving it via\n * the adapter wakes it and lets it self-complete the interrupted turn; we tail\n * its live stream (forwarding chunks to the parent's connections) until it\n * reaches terminal, then inspect for the collected result.\n *\n * The wait is PROGRESS-KEYED, not a flat wall clock (which previously abandoned\n * healthy, still-advancing children whose recovery simply outran a fixed\n * budget). `noProgressTimeoutMs` bounds how long the parent waits with NO\n * forward progress; it is reset on every forwarded chunk. As long as the child\n * keeps streaming it is followed through to terminal. The loop also RE-ARMS\n * across stream-closes (a child re-evicted mid-recovery, or a tail that ends\n * before terminal) as long as the prior attempt made progress, so a child that\n * dies and recovers again during deploy churn is still collected. A genuinely\n * silent/hung child can never block recovery forever: it seals `interrupted`\n * after one `noProgressTimeoutMs` window. `maxWindowMs` is an OPTIONAL hard\n * wall-clock ceiling (default `Infinity` — uncapped, mirroring #1672's\n * `maxRecoveryWork`); set it finite to also bound a child that keeps\n * progressing, which seals `window-exceeded` and tears the child down.\n *\n * Returns the terminal `result` (and `completedAt`) when the child reaches a\n * terminal status, plus the advanced broadcast `sequence`. Returns\n * `{ result: undefined }` when there is no `tailAgentToolRun` adapter, the\n * child makes no progress within a full no-progress window, or the ceiling is\n * reached while the child is still non-terminal — the caller then seals\n * `interrupted`.\n */\n private async _reattachAgentToolRunToTerminal<Output>(\n adapter: AgentToolChildAdapter<unknown, Output>,\n row: Pick<\n AgentToolRunStorageRow,\n \"run_id\" | \"agent_type\" | \"parent_tool_call_id\"\n >,\n sequence: number,\n noProgressTimeoutMs: number = DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS,\n maxWindowMs: number = DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS\n ): Promise<{\n sequence: number;\n result?: RunAgentToolResult<Output>;\n completedAt?: number;\n reason?: AgentToolInterruptedReason;\n }> {\n if (typeof adapter.tailAgentToolRun !== \"function\") {\n // Defensive: a real (RPC) child stub reports every method as a `function`,\n // so this only fires for an in-process adapter that genuinely omits the\n // method. A real child that can't tail surfaces as a tail-call failure\n // below (caught → `no-progress`), not here.\n return { sequence, reason: \"not-tailable\" };\n }\n\n this._emit(\"agent_tool:recovery:reattach\", {\n runId: row.run_id,\n agentType: row.agent_type,\n budgetMs: noProgressTimeoutMs\n });\n\n const collectTerminal = async (\n seq: number\n ): Promise<{\n sequence: number;\n result: RunAgentToolResult<Output>;\n completedAt?: number;\n } | null> => {\n let inspection: AgentToolRunInspection<Output> | null = null;\n try {\n inspection = await adapter.inspectAgentToolRun(row.run_id);\n } catch {\n // Treat an un-inspectable child as still non-terminal.\n return null;\n }\n if (\n inspection &&\n inspection.status !== \"running\" &&\n inspection.status !== \"starting\"\n ) {\n return {\n sequence: seq,\n result: this._terminalResultFromInspection<Output>(\n row.agent_type,\n inspection\n ),\n completedAt: inspection.completedAt\n };\n }\n return null;\n };\n\n let nextSequence = sequence;\n\n // A non-positive no-progress budget means \"do not wait\" — only collect an\n // already-terminal child without tailing. A non-finite (`Infinity`) budget\n // is the OPPOSITE — \"never seal on no-progress\": it falls through to the\n // tail loop below, where a non-finite budget disables the idle timer so a\n // silent-but-alive child is followed until its stream closes (or the hard\n // ceiling fires), matching the `maxWindowMs` \"Infinity = off\" convention.\n if (!(noProgressTimeoutMs > 0)) {\n return (\n (await collectTerminal(nextSequence)) ?? {\n sequence: nextSequence,\n reason: \"no-progress\"\n }\n );\n }\n\n // Optional hard wall-clock ceiling (default Infinity = off). A hung child is\n // already bounded by the no-progress budget; this only additionally bounds a\n // child that keeps progressing, when an integrator opts into a finite cap.\n const ceilingController = new AbortController();\n let ceilingTimer: ReturnType<typeof setTimeout> | undefined;\n if (maxWindowMs > 0 && Number.isFinite(maxWindowMs)) {\n ceilingTimer = setTimeout(() => ceilingController.abort(), maxWindowMs);\n }\n\n // Defaults to the no-progress cause; promoted to `window-exceeded` if the\n // hard ceiling is what ends the wait.\n let reason: AgentToolInterruptedReason = \"no-progress\";\n try {\n // Re-arm loop: keep tailing as long as the child makes forward progress.\n // Each attempt forwards live chunks until the child reaches terminal (its\n // stream closes), goes silent for a full no-progress window, or the ceiling\n // fires. Only a full no-progress window with no terminal seals\n // `interrupted`; a still-streaming or re-evicted-but-advancing child is\n // followed through.\n while (!ceilingController.signal.aborted) {\n // Tail from the child's CURRENT last chunk, not from -1: stored chunks\n // are already delivered to connected clients via `_replayAgentToolRuns`\n // on reconnect, so replaying them here would duplicate parts (the client\n // reducer appends by arrival order). Forwarding only chunks produced\n // after this point keeps the live stream correct without dupes.\n let afterSequence = -1;\n try {\n const existing = await adapter.getAgentToolChunks(row.run_id);\n const last = existing[existing.length - 1];\n if (last) afterSequence = last.sequence;\n } catch {\n // Fall back to a full tail if the chunk probe fails.\n }\n\n const beforeSequence = nextSequence;\n // Defaults to a non-`done` end so a tail that throws below does NOT\n // re-arm (we only re-arm on a verified clean stream-close).\n let streamEnded: \"done\" | \"idle\" | \"aborted\" = \"idle\";\n try {\n // NOTE: the ceiling signal is NOT forwarded to `tailAgentToolRun` — an\n // AbortSignal can't be serialized across the child-facet DO RPC. We\n // bound the wait parent-side: the ceiling/no-progress budget ends our\n // local forward loop and releases the read view, but never cancels the\n // child (it must keep advancing toward its own terminal so this — or a\n // later — inspect can still collect it).\n const stream = await adapter.tailAgentToolRun(row.run_id, {\n afterSequence\n });\n // Resolves when the child reaches terminal (the adapter closes the\n // tail), goes silent for a full no-progress window, or the ceiling\n // aborts our controller.\n const forwarded = await this._forwardAgentToolStream(\n stream,\n row.parent_tool_call_id ?? undefined,\n row.run_id,\n nextSequence,\n ceilingController.signal,\n noProgressTimeoutMs\n );\n nextSequence = forwarded.next;\n streamEnded = forwarded.ended;\n } catch {\n // Tail failures fall through to an inspect; the child remains\n // authoritative for terminal status and durable chunk replay.\n }\n\n const terminal = await collectTerminal(nextSequence);\n if (terminal) return terminal;\n\n if (ceilingController.signal.aborted) {\n reason = \"window-exceeded\";\n break;\n }\n\n // Re-arm ONLY when the child's stream closed cleanly (`done`) AND it\n // made forward progress this attempt — i.e. a re-evicted-but-advancing\n // child that closed before terminal. An `idle` end means a full\n // no-progress window elapsed (genuinely stalled) ⇒ seal `no-progress`\n // now; re-arming there would both mis-read a stall as recoverable and\n // abandon a fresh pending reader every cycle. No progress likewise\n // seals.\n if (streamEnded !== \"done\") break;\n if (nextSequence <= beforeSequence) break;\n }\n } finally {\n if (ceilingTimer !== undefined) clearTimeout(ceilingTimer);\n }\n\n return { sequence: nextSequence, reason };\n }\n\n private async _replayAgentToolRuns(connection: Connection): Promise<void> {\n const rows = this.sql<{\n run_id: string;\n parent_tool_call_id: string | null;\n agent_type: string;\n input_preview: string | null;\n status: AgentToolRunStatus;\n summary: string | null;\n output_json: string | null;\n error_message: string | null;\n interrupted_reason: string | null;\n child_still_running: number | null;\n display_metadata: string | null;\n display_order: number;\n }>`\n SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,\n summary, output_json, error_message, interrupted_reason,\n child_still_running, display_metadata, display_order\n FROM cf_agent_tool_runs\n ORDER BY started_at ASC\n `;\n\n for (const row of rows) {\n const parentToolCallId = row.parent_tool_call_id ?? undefined;\n let sequence = 0;\n this._broadcastAgentToolEvent(\n parentToolCallId,\n sequence++,\n {\n kind: \"started\",\n runId: row.run_id,\n agentType: row.agent_type,\n inputPreview: this._parseAgentToolJson(row.input_preview),\n order: row.display_order,\n display: this._parseAgentToolJson(row.display_metadata) as\n | AgentToolDisplayMetadata\n | undefined\n },\n true,\n connection\n );\n\n try {\n sequence = await this._broadcastAgentToolStoredChunks(\n row,\n sequence,\n true,\n connection\n );\n } catch {\n // Keep replay best-effort per run.\n }\n\n if (this._isAgentToolTerminal(row.status)) {\n this._broadcastAgentToolTerminal(\n parentToolCallId,\n sequence,\n {\n runId: row.run_id,\n agentType: row.agent_type,\n status: row.status as RunAgentToolResult[\"status\"],\n output: this._parseAgentToolJson(row.output_json),\n summary: row.summary ?? undefined,\n error: row.error_message ?? undefined,\n ...this._agentToolInterruptedExtrasFromRow(row)\n },\n true,\n connection\n );\n }\n }\n }\n\n private async _reconcileAgentToolRuns(options?: {\n deferFinishHooks?: boolean;\n childInspectionTimeoutMs?: number;\n totalRecoveryTimeoutMs?: number;\n reattachTimeoutMs?: number;\n reattachMaxWindowMs?: number;\n runIds?: readonly string[];\n }): Promise<DeferredAgentToolFinish[]> {\n const reattachTimeoutMs =\n options?.reattachTimeoutMs ??\n this._resolvedOptions.agentToolReattachNoProgressTimeoutMs;\n const reattachMaxWindowMs =\n options?.reattachMaxWindowMs ??\n this._resolvedOptions.agentToolReattachMaxWindowMs;\n const startedAt = Date.now();\n const totalTimeoutMs =\n options?.totalRecoveryTimeoutMs ??\n DEFAULT_AGENT_TOOL_RECOVERY_TOTAL_TIMEOUT_MS;\n const deadlineAt =\n totalTimeoutMs > 0\n ? startedAt + totalTimeoutMs\n : Number.POSITIVE_INFINITY;\n const deferredFinishes: DeferredAgentToolFinish[] = [];\n const rows = this.sql<AgentToolRunStorageRow>`\n SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,\n summary, output_json, error_message, interrupted_reason,\n child_still_running, display_metadata, display_order,\n started_at, completed_at\n FROM cf_agent_tool_runs\n WHERE status IN ('starting', 'running') AND detached = 0\n ORDER BY started_at ASC\n `;\n // NOTE: detached runs are deliberately excluded. The awaited reconcile seals\n // a still-running, not-tailable run `interrupted` because a lost observer\n // means the dispatching turn cannot continue. For a DETACHED run a lost\n // observer is the NORMAL state — sealing it would defeat the feature — so\n // detached runs are owned by the self-scheduling `_cfDetachedReconcileTick`\n // backbone instead, which keeps them alive within budget and delivers on\n // terminal. The backbone is (re-)armed on startup by\n // `_scheduleAgentToolRunRecovery`.\n const runIds =\n options?.runIds !== undefined ? new Set(options.runIds) : undefined;\n const recoveryRows = rows.filter(\n (row) => !runIds || runIds.has(row.run_id)\n );\n this._emit(\"agent_tool:recovery:begin\", {\n runCount: recoveryRows.length,\n totalTimeoutMs\n });\n const finalizeRow = async (\n row: AgentToolRunStorageRow,\n result: RunAgentToolResult,\n sequence: number,\n completedAt: number | undefined\n ): Promise<void> => {\n this._emit(\"agent_tool:recovery:row\", {\n runId: row.run_id,\n agentType: row.agent_type,\n status: result.status,\n reason: result.error,\n elapsedMs: Date.now() - startedAt\n });\n const deferredFinish = await this._finishAgentToolRun(\n this._agentToolRunInfoFromRow(row),\n result,\n {\n sequence,\n completedAt,\n deferFinishHook: options?.deferFinishHooks\n }\n );\n if (deferredFinish) {\n deferredFinishes.push(deferredFinish);\n }\n };\n\n // Pass 1 — deadline-bounded inspect/classify sweep. Terminal and\n // non-recoverable rows are finalized immediately; still-running tail-able\n // children are queued for the parallel re-attach pass below. The shared\n // `deadlineAt` only bounds this fast classification — re-attach (which can\n // legitimately run for the child's lifetime) must NOT count against it, or\n // one slow child would starve every later sibling of recovery (#1630).\n const reattachQueue: Array<{\n row: AgentToolRunStorageRow;\n adapter: AgentToolChildAdapter;\n }> = [];\n for (const row of recoveryRows) {\n const sequence = 1;\n const remainingMs = deadlineAt - Date.now();\n if (remainingMs <= 0) {\n this._emit(\"agent_tool:recovery:deadline\", {\n runId: row.run_id,\n agentType: row.agent_type,\n elapsedMs: Date.now() - startedAt\n });\n await finalizeRow(\n row,\n {\n runId: row.run_id,\n agentType: row.agent_type,\n status: \"interrupted\",\n reason: \"recovery-deadline\",\n error: this._interruptedMessageForReason(\"recovery-deadline\")\n },\n sequence,\n undefined\n );\n continue;\n }\n const childTimeout =\n options?.childInspectionTimeoutMs ??\n DEFAULT_AGENT_TOOL_RECOVERY_TIMEOUT_MS;\n const boundedChildTimeout =\n childTimeout > 0 ? Math.min(childTimeout, remainingMs) : remainingMs;\n const recovery = await this._inspectAgentToolRunForRecovery(\n row,\n sequence,\n boundedChildTimeout\n );\n if (recovery.status !== \"inspected\") {\n await finalizeRow(\n row,\n (() => {\n const reason: AgentToolInterruptedReason =\n recovery.status === \"timed-out\"\n ? \"inspect-timeout\"\n : \"inspect-failed\";\n return {\n runId: row.run_id,\n agentType: row.agent_type,\n status: \"interrupted\" as const,\n reason,\n error: this._interruptedMessageForReason(reason)\n };\n })(),\n sequence,\n undefined\n );\n continue;\n }\n const inspection = recovery.inspection;\n const stillRunning =\n !inspection ||\n inspection.status === \"running\" ||\n inspection.status === \"starting\";\n if (\n stillRunning &&\n typeof recovery.adapter.tailAgentToolRun === \"function\"\n ) {\n // Defer to the parallel re-attach pass — keep the row non-terminal so\n // re-attach can collect the child's real terminal result. No stored-chunk\n // broadcast here: re-attach forwards only new chunks, and a reconnected\n // client already replays stored chunks via `_replayAgentToolRuns`.\n reattachQueue.push({ row, adapter: recovery.adapter });\n continue;\n }\n let sequenceAfterReplay = sequence;\n try {\n sequenceAfterReplay =\n await this._broadcastAgentToolStoredChunksFromAdapter(\n recovery.adapter,\n row,\n sequence,\n undefined,\n undefined,\n boundedChildTimeout\n );\n } catch {\n // Terminal reconciliation should still complete if chunk replay fails.\n }\n if (stillRunning) {\n await finalizeRow(\n row,\n {\n runId: row.run_id,\n agentType: row.agent_type,\n status: \"interrupted\",\n reason: \"not-tailable\",\n // The child has no live-tail adapter, so it was never torn down and\n // may still self-complete and be collected by a later inspect.\n childStillRunning: true,\n error: this._interruptedMessageForReason(\"not-tailable\")\n },\n sequenceAfterReplay,\n undefined\n );\n } else {\n await finalizeRow(\n row,\n this._terminalResultFromInspection(row.agent_type, inspection),\n sequenceAfterReplay,\n inspection.completedAt\n );\n }\n }\n\n // Pass 2 — re-attach still-running children IN PARALLEL, each bounded by\n // its own re-attach budget, so a slow/hung child only delays itself and can\n // never cause a sibling run to be wrongly abandoned (#1630).\n await Promise.all(\n reattachQueue.map(async ({ row, adapter }) => {\n const reattach = await this._reattachAgentToolRunToTerminal(\n adapter,\n row,\n 1,\n reattachTimeoutMs,\n reattachMaxWindowMs\n );\n if (reattach.result) {\n await finalizeRow(\n row,\n reattach.result,\n reattach.sequence,\n reattach.completedAt\n );\n return;\n }\n // The parent has genuinely given up on this still-running child — tear\n // it down so it stops consuming a fiber / keep-alive (#1630).\n const tornDown = await this._teardownGivenUpAgentToolChild(\n adapter,\n row.run_id,\n reattach.reason\n );\n await finalizeRow(\n row,\n {\n runId: row.run_id,\n agentType: row.agent_type,\n status: \"interrupted\",\n reason: reattach.reason,\n childStillRunning: !tornDown,\n error: this._interruptedMessageForReason(reattach.reason)\n },\n reattach.sequence,\n reattach.completedAt\n );\n })\n );\n this._emit(\"agent_tool:recovery:complete\", {\n runCount: recoveryRows.length,\n elapsedMs: Date.now() - startedAt\n });\n return deferredFinishes;\n }\n\n private async _inspectAgentToolRunForRecovery(\n row: AgentToolRunStorageRow,\n _sequence: number,\n timeoutMs = DEFAULT_AGENT_TOOL_RECOVERY_TIMEOUT_MS\n ): Promise<AgentToolRecoveryInspection> {\n const inspect = (async (): Promise<AgentToolRecoveryInspection> => {\n const child = await this._cf_resolveSubAgent(row.agent_type, row.run_id);\n const adapter = this._asAgentToolChildAdapter(child);\n const inspection = await adapter.inspectAgentToolRun(row.run_id);\n return { status: \"inspected\", adapter, inspection };\n })().catch((): AgentToolRecoveryInspection => ({ status: \"failed\" }));\n\n if (timeoutMs <= 0) return inspect;\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<AgentToolRecoveryInspection>((resolve) => {\n timeoutId = setTimeout(() => {\n resolve({ status: \"timed-out\" });\n }, timeoutMs);\n });\n\n const result = await Promise.race([inspect, timeout]);\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n return result;\n }\n\n private _scheduleAgentToolRunRecovery(options?: {\n childInspectionTimeoutMs?: number;\n totalRecoveryTimeoutMs?: number;\n reattachTimeoutMs?: number;\n reattachMaxWindowMs?: number;\n runIds?: readonly string[];\n }): Promise<void> {\n if (this._agentToolRunRecoveryPromise) {\n return this._agentToolRunRecoveryPromise;\n }\n\n if (options?.runIds && options.runIds.length === 0) {\n return Promise.resolve();\n }\n\n const recovery = (async () => {\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n const recoveredAgentToolFinishes = await this._reconcileAgentToolRuns({\n deferFinishHooks: true,\n childInspectionTimeoutMs: options?.childInspectionTimeoutMs,\n totalRecoveryTimeoutMs: options?.totalRecoveryTimeoutMs,\n reattachTimeoutMs: options?.reattachTimeoutMs,\n reattachMaxWindowMs: options?.reattachMaxWindowMs,\n runIds: options?.runIds\n });\n await this._runDeferredAgentToolFinishHooks(recoveredAgentToolFinishes);\n // Re-arm the detached backbone if this DO woke with outstanding detached\n // runs (the schedule row survives eviction, but this also recreates it if\n // a dispatching turn crashed after inserting the run row but before\n // arming the schedule).\n if (this._hasOutstandingDetachedRuns()) {\n await this._armDetachedBackbone();\n }\n })()\n .catch(async (error) => {\n this._emit(\"agent_tool:recovery:failed\", {\n error: error instanceof Error ? error.message : String(error)\n });\n try {\n await this.onError(error);\n } catch {\n // Background recovery must never make a started agent unreachable.\n }\n })\n .finally(() => {\n this._agentToolRunRecoveryPromise = undefined;\n });\n\n this._agentToolRunRecoveryPromise = recovery;\n this.ctx.waitUntil(recovery);\n return recovery;\n }\n\n private _agentToolRunRecoveryRunIds(): string[] {\n return this.sql<{ run_id: string }>`\n SELECT run_id\n FROM cf_agent_tool_runs\n WHERE status IN ('starting', 'running')\n ORDER BY started_at ASC\n `.map((row) => row.run_id);\n }\n\n private async _getAgentToolChunksForRecovery(\n adapter: AgentToolChildAdapter,\n runId: string,\n timeoutMs?: number\n ): Promise<AgentToolStoredChunk[] | undefined> {\n const chunks = adapter.getAgentToolChunks(runId).catch(() => undefined);\n if (timeoutMs === undefined || timeoutMs <= 0) return chunks;\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<undefined>((resolve) => {\n timeoutId = setTimeout(() => resolve(undefined), timeoutMs);\n });\n const result = await Promise.race([chunks, timeout]);\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n return result;\n }\n\n /**\n * Shared facet resolution — takes a CamelCase class name string\n * (matching `ctx.exports`) rather than a class reference. Both\n * `subAgent(cls, name)` and `_cf_invokeSubAgent(className, ...)`\n * funnel through here so registry bookkeeping and the\n * `_cf_initAsFacet` handshake are consistent.\n *\n * @internal\n */\n private _cf_resolveSubAgent(\n className: string,\n name: string\n ): Promise<unknown> {\n return this._dynamicAgents.resolve(className, name);\n }\n\n /**\n * Run `body` in a fresh invocation scope with no native request/\n * connection context attached, so a child-facet RPC never sees\n * parent-owned I/O handles.\n * @internal\n */\n private _runFacetInitInvocation<T>(body: () => Promise<T>): Promise<T> {\n return runInInvocation(\n {\n agent: this,\n connection: undefined,\n request: undefined,\n email: undefined\n },\n body\n );\n }\n\n /**\n * Forcefully abort a running sub-agent. The child stops executing\n * immediately and will be restarted on next {@link subAgent} call.\n * Pending RPC calls receive the reason as an error.\n * Transitively aborts the child's own children.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @param cls The Agent subclass used when creating the child\n * @param name Name of the child to abort\n * @param reason Error thrown to pending/future RPC callers\n *\n * @deprecated Use {@link Agent.dynamicAgents | this.dynamicAgents.abort()} instead.\n */\n abortSubAgent(cls: SubAgentClass, name: string, reason?: unknown): void {\n this.dynamicAgents.abort(cls, name, reason);\n }\n\n /**\n * Delete a sub-agent: abort it if running, then permanently wipe its\n * storage. Transitively deletes the child's own children.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @param cls The Agent subclass used when creating the child\n * @param name Name of the child to delete\n *\n * @deprecated Use {@link Agent.dynamicAgents | this.dynamicAgents.delete()} instead.\n */\n deleteSubAgent(cls: SubAgentClass, name: string): Promise<void> {\n return this.dynamicAgents.delete(cls, name);\n }\n\n // ── Sub-agent registry (backs `hasSubAgent` / `listSubAgents`) ──────────\n\n /**\n * Whether this agent has previously spawned (and not deleted) a\n * sub-agent of the given class and name. Backed by an\n * auto-maintained SQLite registry in the parent's storage.\n *\n * Intended for strict-registry access patterns in\n * `onBeforeSubAgent` or similar gating logic.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @example\n * ```ts\n * async onBeforeSubAgent(req, { className, name }) {\n * if (!this.hasSubAgent(className, name)) {\n * return new Response(\"Not found\", { status: 404 });\n * }\n * }\n * ```\n *\n * @deprecated Use {@link Agent.dynamicAgents | this.dynamicAgents.has()} instead.\n */\n hasSubAgent<T extends Agent>(cls: SubAgentClass<T>, name: string): boolean;\n hasSubAgent(className: string, name: string): boolean;\n hasSubAgent(classOrName: SubAgentClass | string, name: string): boolean {\n return typeof classOrName === \"string\"\n ? this.dynamicAgents.has(classOrName, name)\n : this.dynamicAgents.has(classOrName, name);\n }\n\n /**\n * List known sub-agents, optionally filtered by class. Reflects\n * the registry rows written by {@link subAgent} and removed by\n * {@link deleteSubAgent}.\n *\n * @experimental The API surface may change before stabilizing.\n *\n * @deprecated Use {@link Agent.dynamicAgents | this.dynamicAgents.list()} instead.\n */\n listSubAgents<T extends Agent>(\n cls: SubAgentClass<T>\n ): Array<{ className: string; name: string; createdAt: number }>;\n listSubAgents(\n className?: string\n ): Array<{ className: string; name: string; createdAt: number }>;\n listSubAgents(\n classOrName?: SubAgentClass | string\n ): Array<{ className: string; name: string; createdAt: number }> {\n if (typeof classOrName === \"string\" || classOrName === undefined) {\n return this.dynamicAgents.list(classOrName);\n }\n return this.dynamicAgents.list(classOrName);\n }\n\n /**\n * Destroy the Agent, removing all state and scheduled tasks.\n *\n * On a top-level agent: drops every table, clears the alarm, and\n * aborts the isolate.\n *\n * On a sub-agent (facet): delegates teardown to the immediate\n * parent so the parent-owned schedule rows for this sub-agent\n * (and any of its descendants) are cancelled, the parent's\n * `cf_agents_sub_agents` registry entry is cleared, and\n * `ctx.facets.delete` wipes the facet's own storage. The\n * `ctx.facets.delete` call aborts this isolate, so this method\n * may not return cleanly when invoked from inside the facet —\n * callers should treat it as fire-and-forget.\n */\n async destroy() {\n if (this._isFacet) {\n this._emit(\"destroy\");\n const root = await this._rootAlarmOwner();\n // The chain: root → … → direct-parent runs ctx.facets.delete\n // on this facet, which aborts this isolate. The await may\n // throw an abort error or never resolve depending on timing —\n // either is acceptable, the cleanup has already been applied.\n await root._cf_destroyDescendantFacet(this.selfPath);\n return;\n }\n\n // Persist the teardown decision FIRST, so a destroy that gets cut short\n // (e.g. the runtime cancelling a request-scoped `waitUntil` it was riding\n // on, #1625) is finished by the next wake — see the `alarm()` preamble —\n // instead of leaving a half-deleted agent whose tables get silently\n // recreated by the constructor. The marker is removed by the\n // `deleteAll()` below, which is also why it is a KV record rather than a\n // SQL row: it must outlive live-resource disposal.\n await this.ctx.storage.put(DESTROY_PENDING_KEY, true);\n await this.lifecycle.disableAlarms();\n\n await this.lifecycle.dispose();\n this._disposables.dispose();\n await this.ctx.storage.deleteAll();\n\n this._destroyed = true;\n\n // `ctx.abort` throws an uncatchable error, so we yield to the event loop\n // to avoid capturing it and let handlers finish cleaning up. When this\n // destroy landed via the alarm preamble, suppressing the alarm retry\n // stops the platform re-running the alarm on a fresh instance whose\n // constructor would recreate the just-deleted schema.\n setTimeout(() => {\n abortWithoutAlarmRetry(this.ctx, \"destroyed\");\n }, 0);\n\n this._emit(\"destroy\");\n }\n\n /**\n * @internal Defer this agent's destruction to its own alarm invocation\n * instead of running it inline (#1625).\n *\n * `destroy()` is a multi-step I/O sequence (drop tables, delete alarm,\n * delete all storage, dispose connections). Running it on the `waitUntil`\n * of a request whose client has already disconnected — the MCP\n * Streamable-HTTP session-DELETE path — gives it little to no\n * post-invocation grace, so the runtime routinely cancels it mid-flight.\n * This method instead performs two fast storage writes (a durable\n * \"condemned\" marker and an immediate alarm) that the caller can await\n * before responding; the alarm then fires as a fresh invocation with its\n * own full execution budget and runs `destroy()` there. If even that\n * invocation is interrupted, the marker survives and the next wake\n * finishes teardown — see the `alarm()` preamble.\n *\n * Unlike `destroy()`, this method does not abort the isolate, so RPC\n * callers don't need to swallow an abort error.\n */\n async _cf_scheduleDestroy(): Promise<void> {\n // Hydrate facet state before deciding. `_isFacet` (and the `_parentPath`\n // /`selfPath` the facet teardown path needs) is only populated by `onStart`\n // /facet bootstrap, and `destroy()` below branches on the in-memory\n // `_isFacet`. Without this, an RPC landing before init would see it as\n // `false`, fall through to `destroy()`'s top-level path, and write the\n // destroy marker on a facet — which the `alarm()`/`_syncHostJobs()`\n // guards forbid (only top-level agents write it; facet teardown is\n // root-coordinated via `ctx.facets.delete`). Mirrors the other internal\n // RPC entrypoints (`_workflow_*`). We must NOT push this into `destroy()`\n // itself: the `alarm()` preamble calls `destroy()` precisely to avoid\n // running `onStart` on a condemned agent.\n await this.__unsafe_ensureInitialized();\n if (this._isFacet) {\n // Facet teardown is coordinated by the root (`ctx.facets.delete` wipes\n // the facet's storage in one step), so there is nothing to defer.\n await this.destroy();\n return;\n }\n // Future, not immediate: see DESTROY_ALARM_DELAY_MS — an immediate alarm\n // aborts the isolate fast enough to race this RPC's response back to the\n // DELETE handler, turning the intended 204 into a 500.\n const destroyAt = Date.now() + DESTROY_ALARM_DELAY_MS;\n await this.ctx.storage.put(DESTROY_PENDING_KEY, destroyAt);\n // The exclusive job arms the wake; the durable marker above remains the\n // authority the alarm preamble consumes before Lifecycle startup.\n await this.lifecycle.jobs.push({\n id: HOST_JOB_DESTROY_ID,\n fn: \"destroy\",\n time: destroyAt,\n exclusive: true\n });\n }\n\n /**\n * Whether a (deferred or interrupted) destroy is pending. Reads the\n * durable marker directly — the in-memory `_isFacet` flag may not be\n * hydrated yet at the call sites, but facets never write the marker.\n */\n private async _pendingDestroyAlarm(): Promise<number | null> {\n const pending = await this.ctx.storage.get<boolean | number>(\n DESTROY_PENDING_KEY\n );\n if (typeof pending === \"number\") return pending;\n return pending === true ? Date.now() : null;\n }\n\n private async _hasPendingDestroy(): Promise<boolean> {\n return (await this._pendingDestroyAlarm()) !== null;\n }\n\n /**\n * Check if a method is callable\n * @param method The method name to check\n * @returns True if the method is marked as callable\n */\n private _isCallable(method: string): boolean {\n return isCallableMethod(this[method as keyof this] as Function);\n }\n\n /**\n * Get all methods marked as callable on this Agent\n * @returns A map of method names to their metadata\n */\n getCallableMethods(): Map<string, CallableMetadata> {\n return new Map(decoratedMethods(this));\n }\n\n // ==========================================\n // Workflow Integration Methods\n // ==========================================\n\n /**\n * Start a workflow and track it in this Agent's database.\n * Automatically injects agent identity into the workflow params.\n *\n * The originating Agent identity is persisted in the workflow params so\n * callbacks (`this.agent` RPC, progress/completion/error, state updates)\n * route back to the exact Agent or sub-agent facet that started the run.\n * Note the following constraints:\n *\n * - **Resolution is by name.** Callbacks re-resolve the originating Agent via\n * `getAgentByName(...)`. Agents addressed by a raw Durable Object id\n * (`idFromString`/`get(id)`) rather than by name will not receive\n * callbacks on the same instance.\n * - **Sub-agent runs are facet-local.** A workflow started from a sub-agent\n * is tracked in that facet's own storage; the parent's `getWorkflows()` /\n * `getWorkflowById()` do not see it. Aggregate across facets yourself if\n * you need a combined view.\n * - **Class names must survive bundling.** The originating path is keyed by\n * `constructor.name`. Ensure your bundler preserves class names\n * (e.g. esbuild `keepNames: true`) so callbacks can be routed.\n *\n * @template P - Type of params to pass to the workflow\n * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW')\n * @param params - Params to pass to the workflow\n * @param options - Optional workflow options. For sub-agents, pass\n * `agentBinding` as the **root** Agent's Durable Object binding name, not a\n * child binding.\n * @returns The workflow instance ID\n *\n * @example\n * ```typescript\n * const workflowId = await this.runWorkflow(\n * 'MY_WORKFLOW',\n * { taskId: '123', data: 'process this' }\n * );\n * ```\n */\n async runWorkflow<P = unknown>(\n workflowName: WorkflowName<Env>,\n params: P,\n options?: RunWorkflowOptions\n ): Promise<string> {\n // Look up the workflow binding by name\n const workflow = this._findWorkflowBindingByName(workflowName);\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowName}' not found in environment`\n );\n }\n\n // Find the binding name for the top-level Agent namespace. Facets\n // are resolved later from this root binding plus their selfPath.\n const agentOrigin = this._workflowOrigin(options);\n if (!agentOrigin) {\n throw new Error(\n \"Could not detect Agent binding name from class name. \" +\n \"Pass it explicitly via options.agentBinding\"\n );\n }\n\n // Workflows instance IDs must start with [a-zA-Z0-9_].\n const workflowId = options?.id ?? `wf_${nanoid()}`;\n\n // Inject agent identity and workflow name into params\n const augmentedParams = {\n ...params,\n __agentName: this.name,\n __agentBinding:\n agentOrigin.kind === \"agent\"\n ? agentOrigin.binding\n : agentOrigin.rootBinding,\n __workflowName: workflowName,\n __agentOrigin: agentOrigin\n };\n\n // Create the workflow instance\n const instance = await workflow.create({\n id: workflowId,\n params: augmentedParams,\n retention: options?.retention\n });\n\n // Track the workflow in our database\n const id = nanoid();\n const metadataJson = options?.metadata\n ? JSON.stringify(options.metadata)\n : null;\n try {\n this.sql`\n INSERT INTO cf_agents_workflows (id, workflow_id, workflow_name, status, metadata)\n VALUES (${id}, ${instance.id}, ${workflowName}, 'queued', ${metadataJson})\n `;\n } catch (e) {\n if (\n e instanceof Error &&\n e.message.includes(\"UNIQUE constraint failed\")\n ) {\n throw new Error(\n `Workflow with ID \"${workflowId}\" is already being tracked`\n );\n }\n throw e;\n }\n\n this._emit(\"workflow:start\", { workflowId: instance.id, workflowName });\n\n return instance.id;\n }\n\n /**\n * Send an event to a running workflow.\n * The workflow can wait for this event using step.waitForEvent().\n *\n * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW')\n * @param workflowId - ID of the workflow instance\n * @param event - Event to send\n *\n * @example\n * ```typescript\n * await this.sendWorkflowEvent(\n * 'MY_WORKFLOW',\n * workflowId,\n * { type: 'approval', payload: { approved: true } }\n * );\n * ```\n */\n async sendWorkflowEvent(\n workflowName: WorkflowName<Env>,\n workflowId: string,\n event: WorkflowEventPayload\n ): Promise<void> {\n const workflow = this._findWorkflowBindingByName(workflowName);\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n await tryN(3, async () => instance.sendEvent(event), {\n shouldRetry: isErrorRetryable,\n baseDelayMs: 200,\n maxDelayMs: 3000\n });\n\n this._emit(\"workflow:event\", { workflowId, eventType: event.type });\n }\n\n /**\n * Approve a waiting workflow.\n * Sends an approval event to the workflow that can be received by waitForApproval().\n *\n * @param workflowId - ID of the workflow to approve\n * @param data - Optional approval data (reason, metadata)\n *\n * @example\n * ```typescript\n * await this.approveWorkflow(workflowId, {\n * reason: 'Approved by admin',\n * metadata: { approvedBy: userId }\n * });\n * ```\n */\n async approveWorkflow(\n workflowId: string,\n data?: { reason?: string; metadata?: Record<string, unknown> }\n ): Promise<void> {\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n await this.sendWorkflowEvent(\n workflowInfo.workflowName as WorkflowName<Env>,\n workflowId,\n {\n type: \"approval\",\n payload: {\n approved: true,\n reason: data?.reason,\n metadata: data?.metadata\n }\n }\n );\n\n this._emit(\"workflow:approved\", { workflowId, reason: data?.reason });\n }\n\n /**\n * Reject a waiting workflow.\n * Sends a rejection event to the workflow that will cause waitForApproval() to throw.\n *\n * @param workflowId - ID of the workflow to reject\n * @param data - Optional rejection data (reason)\n *\n * @example\n * ```typescript\n * await this.rejectWorkflow(workflowId, {\n * reason: 'Request denied by admin'\n * });\n * ```\n */\n async rejectWorkflow(\n workflowId: string,\n data?: { reason?: string }\n ): Promise<void> {\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n await this.sendWorkflowEvent(\n workflowInfo.workflowName as WorkflowName<Env>,\n workflowId,\n {\n type: \"approval\",\n payload: {\n approved: false,\n reason: data?.reason\n }\n }\n );\n\n this._emit(\"workflow:rejected\", { workflowId, reason: data?.reason });\n }\n\n /**\n * Terminate a running workflow.\n * This immediately stops the workflow and sets its status to \"terminated\".\n *\n * @param workflowId - ID of the workflow to terminate (must be tracked via runWorkflow)\n * @throws Error if workflow not found in tracking table\n * @throws Error if workflow binding not found in environment\n * @throws Error if workflow is already completed/errored/terminated (from Cloudflare)\n *\n * @example\n * ```typescript\n * await this.terminateWorkflow(workflowId);\n * ```\n */\n async terminateWorkflow(workflowId: string): Promise<void> {\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n const workflow = this._findWorkflowBindingByName(\n workflowInfo.workflowName as WorkflowName<Env>\n );\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowInfo.workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n await tryN(3, async () => instance.terminate(), {\n shouldRetry: isErrorRetryable,\n baseDelayMs: 200,\n maxDelayMs: 3000\n });\n\n // Update tracking table with new status\n const status = await instance.status();\n this._updateWorkflowTracking(workflowId, status);\n\n this._emit(\"workflow:terminated\", {\n workflowId,\n workflowName: workflowInfo.workflowName\n });\n }\n\n /**\n * Pause a running workflow.\n * The workflow can be resumed later with resumeWorkflow().\n *\n * @param workflowId - ID of the workflow to pause (must be tracked via runWorkflow)\n * @throws Error if workflow not found in tracking table\n * @throws Error if workflow binding not found in environment\n * @throws Error if workflow is not running (from Cloudflare)\n *\n * @example\n * ```typescript\n * await this.pauseWorkflow(workflowId);\n * ```\n */\n async pauseWorkflow(workflowId: string): Promise<void> {\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n const workflow = this._findWorkflowBindingByName(\n workflowInfo.workflowName as WorkflowName<Env>\n );\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowInfo.workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n await tryN(3, async () => instance.pause(), {\n shouldRetry: isErrorRetryable,\n baseDelayMs: 200,\n maxDelayMs: 3000\n });\n\n const status = await instance.status();\n this._updateWorkflowTracking(workflowId, status);\n\n this._emit(\"workflow:paused\", {\n workflowId,\n workflowName: workflowInfo.workflowName\n });\n }\n\n /**\n * Resume a paused workflow.\n *\n * @param workflowId - ID of the workflow to resume (must be tracked via runWorkflow)\n * @throws Error if workflow not found in tracking table\n * @throws Error if workflow binding not found in environment\n * @throws Error if workflow is not paused (from Cloudflare)\n *\n * @example\n * ```typescript\n * await this.resumeWorkflow(workflowId);\n * ```\n */\n async resumeWorkflow(workflowId: string): Promise<void> {\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n const workflow = this._findWorkflowBindingByName(\n workflowInfo.workflowName as WorkflowName<Env>\n );\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowInfo.workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n await tryN(3, async () => instance.resume(), {\n shouldRetry: isErrorRetryable,\n baseDelayMs: 200,\n maxDelayMs: 3000\n });\n\n const status = await instance.status();\n this._updateWorkflowTracking(workflowId, status);\n\n this._emit(\"workflow:resumed\", {\n workflowId,\n workflowName: workflowInfo.workflowName\n });\n }\n\n /**\n * Restart a workflow instance.\n * This re-runs the workflow from the beginning with the same ID.\n *\n * @param workflowId - ID of the workflow to restart (must be tracked via runWorkflow)\n * @param options - Optional settings\n * @param options.resetTracking - If true (default), resets created_at and clears error fields.\n * If false, preserves original timestamps.\n * @throws Error if workflow not found in tracking table\n * @throws Error if workflow binding not found in environment\n *\n * @example\n * ```typescript\n * // Reset tracking (default)\n * await this.restartWorkflow(workflowId);\n *\n * // Preserve original timestamps\n * await this.restartWorkflow(workflowId, { resetTracking: false });\n * ```\n */\n async restartWorkflow(\n workflowId: string,\n options: { resetTracking?: boolean } = {}\n ): Promise<void> {\n const { resetTracking = true } = options;\n\n const workflowInfo = this.getWorkflow(workflowId);\n if (!workflowInfo) {\n throw new Error(`Workflow ${workflowId} not found in tracking table`);\n }\n\n const workflow = this._findWorkflowBindingByName(\n workflowInfo.workflowName as WorkflowName<Env>\n );\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowInfo.workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n await tryN(3, async () => instance.restart(), {\n shouldRetry: isErrorRetryable,\n baseDelayMs: 200,\n maxDelayMs: 3000\n });\n\n if (resetTracking) {\n // Reset tracking fields for fresh start\n const now = Math.floor(Date.now() / 1000);\n this.sql`\n UPDATE cf_agents_workflows\n SET status = 'queued',\n created_at = ${now},\n updated_at = ${now},\n completed_at = NULL,\n error_name = NULL,\n error_message = NULL\n WHERE workflow_id = ${workflowId}\n `;\n } else {\n // Just update status from Cloudflare\n const status = await instance.status();\n this._updateWorkflowTracking(workflowId, status);\n }\n\n this._emit(\"workflow:restarted\", {\n workflowId,\n workflowName: workflowInfo.workflowName\n });\n }\n\n /**\n * Find a workflow binding by its name.\n */\n private _findWorkflowBindingByName(\n workflowName: string\n ): Workflow | undefined {\n const binding = (this.env as Record<string, unknown>)[workflowName];\n if (\n binding &&\n typeof binding === \"object\" &&\n \"create\" in binding &&\n \"get\" in binding\n ) {\n return binding as Workflow;\n }\n return undefined;\n }\n\n /**\n * Get all workflow binding names from the environment.\n */\n private _getWorkflowBindingNames(): string[] {\n const names: string[] = [];\n for (const [key, value] of Object.entries(\n this.env as Record<string, unknown>\n )) {\n if (\n value &&\n typeof value === \"object\" &&\n \"create\" in value &&\n \"get\" in value\n ) {\n names.push(key);\n }\n }\n return names;\n }\n\n /**\n * Get the status of a workflow and update the tracking record.\n *\n * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW')\n * @param workflowId - ID of the workflow instance\n * @returns The workflow status\n */\n async getWorkflowStatus(\n workflowName: WorkflowName<Env>,\n workflowId: string\n ): Promise<InstanceStatus> {\n const workflow = this._findWorkflowBindingByName(workflowName);\n if (!workflow) {\n throw new Error(\n `Workflow binding '${workflowName}' not found in environment`\n );\n }\n\n const instance = await workflow.get(workflowId);\n const status = await instance.status();\n\n // Update the tracking record\n this._updateWorkflowTracking(workflowId, status);\n\n return status;\n }\n\n /**\n * Get a tracked workflow by ID.\n *\n * @param workflowId - Workflow instance ID\n * @returns Workflow info or undefined if not found\n */\n getWorkflow(workflowId: string): WorkflowInfo | undefined {\n const rows = this.sql<WorkflowTrackingRow>`\n SELECT * FROM cf_agents_workflows WHERE workflow_id = ${workflowId}\n `;\n\n if (!rows || rows.length === 0) {\n return undefined;\n }\n\n return this._rowToWorkflowInfo(rows[0]);\n }\n\n /**\n * Query tracked workflows with cursor-based pagination.\n *\n * @param criteria - Query criteria including optional cursor for pagination\n * @returns WorkflowPage with workflows, total count, and next cursor\n *\n * @example\n * ```typescript\n * // First page\n * const page1 = this.getWorkflows({ status: 'running', limit: 20 });\n *\n * // Next page\n * if (page1.nextCursor) {\n * const page2 = this.getWorkflows({\n * status: 'running',\n * limit: 20,\n * cursor: page1.nextCursor\n * });\n * }\n * ```\n */\n getWorkflows(criteria: WorkflowQueryCriteria = {}): WorkflowPage {\n const limit = Math.min(criteria.limit ?? 50, 100);\n const isAsc = criteria.orderBy === \"asc\";\n\n // Get total count (ignores cursor and limit)\n const total = this._countWorkflows(criteria);\n\n // Build base query\n let query = \"SELECT * FROM cf_agents_workflows WHERE 1=1\";\n const params: (string | number | boolean)[] = [];\n\n if (criteria.status) {\n const statuses = Array.isArray(criteria.status)\n ? criteria.status\n : [criteria.status];\n const placeholders = statuses.map(() => \"?\").join(\", \");\n query += ` AND status IN (${placeholders})`;\n params.push(...statuses);\n }\n\n if (criteria.workflowName) {\n query += \" AND workflow_name = ?\";\n params.push(criteria.workflowName);\n }\n\n if (criteria.metadata) {\n for (const [key, value] of Object.entries(criteria.metadata)) {\n query += ` AND json_extract(metadata, '$.' || ?) = ?`;\n params.push(key, value);\n }\n }\n\n // Apply cursor for keyset pagination\n if (criteria.cursor) {\n const cursor = this._decodeCursor(criteria.cursor);\n if (isAsc) {\n // ASC: get items after cursor\n query +=\n \" AND (created_at > ? OR (created_at = ? AND workflow_id > ?))\";\n } else {\n // DESC: get items before cursor\n query +=\n \" AND (created_at < ? OR (created_at = ? AND workflow_id < ?))\";\n }\n params.push(cursor.createdAt, cursor.createdAt, cursor.workflowId);\n }\n\n // Order by created_at and workflow_id for consistent keyset pagination\n query += ` ORDER BY created_at ${isAsc ? \"ASC\" : \"DESC\"}, workflow_id ${isAsc ? \"ASC\" : \"DESC\"}`;\n\n // Fetch limit + 1 to detect if there are more pages\n query += \" LIMIT ?\";\n params.push(limit + 1);\n\n const rows = this.ctx.storage.sql\n .exec(query, ...params)\n .toArray() as WorkflowTrackingRow[];\n\n const hasMore = rows.length > limit;\n const resultRows = hasMore ? rows.slice(0, limit) : rows;\n const workflows = resultRows.map((row) => this._rowToWorkflowInfo(row));\n\n // Build next cursor from last item\n const nextCursor =\n hasMore && workflows.length > 0\n ? this._encodeCursor(workflows[workflows.length - 1])\n : null;\n\n return { workflows, total, nextCursor };\n }\n\n /**\n * Count workflows matching criteria (for pagination total).\n */\n private _countWorkflows(\n criteria: Omit<WorkflowQueryCriteria, \"limit\" | \"cursor\" | \"orderBy\"> & {\n createdBefore?: Date;\n }\n ): number {\n let query = \"SELECT COUNT(*) as count FROM cf_agents_workflows WHERE 1=1\";\n const params: (string | number | boolean)[] = [];\n\n if (criteria.status) {\n const statuses = Array.isArray(criteria.status)\n ? criteria.status\n : [criteria.status];\n const placeholders = statuses.map(() => \"?\").join(\", \");\n query += ` AND status IN (${placeholders})`;\n params.push(...statuses);\n }\n\n if (criteria.workflowName) {\n query += \" AND workflow_name = ?\";\n params.push(criteria.workflowName);\n }\n\n if (criteria.metadata) {\n for (const [key, value] of Object.entries(criteria.metadata)) {\n query += ` AND json_extract(metadata, '$.' || ?) = ?`;\n params.push(key, value);\n }\n }\n\n if (criteria.createdBefore) {\n query += \" AND created_at < ?\";\n params.push(Math.floor(criteria.createdBefore.getTime() / 1000));\n }\n\n const result = this.ctx.storage.sql.exec(query, ...params).toArray() as {\n count: number;\n }[];\n\n return result[0]?.count ?? 0;\n }\n\n /**\n * Encode a cursor from workflow info for pagination.\n * Stores createdAt as Unix timestamp in seconds (matching DB storage).\n */\n private _encodeCursor(workflow: WorkflowInfo): string {\n return btoa(\n JSON.stringify({\n c: Math.floor(workflow.createdAt.getTime() / 1000),\n i: workflow.workflowId\n })\n );\n }\n\n /**\n * Decode a pagination cursor.\n * Returns createdAt as Unix timestamp in seconds (matching DB storage).\n */\n private _decodeCursor(cursor: string): {\n createdAt: number;\n workflowId: string;\n } {\n try {\n const data = JSON.parse(atob(cursor));\n if (typeof data.c !== \"number\" || typeof data.i !== \"string\") {\n throw new Error(\"Invalid cursor structure\");\n }\n return { createdAt: data.c, workflowId: data.i };\n } catch {\n throw new Error(\n \"Invalid pagination cursor. The cursor may be malformed or corrupted.\"\n );\n }\n }\n\n /**\n * Delete a workflow tracking record.\n *\n * @param workflowId - ID of the workflow to delete\n * @returns true if a record was deleted, false if not found\n */\n deleteWorkflow(workflowId: string): boolean {\n // First check if workflow exists\n const existing = this.sql<{ count: number }>`\n SELECT COUNT(*) as count FROM cf_agents_workflows WHERE workflow_id = ${workflowId}\n `;\n if (!existing[0] || existing[0].count === 0) {\n return false;\n }\n this.sql`DELETE FROM cf_agents_workflows WHERE workflow_id = ${workflowId}`;\n return true;\n }\n\n /**\n * Delete workflow tracking records matching criteria.\n * Useful for cleaning up old completed/errored workflows.\n *\n * @param criteria - Criteria for which workflows to delete\n * @returns Number of records matching criteria (expected deleted count)\n *\n * @example\n * ```typescript\n * // Delete all completed workflows created more than 7 days ago\n * const deleted = this.deleteWorkflows({\n * status: 'complete',\n * createdBefore: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)\n * });\n *\n * // Delete all errored and terminated workflows\n * const deleted = this.deleteWorkflows({\n * status: ['errored', 'terminated']\n * });\n * ```\n */\n deleteWorkflows(\n criteria: Omit<WorkflowQueryCriteria, \"limit\" | \"orderBy\"> & {\n createdBefore?: Date;\n } = {}\n ): number {\n let query = \"DELETE FROM cf_agents_workflows WHERE 1=1\";\n const params: (string | number | boolean)[] = [];\n\n if (criteria.status) {\n const statuses = Array.isArray(criteria.status)\n ? criteria.status\n : [criteria.status];\n const placeholders = statuses.map(() => \"?\").join(\", \");\n query += ` AND status IN (${placeholders})`;\n params.push(...statuses);\n }\n\n if (criteria.workflowName) {\n query += \" AND workflow_name = ?\";\n params.push(criteria.workflowName);\n }\n\n if (criteria.metadata) {\n for (const [key, value] of Object.entries(criteria.metadata)) {\n query += ` AND json_extract(metadata, '$.' || ?) = ?`;\n params.push(key, value);\n }\n }\n\n if (criteria.createdBefore) {\n query += \" AND created_at < ?\";\n params.push(Math.floor(criteria.createdBefore.getTime() / 1000));\n }\n\n const cursor = this.ctx.storage.sql.exec(query, ...params);\n return cursor.rowsWritten;\n }\n\n /**\n * Migrate workflow tracking records from an old binding name to a new one.\n * Use this after renaming a workflow binding in wrangler.toml.\n *\n * @param oldName - Previous workflow binding name\n * @param newName - New workflow binding name\n * @returns Number of records migrated\n *\n * @example\n * ```typescript\n * // After renaming OLD_WORKFLOW to NEW_WORKFLOW in wrangler.toml\n * async onStart() {\n * const migrated = this.migrateWorkflowBinding('OLD_WORKFLOW', 'NEW_WORKFLOW');\n * }\n * ```\n */\n migrateWorkflowBinding(oldName: string, newName: string): number {\n // Validate new binding exists\n if (!this._findWorkflowBindingByName(newName)) {\n throw new Error(`Workflow binding '${newName}' not found in environment`);\n }\n\n const result = this.sql<{ count: number }>`\n SELECT COUNT(*) as count FROM cf_agents_workflows WHERE workflow_name = ${oldName}\n `;\n const count = result[0]?.count ?? 0;\n\n if (count > 0) {\n this\n .sql`UPDATE cf_agents_workflows SET workflow_name = ${newName} WHERE workflow_name = ${oldName}`;\n console.log(\n `[Agent] Migrated ${count} workflow(s) from '${oldName}' to '${newName}'`\n );\n }\n\n return count;\n }\n\n /**\n * Update workflow tracking record from InstanceStatus\n */\n private _updateWorkflowTracking(\n workflowId: string,\n status: InstanceStatus\n ): void {\n const statusName = status.status;\n const now = Math.floor(Date.now() / 1000);\n\n // Determine if workflow is complete\n const completedStatuses: WorkflowStatus[] = [\n \"complete\",\n \"errored\",\n \"terminated\"\n ];\n const completedAt = completedStatuses.includes(statusName) ? now : null;\n\n // Extract error info if present\n const errorName = status.error?.name ?? null;\n const errorMessage = status.error?.message ?? null;\n\n this.sql`\n UPDATE cf_agents_workflows\n SET status = ${statusName},\n error_name = ${errorName},\n error_message = ${errorMessage},\n updated_at = ${now},\n completed_at = ${completedAt}\n WHERE workflow_id = ${workflowId}\n `;\n }\n\n /**\n * Convert a database row to WorkflowInfo\n */\n private _rowToWorkflowInfo(row: WorkflowTrackingRow): WorkflowInfo {\n return {\n id: row.id,\n workflowId: row.workflow_id,\n workflowName: row.workflow_name,\n status: row.status,\n metadata: row.metadata ? JSON.parse(row.metadata) : null,\n error: row.error_name\n ? { name: row.error_name, message: row.error_message ?? \"\" }\n : null,\n createdAt: new Date(row.created_at * 1000),\n updatedAt: new Date(row.updated_at * 1000),\n completedAt: row.completed_at ? new Date(row.completed_at * 1000) : null\n };\n }\n\n private _workflowOrigin(\n options: RunWorkflowOptions | undefined\n ): AgentWorkflowOrigin | undefined {\n if (this._isFacet) {\n const root = this._parentPath[0];\n const rootBindingName =\n options?.agentBinding ??\n (root ? this._findAgentBindingNameForClass(root.className) : undefined);\n\n if (!rootBindingName) return undefined;\n\n return {\n kind: \"facet\",\n version: 1,\n rootBinding: rootBindingName,\n path: this.selfPath.map((step) => ({ ...step }))\n };\n }\n\n const agentBindingName =\n options?.agentBinding ??\n this._findAgentBindingNameForClass(this._ParentClass.name);\n if (!agentBindingName) return undefined;\n\n return {\n kind: \"agent\",\n version: 1,\n binding: agentBindingName,\n name: this.name\n };\n }\n\n private _findAgentBindingNameForClass(className: string): string | undefined {\n for (const [key, value] of Object.entries(\n this.env as Record<string, unknown>\n )) {\n if (\n value &&\n typeof value === \"object\" &&\n \"idFromName\" in value &&\n typeof value.idFromName === \"function\"\n ) {\n // Check if this namespace's binding name matches our class name\n if (\n key === className ||\n camelCaseToKebabCase(key) === camelCaseToKebabCase(className)\n ) {\n return key;\n }\n }\n }\n return undefined;\n }\n\n private _findBindingNameForNamespace(\n namespace: DurableObjectNamespace<McpAgent>\n ): string | undefined {\n for (const [key, value] of Object.entries(\n this.env as Record<string, unknown>\n )) {\n if (value === namespace) {\n return key;\n }\n }\n return undefined;\n }\n\n // ==========================================\n // Workflow Lifecycle Callbacks\n // ==========================================\n\n /**\n * Handle a callback from a workflow.\n * Invoked via the internal `_workflow_handleCallback` RPC whenever an\n * {@link AgentWorkflow} reports progress, completion, an error, or a custom\n * event back to its originating Agent (or sub-agent facet).\n * Override this to handle all callback types in one place.\n *\n * @param callback - The callback payload\n */\n async onWorkflowCallback(callback: WorkflowCallback): Promise<void> {\n const now = Math.floor(Date.now() / 1000);\n\n switch (callback.type) {\n case \"progress\":\n // Update tracking status to \"running\" when receiving progress\n // Only transition from queued/waiting to avoid overwriting terminal states\n this.sql`\n UPDATE cf_agents_workflows\n SET status = 'running', updated_at = ${now}\n WHERE workflow_id = ${callback.workflowId} AND status IN ('queued', 'waiting')\n `;\n await this.onWorkflowProgress(\n callback.workflowName,\n callback.workflowId,\n callback.progress\n );\n break;\n case \"complete\":\n // Update tracking status to \"complete\"\n // Don't overwrite if already terminated/paused (race condition protection)\n this.sql`\n UPDATE cf_agents_workflows\n SET status = 'complete', updated_at = ${now}, completed_at = ${now}\n WHERE workflow_id = ${callback.workflowId}\n AND status NOT IN ('terminated', 'paused')\n `;\n await this.onWorkflowComplete(\n callback.workflowName,\n callback.workflowId,\n callback.result\n );\n break;\n case \"error\":\n // Update tracking status to \"errored\"\n // Don't overwrite if already terminated/paused (race condition protection)\n this.sql`\n UPDATE cf_agents_workflows\n SET status = 'errored', updated_at = ${now}, completed_at = ${now},\n error_name = 'WorkflowError', error_message = ${callback.error}\n WHERE workflow_id = ${callback.workflowId}\n AND status NOT IN ('terminated', 'paused')\n `;\n await this.onWorkflowError(\n callback.workflowName,\n callback.workflowId,\n callback.error\n );\n break;\n case \"event\":\n // No status change for events - they can occur at any stage\n await this.onWorkflowEvent(\n callback.workflowName,\n callback.workflowId,\n callback.event\n );\n break;\n }\n }\n\n /**\n * Called when a workflow reports progress.\n * Override to handle progress updates.\n *\n * @param workflowName - Workflow binding name\n * @param workflowId - ID of the workflow\n * @param progress - Typed progress data (default: DefaultProgress)\n */\n async onWorkflowProgress(\n // oxlint-disable-next-line no-unused-vars\n workflowName: string,\n // oxlint-disable-next-line no-unused-vars\n workflowId: string,\n // oxlint-disable-next-line no-unused-vars\n progress: unknown\n ): Promise<void> {\n // Override to handle progress updates\n }\n\n /**\n * Called when a workflow completes successfully.\n * Override to handle completion.\n *\n * @param workflowName - Workflow binding name\n * @param workflowId - ID of the workflow\n * @param result - Optional result data\n */\n async onWorkflowComplete(\n // oxlint-disable-next-line no-unused-vars\n workflowName: string,\n // oxlint-disable-next-line no-unused-vars\n workflowId: string,\n // oxlint-disable-next-line no-unused-vars\n result?: unknown\n ): Promise<void> {\n // Override to handle completion\n }\n\n /**\n * Called when a workflow encounters an error.\n * Override to handle errors.\n *\n * @param workflowName - Workflow binding name\n * @param workflowId - ID of the workflow\n * @param error - Error message\n */\n async onWorkflowError(\n workflowName: string,\n workflowId: string,\n error: string\n ): Promise<void> {\n console.error(\n `Workflow error [${workflowName}/${workflowId}]: ${error}\\n` +\n \"Override onWorkflowError() in your Agent to handle workflow errors.\"\n );\n }\n\n /**\n * Called when a workflow sends a custom event.\n * Override to handle custom events.\n *\n * @param workflowName - Workflow binding name\n * @param workflowId - ID of the workflow\n * @param event - Custom event payload\n */\n async onWorkflowEvent(\n // oxlint-disable-next-line no-unused-vars\n workflowName: string,\n // oxlint-disable-next-line no-unused-vars\n workflowId: string,\n // oxlint-disable-next-line no-unused-vars\n event: unknown\n ): Promise<void> {\n // Override to handle custom events\n }\n\n // ============================================================\n // Internal RPC methods for AgentWorkflow communication\n // These are called via DO RPC, not exposed via HTTP\n // ============================================================\n\n /**\n * Handle a workflow callback via RPC.\n * @internal - Called by AgentWorkflow, do not call directly\n */\n async _workflow_handleCallback(callback: WorkflowCallback): Promise<void> {\n await this.__unsafe_ensureInitialized();\n await this.onWorkflowCallback(callback);\n }\n\n /**\n * Broadcast a message to all connected clients via RPC.\n * @internal - Called by AgentWorkflow, do not call directly\n */\n async _workflow_broadcast(message: unknown): Promise<void> {\n await this.__unsafe_ensureInitialized();\n this.broadcast(JSON.stringify(message));\n }\n\n /**\n * Update agent state via RPC.\n * @internal - Called by AgentWorkflow, do not call directly\n */\n async _workflow_updateState(\n action: \"set\" | \"merge\" | \"reset\",\n state?: unknown\n ): Promise<void> {\n await this.__unsafe_ensureInitialized();\n if (action === \"set\") {\n this.setState(state as State);\n } else if (action === \"merge\") {\n const currentState = this.state ?? ({} as State);\n this.setState({\n ...currentState,\n ...(state as Record<string, unknown>)\n } as State);\n } else if (action === \"reset\") {\n this.setState(this.initialState);\n }\n }\n\n /**\n * Connect to a new MCP Server via RPC (Durable Object binding)\n *\n * The binding name and props are persisted to storage so the connection\n * is automatically restored after Durable Object hibernation.\n *\n * @example\n * await this.addMcpServer(\"counter\", env.MY_MCP);\n * await this.addMcpServer(\"counter\", env.MY_MCP, { props: { userId: \"123\" } });\n */\n async addMcpServer<T extends McpAgent>(\n serverName: string,\n binding: DurableObjectNamespace<T>,\n options?: AddRpcMcpServerOptions\n ): Promise<{ id: string; state: typeof MCPConnectionState.READY }>;\n\n /**\n * Connect to a new MCP Server via HTTP (SSE or Streamable HTTP)\n *\n * @example\n * await this.addMcpServer(\"github\", \"https://mcp.github.com\");\n * await this.addMcpServer(\"github\", \"https://mcp.github.com\", { transport: { type: \"sse\" } });\n * await this.addMcpServer(\"github\", url, callbackHost, agentsPrefix, options); // legacy\n */\n async addMcpServer(\n serverName: string,\n url: string,\n callbackHostOrOptions?: string | AddMcpServerOptions,\n agentsPrefix?: string,\n options?: Pick<AddMcpServerOptions, \"client\" | \"transport\">\n ): Promise<\n | {\n id: string;\n state: typeof MCPConnectionState.AUTHENTICATING;\n authUrl: string;\n }\n | { id: string; state: typeof MCPConnectionState.READY }\n >;\n\n async addMcpServer<T extends McpAgent>(\n serverName: string,\n urlOrBinding: string | DurableObjectNamespace<T>,\n callbackHostOrOptions?:\n | string\n | AddMcpServerOptions\n | AddRpcMcpServerOptions,\n agentsPrefix?: string,\n options?: Pick<AddMcpServerOptions, \"client\" | \"transport\">\n ): Promise<\n | {\n id: string;\n state: typeof MCPConnectionState.AUTHENTICATING;\n authUrl: string;\n }\n | {\n id: string;\n state: typeof MCPConnectionState.READY;\n authUrl?: undefined;\n }\n > {\n const isHttpTransport = typeof urlOrBinding === \"string\";\n const normalizedUrl = isHttpTransport\n ? new URL(urlOrBinding).href\n : undefined;\n\n // Extract and normalize a caller-supplied stable id, if any. The same\n // option field is accepted on both the HTTP and RPC option shapes.\n let requestedId: string | undefined;\n if (\n typeof callbackHostOrOptions === \"object\" &&\n callbackHostOrOptions !== null &&\n typeof (callbackHostOrOptions as { id?: unknown }).id === \"string\"\n ) {\n const rawId = (callbackHostOrOptions as { id: string }).id;\n requestedId = normalizeServerId(rawId);\n }\n\n const allServers = this.mcp.listServers();\n\n const existingServer = allServers.find(\n (s) =>\n s.name === serverName &&\n (!isHttpTransport || new URL(s.server_url).href === normalizedUrl)\n );\n\n if (requestedId) {\n // Collision check 1: a caller-supplied id may only re-resolve to an\n // existing server when the (name, url) also matches. Otherwise storage\n // (INSERT OR REPLACE on id) would silently overwrite the existing row.\n const idConflict = allServers.find((s) => {\n if (s.id !== requestedId) return false;\n if (s.name !== serverName) return true;\n if (isHttpTransport) {\n return new URL(s.server_url).href !== normalizedUrl;\n }\n return false;\n });\n if (idConflict) {\n throw new Error(\n `MCP server id \"${requestedId}\" is already in use by server \"${idConflict.name}\" (${idConflict.server_url}). ` +\n `Stable ids must be unique per (name, url).`\n );\n }\n\n // JIT-migrate: the same (name, url) is already registered under a\n // different id (typically an auto-generated nanoid from a previous\n // call that didn't supply `id`). This is the natural upgrade path —\n // a user adds `{ id: \"github\" }` to an existing `addMcpServer` call.\n // Rename the existing row + connection + OAuth keys to the new id in\n // place so the caller's contract (\"the id I get back is the id I\n // asked for\") holds and no stale storage rows are left behind.\n if (existingServer && existingServer.id !== requestedId) {\n await this.mcp.migrateServerId(\n existingServer.id,\n requestedId,\n this.name\n );\n existingServer.id = requestedId;\n }\n }\n\n if (existingServer && this.mcp.mcpConnections[existingServer.id]) {\n const conn = this.mcp.mcpConnections[existingServer.id];\n if (conn.connectionState === MCPConnectionState.AUTHENTICATING) {\n const authProvider = conn.options.transport.authProvider;\n const authUrl =\n (await this._redeemableAuthUrl(\n existingServer.id,\n authProvider?.authUrl,\n authProvider\n )) ??\n (await this._redeemableAuthUrl(\n existingServer.id,\n existingServer.auth_url,\n authProvider\n ));\n if (authUrl) {\n return {\n id: existingServer.id,\n state: MCPConnectionState.AUTHENTICATING,\n authUrl\n };\n }\n\n const reconnectResult = await this.mcp.connectToServer(\n existingServer.id\n );\n if (reconnectResult.state === MCPConnectionState.AUTHENTICATING) {\n if (!reconnectResult.authUrl) {\n throw new Error(\"OAuth configuration incomplete: missing authUrl\");\n }\n return {\n id: existingServer.id,\n state: reconnectResult.state,\n authUrl: reconnectResult.authUrl\n };\n }\n if (reconnectResult.state === MCPConnectionState.CONNECTED) {\n const discoverResult = await this.mcp.discoverIfConnected(\n existingServer.id\n );\n if (!discoverResult?.success) {\n throw new Error(\n `Failed to discover MCP server capabilities: ${discoverResult?.error ?? \"connection not found\"}`\n );\n }\n return {\n id: existingServer.id,\n state: MCPConnectionState.READY\n };\n }\n throw new Error(\n `Failed to connect to MCP server at ${normalizedUrl}: ${reconnectResult.error}`\n );\n }\n if (conn.connectionState === MCPConnectionState.FAILED) {\n throw new Error(\n `MCP server \"${serverName}\" is in failed state: ${conn.connectionError}`\n );\n }\n return { id: existingServer.id, state: MCPConnectionState.READY };\n }\n\n // RPC transport path: second argument is a DurableObjectNamespace\n if (typeof urlOrBinding !== \"string\") {\n const rpcOpts = callbackHostOrOptions as\n | AddRpcMcpServerOptions\n | undefined;\n\n const normalizedName = serverName.toLowerCase().replace(/\\s+/g, \"-\");\n\n // Prefer the caller-supplied stable id, falling back to the existing\n // server's id (for restore-through-addMcpServer), then to a generated id.\n const reconnectId = requestedId ?? existingServer?.id;\n const { id } = await this.mcp.connect(\n `${RPC_DO_PREFIX}${normalizedName}`,\n {\n reconnect: reconnectId ? { id: reconnectId } : undefined,\n transport: {\n type: \"rpc\" as TransportType,\n namespace:\n urlOrBinding as unknown as DurableObjectNamespace<McpAgent>,\n name: normalizedName,\n props: rpcOpts?.props\n }\n }\n );\n\n const conn = this.mcp.mcpConnections[id];\n if (conn && conn.connectionState === MCPConnectionState.CONNECTED) {\n const discoverResult = await this.mcp.discoverIfConnected(id);\n if (discoverResult && !discoverResult.success) {\n throw new Error(\n `Failed to discover MCP server capabilities: ${discoverResult.error}`\n );\n }\n } else if (conn && conn.connectionState === MCPConnectionState.FAILED) {\n throw new Error(\n `Failed to connect to MCP server \"${serverName}\" via RPC: ${conn.connectionError}`\n );\n }\n\n const bindingName = this._findBindingNameForNamespace(\n urlOrBinding as unknown as DurableObjectNamespace<McpAgent>\n );\n if (bindingName) {\n this.mcp.saveRpcServerToStorage(\n id,\n serverName,\n normalizedName,\n bindingName,\n rpcOpts?.props\n );\n }\n\n return { id, state: MCPConnectionState.READY };\n }\n\n // HTTP transport path\n const httpOptions = callbackHostOrOptions as\n | string\n | AddMcpServerOptions\n | undefined;\n\n let resolvedCallbackHost: string | undefined;\n let resolvedAgentsPrefix: string;\n let resolvedOptions:\n | Pick<AddMcpServerOptions, \"client\" | \"transport\" | \"retry\">\n | undefined;\n\n let resolvedCallbackPath: string | undefined;\n\n if (typeof httpOptions === \"object\" && httpOptions !== null) {\n resolvedCallbackHost = httpOptions.callbackHost;\n resolvedCallbackPath = httpOptions.callbackPath;\n resolvedAgentsPrefix = httpOptions.agentsPrefix ?? \"agents\";\n resolvedOptions = {\n client: httpOptions.client,\n transport: httpOptions.transport,\n retry: httpOptions.retry\n };\n } else {\n resolvedCallbackHost = httpOptions;\n resolvedAgentsPrefix = agentsPrefix ?? \"agents\";\n resolvedOptions = options;\n }\n\n // Enforce callbackPath when sendIdentityOnConnect is false and callbackHost is provided\n if (\n !this._resolvedOptions.sendIdentityOnConnect &&\n resolvedCallbackHost &&\n !resolvedCallbackPath\n ) {\n throw new Error(\n \"callbackPath is required in addMcpServer options when sendIdentityOnConnect is false — \" +\n \"the default callback URL would expose the instance name. \" +\n \"Provide a callbackPath and route the callback request to this agent via getAgentByName.\"\n );\n }\n\n // Try to derive callbackHost from the current request or connection URI\n if (!resolvedCallbackHost) {\n const { request, connection } = getCurrentAgent();\n if (request) {\n const requestUrl = new URL(request.url);\n resolvedCallbackHost = `${requestUrl.protocol}//${requestUrl.host}`;\n } else if (connection?.uri) {\n const connectionUrl = new URL(connection.uri);\n resolvedCallbackHost = `${connectionUrl.protocol}//${connectionUrl.host}`;\n }\n }\n\n // Build the callback URL if we have a host (needed for OAuth, optional for non-OAuth servers)\n let callbackUrl: string | undefined;\n if (resolvedCallbackHost) {\n const normalizedHost = resolvedCallbackHost.replace(/\\/$/, \"\");\n callbackUrl = resolvedCallbackPath\n ? `${normalizedHost}/${resolvedCallbackPath.replace(/^\\//, \"\")}`\n : `${normalizedHost}/${resolvedAgentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;\n }\n\n const id = requestedId ?? existingServer?.id ?? nanoid(8);\n\n // Only create authProvider if we have a callbackUrl (needed for OAuth servers)\n let authProvider:\n | ReturnType<typeof this.createMcpOAuthProvider>\n | undefined;\n if (callbackUrl) {\n authProvider = this.createMcpOAuthProvider(callbackUrl);\n authProvider.serverId = id;\n }\n\n // Use the transport type specified in options, or default to \"auto\"\n const transportType: TransportType =\n resolvedOptions?.transport?.type ?? \"auto\";\n\n // allows passing through transport headers if necessary\n // this handles some non-standard bearer auth setups (i.e. MCP server behind CF access instead of OAuth)\n let headerTransportOpts: SSEClientTransportOptions = {};\n if (resolvedOptions?.transport?.headers) {\n headerTransportOpts = {\n eventSourceInit: {\n fetch: (url, init) =>\n fetch(url, {\n ...init,\n headers: resolvedOptions?.transport?.headers\n })\n },\n requestInit: {\n headers: resolvedOptions?.transport?.headers\n }\n };\n }\n\n // Register server (also saves to storage)\n await this.mcp.registerServer(id, {\n url: normalizedUrl!,\n name: serverName,\n callbackUrl,\n client: resolvedOptions?.client,\n transport: {\n ...headerTransportOpts,\n authProvider,\n type: transportType,\n skipIssuerMetadataValidation:\n resolvedOptions?.transport?.skipIssuerMetadataValidation\n },\n retry: resolvedOptions?.retry\n });\n\n const result = await this.mcp.connectToServer(id);\n\n if (result.state === MCPConnectionState.FAILED) {\n // Server stays in storage so user can retry via connectToServer(id)\n throw new Error(\n `Failed to connect to MCP server at ${normalizedUrl}: ${result.error}`\n );\n }\n\n if (result.state === MCPConnectionState.AUTHENTICATING) {\n if (!callbackUrl) {\n throw new Error(\n \"This MCP server requires OAuth authentication. \" +\n \"Provide callbackHost in addMcpServer options to enable the OAuth flow.\"\n );\n }\n return { id, state: result.state, authUrl: result.authUrl };\n }\n\n // State is CONNECTED - discover capabilities\n const discoverResult = await this.mcp.discoverIfConnected(id);\n\n if (discoverResult && !discoverResult.success) {\n // Server stays in storage - connection is still valid, user can retry discovery\n throw new Error(\n `Failed to discover MCP server capabilities: ${discoverResult.error}`\n );\n }\n\n return { id, state: MCPConnectionState.READY };\n }\n\n private async _redeemableAuthUrl(\n serverId: string,\n authUrl: string | null | undefined,\n authProvider: AgentMcpOAuthProvider | undefined\n ): Promise<string | undefined> {\n if (!this._isAbsoluteHttpUrl(authUrl) || !authProvider) return;\n const state = new URL(authUrl).searchParams.get(\"state\");\n if (!state) return authUrl;\n\n authProvider.serverId = serverId;\n try {\n return (await authProvider.checkState(state)).valid ? authUrl : undefined;\n } catch {\n return undefined;\n }\n }\n\n private _isAbsoluteHttpUrl(\n value: string | null | undefined\n ): value is string {\n if (!value) return false;\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n }\n\n async removeMcpServer(id: string) {\n await this.mcp.removeServer(id);\n }\n\n getMcpServers(): MCPServersState {\n const mcpState: MCPServersState = {\n prompts: this.mcp.listPrompts(),\n resources: this.mcp.listResources(),\n servers: {},\n tools: this.mcp.listTools()\n };\n\n const servers = this.mcp.listServers();\n\n if (servers && Array.isArray(servers) && servers.length > 0) {\n for (const server of servers) {\n const serverConn = this.mcp.mcpConnections[server.id];\n\n // Determine the default state when no connection exists\n let defaultState: \"authenticating\" | \"not-connected\" = \"not-connected\";\n if (!serverConn && server.auth_url) {\n // If there's an auth_url but no connection, it's waiting for OAuth\n defaultState = \"authenticating\";\n }\n\n mcpState.servers[server.id] = {\n auth_url: server.auth_url,\n capabilities: serverConn?.serverCapabilities ?? null,\n error: sanitizeErrorString(serverConn?.connectionError ?? null),\n instructions: serverConn?.instructions ?? null,\n name: server.name,\n server_url: server.server_url,\n state: serverConn?.connectionState ?? defaultState\n };\n }\n }\n\n return mcpState;\n }\n\n /**\n * Create the OAuth provider used when connecting to MCP servers that require authentication.\n *\n * Override this method in a subclass to supply a custom OAuth provider implementation,\n * for example to use pre-registered client credentials, mTLS-based authentication,\n * or any other OAuth flow beyond dynamic client registration.\n *\n * @example\n * // Custom OAuth provider\n * class MyAgent extends Agent {\n * createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider {\n * return new MyCustomOAuthProvider(\n * this.ctx.storage,\n * this.name,\n * callbackUrl\n * );\n * }\n * }\n *\n * @param callbackUrl The OAuth callback URL for the authorization flow\n * @returns An {@link AgentMcpOAuthProvider} instance used by {@link addMcpServer}\n */\n createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider {\n return new DurableObjectOAuthClientProvider(\n this.ctx.storage,\n this.name,\n callbackUrl\n );\n }\n\n private broadcastMcpServers() {\n this._broadcastProtocol(\n JSON.stringify({\n mcp: this.getMcpServers(),\n type: MessageType.CF_AGENT_MCP_SERVERS\n })\n );\n }\n}\n\n// A set of classes that have been wrapped with agent context\nconst wrappedClasses = new Set<typeof Agent.prototype.constructor>();\n\n/**\n * Namespace for creating Agent instances\n * @template Agentic Type of the Agent class\n * @deprecated Use DurableObjectNamespace instead\n */\nexport type AgentNamespace<Agentic extends Agent<Cloudflare.Env>> =\n DurableObjectNamespace<Agentic>;\n\n/**\n * Agent's durable context\n */\nexport type AgentContext = DurableObjectState;\n\n// Email routing - deprecated resolver kept in root for upgrade discoverability\n// Other email utilities moved to agents/email subpath\nexport { createHeaderBasedEmailResolver } from \"./email\";\n\nimport type { EmailResolver } from \"./email\";\n\nexport type EmailRoutingOptions<Env> = AgentOptions<Env> & {\n resolver: EmailResolver<Env>;\n /**\n * Callback invoked when no routing information is found for an email.\n * Use this to reject the email or perform custom handling.\n * If not provided, a warning is logged and the email is dropped.\n */\n onNoRoute?: (email: ForwardableEmailMessage) => void | Promise<void>;\n};\n\n// RpcTarget bridge for email callbacks. Consolidates the email event's\n// mutation methods (setReject, forward, reply) into a single disposable\n// RPC target instead of anonymous closures. This allows the runtime to\n// tear down the bidirectional RPC session when _onEmail returns,\n// rather than keeping the DO pinned for the caller's entire context\n// lifetime (~100-120s for CF Email Routing handlers).\nclass EmailBridge extends RpcTarget {\n #email: ForwardableEmailMessage;\n\n constructor(email: ForwardableEmailMessage) {\n super();\n this.#email = email;\n }\n\n async getRaw(): Promise<Uint8Array> {\n const reader = this.#email.raw.getReader();\n const chunks: Uint8Array[] = [];\n let done = false;\n while (!done) {\n const { value, done: readerDone } = await reader.read();\n done = readerDone;\n if (value) {\n chunks.push(value);\n }\n }\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n return combined;\n }\n\n setReject(reason: string) {\n this.#email.setReject(reason);\n }\n\n forward(rcptTo: string, headers?: Headers): Promise<EmailSendResult> {\n return this.#email.forward(rcptTo, headers);\n }\n\n reply(options: {\n from: string;\n to: string;\n raw: string;\n }): Promise<EmailSendResult> {\n return this.#email.reply(\n new EmailMessage(options.from, options.to, options.raw)\n );\n }\n\n [Symbol.dispose]() {\n // Intentionally empty — the runtime calls this when the last\n // stub is disposed, signaling that the RPC target is no longer\n // needed and the bidirectional connection can be torn down.\n }\n}\n\n// Cache the agent namespace map for email routing\n// This maps original names, kebab-case, and lowercase versions to namespaces\nconst agentMapCache = new WeakMap<\n Record<string, unknown>,\n { map: Record<string, unknown>; originalNames: string[] }\n>();\n\n/**\n * Route an email to the appropriate Agent\n * @param email The email to route\n * @param env The environment containing the Agent bindings\n * @param options The options for routing the email\n * @returns A promise that resolves when the email has been routed\n */\nexport async function routeAgentEmail<\n Env extends Cloudflare.Env = Cloudflare.Env\n>(\n email: ForwardableEmailMessage,\n env: Env,\n options: EmailRoutingOptions<Env>\n): Promise<void> {\n const routingInfo = await options.resolver(email, env);\n\n if (!routingInfo) {\n if (options.onNoRoute) {\n await options.onNoRoute(email);\n } else {\n console.warn(\"No routing information found for email, dropping message\");\n }\n return;\n }\n\n // Build a map that includes original names, kebab-case, and lowercase versions\n if (!agentMapCache.has(env as Record<string, unknown>)) {\n const map: Record<string, unknown> = {};\n const originalNames: string[] = [];\n for (const [key, value] of Object.entries(env as Record<string, unknown>)) {\n if (\n value &&\n typeof value === \"object\" &&\n \"idFromName\" in value &&\n typeof value.idFromName === \"function\"\n ) {\n // Add the original name, kebab-case version, and lowercase version\n map[key] = value;\n map[camelCaseToKebabCase(key)] = value;\n map[key.toLowerCase()] = value;\n originalNames.push(key);\n }\n }\n agentMapCache.set(env as Record<string, unknown>, {\n map,\n originalNames\n });\n }\n\n const cached = agentMapCache.get(env as Record<string, unknown>)!;\n const namespace = cached.map[routingInfo.agentName];\n\n if (!namespace) {\n // Provide helpful error message listing available agents\n const availableAgents = cached.originalNames.join(\", \");\n throw new Error(\n `Agent namespace '${routingInfo.agentName}' not found in environment. Available agents: ${availableAgents}`\n );\n }\n\n const agent = await getAgentByName(\n namespace as unknown as DurableObjectNamespace<Agent<Env>>,\n routingInfo.agentId\n );\n\n // Use an RpcTarget bridge instead of bare closures so the runtime\n // can cleanly tear down the bidirectional session after _onEmail returns\n const bridge = new EmailBridge(email);\n\n await agent._onEmail({\n from: email.from,\n to: email.to,\n headers: email.headers,\n rawSize: email.rawSize,\n _secureRouted: routingInfo._secureRouted,\n _bridge: bridge\n });\n}\n\n/**\n * A wrapper for streaming responses in callable methods\n */\nexport class StreamingResponse {\n private _connection: Connection;\n private _id: string;\n private _closed = false;\n\n constructor(connection: Connection, id: string) {\n this._connection = connection;\n this._id = id;\n }\n\n private _send(response: RPCResponse): boolean {\n const facetSent = sendFacetStreamingResponse(this, response);\n if (facetSent !== null) return facetSent;\n return sendRpcResponseIfOpen(this._connection, response);\n }\n\n /**\n * Whether the stream has been closed (via end() or error())\n */\n get isClosed(): boolean {\n return this._closed;\n }\n\n /**\n * Send a chunk of data to the client\n * @param chunk The data to send\n * @returns false if stream is already closed (no-op), true if sent\n */\n send(chunk: unknown): boolean {\n if (this._closed) {\n console.warn(\n \"StreamingResponse.send() called after stream was closed - data not sent\"\n );\n return false;\n }\n const response: RPCResponse = {\n done: false,\n id: this._id,\n result: chunk,\n success: true,\n type: MessageType.RPC\n };\n return this._send(response);\n }\n\n /**\n * End the stream and send the final chunk (if any)\n * @param finalChunk Optional final chunk of data to send\n * @returns false if stream is already closed (no-op), true if sent\n */\n end(finalChunk?: unknown): boolean {\n if (this._closed) {\n return false;\n }\n this._closed = true;\n const response: RPCResponse = {\n done: true,\n id: this._id,\n result: finalChunk,\n success: true,\n type: MessageType.RPC\n };\n return this._send(response);\n }\n\n /**\n * Send an error to the client and close the stream\n * @param message Error message to send\n * @returns false if stream is already closed (no-op), true if sent\n */\n error(message: string): boolean {\n if (this._closed) {\n return false;\n }\n this._closed = true;\n const response: RPCResponse = {\n error: message,\n id: this._id,\n success: false,\n type: MessageType.RPC\n };\n return this._send(response);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,2BAA2B,OAAyB;CAClE,OACE,iBAAiB,aACjB,MAAM,QAAQ,SAAS,8BAA8B;AAEzD;AAeA,MAAa,8BACX,IAAI,kBAAyD;AAE/D,SAAgB,2BACd,QACA,UAC0B;CAC1B,IAAI;EAQF,OAAO;GAAE,MAAM;GAAM,YAPF,QAAQ,QACzB,OAAO,KAAK,KAAK,UAAU,QAAQ,CAAC,CACtC,CAAC,CAAC,OAAO,UAAmB;IAC1B,IAAI,CAAC,2BAA2B,KAAK,GACnC,QAAQ,MAAM,+CAA+C,KAAK;GAEtE,CAC8B;EAAE;CAClC,SAAS,OAAO;EACd,IAAI,2BAA2B,KAAK,GAClC,OAAO;GAAE,MAAM;GAAO,YAAY,QAAQ,QAAQ;EAAE;EAEtD,MAAM;CACR;AACF;AAOA,MAAM,uDAAuC,IAAI,QAG/C;;;;;;AAOF,SAAgB,+BACd,QACA,aACM;CACN,qCAAqC,IAAI,QAAQ;EAC/C;EACA,yBAAS,IAAI,IAAI;CACnB,CAAC;AACH;;;;;;AAOA,SAAgB,2BACd,QACA,UACgB;CAChB,MAAM,QAAQ,qCAAqC,IAAI,MAAM;CAC7D,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,WAAW,2BAA2B,MAAM,aAAa,QAAQ;CACvE,MAAM,QAAQ,IAAI,SAAS,UAAU;CACrC,SAAc,WAAW,cACvB,MAAM,QAAQ,OAAO,SAAS,UAAU,CAC1C;CACA,OAAO,SAAS;AAClB;AAEA,eAAsB,wCACpB,QACe;CACf,MAAM,QAAQ,qCAAqC,IAAI,MAAM;CAC7D,IAAI,CAAC,OAAO;CAEZ,IAAI;EACF,MAAM,QAAQ,IAAI,MAAM,OAAO;CACjC,UAAU;EACR,qCAAqC,OAAO,MAAM;CACpD;AACF;;;;;;;;AAOA,IAAa,+BAAb,cACU,UAEV;CAQE,YACE,YACA,WAKA;EACA,MAAM;;;EACN,uBAAA,aAAA,MAAmB,UAAA;EACnB,uBAAA,YAAA,MAAkB,SAAA;CACpB;CAEA,KAAK,SAAuD;EAC1D,uBAAA,aAAA,IAAA,CAAA,CAAiB,KAAK,OAAO;CAC/B;CAEA,MAAM,MAAe,QAAuB;EAC1C,uBAAA,aAAA,IAAA,CAAA,CAAiB,MAAM,MAAM,MAAM;CACrC;CAEA,SAAS,OAAyB;EAChC,OAAA,uBAAA,aAAO,IAAA,CAAA,CAAiB,SAAS,KAAK;CACxC;CAEA,UACE,WACA,SACA,SACsB;EACtB,OAAA,uBAAA,YAAO,IAAA,CAAA,EAAA,KAAA,MAAkB,WAAW,SAAS,OAAO;CACtD;AACF;;;;;;;AAMA,IAAa,mCAAb,MAA0F;CAIxF,YAAY,MAA2B,cAAsB;;;EAC3D,uBAAA,OAAA,MAAa,IAAA;EACb,uBAAA,eAAA,MAAqB,YAAA;CACvB;CAEA,KAAK,SAAgE;EACnE,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,6BAAA,uBAAA,eAA6B,IAAA,GAAoB,OAAO;CAC5E;CAEA,MAAM,MAAe,QAAgC;EACnD,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,4BAAA,uBAAA,eAChB,IAAA,GACA,MACA,MACF;CACF;CAEA,SAAS,OAAkC;EACzC,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,+BAAA,uBAAA,eAA+B,IAAA,GAAoB,KAAK;CAC5E;CAEA,UACE,WACA,SACA,SACe;EACf,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,wBAAwB,WAAW,SAAS,OAAO;CACvE;AACF;;;ACvMA,MAAa,oCAAoC;AACjD,MAAa,qCAAqC;AAClD,MAAa,oCAAoC;AAMjD,eAAsB,UAAU,OAAgC;CAC9D,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;CAC5C,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;CAC1D,OAAO,CAAC,GAAG,IAAI,WAAW,MAAM,CAAC,CAAC,CAC/B,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CACjD,KAAK,EAAE;AACZ;AAEA,SAAgB,mBACd,aACA,QACQ;CACR,OAAO,GAAG,oCAAoC,mBAAmB,WAAW,EAAE,GAAG;AACnF;AAEA,SAAgB,8BACd,cACe;CACf,IAAI,CAAC,aAAa,WAAA,eAA4C,GAC5D,OAAO;CAET,MAAM,OAAO,aAAa,MAAM,EAAwC;CACxE,MAAM,YAAY,KAAK,YAAY,GAAG;CACtC,IAAI,cAAc,IAAI,OAAO;CAE7B,IAAI;EACF,OAAO,mBAAmB,KAAK,MAAM,GAAG,SAAS,CAAC;CACpD,QAAQ;EACN,OAAO;CACT;AACF;;;;;AAMA,SAAgB,kBACd,OACqD;CACrD,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;CAClC,OAAO,MAAM,OACV,UACC,SAAS,QACT,OAAO,UAAU,YACjB,OAAQ,MAAkC,cAAc,YACxD,OAAQ,MAA6B,SAAS,QAClD;AACF;AAEA,SAAgB,aACd,MACe;CACf,IAAI,CAAC,MAAM,OAAO;CAClB,OAAO,KACJ,KACE,SACC,GAAG,mBAAmB,KAAK,SAAS,EAAE,GAAG,mBAAmB,KAAK,IAAI,GACzE,CAAC,CACA,KAAK,GAAG;AACb;;;;;;;;;;;;;;AC5CA,IAAa,uBAAb,MAAkC;CAIhC,YAAY,MAAmC;;;2CAFtC,KAAA;EAGP,uBAAA,SAAA,MAAa,IAAA;CACf;CAaA,SAAe;EACb,IAAA,uBAAA,QAAI,IAAA,GAAa;EAIjB,uBAAA,SAAA,IAAA,CAAA,CAAW,GAAG;;;;;;;;;;EAUd,kBAAA,6BAAA,MAAA,qBAAA,CAAA,CAAA,KAAA,MACE,mEACF;EACA,kBAAA,6BAAA,MAAA,qBAAA,CAAA,CAAA,KAAA,MACE,gEACF;EACA,uBAAA,QAAA,MAAc,IAAA;CAChB;CAEA,OACE,WACA,MACA,UACM;EACN,KAAK,OAAO;EACZ,uBAAA,SAAA,IAAA,CAAA,CAAW,GAAG;;;;WAIP,UAAU,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,SAAS,QAAQ,IAAI,SAAS,KAAK;;CAElF;CAEA,IACE,WACA,MAIO;EACP,KAAK,OAAO;EAUZ,OAAO,uBAAA,SATM,IAAA,CAAA,CAAW,GAGtB;;;sBAGgB,UAAU,cAAc,KAAK;;MAGnC,MAAM;CACpB;CAEA,MAAM,SACJ,WACA,MACA,WAKC;EACD,MAAM,MAAM,KAAK,IAAI,WAAW,IAAI;EACpC,IAAI,KAAK;GACP,IACE,IAAI,qBAAA,aACJ,OAAO,IAAI,kBAAkB,UAE7B,OAAO;IACL,SAAS;IACT,MAAM,IAAI;IACV,UAAU;GACZ;GAEF,OAAO;IACL,SAAS;IACT;IACA,UAAU;GACZ;EACF;EAOA,OAAO;GACL,SAAS;GACT,MAAM,mBAAmB,MAAM,MAHZ,UAAU,KAAK,UAAU,SAAS,CAAC,CAGjB;GACrC,UAAU;EACZ;CACF;CAEA,OAAO,WAAmB,MAAoB;EAC5C,KAAK,OAAO;EACZ,uBAAA,SAAA,IAAA,CAAA,CAAW,GAAG;;sBAEI,UAAU,cAAc,KAAK;;CAEjD;CAEA,IAAI,WAAmB,MAAuB;EAC5C,KAAK,OAAO;EAKZ,QAAQ,uBAAA,SAJK,IAAA,CAAA,CAAW,GAAkB;;sBAExB,UAAU,cAAc,KAAK;MAElC,EAAE,EAAE,KAAK,KAAK;CAC7B;CAEA,KACE,WAC+D;EAC/D,KAAK,OAAO;EAWZ,QAVa,YACT,uBAAA,SAAA,IAAA,CAAA,CAAW,GAAwD;;0BAEjD,UAAU;;YAG5B,uBAAA,SAAA,IAAA,CAAA,CAAW,GAAwD;;;WAI3D,KAAK,OAAO;GACtB,WAAW,EAAE;GACb,MAAM,EAAE;GACR,WAAW,EAAE;EACf,EAAE;CACJ;AACF;AAlJE,SAAA,sBAAsB,KAAmB;CACvC,IAAI;EACF,uBAAA,SAAA,IAAA,CAAA,CAAW,WAAW,GAAG;CAC3B,SAAS,GAAG;EAEV,IAAI,EADY,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAA,CAC5C,YAAY,CAAC,CAAC,SAAS,kBAAkB,GACpD,MAAM;CAEV;AACF;;;;;;;;;;;;ACGF,MAAa,6BAA6B;AAC1C,MAAa,wBAAwB;;AAGrC,MAAa,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwB1C,IAAa,wBAAb,cAA2C,oBAAoB;CA6B7D,YAAY,MAA4B;EACtC,MAAM,gBAAgB;;;0EAnBA,IAAI,IAAY,CAAA;mDAGvB,IAAI,kBAAuD,CAAA;wEAOtD,IAAI,IAA0C,CAAA;8EAGxC,IAAI,IAA2B,CAAA;;EAOzD,uBAAA,OAAA,MAAa,IAAA;EACb,KAAK,WAAW,IAAI,qBAAqB;GACvC,KAAK,KAAK,IAAI,KAAK,IAAI;GACvB,aAAa,QAAQ,KAAK,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG;EACzD,CAAC;CACH;CAEA,iBACE,WACsB;EAKtB,OAAO,uBAAA,OAJM,IAAA,CAAA,CAAW,GAAuB;;;MAInC,QAAQ,QAAQ;GAC1B,IAAI;IACF,MAAM,eAAe,KAAK,MAAM,IAAI,UAAU;IAC9C,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,uBAAuB,WAAW,YAAY;GAClE,QAAQ;IACN,OAAO;GACT;EACF,CAAC;CACH;CAEA,uBAAuB,WAA+C;EACpE,KAAK,MAAM,OAAO,KAAK,iBAAiB,SAAS,GAC/C,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAG;;iCAEa,IAAI,eAAe;yBAC3B,IAAI,OAAO;;CAGlC;CAEA,wBAA2D;EACzD,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,UAAU,OAAO,KAAA;EACjC,MAAM,MAAM,aAAA,uBAAA,OAAa,IAAA,CAAA,CAAW,QAAQ;EAC5C,OAAO,MAAM;GAAE;GAAK,MAAM,KAAK,UAAA,uBAAA,OAAU,IAAA,CAAA,CAAW,QAAQ;EAAE,IAAI,KAAA;CACpE;CAEA,MAAM,qBACJ,UACkB;EAClB,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,UAAU,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,UAAU,MAAM,QAAQ;EACpE,QAAQ,MAAM,KAAK,eAAe,EAAA,CAAG,mBACnC,KAAA,GACA,QACF;CACF;CAEA,MAAM,uBACJ,QACA,UACkB;EAClB,IAAI;EACJ,IAAI;GACF,aAAa,KAAK,MAAM,OAAO,IAAI;EACrC,QAAQ;GACN,MAAM,IAAI,MAAM,kDAAkD;EACpE;EAEA,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW;EAC5B,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,uBAAuB,UAAU,UAAU,GACzD,MAAM,IAAI,MACR,yCAAyC,KAAK,UAAU,QAAQ,EAAE,EACpE;EAEF,IAAI,SAAS,WAAW,WAAW,QACjC,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,UAAU,MAAM,QAAQ;EAG5C,MAAM,OAAO,WAAW,SAAS;EACjC,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,YAAY,KAAK,WAAW,KAAK,IAAI,GAAG;GACtD,MAAM,YAAY,WAAW,MAAM,GAAG,SAAS,SAAS,CAAC;GACzD,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,UACb,OAAO,MAAM,KAAK,eAAe,EAAA,CAAG,uBAAuB,SAAS;QAEpE,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,uBAAuB,SAAS;GAEnD,OAAO;EACT;EAMA,QACE,MAAA,uBAAA,OALkB,IAAA,CAAA,CAAW,oBAC7B,KAAK,WACL,KAAK,IACP,EAAA,CAQE,mBAAmB,QAAQ,QAAQ;CACvC;;CAGA,eACE,QACA,UACkB;EAClB,OAAO,SACH,KAAK,uBAAuB,QAAQ,QAAQ,IAAA,uBAAA,OAC5C,IAAA,CAAA,CAAW,UAAU,MAAM,QAAQ;CACzC;CAEA,MAAM,iBAA+C;EACnD,MAAM,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,YAAY;EACpC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,uCAAuC;EAIzD,MAAM,UAAA,uBAAA,OADM,IAAA,CAAA,CAAW,IACH,UAAU,KAAK;EAGnC,IAAI,CAAC,SACH,MAAM,IAAI,MACR,2BAA2B,KAAK,UAAU,qBAC5C;EAGF,OAAQ,MAAM,eACZ,SACA,KAAK,IACP;CACF;CAEA,qBAA8B;EAC5B,MAAM,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,YAAY;EACpC,IAAI,CAAC,MAAM,OAAO;EAGlB,MAAM,UAAA,uBAAA,OADM,IAAA,CAAA,CAAW,IACH,UAAU,KAAK;EAGnC,IAAI,CAAC,SAAS,YAAY,OAAO;EAEjC,OAAO,QAAQ,WAAW,KAAK,IAAI,CAAC,CAAC,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,IAAI,EAAE;CAC/D;;;;;;CAOA,MAAM,cAAc,WAAwD;EAC1E,MAAM,SAAS,aAAa,SAAS;EACrC,IAAI,QAAQ;GACV,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,UAAU,4CACzB,MACF;GACA,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,MAAM,4CACrB,MACF;EACF;EACA,KAAK,uBAAuB,SAAS;EACrC,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,cAAc;CACjC;;;;CAKA,MAAM,iBACJ,WACiB;EAEjB,MAAM,QAAQ,GADO,aAAa,SACN,KAAK,UAAU,GAAG,OAAO,CAAC;EACtD,uBAAA,uBAAA,IAAA,CAAA,CAA2B,IAAI,KAAK;EACpC,uBAAA,OAAA,IAAA,CAAA,CAAW;EACX,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,mBAAmB,GAChC,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,cAAc;EAEjC,OAAO;CACT;;;;;CAMA,MAAM,iBAAiB,OAA8B;EACnD,IAAI,CAAA,uBAAA,uBAAC,IAAA,CAAA,CAA2B,OAAO,KAAK,GAAG;EAC/C,uBAAA,OAAA,IAAA,CAAA,CAAW,iBAAiB,KAAK,IAAI,GAAA,uBAAA,OAAG,IAAA,CAAA,CAAW,iBAAiB,CAAC;EACrE,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,cAAc;CACjC;;;;;CAMA,MAAM,YACJ,WACA,OACe;EACf,MAAM,gBAAgB,KAAK,UAAU,SAAS;EAC9C,MAAM,eAAe,aAAa,SAAS;EAC3C,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,uDAAuD;EAEzE,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAG;;;;WAIP,cAAc,IAAI,aAAa,IAAI,MAAM,IAAI,KAAK,IAAI,EAAE;;EAE/D,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,cAAc;CACjC;;;;;;CAOA,MAAM,iBAAgC;EAEpC,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,YAAY,SAAS,GAAG;EAEvC,MAAM,OAAO,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAuB;;;;;EAK/C,MAAM,kCAAkB,IAAI,IAAgC;EAC5D,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,gBAAgB,IAAI,IAAI,cAAc,GACzC,gBAAgB,IAAI,IAAI,gBAAgB,GAAG;EAI/C,KAAK,MAAM,OAAO,gBAAgB,OAAO,GAAG;GAC1C,IAAI;GACJ,IAAI;IACF,YAAY,KAAK,MAAM,IAAI,UAAU;GACvC,SAAS,GAAG;IACV,QAAQ,KACN,gDAAgD,IAAI,eAAe,yBACnE,CACF;IACA,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAG;;mCAEa,IAAI,eAAe;;IAE9C;GACF;GAEA,IAAI;IAKF,IAAI,MAAA,uBAAA,OADI,IAAA,CAAA,CAAW,2BAA2B,SAAS,MACrC,GAChB,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAG;;qCAEa,IAAI,eAAe;;GAGlD,SAAS,GAAG;IAGV,QAAQ,MACN,iDAAiD,IAAI,eAAe,IACpE,CACF;GACF;EACF;CACF;;;;;;CAOA,MAAM,qBACJ,WACiB;EACjB,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW;EAC5B,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,uBAAuB,UAAU,SAAS,GACxD,MAAM,IAAI,MACR,gDAAgD,KAAK,UAAU,QAAQ,EAAE,EAC3E;EAGF,IAAI,SAAS,WAAW,UAAU,QAAQ;GACxC,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,gBAAgB;GAIjC,OAAO,uBAAA,OAHM,IAAA,CAAA,CAAW,GAAsB;;QAGlC,EAAE,EAAE,SAAS;EAC3B;EAEA,MAAM,OAAO,UAAU,SAAS;EAChC,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,YAAY,KAAK,WAAW,KAAK,IAAI,GAInD,OAAO;EAST,QAAO,MANY,KAAK,QAAQ,KAAK,WAAW,KAAK,IAAI,EAAA,CAM3C,2BAA2B,SAAS;CACpD;;;;;;;CAQA,MAAM,gBACJ,YACA,QACA,MACkB;EAClB,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,2BAA2B;EAE5C,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW;EAC5B,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,uBAAuB,UAAU,UAAU,GACzD,MAAM,IAAI,MACR,8CAA8C,KAAK,UAAU,QAAQ,EAAE,EACzE;EAGF,IAAI,SAAS,WAAW,WAAW,QAAQ;GASzC,MAAM,KAAA,uBAAA,OADS,IACC,CAAC,CAAC;GAClB,IACE,qBAAqB,MAAM,KAC3B,UAAU,OAAO,aACjB,OAAO,OAAO,YAEd,MAAM,IAAI,MACR,2BAA2B,OAAO,uBAAA,uBAAA,OAC/B,IAAA,CAAA,CACE,YAAY,KAChB,EACH;GAEF,OAAO,MAAO,GAA6C,MAAA,uBAAA,OACzD,IAAA,GACA,IACF;EACF;EAEA,MAAM,OAAO,WAAW,SAAS;EACjC,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,YAAY,KAAK,WAAW,KAAK,IAAI,GACnD,MAAM,IAAI,MACR,6BAA6B,KAAK,UAAU,IAAI,KAAK,KAAK,oBAC5D;EAWF,OAAO,OAAM,MARM,KAAK,QAAQ,KAAK,WAAW,KAAK,IAAI,EAAA,CAQrC,oBAAoB,YAAY,QAAQ,IAAI;CAClE;;;;;;;;CASA,MAAM,kBACJ,YACe;EACf,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW;EAE5B,IAAI,WAAW,WAAW,GACxB,MAAM,IAAI,MACR,4DACF;EAEF,IAAI,SAAS,UAAU,WAAW,QAChC,MAAM,IAAI,MACR,iEACF;EAEF,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,uBAAuB,UAAU,UAAU,GACzD,MAAM,IAAI,MACR,2EACF;EAMF,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,YAAY,WAAW,GACpC,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,uBAAuB,UAAU;EAGpD,IAAI,SAAS,WAAW,WAAW,SAAS,GAAG;GAG7C,MAAM,SAAS,WAAW,WAAW,SAAS;GAC9C,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;GACvB,IAAI,CAAC,IAAI,QACP,MAAM,IAAI,MACR,oKAGF;GAEF,IAAI;IACF,IAAI,OAAO,OAAO,GAAG,OAAO,UAAU,IAAI,OAAO,MAAM;GACzD,QAAQ,CAER;GACA,KAAK,SAAS,OAAO,OAAO,WAAW,OAAO,IAAI;GAClD;EACF;EAGA,MAAM,OAAO,WAAW,SAAS;EACjC,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,YAAY,KAAK,WAAW,KAAK,IAAI,GAEnD;EAQF,OAAM,MANa,KAAK,QAAQ,KAAK,WAAW,KAAK,IAAI,EAAA,CAM5C,2BAA2B,UAAU;CACpD;;;;;;;;CASA,MAAM,QAAQ,WAAmB,MAAgC;EAC/D,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;EACvB,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,SACtB,MAAM,IAAI,MACR,+JAGF;EAEF,IAAI,qBAAqB,SAAS,MAAA,OAKhC,MAAM,IAAI,MACR,yBAAyB,UAAU,0HAGrC;EAEF,MAAM,MAAM,IAAI,QAAQ;EACxB,IAAI,CAAC,KACH,MAAM,IAAI,MACR,oBAAoB,UAAU,6IAGhC;EAEF,IAAI,KAAK,SAAS,IAAI,GAGpB,MAAM,IAAI,MACR,kEACF;EAIF,MAAM,WAAW,GAAG,UAAU,IAAI;EAKlC,MAAM,kBAAA,uBAAA,OAAkB,IAAA,CAAA,CAAW;EACnC,MAAM,YAAY,CAAC,GAAG,iBAAiB;GAAE;GAAW;EAAK,CAAC;EAM1D,MAAM,gBAAA,uBAAA,OACJ,IAAA,CAAA,CAAW,YAAY,EAAE,EAAE,aAAA,uBAAA,OAC1B,IAAA,CAAA,CAA4D,YAC1D;EACL,MAAM,SAAS,IAAI,QAAQ;EAC3B,IAAI,CAAC,QAAQ,YAAY;GAcvB,MAAM,mBADgB,yBAAyB,KAAK,aACf,IACjC,oBAAoB,cAAc,yGAClC;GACJ,MAAM,IAAI,MACR,sDAAsD,cAAc,oEAAoE,cAAc,6CAA6C,iBAAiB,kIACtN;EACF;EACA,MAAM,WAAW,MAAM,KAAK,SAAS,SAAS,WAAW,MAAM,SAAS;EACxE,MAAM,UAAU,OAAO,WAAW,SAAS,IAAI;EAC/C,MAAM,OAAO,IAAI,OAAO,IAAI,iBAAiB;GAC3C,OAAO;GACP,IAAI;EACN,EAAE;EAUF,KAAK,SAAS,OAAO,WAAW,MAAM,QAAQ;EAU9C,IAAI;GACF,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,wBAAwB,YAAY;IACnD,MACE,KAOA,gBAAgB,MAAM,iBAAiB,SAAS,IAAI;GACxD,CAAC;EACH,SAAS,OAAO;GACd,IAAI,CAAC,SAAS,UACZ,KAAK,SAAS,OAAO,WAAW,IAAI;GAEtC,MAAM;EACR;EAEA,OAAO;CACT;;;;;CAMA,MAAM,WAAmB,MAAc,QAAwB;EAC7D,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;EACvB,IAAI,CAAC,IAAI,QACP,MAAM,IAAI,MACR,2IAGF;EAEF,MAAM,WAAW,GAAG,UAAU,IAAI;EAClC,IAAI,OAAO,MAAM,UAAU,MAAM;CACnC;;;;;CAMA,MAAM,OAAO,WAAmB,MAA6B;EAC3D,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;EACvB,IAAI,CAAC,IAAI,QACP,MAAM,IAAI,MACR,4IAGF;EAEF,MAAM,WAAW,GAAG,UAAU,IAAI;EAClC,MAAM,YAAY,CAAC,GAAA,uBAAA,OAAG,IAAA,CAAA,CAAW,UAAU;GAAE;GAAW;EAAK,CAAC;EAC9D,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,UAEb,OAAM,MADa,KAAK,eAAe,EAAA,CAC5B,uBAAuB,SAAS;OAE3C,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,uBAAuB,SAAS;EAQnD,IAAI;GACF,IAAI,OAAO,OAAO,QAAQ;EAC5B,QAAQ,CAER;EACA,KAAK,SAAS,OAAO,WAAW,IAAI;CACtC;;CAKA,0BAAgC;EAC9B,uBAAA,qBAAA,IAAA,CAAA,CAAyB,MAAM;CACjC;;CAGA,qBAAqB,IAAoC;EACvD,MAAM,SAAA,uBAAA,qBAAS,IAAA,CAAA,CAAyB,IAAI,EAAE;EAC9C,IAAI,CAAC,QAAQ,OAAO,KAAA;EACpB,OAAO,KAAK,uBAAuB,OAAO,IAAI;CAChD;;CAGA,CAAC,sBAAsB,KAAoC;EACzD,KAAK,MAAM,UAAA,uBAAA,qBAAU,IAAA,CAAA,CAAyB,OAAO,GACnD,IAAI,CAAC,OAAO,OAAO,KAAK,KAAK,SAAS,GAAG,GACvC,MAAM,KAAK,uBAAuB,OAAO,IAAI;CAGnD;CAEA,aACE,cAC8C;EAC9C,MAAM,UAAA,uBAAA,gBAAU,IAAA,CAAA,CAAoB,SAAS;EAC7C,IAAI,iBAAiB,KAAA,KAAa,SAAS,iBAAiB,cAC1D;EAEF,OAAO,SAAS;CAClB;;;;;;;CAQA,yBACE,cACA,eACA,WACM;EACN,MAAM,eAAe,KAAK,aAAa,YAAY;EACnD,MAAM,8BAAA,uBAAA,2BACJ,IAAA,CAAA,CAA+B,IAAI,YAAY;EACjD,IAAI;EACJ,IAAI,gBAAgB,CAAC,6BACnB,IAAI;GACF,UAAU,QAAQ,QAAQ,UAAU,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;EAClE,SAAS,OAAO;GACd,UAAU,QAAQ,OAAO,KAAK;EAChC;OAEA,WAAW,+BAA+B,QAAQ,QAAQ,EAAA,CAAG,KAC3D,YAAY;GAEV,MAAM,UACJ,IAAI,iCAAiC,MAFpB,KAAK,eAAe,GAEM,YAAY,CACzD;EACF,CACF;EAEF,MAAM,aAAa,QAAQ,OAAO,UAAmB;GACnD,kBAAA,8BAAA,MAAA,iCAAA,CAAA,CAAA,KAAA,MACE,cACA,eACA,KACF;EACF,CAAC;EAED,uBAAA,2BAAA,IAAA,CAAA,CAA+B,IAAI,cAAc,UAAU;EAC3D,uBAAA,OAAA,IAAA,CAAA,CAAW,IAAI,UAAU,UAAU;EACnC,WAAgB,WAAW;GACzB,IAAA,uBAAA,2BAAI,IAAA,CAAA,CAA+B,IAAI,YAAY,MAAM,YACvD,uBAAA,2BAAA,IAAA,CAAA,CAA+B,OAAO,YAAY;EAEtD,CAAC;CACH;;;;;;;;;CAUA,MAAM,eACJ,WACA,SACA,SACA,gBACe;EACf,MAAM,eAAe,kBAAkB,KAAK,aAAa;EACzD,MAAM,qCAAqB,IAAI,IAAI,CACjC,GAAA,uBAAA,yBAAI,IAAA,IAA+B,CAAA,uBAAA,yBAAC,IAAA,CAA4B,IAAI,CAAC,GACrE,GAAA,uBAAA,2BAAG,IAAA,CAAA,CAA+B,OAAO,CAC3C,CAAC;EACD,IAAI;EACJ,IAAI,gBAAgB,mBAAmB,SAAS,GAC9C,IAAI;GACF,UAAU,QAAQ,QAChB,aAAa,UAAU,WAAW,SAAS,OAAO,CACpD;EACF,SAAS,OAAO;GACd,UAAU,QAAQ,OAAO,KAAK;EAChC;OAEA,UAAU,QAAQ,IAAI,kBAAkB,CAAC,CAAC,KAAK,YAAY;GAEzD,OAAM,MADa,KAAK,eAAe,EAAA,CAC5B,wBAAwB,WAAW,SAAS,OAAO;EAChE,CAAC;EAEH,MAAM,aAAa,QAAQ,OAAO,UAAmB;GACnD,QAAQ,MAAM,iDAAiD;IAC7D,WAAW;IACX;GACF,CAAC;EACH,CAAC;EAED,uBAAA,yBAAA,MAA+B,UAAA;EAC/B,uBAAA,OAAA,IAAA,CAAA,CAAW,IAAI,UAAU,UAAU;EACnC,WAAgB,WAAW;GACzB,IAAA,uBAAA,yBAAI,IAAA,MAAiC,YACnC,uBAAA,yBAAA,MAA+B,KAAA,CAAA;EAEnC,CAAC;EACD,MAAM;CACR;CAcA,MAAM,kBACJ,SACA,SACe;EACf,MAAM,KAAK,eAAA,uBAAA,OAAe,IAAA,CAAA,CAAW,UAAU,SAAS,OAAO;CACjE;CAEA,MAAM,gBACJ,WACA,SACA,SACe;EACf,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,UAAU;GACvB,MAAM,KAAK,eAAe,WAAW,SAAS,OAAO;GACrD;EACF;EAEA,KAAK,MAAM,cAAA,uBAAA,OAAc,IAAA,CAAA,CAAW,YAAY,eAAe,GAAG;GAChE,IAAI,SAAS,SAAS,WAAW,EAAE,GAAG;GACtC,MAAM,aAAa,KAAK,qBAAqB,UAAU;GACvD,IAAI,CAAC,YAAY;GACjB,IAAI,CAAC,KAAK,gBAAgB,YAAY,SAAS,GAAG;GAClD,WAAW,KAAK,OAAO;EACzB;CACF;CAEA,MAAM,gBACJ,WACuC;EACvC,MAAM,QAAsC,CAAC;EAC7C,KAAK,MAAM,cAAA,uBAAA,OAAc,IAAA,CAAA,CAAW,YAAY,eAAe,GAAG;GAChE,MAAM,OAAA,kBAAA,8BAAO,MAAA,sBAAA,CAAA,CAAA,KAAA,MAA4B,YAAY,SAAS;GAC9D,IAAI,MAAM,MAAM,KAAK,IAAI;EAC3B;EACA,OAAO;CACT;CAEA,MAAM,iBACJ,cACA,SACe;EACf,MAAM,aAAA,uBAAA,OAAa,IAAA,CAAA,CAAW,YAAY,cAAc,YAAY;EACpE,IAAI,CAAC,cAAc,CAAC,KAAK,yBAAyB,UAAU,GAC1D;EAEF,WAAW,KAAK,OAAO;CACzB;CAEA,MAAM,gBACJ,cACA,MACA,QACe;EACf,MAAM,aAAA,uBAAA,OAAa,IAAA,CAAA,CAAW,YAAY,cAAc,YAAY;EACpE,IAAI,CAAC,cAAc,CAAC,KAAK,yBAAyB,UAAU,GAC1D;EAEF,WAAW,MAAM,MAAM,MAAM;CAC/B;CAEA,MAAM,mBACJ,cACA,OACkB;EAClB,MAAM,aAAA,uBAAA,OAAa,IAAA,CAAA,CAAW,YAAY,cAAc,YAAY;EACpE,IAAI,CAAC,cAAc,CAAC,KAAK,yBAAyB,UAAU,GAC1D,OAAO;EAET,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;EAC9C,WAAW,SAAS,KAAK;EACzB,OAAO,KAAK,kBAAkB,UAAU;CAC1C;CAgCA,qBACE,YACqC;EACrC,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;EAC9C,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW,0BAC1B,YACA,0BACF;EACA,IAAI,OAAO,aAAa,UAAU,OAAO;EAEzC,OAAA,kBAAA,8BAAO,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAuB,QAAQ,CAAC,EAAE,QAAQ;CACnD;CA4BA,gBACE,GACA,GACS;EACT,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;EAClC,OAAO,EAAE,OACN,MAAM,UACL,KAAK,cAAc,EAAE,MAAM,EAAE,aAAa,KAAK,SAAS,EAAE,MAAM,EAAE,IACtE;CACF;CAEA,yBAAyB,YAAiC;EACxD,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;EAC9C,OACE,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,0BAChB,YACA,0BACF,MAAM;CAEV;CAEA,uBAAuB,YAAiC;EACtD,IAAI,CAAC,WAAW,KAAK,OAAO;EAC5B,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;EACvB,OACE,kBAAkB,WAAW,KAAK,EAChC,cAAc,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA,EACzD,CAAC,MAAM;CAEX;CAEA,oBAAoB,SAA2B;EAC7C,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;EACvB,OACE,kBAAkB,QAAQ,KAAK,EAC7B,cAAc,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA,EACzD,CAAC,MAAM;CAEX;CAEA,MAAM,wBACJ,YACA,SACA,SACkB;EAClB,MAAM,SAAS,MAAA,kBAAA,8BAAM,MAAA,kBAAA,CAAA,CAAA,KAAA,MAAwB,YAAY,SAAS,OAAO;EACzE,IAAI,CAAC,QAAQ,OAAO;EAEpB,MAAM,OAAO,MAAM,mCAAA,kBAAA,8BACjB,MAAA,uBAAA,CAAA,CAAA,KAAA,MAA6B,UAAU,GACvC,OAAO,IACT;EACA,OAAO;CACT;CA6BA,MAAM,wBACJ,YACA,SACA,aACkB;EAClB,MAAM,SAAS,MAAA,kBAAA,8BAAM,MAAA,kBAAA,CAAA,CAAA,KAAA,MAAwB,UAAU;EACvD,IAAI,CAAC,QAAQ,OAAO;EAEpB,MAAM,SAAA,kBAAA,8BAAS,MAAA,uBAAA,CAAA,CAAA,KAAA,MAA6B,UAAU;EACtD,MAAM,OAAO,MAAM,mCACjB,SACA,QACA,OAAO,MACP,eAAe,MACjB;EACA,OAAO;CACT;CAEA,MAAM,sBACJ,YACA,MACA,QACA,UACkB;EAClB,MAAM,SAAS,MAAA,kBAAA,8BAAM,MAAA,kBAAA,CAAA,CAAA,KAAA,MAAwB,UAAU;EACvD,IAAI,CAAC,QAAQ,OAAO;EAEpB,MAAM,OAAO,MAAM,iCACjB,MACA,QACA,UAAA,kBAAA,8BACA,MAAA,uBAAA,CAAA,CAAA,KAAA,MAA6B,UAAU,GACvC,OAAO,IACT;EACA,OAAO;CACT;CA4EA,MAAM,uBACJ,QACA,MACe;EACf,MAAM,KAAK,cAAc,QAAQ,KAAK,IAAI,YAAY;GACpD,MAAM,aAAa,KAAK,uBAAuB,IAAI;GACnD,MAAM,UAAU,IAAI,QAAQ,KAAK,OAAO,uBAAuB,EAC7D,SAAS,KAAK,eAChB,CAAC;GACD,IACE,MAAM,KAAK,wBAAwB,YAAY,SAAS,EACtD,MAAM,KACR,CAAC,GAED;GAGF,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,2BAA2B,YAAY,EAAE,QAAQ,CAAC,GAC/D,uBAAA,OAAA,IAAA,CAAA,CAAW,sBAAsB,YAAY,IAAI;GAEnD,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,2BAA2B,YAAY,EAAE,QAAQ,CAAC,GAChE,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;GAGhD,MAAM,YAAY,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,kBAAkB,YAAY,EAC/D,QACF,CAAC;GACD,WAA8C,OAAO,CACnD,WAAW,IACX,GAAG,UAAU,QAAQ,QAAQ,QAAQ,WAAW,EAAE,CACpD;GACA,KAAK,uBAAuB,UAAU;GACtC,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,UAAU,YAAY,EAAE,QAAQ,CAAC;GAClD,KAAK,uBAAuB,UAAU;GAGtC,MAAA,uBAAA,2BAAM,IAAA,CAAA,CAA+B,IAAI,KAAK,EAAE;EAClD,CAAC;CACH;CAEA,MAAM,uBACJ,SACA,QACA,MACA,cAA4C,QAC7B;EACf,MAAM,aAAa,KAAK,uBAAuB,IAAI;EACnD,KAAK,uBAAuB,UAAU;EACtC,MAAM,eAAsD,EAC1D,QAAQ,YACV;EACA,IAAI;GACF,MAAM,4BAA4B,IAAI,oBACpC,KAAK,cAAc,QAAQ,KAAK,UAAA,uBAAA,OAC9B,IAAA,CAAA,CAAW,UAAU,YAAY,OAAO,CAC1C,CACF;EACF,UAAU;GACR,aAAa,SAAS,KAAA;EACxB;CACF;CAEA,MAAM,qBACJ,MACA,QACA,UACA,QACA,MACe;EACf,MAAM,aAAa,KAAK,uBAAuB,IAAI;EACnD,KAAK,uBAAuB,UAAU;EACtC,MAAM,KAAK,cAAc,QAAQ,KAAK,UAAA,uBAAA,OACpC,IAAA,CAAA,CAAW,QAAQ,YAAY,MAAM,QAAQ,QAAQ,CACvD;EACA,uBAAA,qBAAA,IAAA,CAAA,CAAyB,OAAO,KAAK,EAAE;CACzC;CAEA,MAAM,cACJ,QACA,cACA,IACY;EACZ,MAAM,UAA+C;GACnD;GACA;EACF;EACA,IAAI;GACF,OAAO,MAAA,uBAAA,gBAAM,IAAA,CAAA,CAAoB,IAAI,SAAS,EAAE;EAClD,UAAU;GAGR,QAAQ,SAAS,KAAA;EACnB;CACF;CAEA,uBAAuB,MAA8C;EACnE,IAAI,SAAA,uBAAA,qBAAS,IAAA,CAAA,CAAyB,IAAI,KAAK,EAAE;EACjD,IAAI,QAAQ;GACV,OAAO,OAAO;GACd,IAAI,OAAO,YAAY;IACrB,OACS,WAIP,MAAM,KAAK;IACb,OACS,WAIP,OAAO,KAAK;IACd,OAAO,OAAO;GAChB;EACF,OAAO;GACL,SAAS,EAAE,KAAK;GAChB,uBAAA,qBAAA,IAAA,CAAA,CAAyB,IAAI,KAAK,IAAI,MAAM;EAC9C;EAEA,MAAM,QAAQ;EACd,MAAM,kBAAA,uBAAA,qBAAkB,IAAA,CAAA,CAAyB,IAAI,KAAK,EAAE,KAAK;EACjE,MAAM,qBAAqB,cAAuB;GAChD,MAAM,UAAA,uBAAA,qBAAU,IAAA,CAAA,CAAyB,IAAI,KAAK,EAAE;GACpD,IAAI,SACF,QAAQ,OAAO;IAAE,GAAG,QAAQ;IAAM,OAAO;GAAU;EAEvD;EAEA,MAAM,aAAa;GACjB,IAAI,KAAK;GACT,KAAK,KAAK;GACV,MAAM,KAAK;GACX,IAAI,QAAQ;IACV,OAAO,UAAU,CAAC,CAAC,KAAK;GAC1B;GACA,SAAS,MAA8C;IACrD,MAAM,eAAe,UAAU,CAAC,CAAC,KAAK;IACtC,MAAM,QAAQ,OAAO,SAAS,aAAa,KAAK,YAAY,IAAI;IAChE,kBAAkB,KAAK;IACvB,MAAM,yBAAyB,KAAK,IAAI,aAAa,WACnD,OAAO,SAAS,KAAK,CACvB;IACA,OAAO;GACT;GACA,KAAK,SAAiD;IACpD,MAAM,yBAAyB,KAAK,IAAI,SAAS,WAC/C,OAAO,KAAK,OAAO,CACrB;GACF;GACA,MAAM,MAAe,QAAiB;IACpC,MAAM,yBAAyB,KAAK,IAAI,UAAU,WAChD,OAAO,MAAM,MAAM,MAAM,CAC3B;GACF;GACA,mBAAmB,CAAC;GACpB,sBAAsB,CAAC;EACzB;EAEA,OAAO,aAAa;EACpB,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;EAC9C,OAAO;CACT;CAEA,uBAAuB,YAA8B;EACnD,uBAAA,OAAA,IAAA,CAAA,CAAW,0BAA0B,YAAY,uBAAuB,CACtE,GAAG,WAAW,IAChB,CAAC;EACD,MAAM,SAAA,uBAAA,qBAAS,IAAA,CAAA,CAAyB,IAAI,WAAW,EAAE;EACzD,uBAAA,qBAAA,IAAA,CAAA,CAAyB,IAAI,WAAW,IAAI;GAC1C,MAAM;IACJ,IAAI,WAAW;IACf,KAAK,WAAW;IAChB,MAAM,CAAC,GAAG,WAAW,IAAI;IACzB,OAAO,KAAK,sBAAsB,UAAU;GAC9C;GACA,YAAY,QAAQ,cAAc;EACpC,CAAC;CACH;;;;;;CAOA,MAAM,sBAAqC;EAGzC,IAAI,MAAA,uBAAA,OADI,IAAA,CAAA,CAAW,IAAI,QAAQ,IAAa,oBAAoB,GACnD,uBAAA,OAAA,IAAA,CAAA,CAAW,WAAW;EAEnC,MAAM,kBAAkB,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,IAAI,QAAQ,IACnD,sBACF;EACA,IAAI,OAAO,oBAAoB,UAC7B,uBAAA,OAAA,IAAA,CAAA,CAAW,aAAa;EAG1B,MAAM,mBAAmB,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,IAAI,QAAQ,IAEpD,uBAAuB;EACzB,IAAI,kBAAkB,gBAAgB,GACpC,uBAAA,OAAA,IAAA,CAAA,CAAW,cAAc;EAG3B,IAAI;GACF,MAAM,KAAK,2BAA2B;EACxC,SAAS,OAAO;GACd,QAAQ,KACN,8DACA,KACF;EACF;CACF;CAEA,MAAM,6BAA4C;EAChD,IAAI,CAAA,uBAAA,OAAC,IAAA,CAAA,CAAW,YAAA,uBAAA,OAAY,IAAA,CAAA,CAAW,YAAY,WAAW,GAAG;EAEjE,IAAI,KAAK,mBAAmB,GAI1B;EAIF,MAAM,QAAQ,OAAM,MADD,KAAK,eAAe,EAAA,CACd,4BAAA,uBAAA,OAA4B,IAAA,CAAA,CAAW,QAAQ;EACxE,KAAK,MAAM,QAAQ,OACjB,uBAAA,qBAAA,IAAA,CAAA,CAAyB,IAAI,KAAK,IAAI,EAAE,KAAK,CAAC;CAElD;CAEA,sBAAsB,YAAiC;EACrD,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;EAC9C,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,mBAAmB,IAAI,UAAU,CAAC,EAAE,OAAO,KAAK;CACpE;CAEA,kBAAkB,YAAiC;EACjD,MAAM,MAAM,KAAK,sBAAsB,UAAU;EACjD,IAAI,OAAO,QAAQ,OAAO,QAAQ,UAAU,OAAO;EACnD,MAAM,GAAG,6BAA6B,GAAG,GAAG,SAAS;EAIrD,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO;CAC/C;;;;;CAMA,MAAM,QACJ,KACA,OAKmB;EACnB,IAAI;EACJ,IAAI;GACF,UAAW,MAAM,KAAK,QAAQ,MAAM,YAAY,MAAM,SAAS;EAGjE,SAAS,KAAK;GAIZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC/D,QAAQ,MAAM,oCAAoC,OAAO;GACzD,IAAI,kBAAkB,KAAK,OAAO,KAAK,YAAY,KAAK,OAAO,GAC7D,OAAO,IAAI,SAAS,eAAe,EAAE,QAAQ,IAAI,CAAC;GAEpD,OAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;EAClD;EAKA,MAAM,YAAY,IAAI,IAAI,IAAI,GAAG;EACjC,UAAU,WAAW,MAAM;EAC3B,MAAM,mBAAmB,IAAI,QAAQ,IAAI,OAAO;EAChD,MAAM,gBAA6B;GACjC,QAAQ,IAAI;GACZ,SAAS;EACX;EACA,IAAI,IAAI,QAAQ,IAAI,SAAS,CAAC,EAAE,YAAY,MAAM,aAChD,iBAAiB,IAAI,4BAA4B,IAAI,GAAG;EAM1D,IAAI,IAAI,QAAQ,IAAI,WAAW,SAAS,IAAI,WAAW,QACrD,cAAc,OAAO,IAAI;EAE3B,MAAM,YAAY,IAAI,QAAQ,WAAW,aAAa;EACtD,OAAO,QAAQ,MAAM,SAAS;CAChC;;;;;CAMA,MAAM,OACJ,WACA,MACA,QACA,MACkB;EAClB,MAAM,OAAO,MAAM,KAAK,QAAQ,WAAW,IAAI;EAC/C,OAAO,MAAM,KAAK,iBAAiB,MAAM,WAAW,QAAQ,IAAI;CAClE;;;;;;;CAQA,MAAM,WACJ,MACA,QACA,MACkB;EAClB,MAAM,CAAC,MAAM,MAAM,GAAG,QAAQ;EAC9B,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,sDAAsD;EAGxE,MAAM,eAAA,uBAAA,OACJ,IAAA,CAAA,CACA,YAAY;EACd,IAAI,KAAK,cAAc,gBAAgB,KAAK,SAAA,uBAAA,OAAS,IAAA,CAAA,CAAW,MAC9D,MAAM,IAAI,MACR,qCAAqC,aAAa,IAAA,uBAAA,OAAI,IAAA,CAAA,CAAW,KAAK,kBACpD,KAAK,UAAU,IAAI,KAAK,KAAK,IACjD;EAGF,IAAI,CAAC,MACH,OAAO,MAAM,KAAK,iBAAA,uBAAA,OAChB,IAAA,GACA,cACA,QACA,IACF;EAGF,MAAM,QAAQ,MAAM,KAAK,QAAQ,KAAK,WAAW,KAAK,IAAI;EAC1D,IAAI,KAAK,WAAW,GAClB,OAAO,MAAM,KAAK,iBAAiB,OAAO,KAAK,WAAW,QAAQ,IAAI;EAIxE,OAAO,MAAMA,MAAO,uBAAuB,CAAC,MAAM,GAAG,IAAI,GAAG,QAAQ,IAAI;CAC1E;CAEA,MAAM,iBACJ,MACA,WACA,QACA,MACkB;EAIlB,MAAM,SAAS;EAIf,IAAI,OAAO,OAAO,YAAY,YAC5B,MAAM,IAAI,MAAM,WAAW,OAAO,iBAAiB,UAAU,EAAE;EAEjE,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,IAAI;CACrC;;;;;;CAOA,MAAM,KACJ,MACA,aAAiE,CAAC,GAClE,eAAe,MACA;EACf,MAAM,aAAA,uBAAA,OAAa,IAAA,CAAA,CAAW,UAAU;EACxC,IAAI,eAAe,cACjB,MAAM,IAAI,MACR,uDAAuD,aAAa,aAAa,WAAW,mGAG9F;EAGF,uBAAA,OAAA,IAAA,CAAA,CAAW,WAAW;EACtB,uBAAA,OAAA,IAAA,CAAA,CAAW,aAAa;EACxB,uBAAA,OAAA,IAAA,CAAA,CAAW,cAAc;EAEzB,MAAM,QAAQ,IAAI;iCAChB,IAAA,CAAA,CAAW,IAAI,QAAQ,IAAI,sBAAsB,IAAI;iCACrD,IAAA,CAAA,CAAW,IAAI,QAAQ,IAAI,wBAAwB,IAAI;iCACvD,IAAA,CAAA,CAAW,IAAI,QAAQ,IAAI,yBAAyB,UAAU;EAChE,CAAC;EAMD,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,2BAA2B;CAC9C;;CAGA,MAAM,cACJ,WACA,OACe;EACf,MAAM,eAAe,aAAa,SAAS;EAC3C,uBAAA,OAAA,IAAA,CAAA,CAAW,GAAG;;gCAEc,aAAa;uBACtB,MAAM;;EAEzB,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,cAAc;CACjC;AACF;AAnwBE,SAAA,kCACE,cACA,WACA,OACM;CACN,QAAQ,MAAM,kDAAkD;EAC9D;EACA;EACA;CACF,CAAC;AACH;AA2EA,SAAA,uBACE,YACA,WACmC;CACnC,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;CAC9C,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW,0BAC1B,YACA,0BACF;CACA,IAAI,OAAO,aAAa,UAAU,OAAO;CAEzC,MAAM,SAAA,kBAAA,8BAAS,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAuB,UAAU,SAAS;CACzD,IAAI,CAAC,QAAQ,OAAO;CAEpB,MAAM,MAAM,KAAK,sBAAsB,UAAU;CACjD,MAAM,UACJ,OAAO,QAAQ,OAAO,QAAQ,WACzB,IAAgC,yBACjC,KAAA;CACN,MAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,QAAQ,QAAuB,OAAO,QAAQ,QAAQ,IAC9D,CAAC,GAAG,WAAW,IAAI;CACvB,OAAO;EACL,IAAI,WAAW;EACf,KAAK,OAAO;EACZ;EACA,OAAO,KAAK,kBAAkB,UAAU;CAC1C;AACF;AAeA,SAAA,kBACE,UACA,QAC4D;CAC5D,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;CACvB,MAAM,eAAe,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA;CAC9D,MAAM,OAAwB,CAAC,GAAA,uBAAA,OAAG,IAAA,CAAA,CAAW,QAAQ;CACrD,IAAI,aAAa;CAEjB,OAAO,MAAM;EACX,MAAM,QAAQ,kBAAkB,YAAY,EAAE,aAAa,CAAC;EAC5D,IAAI,CAAC,OAAO;EACZ,KAAK,KAAK;GAAE,WAAW,MAAM;GAAY,MAAM,MAAM;EAAU,CAAC;EAChE,MAAM,YAAY,IAAI,IAAI,UAAU;EACpC,UAAU,WAAW,MAAM;EAC3B,aAAa,UAAU,SAAS;EAChC,IAAI,UAAU,KAAK,gBAAgB,MAAM,MAAM,GAC7C,OAAO;GAAE;GAAM,KAAK;EAAW;CAEnC;CAEA,IAAI,KAAK,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW,SAAS,QAAQ,OAAO;CACvD,IAAI,QAAQ,OAAO;CACnB,OAAO;EAAE;EAAM,KAAK;CAAW;AACjC;AAyDA,SAAA,wBACE,YAC8B;CAG9B,MAAM,0BAAA,uBAAA,OAA0B,IAAA,CAAA,CAAW,WACvC,KAAK,aAAa,WAAW,EAAE,IAC/B,KAAA;CAEJ,OAAO,IAAI,6BACT,aACC,WAAW,SAAS,YAAY;EAC/B,IAAI,yBACF,OAAO,KAAK,eACV,WACA,SACA,SACA,uBACF;EAIF,OAAA,uBAAA,OAAO,IAAA,CAAA,CAAW,wBAAwB,WAAW,SAAS,OAAO;CACvE,CACF;AACF;AAuCA,eAAA,mBACE,YACA,SACA,UAA6B,EAAE,MAAM,MAAM,GAInC;CACR,uBAAA,OAAA,IAAA,CAAA,CAAW,yBAAyB,UAAU;CAC9C,MAAM,WAAA,uBAAA,OAAW,IAAA,CAAA,CAAW,0BAC1B,YACA,0BACF;CACA,MAAM,MAAM,OAAO,aAAa,WAAW,WAAW,WAAW;CACjE,IAAI,CAAC,KAAK,OAAO;CAEjB,MAAM,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW;CACvB,IAAI,QAAQ,kBAAkB,KAAK,EACjC,cAAc,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA,EACzD,CAAC;CACD,IAAI,CAAC,OAAO,OAAO;CACnB,IAAA,uBAAA,OACE,IAAA,CAAA,CAAW,aAAa,SAAS,MAAM,cAAA,uBAAA,OACvC,IAAA,CAAA,CAAW,SAAS,MAAM,WAC1B;EACA,MAAM,UAAU,IAAI,IAAI,GAAG;EAC3B,QAAQ,WAAW,MAAM;EACzB,QAAQ,kBAAkB,QAAQ,SAAS,GAAG,EAC5C,cAAc,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA,EACzD,CAAC;EACD,IAAI,CAAC,OAAO,OAAO;CACrB;CAEA,IAAI,aAAa;CACjB,IAAI,WAAW,QAAQ,MAAM;EAC3B,MAAM,WAAW,MAAA,uBAAA,OAAM,IAAA,CAAA,CAAW,iBAAiB,SAAS;GAC1D,WAAW,MAAM;GACjB,MAAM,MAAM;EACd,CAAC;EACD,IAAI,oBAAoB,UAAU;GAChC,WAAW,MAAM,MAAM,+BAA+B;GACtD,OAAO;EACT;EACA,aAAa,oBAAoB,UAAU,WAAW;CACxD;CAEA,MAAM,QAAS,MAAM,KAAK,QACxB,MAAM,YACN,MAAM,SACR;CAEA,MAAM,WAAW,IAAI,IAAI,YAAY,OAAO,GAAG;CAC/C,SAAS,WAAW,MAAM;CAC1B,MAAM,MAAM,KAAK,sBAAsB,UAAU;CACjD,MAAM,UACJ,OAAO,QAAQ,OAAO,QAAQ,WACzB,IAAgC,yBACjC,KAAA;CACN,MAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,QAAQ,QAAuB,OAAO,QAAQ,QAAQ,IAC9D,CAAC,GAAG,WAAW,IAAI;CAEvB,OAAO;EACL;EACA,MAAM;GACJ,IAAI,WAAW;GACf,KAAK,SAAS,SAAS;GACvB;GACA,OAAO,KAAK,kBAAkB,UAAU;GACxC,gBAAgB,aAAa,CAAC,GAAG,WAAW,OAAO,IAAI,KAAA;EACzD;CACF;AACF;;;;;;;;;;;;;;;;;AC1qCF,IAAa,gBAAb,MAA2B;;CAIzB,YAAY,UAAiC;;EAC3C,uBAAA,WAAA,MAAiB,QAAA;CACnB;;;;;;;;CASA,MAAM,IACJ,KACA,MAC8B;EAC9B,OAAQ,MAAA,uBAAA,WAAM,IAAA,CAAA,CAAe,QAC3B,IAAI,MACJ,IACF;CACF;;;;;;;;;CAUA,MAAM,KAAwB,MAAc,QAAwB;EAClE,uBAAA,WAAA,IAAA,CAAA,CAAe,MAAM,IAAI,MAAM,MAAM,MAAM;CAC7C;;;;;;;CAQA,OAAO,KAAwB,MAA6B;EAC1D,OAAA,uBAAA,WAAO,IAAA,CAAA,CAAe,OAAO,IAAI,MAAM,IAAI;CAC7C;CAWA,IAAI,aAAyC,MAAuB;EAClE,MAAM,YACJ,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAC9D,OAAA,uBAAA,WAAO,IAAA,CAAA,CAAe,SAAS,IAAI,WAAW,IAAI;CACpD;CAeA,KACE,aAC+D;EAC/D,MAAM,YACJ,OAAO,gBAAgB,WAAW,cAAc,aAAa;EAC/D,OAAA,uBAAA,WAAO,IAAA,CAAA,CAAe,SAAS,KAAK,SAAS;CAC/C;AACF;;;ACjGA,SAAgB,oBAAoB,OAIhB;CAClB,OAAO;EAGL,8BAA8B;EAG9B,iCAAiC;EACjC,gCAAgC,MAAM;EACtC,kCAAkC,MAAM;EACxC,qBAAqB,MAAM;CAC7B;AACF;;;;;;;;;;AC0QA,SAAS,gBACP,OACA,MACA,SACG;CACH,OAAOC,sCAAa,IAAI,aAAa,oBAAoB,MAAM,OAAO,CAAC;AACzE;AAEA,SAAS,sBACP,YACA,UACS;CACT,IAAI;EACF,WAAW,KAAK,KAAK,UAAU,QAAQ,CAAC;EACxC,OAAO;CACT,SAAS,OAAO;EACd,IAAI,2BAA2B,KAAK,GAAG,OAAO;EAC9C,MAAM;CACR;AACF;;;;AAKA,SAAS,aAAa,KAAiC;CACrD,OACE,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACV,IAAI,SAAA,SACJ,QAAQ,OACR,OAAO,IAAI,OAAO,YAClB,YAAY,OACZ,OAAO,IAAI,WAAW,YACtB,UAAU,OACV,MAAM,QAAS,IAAmB,IAAI;AAE1C;;;;AAKA,SAAS,qBAAqB,KAAyC;CACrE,OACE,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACV,IAAI,SAAA,oBACJ,WAAW;AAEf;AAkLA,MAAM,YAAY,IAAI,kBAInB;AAyHH,MAAM,iCAAiC;AACvC,MAAM,yCAAyC;AAC/C,MAAM,+CAA+C;AAcrD,MAAM,sBAAsB;AAG5B,MAAM,yBAAyB;AAC/B,MAAM,2BAA2B;AACjC,MAAM,sBAAsB;AAU5B,MAAM,yBAAyB;AAS/B,MAAM,gCAAgC,IAAI;AAG1C,MAAM,iCAAiC;AAUvC,MAAM,qDAAqD;AAY3D,MAAM,4CAA4C,OAAO;AASzD,MAAM,iCAAiC,OAAU,KAAK;AAOtD,MAAM,yCAAyC,OAAU;AAKzD,MAAM,6BAA6B;AAKnC,MAAM,8BAA8B;CAAC;CAAG;CAAI;CAAI;AAAG;AAOnD,MAAM,qCAAqC;AAC3C,MAAM,8BAA8B;AAIpC,MAAM,2BAA2B;;;;;;;AAgBjC,MAAM,yBAAyB;AAE/B,MAAM,wBAAwB;AAC9B,MAAM,eAAe;AAGrB,MAAM,oBAAoB;AAE1B,MAAM,gBAAgB,CAAC;;;;;AAMvB,MAAM,kBAAkB;;;;;;AAOxB,MAAM,qBAAqB;;;;;AAY3B,MAAM,mCAAwC,IAAI,IAAI;CACpD;CACA;CACA;CACA;CACA;AACF,CAAC;;AAGD,SAAS,mBAAmB,KAAuC;CACjE,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,IAAI,iBAAiB,IAAI,GAAG,GAAG,OAAO;CAExC,OAAO;AACT;;AAGA,SAAS,kBACP,KACgC;CAChC,MAAM,SAAkC,CAAC;CACzC,IAAI,cAAc;CAClB,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,IAAI,CAAC,iBAAiB,IAAI,GAAG,GAAG;EAC9B,OAAO,OAAO,IAAI;EAClB,cAAc;CAChB;CAEF,OAAO,cAAc,SAAS;AAChC;;AAGA,SAAS,qBACP,KACyB;CACzB,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,IAAI,iBAAiB,IAAI,GAAG,GAC1B,OAAO,OAAO,IAAI;CAGtB,OAAO;AACT;;AAGA,MAAM,0BAA0B;;;;;;AAQhC,MAAM,kCAAkB,IAAI,OAE1B,yDACA,GACF;AAEA,SAAS,oBAAoB,OAAqC;CAChE,IAAI,UAAU,MAAM,OAAO;CAE3B,IAAI,YAAY,MAAM,QAAQ,iBAAiB,EAAE;CACjD,IAAI,UAAU,SAAS,yBACrB,YAAY,UAAU,UAAU,GAAG,uBAAuB,IAAI;CAEhE,OAAO;AACT;;;;;AAMA,MAAM,8CAA8B,IAAI,QAAkB;;;;;AAM1D,MAAM,6CAA6B,IAAI,QAAkB;;;;;AAMzD,MAAa,+BAA+B;;CAE1C,uBAAuB;;;;;;CAMvB,4BAA4B;;;;;CAK5B,qBAAqB;;CAErB,OAAO;EACL,aAAa;EACb,aAAa;EACb,YAAY;CACd;;CAEA,4BAA4B;;CAE5B,6BAA6B;;;;;;CAM7B,uBAAuB,OAAU,KAAK;;;;;;;;;CAStC,sCACE;;;;;;;;;;;CAWF,8BAA8B;CAC9B,qBAAqB;CACrB,4BAA4B;;;;;;;;;CAS5B,4BAA4B;AAC9B;;;;;AA4HA,SAAS,kBACP,KAC0B;CAC1B,MAAM,MAAM,IAAI;CAChB,IAAI,OAAO,QAAQ,UAAU,OAAO,KAAA;CACpC,OAAO,KAAK,MAAM,GAAG;AACvB;;;;;;AAOA,SAAS,mBACP,WACA,UACkE;CAClE,OAAO;EACL,aAAa,WAAW,eAAe,SAAS;EAChD,aAAa,WAAW,eAAe,SAAS;EAChD,YAAY,WAAW,cAAc,SAAS;CAChD;AACF;;AAOA,MAAa,kBAAkBC;;;;;;AAW/B,SAAS,iBACP,QAIiB;CACjB,OAAO,SAAU,GAAG,MAAoC;EACtD,MAAM,EAAE,UAAU,gBAAgB;EAElC,IAAI,UAAU,MAEZ,OAAO,OAAO,MAAM,MAAM,IAAI;EAIhC,OAAO,gBACL;GACE,OAAO;GACP,YAAY,KAAA;GACZ,SAAS,KAAA;GACT,OAAO,KAAA;EACT,SACM;GACJ,OAAO,OAAO,MAAM,MAAM,IAAI;EAChC,CACF;CACF;AACF;;;;;;AAsBA,IAAa,QAAb,MAAa,cAIH,cAAmB;;CAuC3B,QAAQ,QAAsC,CAAC;;CAG/C,UAAU,UAAiD;EACzD,OAAO,IAAI,SAAS,mBAAmB,EAAE,QAAQ,IAAI,CAAC;CACxD;;CAGA,UACE,aACA,UACsB,CAAC;;CAGzB,UACE,aACA,UACsB,CAAC;;CAGzB,QACE,aACA,OACA,SACA,WACsB,CAAC;;CAGzB,kBACE,aACA,UAC8B;EAC9B,OAAO,CAAC;CACV;;CAGA,MAAM,2BAA2B,OAA8B;EAC7D,MAAM,KAAK,UAAU,MAAM,KAAK;CAClC;;CAgEA,IAAY,iBAAwC;EAClD,KAAK,2BAA2B,IAAI,sBAClC,IACF;EACA,OAAO,KAAK;CACd;;;;;;;;;;;;;;;;;;;;CAwBA,IAAI,gBAAkC;EACpC,KAAK,sBAAsB,IAAIC,cAAiB,KAAK,cAAc;EACnE,OAAO,KAAK;CACd;;;;;;;;;;;;;;;;;;CA2FA,IAAI,kBAA0B;EAC5B,OAAO,KAAK,IAAI,GAAG,SAAS;CAC9B;;;;CAKA,IAAI,QAAe;EACjB,IAAI,KAAK,WAAW,eAElB,OAAO,KAAK;EAId,MAAM,SAAS,KAAK,GAAiC;qDACJ,aAAa;;EAK9D,IAAI,OAAO,SAAS,GAAG;GACrB,MAAM,QAAQ,OAAO,EAAE,CAAC;GAExB,IAAI;IACF,KAAK,SAAS,KAAK,MAAM,KAAK;GAChC,SAAS,GAAG;IACV,QAAQ,MACN,+DACA,CACF;IACA,IAAI,KAAK,iBAAiB,eAAe;KACvC,KAAK,SAAS,KAAK;KAEnB,KAAK,kBAAkB,KAAK,YAAY;IAC1C,OAAO;KAEL,KAAK,GAAG,0CAA0C;KAClD;IACF;GACF;GACA,OAAO,KAAK;EACd;EAKA,IAAI,KAAK,iBAAiB,eAExB;EAIF,KAAK,kBAAkB,KAAK,YAAY;EACxC,OAAO,KAAK;CACd;CAkBA,IAAY,mBAAyC;EACnD,IAAI,KAAK,gBAAgB,OAAO,KAAK;EACrC,MAAM,OAAO,KAAK;EAClB,MAAM,YAAY,KAAK,SAAS;EAChC,KAAK,iBAAiB;GACpB,uBACE,KAAK,SAAS,yBACd,6BAA6B;GAC/B,4BACE,KAAK,SAAS,8BACd,6BAA6B;GAC/B,qBACE,KAAK,SAAS,uBACd,6BAA6B;GAC/B,OAAO;IACL,aACE,WAAW,eACX,6BAA6B,MAAM;IACrC,aACE,WAAW,eACX,6BAA6B,MAAM;IACrC,YACE,WAAW,cAAc,6BAA6B,MAAM;GAChE;GACA,4BACE,KAAK,SAAS,8BACd,6BAA6B;GAC/B,6BACE,KAAK,SAAS,+BACd,6BAA6B;GAC/B,uBACE,KAAK,SAAS,yBACd,6BAA6B;GAC/B,sCACE,KAAK,SAAS,wCACd,6BAA6B;GAC/B,8BACE,KAAK,SAAS,gCACd,6BAA6B;GAC/B,qBACE,KAAK,SAAS,uBACd,6BAA6B;GAC/B,4BACE,KAAK,SAAS,8BACd,6BAA6B;GAC/B,4BACE,KAAK,SAAS,8BACd,6BAA6B;EACjC;EACA,OAAO,KAAK;CACd;;;;;CAWA,MACE,MACA,UAAmC,CAAC,GAC9B;EACN,KAAK,eAAe,KAAK;GACvB;GACA,OAAO,KAAK,aAAa;GACzB,MAAM,KAAK;GACX;GACA,WAAW,KAAK,IAAI;EACtB,CAAuB;CACzB;CAeA,eACE,WACA,cACA,YACA,KACgB;EAGhB,IAAI;EACJ,IAAI;GACF,UAAU,KAAK;EACjB,QAAQ;GACN,UAAU,KAAA;EACZ;EAEA,OAAO,OAAO,SACZ,WACA;GACE,GAAG,oBAAoB;IACrB,gBAAgB,KAAK,aAAa;IAClC,WAAW,KAAK,IAAI,GAAG,SAAS;IAChC,aAAa;GACf,CAAC;GACD,oCAAoC;GACpC,qCAAqC;GACrC,oCAAoC;GACpC,mCAAmC;GACnC,GAAG;EACL,IACC,SACC,KAAK,qBAAqB,oBAAoB,MAAM,gBAAgB,CAAC,GACvEF,sCAAa,SAAS,CAAC,EAAE,eAAe,KAAA,IACpC,KAAA,IACA,EAAE,mBAAmB,KAAK,CAChC;CACF;;;;;;;;CASA,IACE,SACA,GAAG,QACH;EACA,IAAI,QAAQ;EACZ,IAAI;GAEF,QAAQ,QAAQ,QACb,KAAK,KAAK,MAAM,MAAM,OAAO,IAAI,OAAO,SAAS,MAAM,KACxD,EACF;GAGA,OAAO,CAAC,GAAG,KAAK,IAAI,QAAQ,IAAI,KAAK,OAAO,GAAG,MAAM,CAAC;EACxD,SAAS,GAAG;GACV,MAAM,IAAI,SAAS,OAAO,CAAC;EAC7B;CACF;;;;;;;;;;CAkBA,gBAAgC;EAI9B,KAAK,GAAG;;;;;;EAOR,MAAM,aAAa,KAAK,GAA6B;qDACJ,sBAAsB;;EAEvE,MAAM,gBACJ,WAAW,SAAS,IAAI,OAAO,WAAW,EAAE,CAAC,KAAK,IAAI;EAExD,IAAI,gBAAgB,wBAAwB;GAC1C,qBAAqB,KAAK,IAAI,OAAO;GAErC,KAAK,GAAG;;;;;;;;GAWR,MAAM,wBAAwB,QAAgB;IAC5C,IAAI;KACF,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG;IAC/B,SAAS,OAAO;KAGd,IAAI,EADF,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAA,CAC1C,YAAY,CAAC,CAAC,SAAS,kBAAkB,GACpD,MAAM;IAEV;GACF;GAEA,qBACE,4DACF;GAGA,KAAK,GAAG;;;;;;;;;;;;;;;;;;GAmBR,KAAK,GAAG;;;GAIR,KAAK,GAAG;;;GAKR,KAAK,IAAI,QAAQ,IAAI,KACnB,4CACA,iBACF;GAGA,KAAK,GAAG;;;;;;;;GAaR,KAAK,GAAG;;;;;;;;;GAUR,KAAK,GAAG;;;;GAOR,KAAK,GAAG;;;;;;;;;;;;;;GAeR,KAAK,GAAG;;;;GAKR,KAAK,GAAG;;;;GAKR,KAAK,GAAG;;;;GAKR,KAAK,GAAG;;;;;;;;;;;;;;;;;;;GAoBR,KAAK,GAAG;;;;GAKR,qBACE,4DACF;GAIA,qBACE,mEACF;GACA,qBACE,uEACF;GAYA,qBACE,+EACF;GACA,qBACE,mEACF;GACA,qBACE,uEACF;GACA,qBACE,0EACF;GACA,qBACE,qEACF;GACA,qBACE,uEACF;GACA,qBACE,sEACF;GACA,qBACE,wEACF;GAQA,qBACE,kFACF;GACA,qBACE,oEACF;GAMA,qBACE,uEACF;GAGA,KAAK,GAAG;;kBAEI,sBAAsB,IAAI,OAAO,sBAAsB,EAAE;;EAEvE;EAEA,KAAK,wBAAwB;GAC3B,iBAAiB;GACjB,gBAAgB;GAChB,UAAU,gBAAgB;EAC5B;CACF;CAEA,YAAY,KAAmB,KAAU;EACvC,MAAM,KAAK,GAAG;EA3uBhB,KAAS,YAAY,UAAU,QAAoB,MAAM,EACvD,4BAA4B,KAAK,iBAAiB,2BACpD,CAAC;EAYD,KAAiB,cAAc,IAAI,WAAW;GAC5C,UAAU;IACR,YAAY,YAAY,QAAQ,KAAK,UAAU,YAAY,GAAG;IAC9D,YAAY,YAAY,YAAY,KAAK,UAAU,YAAY,OAAO;IACtE,UAAU,YAAY,MAAM,QAAQ,aAClC,KAAK,QAAQ,YAAY,MAAM,QAAQ,QAAQ;IACjD,UAAU,YAAY,UAAU,KAAK,QAAQ,YAAY,KAAK;GAChE;GAMA,WAAW,uBAAuB,IAAI;GACtC,oBAAoB,YAAY,QAC9B,KAAK,kBAAkB,YAAY,GAAG;EAC1C,CAAC;EA2CD,KAAQ,SAAS;EACjB,KAAQ,eAAe,IAAI,gBAAgB;EAC3C,KAAQ,aAAa;EAOrB,KAAQ,qCAAqB,IAAI,QAM/B;EAQF,KAAQ,uBAA+C;EAGvD,KAAQ,WAAW;EAEnB,KAAQ,+CAA+B,IAAI,IAAY;EAgBvD,KAAQ,cAA4C,CAAC;EAGrD,KAAQ,+BAA+B;EASvC,KAAA,iBAAiB;EAyCjB,KAAQ,wCAAwB,IAAI,IAAY;EAEhD,KAAQ,gDAAgC,IAAI,IAA6B;EAEzE,KAAQ,0CAA0B,IAAI,IAA2B;EAEjE,KAAQ,+CAA+B,IAAI,IAA6B;EAExE,KAAQ,8BAA8B;EAOtC,KAAQ,2BAA2B;EAInC,KAAQ,0BAAyC,QAAQ,QAAQ;EAEjE,KAAQ,2BAA2B;EAEnC,KAAQ,eACN,OAAO,eAAe,IAAI,CAAC,CAAC;EA6C9B,KAAA,eAAsB;EAkJtB,KAAA,gBAAgC;EAmwDhC,KAAQ,iBAAiB;EA08EzB,KAAA,0BAA0B;EAj2HxB,MAAM,YAAY;EAClB,2BAA2B,KAAK,WAAW;GACzC,IAAI,SAAS;IACX,OAAO,UAAU,uBAAuB;GAC1C;GACA,SAAS,aAAa,KAAK,sBAAsB,QAAQ;GACzD,KAAK,QAAQ,aAAa,KAAK,wBAAwB,QAAQ,QAAQ;EACzE,CAAC;EACD,sBAAsB,KAAK,YAAY,UAAU;GAC/C,MAAM,UACJ,MAAM,YAAY,QAClB,OAAO,MAAM,YAAY,YACzB,CAAC,MAAM,QAAQ,MAAM,OAAO,IACvB,MAAM,UACP,EAAE,OAAO,MAAM,QAAQ;GAG7B,KAAK,MAAM,MAAM,MAAoC,OAAO;EAC9D,CAAC;EAQD,wBAAwB,KAAK,YAAY,KAAK,UAC5C,gBACE;GACE,OAAO;GACP,YAAY,OAAO;GACnB,SAAS,OAAO;GAChB,OAAO,KAAA;EACT,GACA,GACF,CACF;EAEA,KAAK,YAAY,IAAI,UAAU;GAC7B,OAAO,KAAK,iBAAiB;GAC7B,4BACE,KAAK,iBAAiB;GACxB,UAAU,UACR,gBACE;IACE,OAAO;IACP,YAAY,KAAA;IACZ,SAAS,KAAA;IACT,OAAO,KAAA;GACT,SACM,KAAK,QAAQ,KAAK,CAC1B;EACJ,CAAC;EAMD,6BAA6B,KAAK,YAAY,SAAS;GACrD,MAAM,SAAS,KAAK;GACpB,IAAI,OAAO,WAAW,YAAY,OAAO,KAAA;GACzC,QAAQ,SAAS,aAEb,OACA,KAAK,MAAM,SAAS,QAAQ;EAClC,CAAC;EAED,KAAK,QAAQ,IAAI,MAAM,EACrB,UAAU,UAAU,KAAK,QAAQ,KAAK,EACxC,CAAC;EAKD,gCAAgC,KAAK,QAAQ,YAAY;GAMvD,OAJE,KAGA,oBACW,KAAK,MAAM,OAAO;EACjC,CAAC;EAYD,0BACE,KAAK,QACJ,SACC,KAAK,kBAAkB,KAC3B;EAEA,KAAK,MAAM,KAAK,eACd,wBACA,kBACA,CAAC,IACA,WAAW;GACV,IAAI,CAAC,eAAe,IAAI,KAAK,WAAW,GAAG;IAEzC,KAAK,uBAAuB;IAC5B,eAAe,IAAI,KAAK,WAAW;GACrC;GAEA,KAAK,eACH,4BACA,kBACA,CAAC,IACA,kBAAkB;IACjB,KAAK,cAAc;IACnB,MAAM,mBAAmB;KACvB,6CACE,KAAK,uBAAuB;KAC9B,4CACE,KAAK,uBAAuB;KAC9B,qCACE,KAAK,uBAAuB;IAChC;IACA,cAAc,gBAAgB;IAC9B,OAAO,gBAAgB;GACzB,CACF;GAGA,OAAO,IAAI,iBAAiB,KAAK,aAAa,MAAM,SAAS;IAC3D,KAAK,KAAK;IACV,qBAAqB,gBACnB,KAAK,uBAAuB,WAAW;GAC3C,CAAC;EACH,CACF;EAKA,KAAK,UACF,IAAI,KAAK,SAAS,CAAC,CACnB,IAAI,KAAK,GAAG,CAAC,CACb,IAAI,KAAK,aAAa,EAAE,UAAU,KAAK,CAAC,CAAC,CACzC,IAAI,KAAK,KAAK,CAAC,CAGf,IAAI,KAAK,cAAc;EAI1B,IAAI,oBAAoB;EACxB,KAAK,aAAa,IAChB,KAAK,IAAI,2BAA2B;GAClC,IAAI,mBAAmB,KAAK,oBAAoB;EAClD,CAAC,CACH;EAGA,KAAK,aAAa,IAChB,KAAK,IAAI,sBAAsB,UAAU;GACvC,KAAK,eAAe,KAAK;IACvB,GAAG;IACH,OAAO,KAAK,aAAa;IACzB,MAAM,KAAK;GACb,CAAC;EACH,CAAC,CACH;EAGA;GACE,MAAM,QAAQ,OAAO,eAAe,IAAI;GACxC,MAAM,YAAY,OAAO,UAAU,eAAe,KAChD,OACA,gBACF;GACA,MAAM,YAAY,OAAO,UAAU,eAAe,KAChD,OACA,eACF;GAEA,IAAI,aAAa,WACf,MAAM,IAAI,MACR,8HAEF;GAGF,IAAI,WAAW;IACb,MAAM,OAAO,KAAK;IAClB,IAAI,CAAC,4BAA4B,IAAI,IAAI,GAAG;KAC1C,4BAA4B,IAAI,IAAI;KACpC,QAAQ,KACN,4FACF;IACF;GACF;GAEA,MAAM,OAAO,MAAM;GACnB,IAAI,MAAM,mBAAmB,KAAK,gBAChC,KAAK,uBAAuB;QACvB,IAAI,MAAM,kBAAkB,KAAK,eACtC,KAAK,uBAAuB;EAGhC;EAEA,MAAM,WAAW,KAAK,QAAQ,KAAK,IAAI;EACvC,KAAK,UAAU,YAAY;GACzB,IAAI,KAAK,YAAY;GACrB,MAAM,SAAS;GACf,IAAI,KAAK,YAAY;GACrB,MAAM,KAAK,qBAAqB;GAGhC,IAAI,KAAK,YAAY;GACrB,MAAM,KAAK,cAAc;EAC3B;EAEA,MAAM,aAAa,KAAK,UAAU,KAAK,IAAI;EAC3C,KAAK,aAAa,YAAqB;GACrC,OAAO,gBACL;IAAE,OAAO;IAAM,YAAY,KAAA;IAAW;IAAS,OAAO,KAAA;GAAU,SAC1D,KAAK,gBAAgB,WAAW,OAAO,CAAC,CAChD;EACF;EAEA,MAAM,aAAa,KAAK,UAAU,KAAK,IAAI;EAC3C,KAAK,YAAY,OAAO,YAAwB,YAAuB;GACrE,MAAM,cAAcG,4BAAwB,SAAS,CAAC,EAAE;GAGxD,IACE,MAAMH,sCAAa,WACjB,KAAK,oCACH,YACA,SACA,WACF,CACF,GAEA;GAEF,KAAK,yBAAyB,UAAU;GACxC,OAAO,gBACL;IAAE,OAAO;IAAM;IAAY,SAAS,KAAA;IAAW,OAAO,KAAA;GAAU,GAChE,YAAY;IACV,IAAI,OAAO,YAAY,UACrB,OAAO,KAAK,gBAAgB,WAAW,YAAY,OAAO,CAAC;IAG7D,IAAI;IACJ,IAAI;KACF,SAAS,KAAK,MAAM,OAAO;IAC7B,SAAS,IAAI;KAEX,OAAO,KAAK,gBAAgB,WAAW,YAAY,OAAO,CAAC;IAC7D;IAEA,IAAI,qBAAqB,MAAM,GAAG;KAEhC,IAAI,KAAK,qBAAqB,UAAU,GAAG;MAEzC,WAAW,KACT,KAAK,UAAU;OACb,MAAA;OACA,OAAO;MACT,CAAC,CACH;MACA;KACF;KACA,IAAI;MACF,KAAK,kBAAkB,OAAO,OAAgB,UAAU;KAC1D,SAAS,GAAG;MAGV,QAAQ,MAAM,kCAAkC,CAAC;MACjD,WAAW,KACT,KAAK,UAAU;OACb,MAAA;OACA,OAAO;MACT,CAAC,CACH;KACF;KACA;IACF;IAEA,IAAI,aAAa,MAAM,GAAG;KACxB,IAAI;MACF,MAAM,EAAE,IAAI,QAAQ,SAAS;MAG7B,MAAM,WAAW,KAAK;MACtB,IAAI,OAAO,aAAa,YACtB,MAAM,IAAI,MAAM,UAAU,OAAO,gBAAgB;MAGnD,IAAI,CAAC,KAAK,YAAY,MAAM,GAC1B,MAAM,IAAI,MAAM,UAAU,OAAO,iBAAiB;MAGpD,MAAM,WAAW,oBAAoB,QAAoB;MAGzD,IAAI,UAAU,WAAW;OACvB,MAAM,SAAS,IAAI,kBAAkB,YAAY,EAAE;OACnD,IAAI,aACF,+BAA+B,QAAQ,WAAW;OAGpD,KAAK,MAAM,OAAO;QAAE;QAAQ,WAAW;OAAK,CAAC;OAE7C,IAAI;QACF,MAAM,SAAS,MAAM,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;OAC9C,SAAS,KAAK;QACZ,QAAQ,MAAM,8BAA8B,OAAO,KAAK,GAAG;QAC3D,KAAK,MAAM,aAAa;SACtB;SACA,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;QACxD,CAAC;QAED,IAAI,CAAC,OAAO,UACV,OAAO,MACL,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;OAEJ;OACA,MAAM,wCAAwC,MAAM;OACpD;MACF;MAGA,MAAM,SAAS,MAAM,SAAS,MAAM,MAAM,IAAI;MAE9C,KAAK,MAAM,OAAO;OAAE;OAAQ,WAAW,UAAU;MAAU,CAAC;MAE5D,MAAM,WAAwB;OAC5B,MAAM;OACN;OACA;OACA,SAAS;OACT,MAAA;MACF;MACA,IAAI,aACF,MAAM,2BAA2B,aAAa,QAAQ,CAAC,CACpD;WAEH,sBAAsB,YAAY,QAAQ;KAE9C,SAAS,GAAG;MACV,MAAM,WAAwB;OAC5B,OACE,aAAa,QAAQ,EAAE,UAAU;OACnC,IAAI,OAAO;OACX,SAAS;OACT,MAAA;MACF;MACA,IAAI,aACF,MAAM,2BAA2B,aAAa,QAAQ,CAAC,CACpD;WAEH,sBAAsB,YAAY,QAAQ;MAG5C,QAAQ,MAAM,cAAc,CAAC;MAC7B,KAAK,MAAM,aAAa;OACtB,QAAQ,OAAO;OACf,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;MAClD,CAAC;KACH;KACA;IACF;IAEA,OAAO,KAAK,gBAAgB,WAAW,YAAY,OAAO,CAAC;GAC7D,CACF;EACF;EAEA,MAAM,aAAa,KAAK,UAAU,KAAK,IAAI;EAC3C,KAAK,YAAY,OAAO,YAAwB,QAA2B;GACzE,KAAK,yBAAyB,UAAU;GACxC,MAAM,mBAAmB,IAAI,QAAQ,QAAQ,IAC3C,0BACF;GACA,IAAI,kBACF,KAAK,0BACH,YACA,4BACA,gBACF;GAIF,IACE,MAAMA,sCAAa,WACjB,KAAK,oCAAoC,YAAY,IAAI,SAAS,EAChE,MAAM,MACR,CAAC,CACH,GAEA;GAIF,OAAO,gBACL;IAAE,OAAO;IAAM;IAAY,SAAS,IAAI;IAAS,OAAO,KAAA;GAAU,GAClE,YAAY;IAGV,IAAI,KAAK,2BAA2B,YAAY,GAAG,GACjD,KAAK,sBAAsB,YAAY,IAAI;IAM7C,IAAI,KAAK,2BAA2B,YAAY,GAAG,GAAG;KAGpD,IAAI,KAAK,iBAAiB,uBAAuB;MAC/C,MAAM,OAAO,KAAK;MAClB,IACE,KAAK,SAAS,0BAA0B,KAAA,KACxC,CAAC,2BAA2B,IAAI,IAAI,KAOpC,CAAC,KAAK;WAMF,CADY,IAAI,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,SAC5B,SAAS,KAAK,IAAI,GAAG;QAChC,2BAA2B,IAAI,IAAI;QACnC,QAAQ,KACN,WAAW,KAAK,KAAK,2BAA2B,KAAK,KAAK,0OAK5D;OACF;;MAEF,WAAW,KACT,KAAK,UAAU;OACb,MAAM,KAAK;OACX,OAAO,qBAAqB,KAAK,aAAa,IAAI;OAClD,MAAA;MACF,CAAC,CACH;KACF;KAEA,MAAM,oCACJ,KAAK,6BAA6B,IAAI,WAAW,EAAE;KACrD,IAAI;KACJ,KAAK,6BAA6B,IAAI,WAAW,EAAE;KACnD,IAAI;MACF,eAAe,KAAK;KACtB,UAAU;MACR,IAAI,CAAC,mCACH,KAAK,6BAA6B,OAAO,WAAW,EAAE;KAE1D;KAEA,IAAI,iBAAiB,KAAA,GACnB,WAAW,KACT,KAAK,UAAU;MACb,OAAO;MACP,MAAA;KACF,CAAC,CACH;KAGF,WAAW,KACT,KAAK,UAAU;MACb,KAAK,KAAK,cAAc;MACxB,MAAA;KACF,CAAC,CACH;IACF,OACE,KAAK,yBAAyB,UAAU;IAG1C,KAAK,MAAM,WAAW,EAAE,cAAc,WAAW,GAAG,CAAC;IACrD,MAAM,KAAK,qBAAqB,UAAU;IAC1C,OAAO,KAAK,gBAAgB,WAAW,YAAY,GAAG,CAAC;GACzD,CACF;EACF;EAEA,MAAM,WAAW,KAAK,QAAQ,KAAK,IAAI;EACvC,KAAK,UAAU,OACb,YACA,MACA,QACA,aACG;GAGH,IACE,MAAMA,sCAAa,WACjB,KAAK,kCACH,YACA,MACA,QACA,QACF,CACF,GAEA;GAEF,OAAO,gBACL;IAAE,OAAO;IAAM;IAAY,SAAS,KAAA;IAAW,OAAO,KAAA;GAAU,SAC1D;IACJ,KAAK,MAAM,cAAc;KACvB,cAAc,WAAW;KACzB;KACA;IACF,CAAC;IACD,OAAO,SAAS,YAAY,MAAM,QAAQ,QAAQ;GACpD,CACF;EACF;EAEA,MAAM,WAAW,KAAK,QAAQ,KAAK,IAAI;EACvC,MAAM,aAAa,OACjB,OACA,WACG;GACH,OAAO,gBACL;IACE,OAAO;IACP,YAAY,KAAA;IACZ,SAAS,KAAA;IACT,OAAO,KAAA;GACT,GACA,YAAY;IACV,MAAM,KAAK,0BAA0B;IAErC,MAAM,KAAK,UAAU,YAAY;KAC/B,oBAAoB;KACpB,KAAK,oBAAoB;KAEzB,MAAM,yBAAyB,MAAM,KAAK,eACxC,sBACA,WACA,CAAC,GACD,YAAY;MACV,KAAK,wBAAwB;MAC7B,MAAM,KAAK,gBAAgB;MAI3B,OAAO,KAAK,4BAA4B;KAC1C,CACF;KACA,OAAO;MACL,iCAAiC,KAAK;MACtC,gDACE,uBAAuB;KAC3B,CAAC;KASD,MAAM,qBAAsB,KACzB;KAEH,MAAM,SAAS,MAAM,KAAK,eACxB,qBACA,WACA,CAAC,SACK,SAAS,KAAK,CACtB;KAEA,MAAM,oBAAqB,KACxB;KAIH,MAAM,2BACJ,OAAO,sBAAsB,aAC5B,OAAO,sBAAsB,YAC5B,sBAAsB;KAC1B,IACE,CAAC,KAAK,gCACN,uBAAuB,qBACvB,0BACA;MACA,KAAK,+BAA+B;MACpC,QAAQ,KACN,kWAMF;KACF;KAEA,KAAK,8BAA8B,EACjC,QAAQ,uBACV,CAAC;KAKD,MAAM,KAAK,cAAc;KACzB,OAAO;IACT,CAAC;GACH,CACF;EACF;EACA,KAAK,WAAW,UACd,KAAK,eAAe,eAAe,WAAW,CAAC,IAAI,WACjD,WAAW,OAAO,MAAM,CAC1B;CACJ;CAEA,MAAc,4BAA2C;EACvD,MAAM,KAAK,eAAe,uBAAuB,WAAW,CAAC,SAC3D,KAAK,eAAe,oBAAoB,CAC1C;CACF;;;;CAKA,0BAAwC;EAiBtC,MAAM,WAAW,KAfU,GAKzB;;;;;;;;MAU6B,QAC5B,QAAQ,CAAC,KAAK,2BAA2B,IAAI,aAAa,CAC7D;EAEA,IAAI,SAAS,SAAS,GAAG;GACvB,MAAM,kBAAkB,KAAK,yBAAyB;GACtD,KAAK,MAAM,EACT,eAAe,SACf,OACA,QACA,eACG,UAAU;IACb,MAAM,aACJ,gBAAgB,WAAW,IACvB,gCAAgC,QAAQ,MAAM,gBAAgB,GAAG,MACjE,gCAAgC,QAAQ;IAC9C,MAAM,YACJ,SAAS,KAAK,YAAY,IACtB,KAAK,OAAO,WAAW,UAAU,eACjC,SAAS,IACP,KAAK,OAAO,YACZ,KAAK,UAAU;IACvB,QAAQ,KACN,iBAAiB,MAAM,4CAA4C,QAAQ,GAAG,UAAU,sCACjD,YACzC;GACF;EACF;CACF;;;;;;;;CASA,mBAA2B,KAAa,aAAuB,CAAC,GAAG;EACjE,MAAM,UAAU,CAAC,GAAG,YAAY,GAAG,KAAK,4BAA4B;EACpE,KAAK,MAAM,QAAQ,KAAK,eAAe,GACrC,IAAI,CAAC,KAAK,4BAA4B,IAAI,GACxC,QAAQ,KAAK,KAAK,EAAE;EAGxB,KAAK,UAAU,KAAK,OAAO;CAC7B;CAEA,kBACE,WACA,SAAgC,UAC1B;EAEN,KAAK,oBAAoB,WAAW,MAAM;EAI1C,KAAK,SAAS;EACd,KAAK,GAAG;;gBAEI,aAAa,IAAI,KAAK,UAAU,SAAS,EAAE;;EAIvD,KAAK,mBACH,KAAK,UAAU;GACb,OAAO;GACP,MAAA;EACF,CAAC,GACD,WAAW,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CACvC;EAIA,MAAM,EAAE,YAAY,SAAS,UAAUA,sCAAa,SAAS,KAAK,CAAC;EACnE,KAAK,IAAI,WACN,YAAY;GACX,IAAI;IACF,MAAM,gBACJ;KAAE,OAAO;KAAM;KAAY;KAAS;IAAM,GAC1C,YAAY;KACV,KAAK,MAAM,cAAc;KACzB,MAAM,KAAK,0BAA0B,WAAW,MAAM;IACxD,GAGA,EAAE,UAAU,KAAK,CACnB;GACF,SAAS,GAAG;IAEV,IAAI;KACF,MAAM,KAAK,QAAQ,CAAC;IACtB,QAAQ,CAER;GACF;EACF,EAAA,CAAG,CACL;CACF;;;;;;CAOA,SAAS,OAAoB;EAE3B,MAAM,QAAQA,sCAAa,SAAS;EACpC,IAAI,OAAO,cAAc,KAAK,qBAAqB,MAAM,UAAU,GACjE,MAAM,IAAI,MAAM,wBAAwB;EAE1C,KAAK,kBAAkB,OAAO,QAAQ;CACxC;;;;;;;;;;;;;CAcA,yBAAiC,YAAwB;EACvD,IAAI,KAAK,mBAAmB,IAAI,UAAU,GAAG;EAK7C,MAAM,aAAa,OAAO,yBAAyB,YAAY,OAAO;EAEtE,IAAI;EACJ,IAAI;EAEJ,IAAI,YAAY,KAAK;GAInB,SAAS,WAAW,IAAI,KAAK,UAAU;GAIvC,SAAS,WAAW,SAAS,KAAK,UAAU;EAC9C,OAAO;GAIL,IAAI,WAAY,WAAW,SAAS;GAIpC,eAAe;GACf,UAAU,UAAmB;IAC3B,WAAW;IACX,OAAO;GACT;EACF;EAEA,KAAK,mBAAmB,IAAI,YAAY;GAAE;GAAQ;EAAO,CAAC;EAG1D,OAAO,eAAe,YAAY,SAAS;GACzC,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,MAAM,MAAM,OAAO;IACnB,IAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,mBAAmB,GAAG,GAClE,OAAO,kBAAkB,GAAG;IAE9B,OAAO;GACT;EACF,CAAC;EAGD,OAAO,eAAe,YAAY,YAAY;GAC5C,cAAc;GACd,UAAU;GACV,MAAM,WAAmD;IACvD,MAAM,MAAM,OAAO;IACnB,MAAM,QACJ,OAAO,QAAQ,OAAO,QAAQ,WAC1B,qBAAqB,GAA8B,IACnD,CAAC;IACP,MAAM,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS;IAE7C,IAAI;IACJ,IAAI,OAAO,cAAc,YAKvB,eAAgB,UAHI,WAChB,kBAAkB,GAA8B,IAChD,GACgE;SAEpE,eAAe;IAIjB,IAAI,UAAU;KACZ,IAAI,gBAAgB,QAAQ,OAAO,iBAAiB,UAClD,OAAO,OAAO;MACZ,GAAI;MACJ,GAAG;KACL,CAAC;KAGH,OAAO,OAAO,KAAK;IACrB;IACA,OAAO,OAAO,YAAY;GAC5B;EACF,CAAC;CACH;;;;;;CAOA,sBAAsB,YAAwB,WAAW,MAAM;EAC7D,KAAK,yBAAyB,UAAU;EACxC,MAAM,YAAY,KAAK,mBAAmB,IAAI,UAAU;EACxD,MAAM,MAAO,UAAU,OAAO,KAAwC,CAAC;EACvE,IAAI,UACF,UAAU,OAAO;GAAE,GAAG;IAAM,kBAAkB;EAAK,CAAC;OAC/C;GAGL,MAAM,GAAG,kBAAkB,GAAG,GAAG,SAAS;GAC1C,UAAU,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,IAAI;EAC7D;CACF;;;;;;;;;CAUA,qBAAqB,YAAiC;EACpD,KAAK,yBAAyB,UAAU;EAKxC,OAAO,CAAC,CAJI,KAAK,mBAAmB,IAAI,UAAU,CAAC,CAAE,OAI1C,CAAC,GAAG;CACjB;;;;;;;;;;;;;CAcA,0BAA0B,YAAwB,KAAsB;EACtE,KAAK,yBAAyB,UAAU;EAKxC,OAJY,KAAK,mBAAmB,IAAI,UAAU,CAAC,CAAE,OAI5C,CAAC,GAAG;CACf;;;;;;;;;;;CAYA,0BACE,YACA,KACA,OACM;EACN,KAAK,yBAAyB,UAAU;EACxC,MAAM,YAAY,KAAK,mBAAmB,IAAI,UAAU;EACxD,MAAM,MAAO,UAAU,OAAO,KAAwC,CAAC;EACvE,IAAI,UAAU,KAAA,GAAW;GACvB,MAAM,GAAG,MAAM,GAAG,GAAG,SAAS;GAC9B,UAAU,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,IAAI;EAC7D,OACE,UAAU,OAAO;GAAE,GAAG;IAAM,MAAM;EAAM,CAAC;CAE7C;;;;;;;CAQA,2BACE,aACA,MACS;EACT,OAAO;CACT;;;;;;;;;;;;;;;;;;CAmBA,2BACE,aACA,MACS;EACT,OAAO;CACT;;;;;;;;;;CAWA,4BAA4B,YAAiC;EAC3D,KAAK,yBAAyB,UAAU;EAKxC,OAAO,CAJK,KAAK,mBAAmB,IAAI,UAAU,CAAC,CAAE,OAI3C,CAAC,GAAG;CAChB;;;;;CAMA,yBAAiC,YAAwB;EACvD,KAAK,yBAAyB,UAAU;EACxC,MAAM,YAAY,KAAK,mBAAmB,IAAI,UAAU;EACxD,MAAM,MAAO,UAAU,OAAO,KAAwC,CAAC;EACvE,UAAU,OAAO;GAAE,GAAG;IAAM,qBAAqB;EAAK,CAAC;CACzD;;;;;;;CASA,oBAAoB,YAAmB,SAAgC,CAEvE;;;;;;;;;CAWA,eAAe,QAA2B,SAAgC,CAE1E;;;;;;;;;;;;CAcA,cAAc,QAA2B,SAAgC,CAEzE;;;;;CAMA,MAAc,0BACZ,OACA,QACe;EACf,QAAQ,KAAK,sBAAb;GACE,KAAK;IACH,MAAM,KAAK,eAAe,OAAO,MAAM;IACvC;GACF,KAAK;IACH,MAAM,KAAK,cAAc,OAAO,MAAM;IACtC;EAEJ;CACF;;;;;;CAOA,MAAM,SAAS,SAOZ;EAMD,MAAM,QAAoB;GACxB,MAAM,QAAQ;GACd,IAAI,QAAQ;GACZ,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,eAAe,QAAQ;GACvB,cAAc,QAAQ,QAAQ,OAAO;GACrC,YAAY,WAAmB,QAAQ,QAAQ,UAAU,MAAM;GAC/D,UAAU,QAAgB,YACxB,QAAQ,QAAQ,QAAQ,QAAQ,OAAO;GACzC,QAAQ,YACN,QAAQ,QAAQ,MAAM,OAAO;EACjC;EAEA,OAAO,gBACL;GAAE,OAAO;GAAM,YAAY,KAAA;GAAW,SAAS,KAAA;GAAW;EAAM,GAChE,YAAY;GACV,KAAK,MAAM,iBAAiB;IAC1B,MAAM,MAAM;IACZ,IAAI,MAAM;IACV,SAAS,MAAM,QAAQ,IAAI,SAAS,KAAK,KAAA;GAC3C,CAAC;GACD,IAAI,aAAa,QAAQ,OAAO,KAAK,YAAY,YAC/C,OAAO,KAAK,gBACT,KAAK,QAAiD,KAAK,CAC9D;QACK;IACL,QAAQ,IAAI,wBAAwB,MAAM,MAAM,OAAO,MAAM,EAAE;IAC/D,QAAQ,IAAI,YAAY,MAAM,QAAQ,IAAI,SAAS,CAAC;IACpD,QAAQ,IACN,qFACF;GACF;EACF,CACF;CACF;;;;;;;;;;CAWA,MAAM,aACJ,OACA,SAQe;EACf,OAAO,KAAK,UAAU,YAAY;GAEhC,IAAI,MAAM,iBAAiB,QAAQ,WAAW,KAAA,GAC5C,MAAM,IAAI,MACR,yKAGF;GAGF,MAAM,YAAY,qBAAqB,KAAK,aAAa,IAAI;GAC7D,MAAM,UAAU,KAAK;GAErB,MAAM,EAAE,sBAAsB,MAAM,OAAO;GAC3C,MAAM,MAAM,kBAAkB;GAC9B,IAAI,UAAU;IAAE,MAAM,MAAM;IAAI,MAAM,QAAQ;GAAS,CAAC;GACxD,IAAI,aAAa,MAAM,IAAI;GAC3B,IAAI,WACF,QAAQ,WAAW,OAAO,MAAM,QAAQ,IAAI,SAAS,OAAO,YAC9D;GACA,IAAI,WAAW;IACb,aAAa,QAAQ,eAAe;IACpC,MAAM,QAAQ;GAChB,CAAC;GAGD,MAAM,YAAY,IAAI,QAAQ,GADf,MAAM,KAAK,MAAM,GAAG,CAAC,CAAC,GACG;GACxC,IAAI,UAAU,eAAe,MAAM,QAAQ,IAAI,YAAY,CAAE;GAC7D,IAAI,UAAU,cAAc,SAAS;GACrC,IAAI,UAAU,gBAAgB,SAAS;GACvC,IAAI,UAAU,cAAc,OAAO;GAGnC,IAAI,OAAO,QAAQ,WAAW,UAAU;IACtC,MAAM,gBAAgB,MAAM,iBAC1B,QAAQ,QACR,WACA,OACF;IACA,IAAI,UAAU,eAAe,cAAc,cAAc;IACzD,IAAI,UAAU,kBAAkB,cAAc,iBAAiB;GACjE;GAEA,IAAI,QAAQ,SACV,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,OAAO,GACvD,IAAI,UAAU,KAAK,KAAK;GAG5B,MAAM,MAAM,MAAM;IAChB,MAAM,MAAM;IACZ,KAAK,IAAI,MAAM;IACf,IAAI,MAAM;GACZ,CAAC;GAID,MAAM,aAAa,MAAM,QAAQ,IAAI,SAAS;GAC9C,KAAK,MAAM,eAAe;IACxB,MAAM,MAAM;IACZ,IAAI,MAAM;IACV,SACE,QAAQ,YAAY,aAAa,OAAO,eAAe,KAAA;GAC3D,CAAC;EACH,CAAC;CACH;;;;;;;;;;;;;;;;;;;;;;CAuBA,MAAM,UAAU,SAAqD;EACnE,OAAO,KAAK,UAAU,YAAY;GAChC,MAAM,SAAS,MAAM,eAAe,SAAS;IAC3C,WAAW,qBAAqB,KAAK,aAAa,IAAI;IACtD,SAAS,KAAK;GAChB,CAAC;GAED,MAAM,WACJ,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO,QAAQ,KAAK;GACjE,KAAK,MAAM,cAAc;IACvB,MAAM;IACN,IAAI,QAAQ;IACZ,SAAS,QAAQ;GACnB,CAAC;GAED,OAAO;EACT,CAAC;CACH;CAEA,MAAc,UAAa,IAA0B;EACnD,IAAI;GACF,OAAO,MAAM,GAAG;EAClB,SAAS,GAAG;GACV,MAAM,KAAK,QAAQ,CAAC;EACtB;CACF;;;;;CAMA,yBAAiC;EAE/B,MAAM,iBAAiB,CAAC,MAAM,SAAS;EACvC,MAAM,8BAAc,IAAI,IAAY;EACpC,KAAK,MAAM,aAAa,gBAAgB;GACtC,IAAI,QAAQ;GACZ,OAAO,SAAS,UAAU,OAAO,WAAW;IAC1C,MAAM,cAAc,OAAO,oBAAoB,KAAK;IACpD,KAAK,MAAM,cAAc,aACvB,YAAY,IAAI,UAAU;IAE5B,QAAQ,OAAO,eAAe,KAAK;GACrC;EACF;EAEA,IAAI,QAAQ,OAAO,eAAe,IAAI;EACtC,IAAI,QAAQ;EACZ,OAAO,SAAS,UAAU,OAAO,aAAa,QAAQ,IAAI;GACxD,MAAM,cAAc,OAAO,oBAAoB,KAAK;GACpD,KAAK,MAAM,cAAc,aAAa;IACpC,MAAM,aAAa,OAAO,yBAAyB,OAAO,UAAU;IAGpE,IACE,YAAY,IAAI,UAAU,KAC1B,WAAW,WAAW,GAAG,KACzB,CAAC,cACD,CAAC,CAAC,WAAW,OACb,OAAO,WAAW,UAAU,YAE5B;IAMF,MAAM,kBAAkB,iBACtB,KAAK,WACP;IAIA,IAAI,KAAK,YAAY,UAAU,GAC7B,qBACE,KAAK,aACL,eACF;IAIF,KAAK,YAAY,UAAU,cAA4B;GACzD;GAEA,QAAQ,OAAO,eAAe,KAAK;GACnC;EACF;CACF;CAIA,QAAQ,mBAAyC,OAAiB;EAChE,IAAI;EACJ,IAAI,qBAAqB,OAAO;GAC9B,WAAW;GAEX,QAAQ,MACN,kCACC,kBAAiC,IAClC,QACF;GACA,QAAQ,MACN,2EACF;EACF,OAAO;GACL,WAAW;GAEX,QAAQ,MAAM,oBAAoB,QAAQ;GAC1C,QAAQ,MAAM,iDAAiD;EACjE;EACA,MAAM;CACR;;;;CAKA,SAAS;EACP,MAAM,IAAI,MAAM,iBAAiB;CACnC;;;;;;;;;;;;;;CAeA,MAAM,MACJ,IACA,SAIY;EACZ,MAAM,WAAW,KAAK,iBAAiB;EACvC,IAAI,SACF,qBAAqB,SAAS,QAAQ;EAExC,OAAO,KAAK,SAAS,eAAe,SAAS,aAAa,IAAI;GAC5D,aAAa,SAAS,eAAe,SAAS;GAC9C,YAAY,SAAS,cAAc,SAAS;GAC5C,aAAa,SAAS;EACxB,CAAC;CACH;;;;;;;;;CAUA,MAAM,MACJ,UACA,SACA,SACiB;EACjB,MAAM,KAAK,OAAO,CAAC;EACnB,IAAI,OAAO,aAAa,UACtB,MAAM,IAAI,MAAM,2BAA2B;EAG7C,IAAI,OAAO,KAAK,cAAc,YAC5B,MAAM,IAAI,MAAM,QAAQ,SAAS,mBAAmB;EAGtD,IAAI,SAAS,OACX,qBAAqB,QAAQ,OAAO,KAAK,iBAAiB,KAAK;EAGjE,MAAM,YAAY,SAAS,QAAQ,KAAK,UAAU,QAAQ,KAAK,IAAI;EAEnE,KAAK,GAAG;;gBAEI,GAAG,IAAI,KAAK,UAAU,OAAO,EAAE,IAAI,SAAS,IAAI,UAAU;;EAGtE,KAAK,MAAM,gBAAgB;GAAY;GAAoB;EAAG,CAAC;EAE/D,KAAU,YAAY,CAAC,CAAC,OAAO,MAAM;GACnC,QAAQ,MAAM,yBAAyB,CAAC;EAC1C,CAAC;EAED,OAAO;CACT;CAIA,MAAc,cAAc;EAC1B,IAAI,KAAK,gBACP;EAEF,KAAK,iBAAiB;EACtB,IAAI;GACF,OAAO,MAAM;IACX,MAAM,SAAS,KAAK,GAAsB;;;;IAK1C,IAAI,CAAC,UAAU,OAAO,WAAW,GAC/B;IAGF,KAAK,MAAM,OAAO,UAAU,CAAC,GAAG;KAC9B,MAAM,WAAW,KAAK,IAAI;KAC1B,IAAI,CAAC,UAAU;MACb,QAAQ,MAAM,YAAY,IAAI,SAAS,WAAW;MAClD,MAAM,KAAK,QAAQ,IAAI,EAAE;MACzB;KACF;KACA,MAAM,EAAE,YAAY,SAAS,UAAUA,sCAAa,SAAS,KAAK,CAAC;KACnE,MAAM,gBACJ;MACE,OAAO;MACP;MACA;MACA;KACF,GACA,YAAY;MAIV,MAAM,EAAE,aAAa,aAAa,eAChC,mBAJgB,kBAChB,GAG2B,GAAG,KAAK,iBAAiB,KAAK;MAC3D,MAAM,gBAAgB,KAAK,MAAM,IAAI,OAAiB;MACtD,IAAI;OACF,MAAM,KACJ,aACA,OAAO,YAAY;QACjB,IAAI,UAAU,GACZ,KAAK,MAAM,eAAe;SACxB,UAAU,IAAI;SACd,IAAI,IAAI;SACR;SACA;QACF,CAAC;QAEH,MACE,SAIA,KAAK,IAAI,CAAC,CAAC,eAAe,GAAG;OACjC,GACA;QAAE;QAAa;OAAW,CAC5B;MACF,SAAS,GAAG;OACV,QAAQ,MACN,mBAAmB,IAAI,SAAS,iBAAiB,YAAY,YAC7D,CACF;OACA,KAAK,MAAM,eAAe;QACxB,UAAU,IAAI;QACd,IAAI,IAAI;QACR,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;QAChD,UAAU;OACZ,CAAC;OACD,IAAI;QACF,MAAM,KAAK,QAAQ,CAAC;OACtB,QAAQ,CAER;MACF,UAAU;OACR,KAAK,QAAQ,IAAI,EAAE;MACrB;KACF,GAGA,EAAE,UAAU,KAAK,CACnB;IACF;GACF;EACF,UAAU;GACR,KAAK,iBAAiB;EACxB;CACF;;;;;CAMA,QAAQ,IAAY;EAClB,KAAK,GAAG,2CAA2C;CACrD;;;;CAKA,aAAa;EACX,KAAK,GAAG;CACV;;;;;CAMA,qBAAqB,UAAkB;EACrC,KAAK,GAAG,iDAAiD;CAC3D;;;;;;CAOA,SAAS,IAA2C;EAClD,MAAM,SAAS,KAAK,GAAsB;kDACI,GAAG;;EAEjD,IAAI,CAAC,UAAU,OAAO,WAAW,GAAG,OAAO,KAAA;EAC3C,MAAM,MAAM,OAAO;EACnB,OAAO;GACL,GAAG;GACH,SAAS,KAAK,MAAM,IAAI,OAA4B;GACpD,OAAO,kBAAkB,GAAyC;EACpE;CACF;;;;;;;CAQA,UAAU,KAAa,OAAoC;EAIzD,OAAO,KAHa,GAAsB;;MAIvC,QACE,QAAQ,KAAK,MAAM,IAAI,OAA4B,CAAC,CAAC,SAAS,KACjE,CAAC,CACA,KAAK,SAAS;GACb,GAAG;GACH,SAAS,KAAK,MAAM,IAAI,OAA4B;GACpD,OAAO,kBAAkB,GAAyC;EACpE,EAAE;CACN;CAEA,yBAAoE;EAClE,OAAO,KAAK,eAAe,sBAAsB;CACnD;CAEA,sBACE,UACkB;EAClB,OAAO,KAAK,eAAe,qBAAqB,QAAQ;CAC1D;CAEA,wBACE,QACA,UACkB;EAClB,OAAO,KAAK,eAAe,uBAAuB,QAAQ,QAAQ;CACpE;;CAGA,mBACE,QACA,UACkB;EAClB,OAAO,KAAK,eAAe,eAAe,QAAQ,QAAQ;CAC5D;CAEA,kBAAwD;EACtD,OAAO,KAAK,eAAe,eAAe;CAC5C;;;;;;;;;;;CAcA,MAAM,uBACJ,WACe;EACf,MAAM,KAAK,eAAe,cAAc,SAAS;CACnD;;;;;;;CAQA,0BACE,WACiB;EACjB,OAAO,KAAK,eAAe,iBAAiB,SAAS;CACvD;;;;;;CAOA,0BAA0B,OAA8B;EACtD,OAAO,KAAK,eAAe,iBAAiB,KAAK;CACnD;;;;;;;CAQA,qBACE,WACA,OACe;EACf,OAAO,KAAK,eAAe,YAAY,WAAW,KAAK;CACzD;;;;;CAMA,uBACE,WACA,OACe;EACf,OAAO,KAAK,eAAe,cAAc,WAAW,KAAK;CAC3D;;;;;;;;;;;;;;;;;;;;;;;CAwBA,SACE,MACA,UACA,SACA,SACsB;EAGtB,OAAO,KAAK,UAAU,IACpB,MACA,UACA,SACA,OACF;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BA,cACE,iBACA,UACA,SACA,SACsB;EAGtB,OAAO,KAAK,UAAU,MAAM,iBAAiB,UAAoB,SAAS;GACxE,OAAO,SAAS;GAChB,YAAY,SAAS;EACvB,CAAC;CACH;;;;;;;;;CAUA,YAAwB,IAAqC;EAC3D,OAAO,KAAK,UAAU,sCAAyC,EAAE;CACnE;;;;;;;;;;CAWA,gBAAgB,IAAoD;EAClE,OAAO,KAAK,UAAU,IAAI,EAAE;CAC9B;;;;;;;;;CAUA,aAAyB,WAA6B,CAAC,GAAkB;EACvE,OAAO,KAAK,UAAU,uCAA0C,QAAQ;CAC1E;;;;;;;;;;CAWA,cAAc,WAA6B,CAAC,GAAiC;EAC3E,OAAO,KAAK,UAAU,KAAK,QAAQ;CACrC;;;;;;;;;;;;;;;CAgBA,eAAe,IAA8B;EAC3C,OAAO,KAAK,UAAU,OAAO,EAAE;CACjC;;;;;;;;;;;;;;;;;;;;;;;;CAyBA,MAAM,YAAiC;EACrC,IAAI,KAAK,UAAU;GACjB,MAAM,OAAO,MAAM,KAAK,gBAAgB;GACxC,MAAM,QAAQ,MAAM,KAAK,0BAA0B,KAAK,QAAQ;GAChE,IAAI,WAAW;GACf,aAAa;IACX,IAAI,UAAU;IACd,WAAW;IACX,MAAM,UAAU,KAAK,0BAA0B,KAAK,CAAC,CAAC,OAAO,MAAM;KACjE,QAAQ,MAAM,8CAA8C,CAAC;IAC/D,CAAC;IACD,KAAK,IAAI,UAAU,OAAO;GAC5B;EACF;EAEA,KAAK;EAEL,IAAI,KAAK,mBAAmB,GAC1B,MAAM,KAAK,cAAc;EAG3B,IAAI,WAAW;EACf,aAAa;GACX,IAAI,UAAU;GACd,WAAW;GACX,KAAK,iBAAiB,KAAK,IAAI,GAAG,KAAK,iBAAiB,CAAC;GAMzD,IAAI,KAAK,mBAAmB,GAC1B,KAAK,IAAI,UACP,KAAK,cAAc,CAAC,CAAC,OAAO,MAAM;IAChC,QAAQ,MACN,+DACA,CACF;GACF,CAAC,CACH;EAEJ;CACF;;;;;;;;;;;;;;;;;CAkBA,MAAM,eAAkB,IAAkC;EACxD,MAAM,UAAU,MAAM,KAAK,UAAU;EACrC,IAAI;GACF,OAAO,MAAM,GAAG;EAClB,UAAU;GACR,QAAQ;EACV;CACF;CAIA,uBAA+B,QAA8B;EAC3D,OACE,WAAW,eACX,WAAW,aACX,WAAW,iBACX,WAAW;CAEf;CAEA,4BAAoC,SAAuB;EACzD,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,OAAO,CAAC,KAAK,uBAAuB,IAAI,MAAM,GAChD;EAGF,MAAM,UAAU,KAAK,6BAA6B,IAAI,OAAO;EAC7D,IAAI,CAAC,SACH;EAGF,KAAK,6BAA6B,OAAO,OAAO;EAChD,KAAK,MAAM,WAAW,SACpB,QAAQ;CAEZ;CAEA,6BAAqC,SAAgC;EACnE,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,OAAO,KAAK,uBAAuB,IAAI,MAAM,GAChD,OAAO,QAAQ,QAAQ;EAGzB,OAAO,IAAI,SAAe,YAAY;GACpC,IAAI,UAAU,KAAK,6BAA6B,IAAI,OAAO;GAC3D,IAAI,CAAC,SAAS;IACZ,0BAAU,IAAI,IAAI;IAClB,KAAK,6BAA6B,IAAI,SAAS,OAAO;GACxD;GACA,QAAQ,IAAI,OAAO;EACrB,CAAC;CACH;CAEA,4BACE,QACyB;EACzB,IAAI,CAAC,QAAQ,OAAO;EACpB,OAAO,IAAI,IAAI,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC;CAC1D;CAEA,sBACE,OACgC;EAChC,IAAI,UAAU,MAAM,OAAO;EAC3B,IAAI;GACF,MAAM,SAAS,KAAK,MAAM,KAAK;GAC/B,IACE,WAAW,QACX,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,MAAM,GAErB,OAAO;EAEX,QAAQ,CAER;EACA,OAAO;CACT;CAEA,oBAA4B,OAA2C;EACrE,IAAI,UAAU,MAAM,OAAO,KAAA;EAC3B,IAAI;GACF,OAAO,KAAK,MAAM,KAAK;EACzB,QAAQ;GACN;EACF;CACF;CAEA,mBAA2B,OAAwB;EACjD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAC9D;CAEA,wBAAgC,UAAkC;EAChE,OAAO,aAAa,KAAA,IAAY,OAAO,KAAK,UAAU,QAAQ;CAChE;CAEA,2BACE,QACe;EACf,IAAI,OAAO,WAAW,SACpB,OAAO,OAAO,UAAU,KAAA,IACpB,OACA,KAAK,mBAAmB,OAAO,KAAK;EAE1C,IAAI,OAAO,WAAW,aAAa,OAAO,WAAW,eACnD,OAAO,OAAO,UAAU;EAE1B,OAAO;CACT;CAEA,iCACE,SACA,QACM;EACN,MAAM,cAAc,KAAK,IAAI;EAC7B,MAAM,WAAW,KAAK,wBAAwB,OAAO,QAAQ;EAC7D,MAAM,eAAe,KAAK,2BAA2B,MAAM;EAC3D,MAAM,WACJ,OAAO,WAAW,eAAe,OAAO,aAAa,KAAA,IACjD,KAAK,UAAU,OAAO,QAAQ,IAC9B,KAAA;EAEN,IAAI,aAAa,KAAA,GAAW;GAC1B,KAAK,GAAG;;uBAES,OAAO,OAAO;kCACH,SAAS;8BACb,SAAS;8BACT,aAAa;6BACd,YAAY;2BACd,QAAQ;;;GAG7B,KAAK,4BAA4B,OAAO;GACxC;EACF;EAEA,KAAK,GAAG;;qBAES,OAAO,OAAO;gCACH,SAAS;4BACb,aAAa;2BACd,YAAY;yBACd,QAAQ;;;EAG7B,KAAK,4BAA4B,OAAO;CAC1C;CAEA,6BACE,SACA,SACA,QACM;EACN,MAAM,cAAc,KAAK,IAAI;EAC7B,IAAI,QAAQ,IAAI;GACd,KAAK,GAAG;;mDAEqC,YAAY;2BACpC,QAAQ;;GAE7B,KAAK,4BAA4B,OAAO;GACxC;EACF;EAEA,MAAM,UAAU,KAAK,mBAAmB,QAAQ,KAAK;EACrD,MAAM,SAAsB,OAAO,UAAU,YAAY;EACzD,KAAK,GAAG;;qBAES,OAAO;4BACA,QAAQ;2BACT,YAAY;yBACd,QAAQ;;EAE7B,KAAK,4BAA4B,OAAO;CAC1C;CAEA,4BACE,SACA,cACgB;EAChB,IAAI,CAAC,cAAc,OAAO;EAC1B,IAAI;GACF,OAAO,KAAK,MAAM,YAAY;EAChC,QAAQ;GACN,QAAQ,KACN,wCAAwC,QAAQ,mBAClD;GACA,OAAO;EACT;CACF;CAEA,sBACE,KACA,YACA,WACyB;EACzB,OAAO;GACL,SAAS,IAAI;GACb,WAAW,IAAI;GACf,SAAS,eAAe;GACxB,gBAAgB,IAAI;GACpB,WAAW,cAAc,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,IAAI;EAChE;CACF;CAEA,MAAc,0BACZ,KACA,WACY;EACZ,MAAM,YAAY,KAAK,iBAAiB;EACxC,IAAI,aAAa,GAAG,OAAO,UAAU;EAMrC,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,QAAQ,KAAK,CACxB,UAAU,GACV,IAAI,SAAY,GAAG,WAAW;IAC5B,QAAQ,iBAAiB;KACvB,uBACE,IAAI,MACF,uCAAuC,UAAU,UAAU,IAAI,KAAK,KAAK,IAAI,GAAG,EAClF,CACF;IACF,GAAG,SAAS;GACd,CAAC,CACH,CAAC;EACH,UAAU;GACR,IAAI,UAAU,KAAA,GAAW,aAAa,KAAK;EAC7C;CACF;CAEA,4BACE,KACA,YACA,OACA,WACA,SAAS,iBACH;EACN,MAAM,eAAe,KAAK,mBAAmB,KAAK;EAClD,MAAM,cAAc,KAAK,IAAI;EAC7B,IAAI,YAAY;GACd,KAAK,GAAG;;;8BAGgB,aAAa;6BACd,YAAY;2BACd,IAAI,GAAG;;;GAG5B,KAAK,4BAA4B,IAAI,EAAE;EACzC;EACA,KAAK,MAAM,yBAAyB;GAClC,GAAG,KAAK,sBAAsB,KAAK,YAAY,SAAS;GACxD,OAAO;GACP;EACF,CAAC;CACH;CAEA,MAAc,sBACZ,KACA,YACkB;EAClB,MAAM,YAAY,KAAK,IAAI;EAC3B,KAAK,MACH,0BACA,KAAK,sBAAsB,KAAK,UAAU,CAC5C;EACA,IAAI;GACF,MAAM,UAAU,MAAM,KAAK,0BAA0B,WACnD,KAAK,6BAA6B,GAAG,CACvC;GACA,IAAI,CAAC,SAAS;IACZ,MAAM,iBAAiB,MAAM,KAAK,iBAAiB,GAAG;IACtD,IAAI,cAAc,gBAChB,KAAK,iCAAiC,IAAI,IAAI,cAAc;GAEhE;GACA,KAAK,MAAM,0BAA0B;IACnC,GAAG,KAAK,sBAAsB,KAAK,YAAY,SAAS;IACxD,QAAQ,UAAU,aAAa,aAAa,YAAY;GAC1D,CAAC;GACD,OAAO;EACT,SAAS,GAAG;GACV,KAAK,4BAA4B,KAAK,YAAY,GAAG,SAAS;GAC9D,QAAQ,MACN,sCAAsC,IAAI,KAAK,KAAK,IAAI,GAAG,KAC3D,CACF;GACA,OAAO;EACT;CACF;CAEA,wBAAgC,KAAsC;EACpE,MAAM,WAAW,KAAK,oBAAoB,IAAI,QAAQ;EACtD,MAAM,aAA8B;GAClC,SAAS,IAAI;GACb,MAAM,IAAI;GACV,QAAQ,IAAI;GACZ,WAAW,IAAI;EACjB;EAEA,IAAI,IAAI,oBAAoB,MAC1B,WAAW,iBAAiB,IAAI;EAElC,IAAI,aAAa,KAAA,GACf,WAAW,WAAW;EAExB,IAAI,IAAI,kBAAkB,MACxB,WAAW,QAAQ,IAAI;EAEzB,MAAM,WAAW,KAAK,sBAAsB,IAAI,aAAa;EAC7D,IAAI,aAAa,MACf,WAAW,WAAW;EAExB,IAAI,IAAI,eAAe,MACrB,WAAW,YAAY,IAAI;EAE7B,IAAI,IAAI,iBAAiB,MACvB,WAAW,YAAY,IAAI;EAG7B,OAAO;CACT;CAEA,MAAc,qBACZ,SACiC;EACjC,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,OAAO,KAAK,uBAAuB,IAAI,MAAM,GAChD,OAAO,MAAM,KAAK,wBAAwB,GAAG,IAAI;EAGnD,IAAI,KAAK,wBAAwB,IAAI,OAAO,GAAG;GAC7C,MAAM,KAAK,6BAA6B,OAAO;GAC/C,OAAO,KAAK,aAAa,OAAO;EAClC;EAEA,MAAM,KAAK,gBAAgB;EAC3B,MAAM,KAAK,6BAA6B,OAAO;EAC/C,OAAO,KAAK,aAAa,OAAO;CAClC;CAEA,WAAmB,SAAwC;EAQzD,OAAO,KAPW,GAAmB;;;;yBAIhB,QAAQ;;MAGjB,MAAM;CACpB;CAEA,gBAAwB,gBAA+C;EAQrE,OAAO,KAPW,GAAmB;;;;gCAIT,eAAe;;MAG/B,MAAM;CACpB;CAEA,eAAuB,SAA+C;EACpE,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,SAAS,IAAI,CAAC,GAAG,GAAG;EAC7D,MAAM,WAAW,KAAK,4BAA4B,SAAS,MAAM;EACjE,IAAI,UACF,OAAO,CAAC,GAAG,QAAQ,CAAC,CACjB,SAAS,WACR,KAAK,uBAAuB,QAAQ,OAAO,SAAS,IAAI,CAC1D,CAAC,CACA,MAAM,GAAG,MACR,EAAE,eAAe,EAAE,aACf,EAAE,SAAS,cAAc,EAAE,QAAQ,IACnC,EAAE,aAAa,EAAE,UACvB,CAAC,CACA,MAAM,GAAG,KAAK;EAGnB,IAAI,SAAS,MACX,OAAO,KAAK,GAAmB;;;;uBAId,QAAQ,KAAK;;gBAEpB,MAAM;;EAIlB,OAAO,KAAK,GAAmB;;;;;cAKrB,MAAM;;CAElB;CAEA,uBACE,QACA,OACA,MACkB;EAClB,IAAI,MACF,OAAO,KAAK,GAAmB;;;;yBAIZ,OAAO,cAAc,KAAK;;gBAEnC,MAAM;;EAIlB,OAAO,KAAK,GAAmB;;;;uBAIZ,OAAO;;cAEhB,MAAM;;CAElB;CAEA,MAAM,aAAa,SAAkD;EACnE,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,OAAO,MAAM,KAAK,wBAAwB,GAAG,IAAI;CACnD;CAEA,MAAM,kBACJ,gBACiC;EACjC,MAAM,MAAM,KAAK,gBAAgB,cAAc;EAC/C,OAAO,MAAM,KAAK,wBAAwB,GAAG,IAAI;CACnD;CAEA,MAAM,WAAW,SAAyD;EACxE,OAAO,KAAK,eAAe,OAAO,CAAC,CAAC,KAAK,QACvC,KAAK,wBAAwB,GAAG,CAClC;CACF;CAEA,MAAM,YAAY,SAAiB,QAAmC;EACpE,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,OAAO,KAAK,uBAAuB,IAAI,MAAM,GAChD,OAAO;EAGT,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,GAAG;;;4BAGgB,UAAU,KAAK;2BAChB,IAAI;yBACN,QAAQ;;;EAG7B,KAAK,8BAA8B,IAAI,OAAO,CAAC,EAAE,MAAM,MAAM;EAC7D,KAAK,4BAA4B,OAAO;EACxC,OAAO;CACT;CAEA,MAAM,iBACJ,gBACA,QACkB;EAClB,MAAM,MAAM,KAAK,gBAAgB,cAAc;EAC/C,OAAO,MAAM,KAAK,YAAY,IAAI,UAAU,MAAM,IAAI;CACxD;CAEA,MAAM,aACJ,SACA,QACkB;EAClB,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,OAAO,IAAI,WAAW,eACzB,OAAO;EAGT,KAAK,iCAAiC,SAAS,MAAM;EACrD,OAAO;CACT;CAEA,MAAM,aAAa,SAAgD;EAIjE,MAAM,mBAAmB,CAAC,GAFxB,KAAK,4BAA4B,SAAS,MAAM,qBAChD,IAAI,IAAiB;GAAC;GAAa;GAAW;EAAO,CAAC,CACnB,CAAC,CAAC,QAAQ,WAC7C,KAAK,uBAAuB,MAAM,CACpC;EACA,IAAI,iBAAiB,WAAW,GAC9B,OAAO;EAGT,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,SAAS,KAAK,CAAC,GAAG,GAAG;EAC9D,MAAM,gBAAgB,SAAS,eAAe,QAAQ;EACtD,MAAM,OAAO,iBACV,SAAS,WACR,KAAK,gCAAgC,QAAQ,OAAO,aAAa,CACnE,CAAC,CACA,MAAM,GAAG,MACR,EAAE,iBAAiB,EAAE,eACjB,EAAE,aAAa,EAAE,cAChB,EAAE,gBAAgB,MAAM,EAAE,gBAAgB,EACjD,CAAC,CACA,MAAM,GAAG,KAAK;EAEjB,KAAK,MAAM,OAAO,MAChB,KAAK,GAAG;;2BAEa,IAAI,SAAS;;;EAKpC,OAAO,KAAK;CACd;CAEA,gCACE,QACA,OACA,eACkB;EAClB,IAAI,kBAAkB,KAAA,GACpB,OAAO,KAAK,GAAmB;;;;yBAIZ,OAAO;;+BAED,cAAc;;gBAE7B,MAAM;;EAIlB,OAAO,KAAK,GAAmB;;;;uBAIZ,OAAO;;cAEhB,MAAM;;CAElB;;;;;;;;;;;;;;CAiBA,MAAM,SACJ,MACA,IACY;EACZ,OAAO,KAAK,kBAAkB,OAAO,GAAG,MAAM,EAAE;CAClD;;;;;;;;;;CAWA,MAAgB,0BACd,MACA,IACA,SACY;EACZ,OAAO,KAAK,kBAAkB,OAAO,GAAG,MAAM,IAAI,OAAO;CAC3D;CAEA,MAAM,WACJ,MACA,IACA,SAC2B;EAC3B,MAAM,UAAU,SAAS,WAAW,OAAO;EAC3C,MAAM,iBAAiB,SAAS;EAChC,IAAI,SAAS,YAAY,KAAA,KAAa,QAAQ,QAAQ,KAAK,MAAM,IAC/D,MAAM,IAAI,MAAM,2BAA2B;EAE7C,IACE,SAAS,mBAAmB,KAAA,KAC5B,QAAQ,eAAe,KAAK,MAAM,IAElC,MAAM,IAAI,MAAM,kCAAkC;EAEpD,MAAM,eAAe,KAAK,WAAW,OAAO;EAC5C,MAAM,gBAAgB,iBAClB,KAAK,gBAAgB,cAAc,IACnC;EAEJ,IACE,gBACA,iBACA,aAAa,aAAa,cAAc,UAExC,MAAM,IAAI,MAAM,sDAAsD;EAExE,IACE,iBACA,SAAS,WACT,cAAc,aAAa,SAE3B,MAAM,IAAI,MAAM,sDAAsD;EAGxE,MAAM,WAAW,gBAAgB;EACjC,IAAI,UAAU;GACZ,IACE,SAAS,qBACT,CAAC,KAAK,uBAAuB,SAAS,MAAM,GAC5C;IACA,MAAM,SAAS,MAAM,KAAK,qBAAqB,SAAS,QAAQ;IAChE,IAAI,QACF,OAAO;KACL,GAAG;KACH,UAAU;IACZ;IAEF,MAAM,IAAI,MAAM,SAAS,SAAS,SAAS,kBAAkB;GAC/D;GACA,OAAO;IACL,GAAG,KAAK,wBAAwB,QAAQ;IACxC,UAAU;GACZ;EACF;EAEA,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,GAAG;;;;;WAKD,QAAQ,IAAI,kBAAkB,KAAK,IAAI,KAAK;WAC5C,SAAS,WAAW,KAAK,UAAU,QAAQ,QAAQ,IAAI,KAAK;WAC5D,IAAI;;EAGX,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,0BAA0B,SAAS;EAGrD,MAAM,YAAY,KAAK,qBAAqB,SAAS,MAAM,EAAE,CAAC,CAC3D,OAAO,UAAU;GAChB,QAAQ,MACN,0BAA0B,KAAK,KAAK,QAAQ,YAC5C,KACF;EACF,CAAC,CAAC,CACD,cAAc;GACb,IAAI,KAAK,wBAAwB,IAAI,OAAO,MAAM,WAChD,KAAK,wBAAwB,OAAO,OAAO;EAE/C,CAAC;EACH,KAAK,wBAAwB,IAAI,SAAS,SAAS;EAEnD,IAAI,SAAS,mBAAmB;GAC9B,MAAM,YAAY,MAAM,KAAK,qBAAqB,OAAO;GACzD,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,SAAS,QAAQ,kBAAkB;GAErD,OAAO;IACL,GAAG;IACH,UAAU;GACZ;EACF;EAEA,OAAO;GACL,GAAG,KAAK,wBAAwB,GAAG;GACnC,UAAU;EACZ;CACF;CAEA,MAAc,qBACZ,SACA,MACA,IACe;EACf,MAAM,MAAM,KAAK,WAAW,OAAO;EACnC,IAAI,CAAC,OAAO,IAAI,WAAW,WACzB;EAGF,MAAM,aAAa,IAAI,gBAAgB;EACvC,KAAK,8BAA8B,IAAI,SAAS,UAAU;EAC1D,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,GAAG;;6CAEiC,IAAI;yBACxB,QAAQ;;EAG7B,MAAM,UAAU,KAAK,WAAW,OAAO;EACvC,IAAI,CAAC,WAAW,QAAQ,WAAW,WAAW;GAC5C,KAAK,8BAA8B,OAAO,OAAO;GACjD;EACF;EAEA,IAAI,UAAU;EACd,IAAI;GACF,MAAM,KAAK,kBAAkB,SAAS,MAAM,IAAI;IAC9C,QAAQ,WAAW;IACnB,SAAS;IACT,mBAAmB,YAAY;KAC7B,UAAU;KACV,KAAK,6BACH,SACA,SACA,WAAW,MACb;IACF;GACF,CAAC;EACH,SAAS,OAAO;GACd,IAAI,CAAC,SACH,KAAK,6BACH,SACA;IAAE,IAAI;IAAO;GAAM,GACnB,WAAW,MACb;EAEJ,UAAU;GACR,KAAK,8BAA8B,OAAO,OAAO;EACnD;CACF;CAEA,MAAc,kBACZ,IACA,MACA,IACA,SACY;EACZ,MAAM,SAAS,SAAS,UAAU,IAAI,gBAAgB,CAAC,CAAC;EACxD,KAAK,eACH,oBACA,SACA;GACE,8BAA8B;GAC9B,gCAAgC;EAClC,SACM;GACJ,KAAK,GAAG;;oBAEI,GAAG,IAAI,KAAK,UAAU,KAAK,IAAI,EAAE;;EAE/C,CACF;EACA,MAAM,YAAY,KAAK,IAAI;EAC3B,KAAK,MAAM,qBAAqB;GAC9B,SAAS;GACT,WAAW;GACX,SAAS,SAAS,YAAY;EAChC,CAAC;EACD,KAAK,sBAAsB,IAAI,EAAE;EAEjC,MAAM,iBAAiB,SAAkB;GACvC,MAAM,WAAW,KAAK,UAAU,IAAI;GACpC,KAAK,eACH,0BACA,SACA;IACE,8BAA8B;IAC9B,gCAAgC;GAClC,SACM;IACJ,KAAK,GAAG;mDACiC,SAAS;yBACnC,GAAG;;IAElB,IAAI,SAAS,SACX,KAAK,GAAG;uDACmC,SAAS;iCAC/B,GAAG;;GAG5B,CACF;EACF;EAEA,IAAI;EACJ,IAAI,qBAAqB;EACzB,IAAI,gBAA4B,CAAC;EACjC,IAAI;GACF,IAAI,sBAAsB,WAAW,CAAC,IACpC,cAAc,SAAS,eAAe;GAGxC,IAAI,KAAK,UAAU;IACjB,OAAO,MAAM,KAAK,gBAAgB;IAClC,MAAM,KAAK,qBAAqB,KAAK,UAAU,EAAE;IACjD,qBAAqB;GACvB;GAEA,UAAU,MAAM,KAAK,UAAU;GAC/B,MAAM,SAAS,SAAkB;IAC/B,cAAc,SAAS,YAAY,QAAQ,UAAU,IAAI,IAAI,IAAI;GACnE;GAEA,IAAI;IACF,MAAM,SAAS,MAAM,UAAU,IAAI;KAAE;KAAI;KAAQ;IAAM,SACrD,GAAG;KAAE;KAAI;KAAQ;KAAO,UAAU;IAAK,CAAC,CAC1C;IACA,SAAS,mBAAmB,EAAE,IAAI,KAAK,CAAC;IACxC,KAAK,MAAM,uBAAuB;KAChC,SAAS;KACT,WAAW;KACX,SAAS,SAAS,YAAY;KAC9B,WAAW,KAAK,IAAI,IAAI;IAC1B,CAAC;IACD,OAAO;GACT,SAAS,OAAO;IACd,SAAS,mBAAmB;KAAE,IAAI;KAAO;IAAM,CAAC;IAChD,KAAK,MAAM,oBAAoB;KAC7B,SAAS;KACT,WAAW;KACX,SAAS,SAAS,YAAY;KAC9B,OAAO,KAAK,mBAAmB,KAAK;KACpC,WAAW,KAAK,IAAI,IAAI;IAC1B,CAAC;IACD,MAAM;GACR;EACF,UAAU;GACR,KAAK,sBAAsB,OAAO,EAAE;GACpC,KAAK,eACH,kBACA,SACA;IACE,8BAA8B;IAC9B,gCAAgC;GAClC,SACM;IACJ,KAAK,GAAG,yCAAyC;GACnD,CACF;GACA,QAAQ;GACR,IAAI,QAAQ,oBACV,IAAI;IACF,MAAM,KAAK,uBAAuB,KAAK,UAAU,EAAE;GACrD,SAAS,GAAG;IAIV,QAAQ,MAAM,6CAA6C,CAAC;GAC9D;EAEJ;CACF;;;;;;;;CASA,MAAM,MAAqB;EACzB,MAAM,MAAM,UAAU,SAAS;EAC/B,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,gCAAgC;EAElD,IAAI,MAAM,IAAI;CAChB;;;;;;;CAQA,gBACE,SAKA,IACY;EACZ,OAAO,UAAU,IAAI,SAAS,EAAE;CAClC;;;;;;;;;;CAWA,MAAM,iBAEJ,MACqC;EACrC,QAAQ,KACN,kBAAkB,KAAK,KAAK,KAAK,KAAK,GAAG,iEAE3C;CACF;;;;;;CAOA,MAAgB,6BAEd,MACkB;EAClB,OAAO;CACT;;CAGA,MAAc,kBAAiC;EAC7C,IAAI,KAAK,6BAA6B;EACtC,KAAK,8BAA8B;EACnC,MAAM,gBAAgB,KAAK,IAAI;EAC/B,MAAM,iBAAiB,KAAK,iBAAiB;EAC7C,MAAM,wBAAwB,KAAK,iBAAiB;EAIpD,IAAI,eAAe;EAEnB,IAAI;GACF,MAAM,OAAO,KAAK,GAKhB;GAEF,KAAK,MAAM,OAAO,MAAM;IACtB,IAAI,iBAAiB,KAAK,KAAK,IAAI,IAAI,gBAAgB,gBAAgB;KACrE,KAAK,MAAM,0BAA0B;MACnC,SAAS,IAAI;MACb,WAAW,IAAI;MACf,QAAQ;MACR,WAAW,KAAK,IAAI,IAAI;KAC1B,CAAC;KACD;IACF;IACA,IAAI,KAAK,sBAAsB,IAAI,IAAI,EAAE,GAAG;IAE5C,MAAM,WAAW,KAAK,4BAA4B,IAAI,IAAI,IAAI,QAAQ;IACtE,MAAM,MAA4B;KAChC,IAAI,IAAI;KACR,MAAM,IAAI;KACV;KACA,WAAW,IAAI;KACf,gBAAgB;IAClB;IAEA,MAAM,aAAa,KAAK,WAAW,IAAI,EAAE;IACzC,KAAK,MAAM,2BAA2B;KACpC,GAAG,KAAK,sBAAsB,KAAK,UAAU;KAC7C,WAAW,KAAK,IAAI,IAAI,IAAI;IAC9B,CAAC;IACD,KAAK,MAAM,yBAAyB;KAClC,SAAS,IAAI;KACb,WAAW,IAAI;KACf,SAAS,eAAe;KACxB,gBAAgB;KAChB,WAAW,KAAK,IAAI,IAAI,IAAI;IAC9B,CAAC;IACD,IAAI,YAAY;KACd,IAAI,KAAK,uBAAuB,WAAW,MAAM,GAAG;MAClD,KAAK,GAAG,yCAAyC,IAAI;MACrD,eAAe;MACf,KAAK,4BAA4B,IAAI,EAAE;MACvC;KACF;KAEA,MAAM,cAAc,KAAK,IAAI;KAC7B,KAAK,GAAG;;;6BAGW,IAAI,SAAS;iCACT,YAAY;+BACd,IAAI,GAAG;;;KAG5B,IAAI,iBAAiB,WAAW,mBAAmB,KAAA;KACnD,IAAI,WAAW,KAAK,sBAAsB,WAAW,aAAa;KAClE,IAAI,SAAS;IACf;IAEA,MAAM,YAAY,MAAM,KAAK,sBAAsB,KAAK,UAAU;IAKlE,MAAM,SACJ,wBAAwB,KACxB,KAAK,IAAI,IAAI,IAAI,aAAa;IAChC,IAAI,aAAa,cAAc,QAAQ;KACrC,IAAI,CAAC,aAAa,CAAC,cAAc,QAC/B,KAAK,MAAM,0BAA0B;MACnC,SAAS,IAAI;MACb,WAAW,IAAI;MACf,QAAQ;MACR,WAAW,KAAK,IAAI,IAAI,IAAI;KAC9B,CAAC;KAEH,KAAK,GAAG,yCAAyC,IAAI;KACrD,eAAe;IACjB;IACA,IAAI,YACF,KAAK,4BAA4B,IAAI,EAAE;GAE3C;GAEA,MAAM,iBAAiB,KAAK,GAAmB;;;;;;;;;GAU/C,KAAK,MAAM,OAAO,gBAAgB;IAChC,IAAI,iBAAiB,KAAK,KAAK,IAAI,IAAI,gBAAgB,gBAAgB;KACrE,KAAK,MAAM,0BAA0B;MACnC,SAAS,IAAI;MACb,WAAW,IAAI;MACf,QAAQ;MACR,WAAW,KAAK,IAAI,IAAI;MACxB,SAAS;KACX,CAAC;KACD;IACF;IACA,IAAI,KAAK,sBAAsB,IAAI,IAAI,QAAQ,GAAG;IAElD,MAAM,WAAW,KAAK,4BACpB,IAAI,UACJ,IAAI,QACN;IACA,MAAM,cAAc,KAAK,IAAI;IAC7B,KAAK,GAAG;;;+BAGe,YAAY;6BACd,IAAI,SAAS;;;IAIlC,MAAM,MAA4B;KAChC,IAAI,IAAI;KACR,MAAM,IAAI;KACV;KACA,WAAW,IAAI;KACf,gBAAgB,IAAI,mBAAmB,KAAA;KACvC,UAAU,KAAK,sBAAsB,IAAI,aAAa;KACtD,QAAQ;KACR,gBAAgB;IAClB;IACA,KAAK,MAAM,2BAA2B;KACpC,GAAG,KAAK,sBAAsB,KAAK,GAAG;KACtC,WAAW,KAAK,IAAI,IAAI,IAAI;IAC9B,CAAC;IACD,KAAK,MAAM,yBAAyB;KAClC,SAAS,IAAI;KACb,WAAW,IAAI;KACf,SAAS;KACT,gBAAgB;KAChB,WAAW,KAAK,IAAI,IAAI,IAAI;IAC9B,CAAC;IAED,MAAM,KAAK,sBAAsB,KAAK,GAAG;IAIzC,eAAe;IACf,KAAK,4BAA4B,IAAI,QAAQ;GAC/C;EACF,UAAU;GACR,KAAK,8BAA8B;GAInC,IAAI,cACF,KAAK,2BAA2B;QAEhC,KAAK,2BAA2B,KAAK,yBAAyB,IAC1D,KAAK,2BAA2B,IAChC;EAER;CACF;;CAGA,MAAM,uBAAsC;EAC1C,MAAM,KAAK,gBAAgB;EAC3B,MAAM,KAAK,qBAAqB;CAClC;CAEA,uBACE,QACA,MACS;EACT,IAAI,OAAO,SAAS,KAAK,QAAQ,OAAO;EACxC,OAAO,OAAO,OACX,MAAM,UACL,KAAK,cAAc,KAAK,MAAM,CAAC,aAC/B,KAAK,SAAS,KAAK,MAAM,CAAC,IAC9B;CACF;;;;;;;CAQA,uBAA8C;EAC5C,OAAO,KAAK,eAAe,eAAe;CAC5C;;;;;;;CAQA,2BACE,WACiB;EACjB,OAAO,KAAK,eAAe,qBAAqB,SAAS;CAC3D;;;;;;;CAQA,oBACE,YACA,QACA,MACkB;EAClB,OAAO,KAAK,eAAe,gBAAgB,YAAY,QAAQ,IAAI;CACrE;;;;;;;;;;;;;;CAeA,2BACE,YACe;EACf,OAAO,KAAK,eAAe,kBAAkB,UAAU;CACzD;;;;;;;;;;;;CAaA,2BAA4C;EAC1C,MAAM,UAAU,KAAK,GAAmB;;;EAGxC,KAAK,MAAM,OAAO,SAChB,IAAI,CAAC,KAAK,sBAAsB,IAAI,IAAI,EAAE,GAAG,OAAO;EAUtD,QAAQ,KAPgB,GAAsB;;;;;;MAO3B,EAAE,EAAE,SAAS,KAAK;CACvC;;;;;;;;;;;CAYA,MAAc,gBAA+B;EAC3C,IAAI,KAAK,YAAY;EACrB,MAAM,KAAK,eAAe,wBAAwB,SAAS,CAAC,GAAG,YAAY;GACzE,MAAM,OAAO,KAAK,UAAU;GAC5B,MAAM,QAAQ,KAAK,IAAI;GAOvB,MAAM,iBAAiB,MAAM,KAAK,qBAAqB;GACvD,IAAI,mBAAmB,MAAM;IAC3B,MAAM,KAAK,KAAK;KACd,IAAI;KACJ,IAAI;KACJ,MAAM;KACN,WAAW;IACb,CAAC;IACD;GACF;GACA,IAAI,KAAK,IAAI,mBAAmB,GAC9B,MAAM,KAAK,OAAO,mBAAmB;GAGvC,IAAI,KAAK,iBAAiB,GACxB,MAAM,KAAK,KAAK;IACd,IAAI;IACJ,IAAI;IACJ,MAAM,QAAQ,KAAK,iBAAiB;GACtC,CAAC;QACI,IAAI,KAAK,IAAI,sBAAsB,GACxC,MAAM,KAAK,OAAO,sBAAsB;GAG1C,MAAM,iBAAiB,KAAK,wBAAwB,KAAK;GACzD,IAAI,mBAAmB,MACrB,MAAM,KAAK,KAAK;IACd,IAAI;IACJ,IAAI;IACJ,MAAM;GACR,CAAC;QACI,IAAI,KAAK,IAAI,wBAAwB,GAC1C,MAAM,KAAK,OAAO,wBAAwB;EAE9C,CAAC;CACH;;;;;CAMA,wBAAgC,OAA8B;EAC5D,IAAI,aAA4B;EAEhC,IAAI,KAAK,yBAAyB,GAAG;GACnC,MAAM,OAAO,KAAK,iBAAiB;GACnC,MAAM,MAAM,KAAK,IACf,KAAK,0BACL,8BACF;GAKA,aAAa,QAJW,KAAK,IAC3B,+BACA,OAAO,KAAK,GAEqB;EACrC;EAKA,KAAK,KAHkB,GAAsB;;MAG9B,EAAE,EAAE,SAAS,KAAK,GAAG;GAClC,MAAM,kBAAkB,QAAQ,KAAK,iBAAiB;GACtD,aACE,eAAe,OACX,kBACA,KAAK,IAAI,YAAY,eAAe;EAC5C;EAEA,OAAO;CACT;;CAGA,UAAgB,CAAC;;;;;;CAOjB,MACE,SACkE;EAClE,OAAO,KAAK,WAAW,QAAQ,IAAI,IAAI,OAAO;CAChD;;;;;CAMA,WACE,IACA,UACkE;EAClE,QAAQ,IAAR;GACE,KAAK,aAIH,OAAO,KAAK,iBAAiB,IACzB,EACE,cACE,KAAK,IAAI,IAAI,KAAK,iBAAiB,oBACvC,IACA,KAAA;GACN,KAAK,gBAAgB;IACnB,MAAM,OAAO,KAAK,wBAAwB,KAAK,IAAI,CAAC;IACpD,OAAO,SAAS,OAAO,KAAA,IAAY,EAAE,cAAc,KAAK;GAC1D;GACA,KAAK,WAGH;GACF;IACE,QAAQ,KAAK,6BAA6B,KAAK,UAAU,EAAE,GAAG;IAC9D;EACJ;CACF;;;;;;;;;;;;;CAcA,MAAgB,mBACd,SACe;EACf,IAAI,CAAC,QAAQ,QAAQ;EAMrB,MAJE,KAGA,+BACgB,KAAK,IAAI;CAC7B;;;;;;;;;;;;CAaA,MAAM,QAAQ;EAQZ,IAAI,MAAM,KAAK,mBAAmB,GAAG;GACnC,MAAM,KAAK,QAAQ;GACnB;EACF;EAEA,MAAM,KAAK,UAAU,MAAM;CAC7B;;;;;;;;;;;;;;;CAkBA,MAAM,MAAM,SAAqC;EAC/C,MAAM,MAAM,KAAK;EACjB,MAAM,QAAQI,kBAAmB,QAAQ,KAAK,EAC5C,cAAc,IAAI,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAA,EACzD,CAAC;EAED,IAAI,CAAC,OACH,OAAO,KAAK,UAAU,MAAM,OAAO;EAIrC,MAAM,WAAW,MAAM,KAAK,iBAAiB,SAAS;GACpD,WAAW,MAAM;GACjB,MAAM,MAAM;EACd,CAAC;EACD,IAAI,oBAAoB,UAAU,OAAO;EACzC,MAAM,aAAa,oBAAoB,UAAU,WAAW;EAE5D,IAAI,QAAQ,QAAQ,IAAI,SAAS,CAAC,EAAE,YAAY,MAAM,aAAa;GACjE,MAAM,gBAAgB,IAAI,QAAQ,WAAW,OAAO;GACpD,MAAM,YAAY,IAAI,IAAI,WAAW,GAAG;GACxC,UAAU,WAAW,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC;GAC1C,cAAc,IAAI,4BAA4B,UAAU,SAAS,CAAC;GAClE,OAAO,KAAK,UAAU,MACpB,IAAI,QAAQ,YAAY,EAAE,SAAS,cAAc,CAAC,CACpD;EACF;EAEA,OAAO,KAAK,mBAAmB,YAAY,KAAK;CAClD;CAEA,UACE,KACA,SACM;EACN,IAAI,KAAK,UAAU;GACjB,KAAU,eAAe,kBAAkB,KAAK,OAAO;GACvD;EACF;EAEA,KAAK,MAAM,cAAc,KAAK,YAAY,eAAe,GAAG;GAC1D,IAAI,SAAS,SAAS,WAAW,EAAE,GAAG;GACtC,IAAI,KAAK,eAAe,yBAAyB,UAAU,GAAG;GAC9D,WAAW,KAAK,GAAG;EACrB;CACF;CAEA,cAAgC,IAA4C;EAC1E,IAAI,KAAK,UAKP,OAAO,KAAK,eAAe,qBAAqB,EAAE;EAKpD,MAAM,aAAa,KAAK,YAAY,cAAsB,EAAE;EAC5D,IACE,CAAC,cACD,KAAK,eAAe,yBAAyB,UAAU,GAEvD;EAEF,OAAO;CACT;CAEA,CAAC,eACC,KAC8B;EAC9B,IAAI,KAAK,UAAU;GAQjB,OAAO,KAAK,eAAe,sBAAsB,GAAG;GAGpD;EACF;EAEA,KAAK,MAAM,cAAc,KAAK,YAAY,eAAuB,GAAG,GAAG;GACrE,IAAI,KAAK,eAAe,yBAAyB,UAAU,GAAG;GAC9D,MAAM;EACR;CACF;CAEA,MAAM,wBACJ,WACA,SACA,SACe;EACf,MAAM,KAAK,eAAe,gBAAgB,WAAW,SAAS,OAAO;CACvE;CAEA,4BACE,WACmC;EACnC,OAAO,KAAK,eAAe,gBAAgB,SAAS;CACtD;CAEA,6BACE,cACA,SACe;EACf,OAAO,KAAK,eAAe,iBAAiB,cAAc,OAAO;CACnE;CAEA,4BACE,cACA,MACA,QACe;EACf,OAAO,KAAK,eAAe,gBAAgB,cAAc,MAAM,MAAM;CACvE;CAEA,+BACE,cACA,OACkB;EAClB,OAAO,KAAK,eAAe,mBAAmB,cAAc,KAAK;CACnE;CAEA,8BAAwC,YAAiC;EACvE,OAAO,KAAK,eAAe,uBAAuB,UAAU;CAC9D;;;;;;;;;CAUA,2BAAqC,SAA2B;EAC9D,OAAO,KAAK,eAAe,oBAAoB,OAAO;CACxD;CAEA,oCACE,YACA,SACA,SACkB;EAClB,OAAO,KAAK,eAAe,wBACzB,YACA,SACA,OACF;CACF;CAEA,oCACE,YACA,SACA,aACkB;EAClB,OAAO,KAAK,eAAe,wBACzB,YACA,SACA,WACF;CACF;CAEA,kCACE,YACA,MACA,QACA,UACkB;EAClB,OAAO,KAAK,eAAe,sBACzB,YACA,MACA,QACA,QACF;CACF;CAEA,mCACE,QACA,MACe;EACf,OAAO,KAAK,eAAe,uBAAuB,QAAQ,IAAI;CAChE;CAEA,mCACE,SACA,QACA,MACA,cAAwC,QACzB;EACf,OAAO,KAAK,eAAe,uBACzB,SACA,QACA,MACA,WACF;CACF;CAEA,iCACE,MACA,QACA,UACA,QACA,MACe;EACf,OAAO,KAAK,eAAe,qBACzB,MACA,QACA,UACA,QACA,IACF;CACF;CAEA,yCAAkE;EAChE,OAAO,KAAK,eAAe,2BAA2B;CACxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CA,MAAM,iBAEJ,UAEA,QACoC,CAEtC;;;;;;;CAQA,mBACE,KACA,OAKmB;EACnB,OAAO,KAAK,eAAe,QAAQ,KAAK,KAAK;CAC/C;;;;;;;;CASA,mBACE,WACA,MACA,QACA,MACkB;EAClB,OAAO,KAAK,eAAe,OAAO,WAAW,MAAM,QAAQ,IAAI;CACjE;;;;;;;;;CAUA,uBACE,MACA,QACA,MACkB;EAClB,OAAO,KAAK,eAAe,WAAW,MAAM,QAAQ,IAAI;CAC1D;;;;;;;;;;;;;;;;;;;;;;;;;CA4BA,gBACE,MACA,aAAiE,CAAC,GAClE,eAAe,MACA;EACf,OAAO,KAAK,eAAe,KAAK,MAAM,YAAY,YAAY;CAChE;CAEA,IAAI,OAAe;EACjB,MAAM,aAAa,KAAK,UAAU;EAClC,OACE,KAAK,cAAc,8BAA8B,UAAU,KAAK;CAEpE;;;;;;;;;;;;;;;;;CAkBA,IAAI,aAA2C;EAC7C,OAAO,KAAK;CACd;;;;;;CAOA,IAAI,WAAyC;EAC3C,OAAO,CACL,GAAG,KAAK,aACR;GACE,WAAY,KAAK,YAAiC;GAClD,MAAM,KAAK;EACb,CACF;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDA,MAAM,YACJ,KAC+B;EAM/B,MAAM,SAAS,KAAK,YAAY,KAAK,YAAY,SAAS;EAC1D,IAAI,CAAC,QACH,MAAM,IAAI,MACR,kBAAkB,KAAK,YAAY,KAAK,8EAE1C;EAEF,IAAI,IAAI,SAAS,OAAO,WACtB,MAAM,IAAI,MACR,eAAe,IAAI,KAAK,4CACf,OAAO,UAAU,UAAU,IAAI,KAAK,iEAE/C;EAEF,IAAI,KAAK,YAAY,SAAS,GAC5B,OAAO,MAAM,KAAK,0BAChB,IAAI,MACJ,KAAK,WACP;EAGF,MAAM,UAAU,KAAK,oCAAuC,IAAI,IAAI;EACpE,IAAI,CAAC,SACH,MAAM,IAAI,MACR,eAAe,IAAI,KAAK,iCAAiC,IAAI,KAAK,+IAGpE;EAEF,OAAO,MAAM,eAAkC,SAAS,OAAO,IAAI;CACrE;CAEA,oCACE,WACuC;EAIvC,OACE,KAAK,6BACF,KAAK,IAAgC,UACxC,KACA,KAAK,6BACFC,QAA0C,UAC7C;CAEJ;CAEA,6BACE,WACuC;EACvC,MAAM,UAAU;EAChB,OAAO,SAAS,aAAa,UAAU,KAAA;CACzC;CAEA,MAAc,0BACZ,WACA,YAC+B;EAC/B,MAAM,CAAC,QAAQ;EACf,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,eAAe,UAAU,yBAAyB;EAGpE,MAAM,cAAc,KAAK,oCACvB,KAAK,SACP;EACA,IAAI,CAAC,aACH,MAAM,IAAI,MACR,eAAe,UAAU,gEACM,KAAK,UAAU,yDAEhD;EAGF,MAAM,kBAAkB,eACtB,aACA,KAAK,IACP;EACA,MAAM,aAAa,WAAW,KAAK,UAAU,EAAE,GAAG,KAAK,EAAE;EACzD,MAAM,eAAe,OAAO,QAAgB,SAAoB;GAG9D,OAAO,OAAM,MAFU,gBAAA,CAEH,uBAAuB,YAAY,QAAQ,IAAI;EACrE;EACA,MAAM,QAAQ;EACd,OAAO,IAAI,MACT,CAAC,GACD,EACE,IAAI,SAAS,MAAM;GACjB,IAAI,qBAAqB,IAAI,GAAG,OAAO,KAAA;GACvC,IAAI,OAAO,SAAS,UAAU,OAAO,KAAA;GACrC,IAAI,SAAS,SACX,OAAO,OAAO,OAA0B,SAAuB;IAC7D,IAAI,MAAM,8BAA8B,OAAO,IAAI,GACjD,MAAM,IAAI,MACR,eAAe,UAAU,2HAE3B;IAGF,OAAO,MAAM,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC;GAC/C;GAEF,OAAO,OAAO,GAAG,SAAoB;IACnC,OAAO,MAAM,aAAa,MAAM,IAAI;GACtC;EACF,EACF,CACF;CACF;CAEA,8BACE,OACA,MACS;EACT,MAAM,cAAc,MAAM,UAAU,IAAI,QAAQ,KAAK,OAAO,IAAI,KAAA;EAChE,MAAM,iBACJ,iBAAiB,UAAU,IAAI,QAAQ,MAAM,OAAO,IAAI,KAAA;EAC1D,OACE,aAAa,IAAI,SAAS,CAAC,EAAE,YAAY,MAAM,eAC/C,gBAAgB,IAAI,SAAS,CAAC,EAAE,YAAY,MAAM;CAEtD;;;;;;;;;;;;;;;;;;;;;;;CAwBA,MAAM,SACJ,KACA,MAC0B;EAC1B,OAAO,KAAK,cAAc,IAAI,KAAK,IAAI;CACzC;CAKA,MAAM,iBAAiB,MAAuC,CAAC;CAE/D,MAAM,kBACJ,MACA,SACe,CAAC;;;;;;;;CASlB,MAAM,WACJ,MACA,WACe,CAAC;;;;;;;;;;CAWlB,MAAM,eACJ,WACA,UACe;EACf,QAAQ,KACN,+IACF;CACF;CAYA,MAAM,aACJ,KACA,SACkE;EAClE,MAAM,QAAQ,QAAQ,SAAS,OAAO,EAAE;EACxC,MAAM,YAAY,IAAI;EACtB,MAAM,WAAW,KAAK,qBAAqB,QAAQ,QAAQ;EAE3D,MAAM,WAAW,KAAK,kBAAkB,KAAK;EAC7C,IAAI,UAAU;GAOZ,IAAI,UAAU;IACZ,IAAI,CAAC,KAAK,4BAA4B,SAAS,MAAM,GACnD,MAAM,KAAK,qBAAqB;IAElC,OAAO;KAAE;KAAO;KAAW,QAAQ;IAAU;GAC/C;GAKA,IACE,SAAS,WAAW,eACpB,SAAS,WAAW,WACpB,SAAS,WAAW,WACpB;IACA,IAAI,SAAS,WAAW,eAAe,SAAS,eAAe,MAC7D,IAAI;KACF,MAAM,QAAQ,MAAM,KAAK,SACvB,KACA,KACF;KAEA,MAAM,aAAa,MADH,KAAK,yBAAwC,KAC9B,CAAC,CAAC,oBAAoB,KAAK;KAC1D,IAAI,YAAY,WAAW,aAAa;MACtC,MAAM,SAAS,KAAK,8BAClB,WACA,UACF;MACA,KAAK,yBACH,OACA,QACA,WAAW,WACb;MACA,OAAO;KACT;IACF,QAAQ,CAER;IAEF,OAAO,KAAK,wBAAgC,QAAQ;GACtD;GASA,IAAI;GACJ,IAAI,gBAAgB;GACpB,IAAI;IACF,MAAM,QAAQ,MAAM,KAAK,SAAS,KAA6B,KAAK;IACpE,MAAM,UAAU,KAAK,yBAAwC,KAAK;IAClE,MAAM,WAAW,MAAM,KAAK,gCAC1B,SACA,UACA,GACA,KAAK,iBAAiB,sCACtB,KAAK,iBAAiB,4BACxB;IACA,IAAI,SAAS,QAAQ;KACnB,MAAM,KAAK,oBACT,KAAK,yBAAyB,QAAQ,GACtC,SAAS,QACT;MAAE,UAAU,SAAS;MAAU,aAAa,SAAS;KAAY,CACnE;KACA,OAAO,SAAS;IAClB;IACA,iBAAiB,SAAS;IAG1B,gBAAgB,MAAM,KAAK,+BACzB,SACA,OACA,SAAS,MACX;GACF,QAAQ,CAER;GACA,OAAO,MAAM,KAAK,gCAChB,UACA,KAAK,6BAA6B,cAAc,GAChD;IAAE,QAAQ;IAAgB,mBAAmB,CAAC;GAAc,CAC9D;EACF;EAEA,MAAM,eAAe,QAAQ,gBAAgB;EAC7C,MAAM,eACJ,QAAQ,gBAAgB,KAAK,yBAAyB,QAAQ,KAAK;EACrE,MAAM,cACJ,QAAQ,YAAY,KAAA,IAAY,KAAK,UAAU,QAAQ,OAAO,IAAI;EACpE,MAAM,mBACJ,iBAAiB,KAAA,IAAY,KAAK,UAAU,YAAY,IAAI;EAC9D,MAAM,YAAY,KAAK,IAAI;EAE3B,IAAI,KAAK,yBAAyB,KAAK,KAAK,yBAAyB;GACnE,MAAM,QAAQ,4BAA4B,KAAK,wBAAwB;GACvE,KAAK,GAAG;;;;;;YAMF,MAAM,IAAI,QAAQ,oBAAoB,KAAK,IAAI,UAAU;YACzD,iBAAiB,gBAAgB,MAAM,IAAI,YAAY;YACvD,aAAa,IAAI,UAAU,IAAI,KAAK,IAAI,EAAE;;;GAGhD,KAAK,yBAAyB,QAAQ,kBAAkB,GAAG;IACzD,MAAM;IACN;IACA;IACA;IACA,OAAO;IACP,SAAS,QAAQ;GACnB,CAAC;GACD,KAAK,yBAAyB,QAAQ,kBAAkB,GAAG;IACzD,MAAM;IACN;IACA;GACF,CAAC;GACD,OAAO;IAAE;IAAO;IAAW,QAAQ;IAAS;GAAM;EACpD;EAEA,MAAM,sBAAsB,WACxB,aACC,SAAS,eAAe,KAAK,iBAAiB,uBAC/C;EACJ,MAAM,6BAA6B,WAC9B,SAAS,sBACV,KAAK,iBAAiB,6BACtB;EACJ,MAAM,2BAA2B,UAAU,eACvC,KAAK,UAAU,SAAS,YAAY,IACpC;EACJ,KAAK,GAAG;;;;;;;;UAQF,MAAM,IAAI,QAAQ,oBAAoB,KAAK,IAAI,UAAU;UACzD,iBAAiB,mBAAmB,YAAY,IAAI,aAAa;UACjE,UAAU,IAAI,WAAW,IAAI,EAAE,IAAI,UAAU,gBAAgB,KAAK;UAClE,UAAU,gBAAgB,KAAK,IAAI,oBAAoB;UACvD,2BAA2B,IAAI,yBAAyB;;;EAI9D,MAAM,UAA4B;GAChC;GACA,kBAAkB,QAAQ;GAC1B;GACA;GACA,QAAQ;GACR,SAAS,QAAQ;GACjB,GAAI,UAAU,iBAAiB,KAAA,IAC3B,EAAE,cAAc,SAAS,aAAa,IACtC,CAAC;GACL;GACA;EACF;EACA,MAAM,KAAK,iBAAiB,OAAO;EACnC,KAAK,yBAAyB,QAAQ,kBAAkB,GAAG;GACzD,MAAM;GACN;GACA;GACA;GACA,OAAO;GACP,SAAS,QAAQ;EACnB,CAAC;EAED,MAAM,QAAQ,MAAM,KAAK,SAAS,KAA6B,KAAK;EACpE,MAAM,UAAU,KAAK,yBAAwC,KAAK;EAClE,MAAM,aAAa,MAAM,QAAQ,kBAAkB,QAAQ,OAAO,EAChE,MACF,CAAC;EACD,KAAK,sBAAsB,KAAK;EAEhC,IAAI,UAAU;GAIZ,IAAI,QAAQ,QACV,QAAQ,KACN,oEAAoE,MAAM,6FAC5E;GAKF,MAAM,KAAK,qBAAqB,EAAE,cAAc,KAAK,CAAC;GAGtD,KAAK,4BAA4B;GACjC,KAAK,IAAI,UACP,KAAK,kBAAiC,SAAS,KAAK,KAAK,CAC3D;GACA,OAAO;IAAE;IAAO;IAAW,QAAQ;GAAU;EAC/C;EAEA,IAAI,WAAW;EACf,IAAI;EACJ,IAAI,QAAQ,QACV,IAAI,QAAQ,OAAO,SAAS;GAC1B,MAAM,QAAQ,mBAAmB,OAAO,QAAQ,OAAO,MAAM;GAK7D,MAAM,SAAqC;IACzC;IACA;IACA,QAAQ;IACR,OAPA,QAAQ,OAAO,kBAAkB,QAC7B,QAAQ,OAAO,OAAO,UACtB,OAAO,QAAQ,OAAO,UAAU,WAAW;GAMjD;GACA,MAAM,KAAK,oBAAoB,SAAS,QAAQ,EAAE,SAAS,CAAC;GAC5D,OAAO;EACT,OAAO;GACL,4BAA4B;IAC1B,QAAa,mBAAmB,OAAO,QAAQ,QAAQ,MAAM;GAC/D;GACA,QAAQ,OAAO,iBAAiB,SAAS,qBAAqB,EAC5D,MAAM,KACR,CAAC;EACH;EAGF,IAAI;GACF,IAAI,QAAQ,kBAAkB;IAC5B,MAAM,SAAS,MAAM,QAAQ,iBAAiB,OAAO,EACnD,eAAe,GACjB,CAAC;IACD,YACE,MAAM,KAAK,wBACT,QACA,QAAQ,kBACR,OACA,UACA,QAAQ,MACV,EAAA,CACA;GACJ,OAAO;IACL,MAAM,SAAS,MAAM,QAAQ,mBAAmB,KAAK;IACrD,WAAW,KAAK,0BACd,QAAQ,kBACR,OACA,QACA,QACF;GACF;GAEA,IAAI,QAAQ,QAAQ,SAAS;IAC3B,MAAM,QAAQ,mBAAmB,OAAO,QAAQ,OAAO,MAAM;IAK7D,MAAM,SAAqC;KACzC;KACA;KACA,QAAQ;KACR,OAPA,QAAQ,OAAO,kBAAkB,QAC7B,QAAQ,OAAO,OAAO,UACtB,OAAO,QAAQ,OAAO,UAAU,WAAW;IAMjD;IACA,MAAM,KAAK,oBAAoB,SAAS,QAAQ,EAAE,SAAS,CAAC;IAC5D,OAAO;GACT;GAEA,MAAM,aACH,MAAM,QAAQ,oBAAoB,KAAK,KAAM;GAChD,MAAM,SAAS,KAAK,8BAClB,WACA,UACF;GACA,MAAM,KAAK,oBAAoB,SAAS,QAAQ;IAC9C;IACA,aAAa,WAAW;GAC1B,CAAC;GACD,OAAO;EACT,SAAS,OAAO;GACd,IAAI,QAAQ,QAAQ,SAAS;IAC3B,MAAM,QAAQ,mBAAmB,OAAO,QAAQ,OAAO,MAAM;IAK7D,MAAM,SAAqC;KACzC;KACA;KACA,QAAQ;KACR,OAPA,QAAQ,OAAO,kBAAkB,QAC7B,QAAQ,OAAO,OAAO,UACtB,OAAO,QAAQ,OAAO,UAAU,WAAW;IAMjD;IACA,MAAM,KAAK,oBAAoB,SAAS,QAAQ,EAAE,SAAS,CAAC;IAC5D,OAAO;GACT;GAEA,MAAM,SAAqC;IACzC;IACA;IACA,QAAQ;IACR,OALc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAMrE;GACA,MAAM,KAAK,oBAAoB,SAAS,QAAQ,EAAE,SAAS,CAAC;GAC5D,OAAO;EACT,UAAU;GACR,IAAI,uBAAuB,QAAQ,QACjC,QAAQ,OAAO,oBAAoB,SAAS,mBAAmB;EAEnE;CACF;;;;;;;CAQA,MAAM,gBAAgB,OAAe,QAAiC;EACpE,MAAM,MAAM,KAAK,kBAAkB,KAAK;EACxC,IAAI,CAAC,KAAK;EACV,IAAI,KAAK,4BAA4B,IAAI,MAAM,GAAG;EAClD,MAAM,aAAa,IAAI,aAAa;EACpC,MAAM,UACJ,kBAAkB,QACd,OAAO,UACP,OAAO,UAAU,qBAAqB;EAC5C,IAAI;GACF,MAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,YAAY,KAAK;GAElE,MADgB,KAAK,yBAAyB,KAClC,CAAC,CAAC,mBAAmB,OAAO,MAAM;EAChD,QAAQ,CAGR;EACA,IAAI,CAAC,YAAY;EACjB,MAAM,KAAK,yBAAyB,OAAO,UAAU;GACnD;GACA,WAAW,IAAI;GACf,QAAQ;GACR,OAAO;EACT,CAAC;CACH;;;;;;;;CASA,qBAA6B,UAMpB;EACP,IAAI,CAAC,UAAU,OAAO;EACtB,IAAI,aAAa,MAAM,OAAO,CAAC;EAC/B,IAAI,eAAe,SAAS;EAC5B,MAAM,eACJ,OAAO,SAAS,WAAW,WAAW,SAAS,OAAO,SAAS,KAAA;EACjE,IAAI,iBAAiB,KAAA;OAIf,OAHc,KAChB,kBAEsB,YACtB,MAAM,IAAI,MACR,oCAAoC,aAAa,uBAAuB,KAAK,YAAY,KAAK,sIAGhG;EAAA,OAEG,IAAI,SAAS;OAMd,OAHgB,KAClB,8BAEwB,YACxB,eAAe;EAAA;EAGnB,OAAO;GACL,GAAI,iBAAiB,KAAA,IAAY,EAAE,aAAa,IAAI,CAAC;GACrD,GAAI,iBAAiB,KAAA,IAAY,EAAE,aAAa,IAAI,CAAC;GACrD,GAAI,SAAS,gBAAgB,KAAA,IACzB,EAAE,aAAa,SAAS,YAAY,IACpC,CAAC;GACL,GAAI,SAAS,uBAAuB,KAAA,IAChC,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;GACL,UAAU;IACR,MAAM,MAAM,SAAS;IACrB,IAAI,CAAC,KAAK,OAAO,CAAC;IAClB,MAAM,QAAQ,MAAM,QAAQ,GAAG,IAAI,MAAM,IAAI;IAC7C,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG,OAAO,CAAC;IAIzD,OAAO,EAAE,cAAc;KAAE;KAAO,MAHE,MAAM,QAAQ,GAAG,IAC/C,YACC,IAAI,QAAQ;IACoB,EAAE;GACzC,EAAA,CAAG;EACL;CACF;CAEA,4BAAoC,QAAqC;EACvE,OAAO,WAAW,eAAe,WAAW,WAAW,WAAW;CACpE;CAEA,8BAA+C;EAK7C,QAAQ,KAJU,GAAkB;;;MAIvB,EAAE,EAAE,KAAK,KAAK;CAC7B;;CAGA,wBAAwC;EAKtC,OAAO,KAJW,GAAkB;;;MAIxB,EAAE,EAAE,KAAK;CACvB;;;;;;;CAQA,8BAA4C;EAC1C,MAAM,YAAY,KAAK,sBAAsB;EAC7C,IAAI,YAAY,oCAAoC;GAClD,KAAK,2BAA2B;GAChC;EACF;EACA,IAAI,KAAK,0BAA0B;EACnC,KAAK,2BAA2B;EAChC,KAAK,MAAM,0CAA0C;GACnD;GACA,WAAW;EACb,CAAC;EACD,QAAQ,KACN,YAAY,UAAU,8DAA8D,mCAAmC,qJACzH;CACF;;;;;;;;CASA,MAAc,kBACZ,SACA,KACA,OACe;EACf,IAAI;GACF,MAAM,QAAQ,MAAM,KAAK,SAAS,KAA6B,KAAK;GACpE,MAAM,UAAU,KAAK,yBAAwC,KAAK;GAClE,IAAI,WAAW;GACf,IAAI,QAAQ,kBAAkB;IAC5B,MAAM,SAAS,MAAM,QAAQ,iBAAiB,OAAO,EACnD,eAAe,GACjB,CAAC;IACD,YACE,MAAM,KAAK,wBACT,QACA,QAAQ,kBACR,OACA,UACA,KAAA,CACF,EAAA,CACA;GACJ;GACA,MAAM,aAAa,MAAM,QAAQ,oBAAoB,KAAK;GAC1D,IACE,cACA,KAAK,4BACH,WAAW,MACb,GACA;IACA,MAAM,SAAS,KAAK,8BAClB,QAAQ,WACR,UACF;IACA,MAAM,KAAK,yBACT,OACA,UACA,QACA;KAAE;KAAU,WAAW;IAAK,GAC5B,WAAW,WACb;GACF;EACF,QAAQ,CAER;CACF;;;;;;;;;;;;;;;;CAiBA,MAAc,yBACZ,OACA,MACA,QACA,SACA,cAAc,KAAK,IAAI,GACR;EACf,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,aAAa,MAAM;EAIzB,MAAM,aACJ,SAAS,WACL;;;;2EAKA;;;;;EAWN,IANgB,KAAK,IAAI,QAAQ,IAAI,KACnC,YACA,KACA,OACA,UACF,CAAC,CAAC,gBACc,GAAG;EAEnB,MAAM,MAAM,KAAK,kBAAkB,KAAK;EACxC,IAAI,CAAC,KAAK;EAEV,KAAK,yBAAyB,OAAO,QAAQ,WAAW;EAOxD,KAAK,4BACH,IAAI,uBAAuB,KAAA,GAC3B,SAAS,YAAY,KAAK,IAAI,GAC9B,MACF;EAEA,MAAM,UAAU,KAAK,yBACnB,KACA,OAAO,QACP,WACF;EACA,MAAM,YAAsC;GAC1C,QAAQ,OAAO;GACf,GAAI,OAAO,YAAY,KAAA,IAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;GAClE,GAAI,OAAO,UAAU,KAAA,IAAY,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;GAC5D,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;GAC/D,GAAI,OAAO,sBAAsB,KAAA,IAC7B,EAAE,mBAAmB,OAAO,kBAAkB,IAC9C,CAAC;EACP;EAEA,MAAM,SAAS,YAAY;GAGzB,IAAI;IACF,MAAM,KAAK,kBAAkB,SAAS,SAAS;GACjD,SAAS,OAAO;IACd,MAAM,KAAK,gBAAgB,KAAK;GAClC;GAEA,MAAM,eAAe,IAAI;GACzB,IAAI,cAAc;IAChB,MAAM,WAAY,KAChB;IAEF,IAAI,OAAO,aAAa,YACtB,IAAI;KACF,MACE,SAIA,KAAK,IAAI,CAAC,CAAC,SAAS,SAAS;IACjC,SAAS,OAAO;KACd,KAAK,MAAM,uCAAuC;MAChD;MACA;MACA,QAAQ,OAAO;MACf,UAAU;MACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;KAC9D,CAAC;KACD,MAAM,KAAK,gBAAgB,KAAK;KAChC,MAAM;IACR;GAEJ;EACF;EASA,MAAM,KAAK,qBAAqB,QAAQ,EAAE,WAAW,SAAS,UAAU,CAAC;EAIzE,IAAI,SAAS,UACX,KAAK,GAAG;;oCAEsB,KAAK,IAAI,EAAE;yBACtB,MAAM;;OAGzB,KAAK,GAAG;;qCAEuB,KAAK,IAAI,EAAE;yBACvB,MAAM;;CAG7B;CAEA,MAAc,gBAAgB,OAA+B;EAC3D,IAAI;GACF,MAAM,KAAK,QAAQ,KAAK;EAC1B,QAAQ,CAGR;CACF;;;;;;;;;;;;;;;;;;CAmBA,MAAgB,qBACd,QACA,UACe;EACf,IAAIL,sCAAa,SAAS,CAAC,EAAE,OAAO;GAClC,MAAM,OAAO;GACb;EACF;EACA,MAAM,gBACJ;GACE,OAAO;GACP,YAAY,KAAA;GACZ,SAAS,KAAA;GACT,OAAO,KAAA;EACT,GACA,QACA,EAAE,UAAU,KAAK,CACnB;CACF;;;;;;CAOA,MAAc,qBAAqB,SAEjB;EAMhB,MAAM,MAAM,KAAK,wBAAwB,WACvC,KAAK,0BAA0B,OAAO,CACxC;EAEA,KAAK,0BAA0B,IAAI,WAC3B,KAAA,SACA,KAAA,CACR;EACA,OAAO;CACT;CAEA,MAAc,0BAA0B,SAEtB;EAEhB,MAAM,SAAQ,MADU,KAAK,cAAc,EAAA,CACnB,QACrB,aAAa,SAAS,aAAa,2BACtC;EAGA,IAAI,MAAM,SAAS,KAAK,CAAC,SAAS,cAAc;GAC9C,KAAK,MAAM,YAAY,MAAM,MAAM,CAAC,GAClC,MAAM,KAAK,eAAe,SAAS,EAAE;GAEvC;EACF;EACA,KAAK,MAAM,YAAY,OACrB,MAAM,KAAK,eAAe,SAAS,EAAE;EAEvC,MAAM,KAAK,SACT,4BAA4B,IAC5B,6BACA,EAAE,cAAc,EAAE,GAGlB,EAAE,YAAY,KAAK,CACrB;CACF;;;;;;;;;CAUA,MAAM,yBACJ,SACe;EACf,MAAM,OAAO,KAAK,GAA2B;;;;;;;;;;;;;;EAe7C,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,QAAQ,IAAI;GAClB,IAAI,aAA4C;GAChD,IAAI;IACF,MAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,YAAY,KAAK;IAElE,aAAa,MADG,KAAK,yBAAyB,KACrB,CAAC,CAAC,oBAAoB,KAAK;GACtD,QAAQ,CAGR;GAOA,IAAI,YAAY,cAAc,IAAI,wBAAwB;IACxD,MAAM,mBAAmB,KAAK,yBAAyB,GAAG;IAC1D,KAAK,MAAM,aAAa,WAAW,YACjC,KAAK,+BAA+B,KAAK,kBAAkB,SAAS;GAExE;GAEA,IACE,cACA,KAAK,4BACH,WAAW,MACb,GACA;IACA,MAAM,SAAS,KAAK,8BAClB,IAAI,YACJ,UACF;IACA,MAAM,KAAK,yBACT,OACA,UACA,QACA;KAAE,UAAU,KAAK,IAAI;KAAG,WAAW;IAAK,GACxC,WAAW,WACb;IACA;GACF;GASA,MAAM,MAAM,KAAK,IAAI;GACrB,MAAM,WAAW,IAAI;GAMrB,MAAM,kBAAkB,YAAY,YAAY,SAC5C,WAAW,WAAW,WAAW,WAAW,SAAS,EAAE,CAAC,KACxD,KAAA;GACJ,MAAM,cAAc;IAClB,YAAY,UAAU;IACtB;IACA,IAAI;GACN,CAAC,CAAC,QAAQ,MAAmB,OAAO,MAAM,QAAQ;GAClD,MAAM,eACJ,YAAY,SAAS,IAAI,KAAK,IAAI,GAAG,WAAW,IAAI,KAAA;GACtD,MAAM,qBAAqB,IAAI;GAC/B,MAAM,eAAe,aAAa,QAAQ,OAAO;GACjD,MAAM,iBACJ,OAAO,uBAAuB,YAC9B,qBAAqB,KACrB,OAAO,SAAS,kBAAkB,KAClC,OAAO,iBAAiB,YACxB,MAAM,gBAAgB;GACxB,KACG,gBAAgB,mBACjB,IAAI,yBAAyB,MAC7B;IACA,IAAI,gBAAgB;IACpB,IAAI;KACF,MAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,YAAY,KAAK;KAElE,MADgB,KAAK,yBAAyB,KAClC,CAAC,CAAC,mBACZ,OACA,eACI,6BACA,sDACN;KACA,gBAAgB;IAClB,QAAQ,CAGR;IACA,MAAM,KAAK,yBACT,OACA,WACA;KACE;KACA,WAAW,IAAI;KACf,QAAQ;KACR,OAAO,eACH,uDACA;KACJ,QAAQ,eAAe,oBAAoB;KAC3C,mBAAmB,CAAC;IACtB,GACA,EAAE,WAAW,KAAK,CACpB;GACF;EACF;EAIA,IAAI,KAAK,4BAA4B,GAAG;GACtC,MAAM,eACJ,OAAO,SAAS,iBAAiB,WAAW,QAAQ,eAAe;GACrE,MAAM,YAAY,KAAK,IACrB,eAAe,GACf,4BAA4B,SAAS,CACvC;GACA,MAAM,KAAK,SACT,4BAA4B,YAC5B,6BACA,EAAE,cAAc,UAAU,CAC5B;EACF;CACF;CAOA,gBAAgB,aAAqC,OAAwB;EAC3E,MAAM,YACJ,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAK9D,QAAQ,KAJU,GAAkB;;uBAEjB,MAAM,oBAAoB,UAAU;MAE1C,EAAE,EAAE,KAAK,KAAK;CAC7B;CAEA,MAAM,mBAAmB,SAGP;EAChB,MAAM,OAAO,KAAK,GAIhB;;;;EAIF,MAAM,eAAe,SAAS,SAC1B,IAAI,IAAY,QAAQ,MAAM,IAC9B;EACJ,MAAM,WAAW,KAAK,QAAQ,QAAQ;GACpC,IAAI,gBAAgB,CAAC,aAAa,IAAI,IAAI,MAAM,GAAG,OAAO;GAC1D,IAAI,SAAS,cAAc,KAAA,GAAW;IACpC,MAAM,OAAO,KAAK,kBAAkB,IAAI,MAAM;IAC9C,IAAI,CAAC,QAAQ,KAAK,cAAc,QAAQ,WAAW,OAAO;GAC5D;GACA,OAAO;EACT,CAAC;EAED,KAAK,MAAM,OAAO,UAAU;GAC1B,IAAI;IACF,MAAM,MAAM,KAAK,sBAAsB,IAAI,UAAU;IACrD,IAAI,IAAI,WAAW,cAAc,IAAI,WAAW,WAAW;KACzD,MAAM,QAAQ,MAAM,KAAK,SAAS,KAAK,IAAI,MAAM;KAEjD,MADgB,KAAK,yBAAyB,KAClC,CAAC,CAAC,mBACZ,IAAI,QACJ,yBACF;IACF;IACA,MAAM,KAAK,eAAe,KAAK,IAAI,MAAM;GAC3C,QAAQ,CAER;GACA,KAAK,GAAG;wDAC0C,IAAI,OAAO;;EAE/D;CACF;CAEA,qBAA6B,QAAyB;EACpD,OACE,WAAW,eACX,WAAW,WACX,WAAW,aACX,WAAW;CAEf;CAEA,2BAA2C;EAKzC,OAAO,KAJW,GAAkB;;;MAIxB,EAAE,EAAE,KAAK;CACvB;CAEA,yBAAiC,OAAyB;EACxD,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,MAAM,GAAG,GAAG;EACxD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;EAClD,IAAI;GACF,MAAM,OAAO,KAAK,UAAU,KAAK;GACjC,OAAO,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,OAAO;EAC1D,QAAQ;GACN,OAAO,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,GAAG;EACnC;CACF;CAEA,kBAA0B,OAA8C;EAatE,OAAO,KAZW,GAA2B;;;;;;;;;uBAS1B,MAAM;;MAGb,MAAM;CACpB;;;;;;;;CASA,mCAA2C,KAI8B;EACvE,IAAI,IAAI,WAAW,eAAe,OAAO,CAAC;EAC1C,OAAO;GACL,GAAI,IAAI,uBAAuB,OAC3B,EAAE,QAAQ,IAAI,mBAAiD,IAC/D,CAAC;GACL,GAAI,IAAI,wBAAwB,OAC5B,EAAE,mBAAmB,IAAI,wBAAwB,EAAE,IACnD,CAAC;EACP;CACF;CAEA,wBACE,KAC4B;EAC5B,MAAM,SAAS,KAAK,oBAAoB,IAAI,WAAW;EAGvD,OAAO;GACL,OAAO,IAAI;GACX,WAAW,IAAI;GACf,QAAQ,IAAI;GACZ,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GACzC,GAAI,IAAI,YAAY,OAAO,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;GACvD,GAAI,IAAI,kBAAkB,OAAO,EAAE,OAAO,IAAI,cAAc,IAAI,CAAC;GACjE,GAAG,KAAK,mCAAmC,GAAG;EAChD;CACF;CAEA,yBACE,KACA,SAA6B,IAAI,QACjC,cAAc,IAAI,gBAAgB,KAAA,GAChB;EAClB,OAAO;GACL,OAAO,IAAI;GACX,kBAAkB,IAAI,uBAAuB,KAAA;GAC7C,WAAW,IAAI;GACf,cAAc,KAAK,oBAAoB,IAAI,aAAa;GACxD;GACA,SAAS,KAAK,oBAAoB,IAAI,gBAAgB;GAGtD,GAAI,IAAI,0BAA0B,OAC9B,EAAE,cAAc,IAAI,uBAAuB,IAC3C,CAAC;GACL,cAAc,IAAI;GAClB,WAAW,IAAI;GACf;EACF;CACF;CAEA,8BACE,WACA,YAC4B;EAC5B,IAAI,WAAW,WAAW,aACxB,OAAO;GACL,OAAO,WAAW;GAClB;GACA,QAAQ;GACR,QAAQ,WAAW;GACnB,SAAS,WAAW;EACtB;EAEF,IAAI,WAAW,WAAW,WACxB,OAAO;GACL,OAAO,WAAW;GAClB;GACA,QAAQ;GACR,OAAO,WAAW;EACpB;EAEF,OAAO;GACL,OAAO,WAAW;GAClB;GACA,QAAQ;GACR,OAAO,WAAW,SAAS;EAC7B;CACF;CAEA,MAAc,oBACZ,KACA,QACA,SAK8C;EAC9C,MAAM,cAAc,SAAS,eAAe,KAAK,IAAI;EACrD,KAAK,yBAAyB,IAAI,OAAO,QAAQ,WAAW;EAC5D,IAAI,SAAS,aAAa,KAAA,GACxB,KAAK,4BACH,IAAI,kBACJ,QAAQ,UACR,MACF;EAEF,MAAM,eACJ,KAAK,kBACH;GAAE,GAAG;GAAK,QAAQ,OAAO;GAAQ;EAAY,GAC7C,MACF;EACF,IAAI,SAAS,iBAAiB,OAAO;EACrC,MAAM,OAAO;CAEf;CAEA,MAAc,iCACZ,OACe;EACf,KAAK,MAAM,QAAQ,OACjB,IAAI;GACF,MAAM,KAAK;EACb,SAAS,OAAO;GACd,IAAI;IACF,MAAM,KAAK,QAAQ,KAAK;GAC1B,QAAQ,CAGR;EACF;CAEJ;CAEA,yBACE,OACA,QACA,cAAc,KAAK,IAAI,GACjB;EAWN,MAAM,oBACJ,OAAO,sBAAsB,KAAA,IACzB,OACA,OAAO,oBACL,IACA;EACR,KAAK,GAAG;;qBAES,OAAO,OAAO;sBACb,OAAO,WAAW,KAAK;0BACnB,KAAK,0BAA0B,OAAO,MAAM,EAAE;4BAC5C,OAAO,SAAS,KAAK;iCAChB,OAAO,UAAU,KAAK;kCACrB,kBAAkB;2BACzB,YAAY;uBAChB,MAAM;;;EAGzB,IAAI,OAAO,WAAW,eAAe,OAAO,WAAW,KAAA,GACrD,KAAK,GAAG;;kDAEoC,KAAK,0BAA0B,OAAO,MAAM,EAAE;0CACtD,OAAO,WAAW,KAAK;yBACxC,MAAM;;CAG7B;CAEA,sBAA8B,OAAqB;EACjD,KAAK,GAAG;;;uBAGW,MAAM;;CAE3B;CAEA,oBAA4B,OAA+B;EACzD,IAAI,UAAU,MAAM,OAAO,KAAA;EAC3B,IAAI;GACF,OAAO,KAAK,MAAM,KAAK;EACzB,QAAQ;GACN,OAAO;EACT;CACF;CAEA,0BAAkC,QAAgC;EAChE,IAAI,WAAW,KAAA,GAAW,OAAO;EACjC,MAAM,OAAO,KAAK,UAAU,MAAM;EAClC,OAAO,SAAS,KAAA,IAAY,OAAO;CACrC;CAEA,yBACE,kBACA,UACA,OACA,QACA,YACM;EACN,MAAM,UAAiC;GACrC,MAAM;GACN;GACA;GACA;GACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC7B;EACA,MAAM,OAAO,KAAK,UAAU,OAAO;EACnC,IAAI,YACF,WAAW,KAAK,IAAI;OAEpB,KAAK,UAAU,IAAI;CAEvB;CAEA,0BACE,kBACA,OACA,QACA,UACA,QACA,YACQ;EACR,IAAI,OAAO;EACX,KAAK,MAAM,SAAS,QAClB,KAAK,yBACH,kBACA,QACA;GAAE,MAAM;GAAS;GAAO,MAAM,MAAM;EAAK,GACzC,QACA,UACF;EAEF,OAAO;CACT;CAEA,MAAc,gCACZ,KAIA,UACA,QACA,YACiB;EACjB,MAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,YAAY,IAAI,MAAM;EACvE,MAAM,UAAU,KAAK,yBAAyB,KAAK;EACnD,OAAO,KAAK,2CACV,SACA,KACA,UACA,QACA,UACF;CACF;CAEA,MAAc,2CACZ,SACA,KACA,UACA,QACA,YACA,WACiB;EACjB,MAAM,SAAS,MAAM,KAAK,+BACxB,SACA,IAAI,QACJ,SACF;EACA,IAAI,CAAC,QAAQ,OAAO;EACpB,OAAO,KAAK,0BACV,IAAI,uBAAuB,KAAA,GAC3B,IAAI,QACJ,QACA,UACA,QACA,UACF;CACF;CAEA,MAAc,wBACZ,QACA,kBACA,OACA,UACA,QACA,eAC+D;EAC/D,IAAI,OAAO;EACX,IAAI,QAAQ,SAAS,OAAO;GAAE;GAAM,OAAO;EAAU;EAKrD,IAAI,QAAqC;EACzC,MAAM,SACJ,OACA,UAAU;EACZ,MAAM,UAAU,IAAI,YAAY;EAChC,IAAI,gBAAgB;EACpB,IAAI,UAAU;EACd,IAAI;EACJ,MAAM,eAAe,IAAI,SAAe,YAAY;GAClD,eAAe;EACjB,CAAC;EACD,IAAI;EACJ,IAAI,QAAQ;GACV,sBAAsB,eAAe;GACrC,OAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;EAChE;EAQA,MAAM,cACJ,OAAO,kBAAkB,YACzB,gBAAgB,KAChB,OAAO,SAAS,aAAa;EAC/B,IAAI;EACJ,IAAI;EACJ,MAAM,cAAc,IAAI,SAAe,YAAY;GACjD,cAAc;EAChB,CAAC;EACD,MAAM,gBAAgB;GACpB,IAAI,CAAC,aAAa;GAClB,IAAI,cAAc,KAAA,GAAW,aAAa,SAAS;GACnD,YAAY,iBAAiB,cAAc,GAAG,aAAa;EAC7D;EAMA,IAAI,yBAAyB;EAC7B,IAAI;GACF,MAAM,gBAAgB,UAAgC;IACpD,KAAK,yBAAyB,kBAAkB,QAAQ;KACtD,MAAM;KACN;KACA,MAAM,MAAM;IACd,CAAC;IAID,KAAK,0BAA0B,OAAO,MAAM,IAAI;IAChD,yBAAyB;IAEzB,QAAQ;GACV;GACA,MAAM,eAAe,SAAiB;IACpC,IAAI;KACF,MAAM,QAAQ,KAAK,MAAM,IAAI;KAC7B,IAAI,OAAO,MAAM,SAAS,UACxB,aAAa,KAA6B;IAE9C,QAAQ,CAGR;GACF;GACA,MAAM,sBAAsB,QAAQ,UAAU;IAC5C,OAAO,MAAM;KACX,MAAM,UAAU,cAAc,QAAQ,IAAI;KAC1C,IAAI,YAAY,IAAI;KACpB,MAAM,OAAO,cAAc,MAAM,GAAG,OAAO,CAAC,CAAC,KAAK;KAClD,gBAAgB,cAAc,MAAM,UAAU,CAAC;KAC/C,IAAI,KAAK,SAAS,GAChB,YAAY,IAAI;IAEpB;IACA,IAAI,SAAS,cAAc,KAAK,CAAC,CAAC,SAAS,GAAG;KAC5C,YAAY,aAAa;KACzB,gBAAgB;IAClB;GACF;GAGA,QAAQ;GACR,OAAO,MAAM;IAIX,MAAM,cAAc,OAAO,KAAK;IAChC,YAAY,YAAY,CAAC,CAAC;IAC1B,MAAM,QAAQ,MAAM,QAAQ,KAAK;KAC/B,YAAY,MAAM,YAAY;MAAE,MAAM;MAAiB;KAAO,EAAE;KAChE,aAAa,YAAY,EAAE,MAAM,QAAiB,EAAE;KACpD,YAAY,YAAY,EAAE,MAAM,OAAgB,EAAE;IACpD,CAAC;IACD,IAAI,MAAM,SAAS,WAAW,MAAM,SAAS,QAAQ;KAInD,UAAU;KACV,QAAQ,MAAM,SAAS,SAAS,SAAS;KACzC;IACF;IACA,MAAM,EAAE,MAAM,UAAU,MAAM;IAC9B,IAAI,MAAM;KACR,iBAAiB,QAAQ,OAAO;KAChC,mBAAmB,IAAI;KACvB;IACF;IACA,IAAI,iBAAiB,YAAY;KAC/B,iBAAiB,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;KACvD,mBAAmB;IACrB,OACE,aAAa,KAAK;IAEpB,IAAI,wBAAwB;KAC1B,yBAAyB;KAOzB,IAAI;MACF,MAAM,KAAK,2BAA2B;KACxC,QAAQ,CAER;IACF;GACF;EACF,UAAU;GACR,IAAI,cAAc,KAAA,GAAW,aAAa,SAAS;GACnD,IAAI,iBAAiB,QACnB,OAAO,oBAAoB,SAAS,aAAa;GAEnD,IAAI,CAAC,SACH,IAAI;IACF,OAAO,YAAY;GACrB,QAAQ,CAER;EAYJ;EACA,OAAO;GAAE;GAAM;EAAM;CACvB;;;;;;;;;;;;;;;;;;;;;CAsBA,MAAgB,6BAA4C,CAAC;;;;;;;;;CAU7D,0BAAkC,OAAe,MAAoB;EACnE,IAAI;EAUJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,QAAQ;GACN;EACF;EACA,IAAI,CAAC,QAAQ;EACb,MAAM,cAAc,OAAO,SAAS;EACpC,IAAI,OAAO,SAAA,yBAAqC,CAAC,aAAa;EAC9D,MAAM,OAAO,OAAO,QAAQ,CAAC;EAC7B,MAAM,KAAK,KAAK,IAAI;EACpB,MAAM,WAAsC;GAC1C,GAAI,OAAO,KAAK,aAAa,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACvE,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;GACpE,GAAI,OAAO,KAAK,UAAU,WAAW,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GAC9D,GAAI,eAAe,OAAO,KAAK,SAAS,WACpC,EAAE,WAAW,KAAK,KAAK,IACvB,CAAC;GACL,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACrD;EACF;EACA,MAAM,MAAM,KAAK,kBAAkB,KAAK;EACxC,IAAI,CAAC,KAAK;EAGV,IAAI,IAAI,UACN,IAAI;GACF,KAAK,GAAG;6DAC6C,GAAG;2BACrC,MAAM;;EAE3B,QAAQ,CAER;EAEF,MAAM,UAAU,KAAK,yBAAyB,GAAG;EACjD,QAAa,QAAQ,KAAK,WAAW,SAAS,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAU;GACxE,QAAQ,MACN,0CAA0C,MAAM,IAChD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;EACF,CAAC;EAKD,IAAI,eAAe,OAAO,KAAK,SAAS,UACtC,KAAK,+BAA+B,KAAK,SAAS;GAChD,MAAM,KAAK;GACX,UAAU,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;GAC9D,IAAI,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;GAC5C,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EACvD,CAAC;CAEL;;;;;;;CAQA,+BACE,KACA,SACA,WACM;EAEN,MAAM,aAAa,KAAK,oBACtB,IAAI,0BAA0B,IAChC;EAIA,MAAM,QAAQ,MAAM,QAAQ,UAAU,IAAI,aAAa,YAAY;EACnE,MAAM,OAAO,MAAM,QAAQ,UAAU,IACjC,YACC,YAAY,QAAQ;EACzB,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,SAAS,UAAU,IAAI,GACzD;EAEF,QAAa,QACX,KAAK,0BAA0B,SAAS,WAAW,IAAI,CACzD,CAAC,CAAC,OAAO,UAAU;GACjB,QAAQ,MACN,sDAAsD,QAAQ,MAAM,IAAI,UAAU,KAAK,KACvF,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;EACF,CAAC;CACH;;;;;;;;CASA,MAAgB,0BACd,MACA,YACA,OACe,CAAC;CAElB,4BACE,kBACA,UACA,QACA,QACA,YACM;EACN,IAAI,OAAO,WAAW,aACpB,KAAK,yBACH,kBACA,UACA;GACE,MAAM;GACN,OAAO,OAAO;GACd,SAAS,OAAO,WAAW;EAC7B,GACA,QACA,UACF;OACK,IAAI,OAAO,WAAW,WAC3B,KAAK,yBACH,kBACA,UACA;GAAE,MAAM;GAAW,OAAO,OAAO;GAAO,QAAQ,OAAO;EAAM,GAC7D,QACA,UACF;OACK,IAAI,OAAO,WAAW,eAC3B,KAAK,yBACH,kBACA,UACA;GACE,MAAM;GACN,OAAO,OAAO;GACd,OAAO,OAAO,SAAS;GACvB,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;GAC/D,GAAI,OAAO,sBAAsB,KAAA,IAC7B,EAAE,mBAAmB,OAAO,kBAAkB,IAC9C,CAAC;EACP,GACA,QACA,UACF;OAEA,KAAK,yBACH,kBACA,UACA;GACE,MAAM;GACN,OAAO,OAAO;GACd,OAAO,OAAO,SAAS;EACzB,GACA,QACA,UACF;CAEJ;CAEA,yBACE,OACsC;EACtC,MAAM,YAAY;EAClB,IACE,OAAO,UAAU,sBAAsB,cACvC,OAAO,UAAU,uBAAuB,cACxC,OAAO,UAAU,wBAAwB,cACzC,OAAO,UAAU,uBAAuB,YAExC,MAAM,IAAI,MACR,sIACF;EAEF,OAAO;CACT;CAEA,sBAA8B,WAAyC;EAErE,MAAM,MADM,KAAK,IACD,UAAU;EAC1B,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,qBAAqB,UAAU,mBAAmB;EAEpE,OAAO;CACT;CAEA,MAAc,gCACZ,KACA,SACA,OACqC;EACrC,IAAI,WAAW;EACf,IAAI;GACF,WAAW,MAAM,KAAK,gCAAgC,KAAK,QAAQ;EACrE,QAAQ,CAER;EACA,MAAM,SAAqC;GACzC,OAAO,IAAI;GACX,WAAW,IAAI;GACf,QAAQ;GACR,OAAO;GACP,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;GAC9D,GAAI,OAAO,sBAAsB,KAAA,IAC7B,EAAE,mBAAmB,MAAM,kBAAkB,IAC7C,CAAC;EACP;EACA,MAAM,KAAK,oBAAoB,KAAK,yBAAyB,GAAG,GAAG,QAAQ,EACzE,SACF,CAAC;EACD,OAAO;CACT;;;;;;CAOA,6BACE,QACQ;EACR,QAAQ,QAAR;GACE,KAAK,eACH,OAAO;GACT,KAAK,mBACH,OAAO;GACT,KAAK,gBACH,OAAO;GACT,KAAK,mBACH,OAAO;GACT,KAAK,kBACH,OAAO;GACT,KAAK,qBACH,OAAO;GACT,SACE,OAAO;EACX;CACF;;;;;;;;;;;;;;;CAgBA,MAAc,+BACZ,SACA,OACA,QACkB;EAClB,IAAI,WAAW,mBAAmB,OAAO;EACzC,IAAI;GACF,MAAM,QAAQ,mBACZ,OACA,+CAA+C,QACjD;GACA,OAAO;EACT,QAAQ;GAEN,OAAO;EACT;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BA,MAAc,gCACZ,SACA,KAIA,UACA,sBAA8B,oDAC9B,cAAsB,2CAMrB;EACD,IAAI,OAAO,QAAQ,qBAAqB,YAKtC,OAAO;GAAE;GAAU,QAAQ;EAAe;EAG5C,KAAK,MAAM,gCAAgC;GACzC,OAAO,IAAI;GACX,WAAW,IAAI;GACf,UAAU;EACZ,CAAC;EAED,MAAM,kBAAkB,OACtB,QAKW;GACX,IAAI,aAAoD;GACxD,IAAI;IACF,aAAa,MAAM,QAAQ,oBAAoB,IAAI,MAAM;GAC3D,QAAQ;IAEN,OAAO;GACT;GACA,IACE,cACA,WAAW,WAAW,aACtB,WAAW,WAAW,YAEtB,OAAO;IACL,UAAU;IACV,QAAQ,KAAK,8BACX,IAAI,YACJ,UACF;IACA,aAAa,WAAW;GAC1B;GAEF,OAAO;EACT;EAEA,IAAI,eAAe;EAQnB,IAAI,EAAE,sBAAsB,IAC1B,OACG,MAAM,gBAAgB,YAAY,KAAM;GACvC,UAAU;GACV,QAAQ;EACV;EAOJ,MAAM,oBAAoB,IAAI,gBAAgB;EAC9C,IAAI;EACJ,IAAI,cAAc,KAAK,OAAO,SAAS,WAAW,GAChD,eAAe,iBAAiB,kBAAkB,MAAM,GAAG,WAAW;EAKxE,IAAI,SAAqC;EACzC,IAAI;GAOF,OAAO,CAAC,kBAAkB,OAAO,SAAS;IAMxC,IAAI,gBAAgB;IACpB,IAAI;KACF,MAAM,WAAW,MAAM,QAAQ,mBAAmB,IAAI,MAAM;KAC5D,MAAM,OAAO,SAAS,SAAS,SAAS;KACxC,IAAI,MAAM,gBAAgB,KAAK;IACjC,QAAQ,CAER;IAEA,MAAM,iBAAiB;IAGvB,IAAI,cAA2C;IAC/C,IAAI;KAOF,MAAM,SAAS,MAAM,QAAQ,iBAAiB,IAAI,QAAQ,EACxD,cACF,CAAC;KAID,MAAM,YAAY,MAAM,KAAK,wBAC3B,QACA,IAAI,uBAAuB,KAAA,GAC3B,IAAI,QACJ,cACA,kBAAkB,QAClB,mBACF;KACA,eAAe,UAAU;KACzB,cAAc,UAAU;IAC1B,QAAQ,CAGR;IAEA,MAAM,WAAW,MAAM,gBAAgB,YAAY;IACnD,IAAI,UAAU,OAAO;IAErB,IAAI,kBAAkB,OAAO,SAAS;KACpC,SAAS;KACT;IACF;IASA,IAAI,gBAAgB,QAAQ;IAC5B,IAAI,gBAAgB,gBAAgB;GACtC;EACF,UAAU;GACR,IAAI,iBAAiB,KAAA,GAAW,aAAa,YAAY;EAC3D;EAEA,OAAO;GAAE,UAAU;GAAc;EAAO;CAC1C;CAEA,MAAc,qBAAqB,YAAuC;EACxE,MAAM,OAAO,KAAK,GAahB;;;;;;;EAQF,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,mBAAmB,IAAI,uBAAuB,KAAA;GACpD,IAAI,WAAW;GACf,KAAK,yBACH,kBACA,YACA;IACE,MAAM;IACN,OAAO,IAAI;IACX,WAAW,IAAI;IACf,cAAc,KAAK,oBAAoB,IAAI,aAAa;IACxD,OAAO,IAAI;IACX,SAAS,KAAK,oBAAoB,IAAI,gBAAgB;GAGxD,GACA,MACA,UACF;GAEA,IAAI;IACF,WAAW,MAAM,KAAK,gCACpB,KACA,UACA,MACA,UACF;GACF,QAAQ,CAER;GAEA,IAAI,KAAK,qBAAqB,IAAI,MAAM,GACtC,KAAK,4BACH,kBACA,UACA;IACE,OAAO,IAAI;IACX,WAAW,IAAI;IACf,QAAQ,IAAI;IACZ,QAAQ,KAAK,oBAAoB,IAAI,WAAW;IAChD,SAAS,IAAI,WAAW,KAAA;IACxB,OAAO,IAAI,iBAAiB,KAAA;IAC5B,GAAG,KAAK,mCAAmC,GAAG;GAChD,GACA,MACA,UACF;EAEJ;CACF;CAEA,MAAc,wBAAwB,SAOC;EACrC,MAAM,oBACJ,SAAS,qBACT,KAAK,iBAAiB;EACxB,MAAM,sBACJ,SAAS,uBACT,KAAK,iBAAiB;EACxB,MAAM,YAAY,KAAK,IAAI;EAC3B,MAAM,iBACJ,SAAS,0BACT;EACF,MAAM,aACJ,iBAAiB,IACb,YAAY,iBACZ,OAAO;EACb,MAAM,mBAA8C,CAAC;EACrD,MAAM,OAAO,KAAK,GAA2B;;;;;;;;;EAiB7C,MAAM,SACJ,SAAS,WAAW,KAAA,IAAY,IAAI,IAAI,QAAQ,MAAM,IAAI,KAAA;EAC5D,MAAM,eAAe,KAAK,QACvB,QAAQ,CAAC,UAAU,OAAO,IAAI,IAAI,MAAM,CAC3C;EACA,KAAK,MAAM,6BAA6B;GACtC,UAAU,aAAa;GACvB;EACF,CAAC;EACD,MAAM,cAAc,OAClB,KACA,QACA,UACA,gBACkB;GAClB,KAAK,MAAM,2BAA2B;IACpC,OAAO,IAAI;IACX,WAAW,IAAI;IACf,QAAQ,OAAO;IACf,QAAQ,OAAO;IACf,WAAW,KAAK,IAAI,IAAI;GAC1B,CAAC;GACD,MAAM,iBAAiB,MAAM,KAAK,oBAChC,KAAK,yBAAyB,GAAG,GACjC,QACA;IACE;IACA;IACA,iBAAiB,SAAS;GAC5B,CACF;GACA,IAAI,gBACF,iBAAiB,KAAK,cAAc;EAExC;EAQA,MAAM,gBAGD,CAAC;EACN,KAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,WAAW;GACjB,MAAM,cAAc,aAAa,KAAK,IAAI;GAC1C,IAAI,eAAe,GAAG;IACpB,KAAK,MAAM,gCAAgC;KACzC,OAAO,IAAI;KACX,WAAW,IAAI;KACf,WAAW,KAAK,IAAI,IAAI;IAC1B,CAAC;IACD,MAAM,YACJ,KACA;KACE,OAAO,IAAI;KACX,WAAW,IAAI;KACf,QAAQ;KACR,QAAQ;KACR,OAAO,KAAK,6BAA6B,mBAAmB;IAC9D,GACA,UACA,KAAA,CACF;IACA;GACF;GACA,MAAM,eACJ,SAAS,4BACT;GACF,MAAM,sBACJ,eAAe,IAAI,KAAK,IAAI,cAAc,WAAW,IAAI;GAC3D,MAAM,WAAW,MAAM,KAAK,gCAC1B,KACA,UACA,mBACF;GACA,IAAI,SAAS,WAAW,aAAa;IACnC,MAAM,YACJ,YACO;KACL,MAAM,SACJ,SAAS,WAAW,cAChB,oBACA;KACN,OAAO;MACL,OAAO,IAAI;MACX,WAAW,IAAI;MACf,QAAQ;MACR;MACA,OAAO,KAAK,6BAA6B,MAAM;KACjD;IACF,EAAA,CAAG,GACH,UACA,KAAA,CACF;IACA;GACF;GACA,MAAM,aAAa,SAAS;GAC5B,MAAM,eACJ,CAAC,cACD,WAAW,WAAW,aACtB,WAAW,WAAW;GACxB,IACE,gBACA,OAAO,SAAS,QAAQ,qBAAqB,YAC7C;IAKA,cAAc,KAAK;KAAE;KAAK,SAAS,SAAS;IAAQ,CAAC;IACrD;GACF;GACA,IAAI,sBAAsB;GAC1B,IAAI;IACF,sBACE,MAAM,KAAK,2CACT,SAAS,SACT,KACA,UACA,KAAA,GACA,KAAA,GACA,mBACF;GACJ,QAAQ,CAER;GACA,IAAI,cACF,MAAM,YACJ,KACA;IACE,OAAO,IAAI;IACX,WAAW,IAAI;IACf,QAAQ;IACR,QAAQ;IAGR,mBAAmB;IACnB,OAAO,KAAK,6BAA6B,cAAc;GACzD,GACA,qBACA,KAAA,CACF;QAEA,MAAM,YACJ,KACA,KAAK,8BAA8B,IAAI,YAAY,UAAU,GAC7D,qBACA,WAAW,WACb;EAEJ;EAKA,MAAM,QAAQ,IACZ,cAAc,IAAI,OAAO,EAAE,KAAK,cAAc;GAC5C,MAAM,WAAW,MAAM,KAAK,gCAC1B,SACA,KACA,GACA,mBACA,mBACF;GACA,IAAI,SAAS,QAAQ;IACnB,MAAM,YACJ,KACA,SAAS,QACT,SAAS,UACT,SAAS,WACX;IACA;GACF;GAGA,MAAM,WAAW,MAAM,KAAK,+BAC1B,SACA,IAAI,QACJ,SAAS,MACX;GACA,MAAM,YACJ,KACA;IACE,OAAO,IAAI;IACX,WAAW,IAAI;IACf,QAAQ;IACR,QAAQ,SAAS;IACjB,mBAAmB,CAAC;IACpB,OAAO,KAAK,6BAA6B,SAAS,MAAM;GAC1D,GACA,SAAS,UACT,SAAS,WACX;EACF,CAAC,CACH;EACA,KAAK,MAAM,gCAAgC;GACzC,UAAU,aAAa;GACvB,WAAW,KAAK,IAAI,IAAI;EAC1B,CAAC;EACD,OAAO;CACT;CAEA,MAAc,gCACZ,KACA,WACA,YAAY,wCAC0B;EACtC,MAAM,WAAW,YAAkD;GACjE,MAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,YAAY,IAAI,MAAM;GACvE,MAAM,UAAU,KAAK,yBAAyB,KAAK;GAEnD,OAAO;IAAE,QAAQ;IAAa;IAAS,YAAA,MADd,QAAQ,oBAAoB,IAAI,MAAM;GACb;EACpD,EAAA,CAAG,CAAC,CAAC,aAA0C,EAAE,QAAQ,SAAS,EAAE;EAEpE,IAAI,aAAa,GAAG,OAAO;EAE3B,IAAI;EACJ,MAAM,UAAU,IAAI,SAAsC,YAAY;GACpE,YAAY,iBAAiB;IAC3B,QAAQ,EAAE,QAAQ,YAAY,CAAC;GACjC,GAAG,SAAS;EACd,CAAC;EAED,MAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;EACpD,IAAI,cAAc,KAAA,GAAW,aAAa,SAAS;EACnD,OAAO;CACT;CAEA,8BAAsC,SAMpB;EAChB,IAAI,KAAK,8BACP,OAAO,KAAK;EAGd,IAAI,SAAS,UAAU,QAAQ,OAAO,WAAW,GAC/C,OAAO,QAAQ,QAAQ;EAGzB,MAAM,YAAY,YAAY;GAC5B,MAAM,IAAI,SAAe,YAAY,WAAW,SAAS,CAAC,CAAC;GAC3D,MAAM,6BAA6B,MAAM,KAAK,wBAAwB;IACpE,kBAAkB;IAClB,0BAA0B,SAAS;IACnC,wBAAwB,SAAS;IACjC,mBAAmB,SAAS;IAC5B,qBAAqB,SAAS;IAC9B,QAAQ,SAAS;GACnB,CAAC;GACD,MAAM,KAAK,iCAAiC,0BAA0B;GAKtE,IAAI,KAAK,4BAA4B,GACnC,MAAM,KAAK,qBAAqB;EAEpC,EAAA,CAAG,CAAC,CACD,MAAM,OAAO,UAAU;GACtB,KAAK,MAAM,8BAA8B,EACvC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAC9D,CAAC;GACD,IAAI;IACF,MAAM,KAAK,QAAQ,KAAK;GAC1B,QAAQ,CAER;EACF,CAAC,CAAC,CACD,cAAc;GACb,KAAK,+BAA+B,KAAA;EACtC,CAAC;EAEH,KAAK,+BAA+B;EACpC,KAAK,IAAI,UAAU,QAAQ;EAC3B,OAAO;CACT;CAEA,8BAAgD;EAC9C,OAAO,KAAK,GAAuB;;;;;MAKjC,KAAK,QAAQ,IAAI,MAAM;CAC3B;CAEA,MAAc,+BACZ,SACA,OACA,WAC6C;EAC7C,MAAM,SAAS,QAAQ,mBAAmB,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;EACtE,IAAI,cAAc,KAAA,KAAa,aAAa,GAAG,OAAO;EAEtD,IAAI;EACJ,MAAM,UAAU,IAAI,SAAoB,YAAY;GAClD,YAAY,iBAAiB,QAAQ,KAAA,CAAS,GAAG,SAAS;EAC5D,CAAC;EACD,MAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,QAAQ,OAAO,CAAC;EACnD,IAAI,cAAc,KAAA,GAAW,aAAa,SAAS;EACnD,OAAO;CACT;;;;;;;;;;CAWA,oBACE,WACA,MACkB;EAClB,OAAO,KAAK,eAAe,QAAQ,WAAW,IAAI;CACpD;;;;;;;CAQA,wBAAmC,MAAoC;EACrE,OAAO,gBACL;GACE,OAAO;GACP,YAAY,KAAA;GACZ,SAAS,KAAA;GACT,OAAO,KAAA;EACT,GACA,IACF;CACF;;;;;;;;;;;;;;;CAgBA,cAAc,KAAoB,MAAc,QAAwB;EACtE,KAAK,cAAc,MAAM,KAAK,MAAM,MAAM;CAC5C;;;;;;;;;;;;CAaA,eAAe,KAAoB,MAA6B;EAC9D,OAAO,KAAK,cAAc,OAAO,KAAK,IAAI;CAC5C;CA2BA,YAAY,aAAqC,MAAuB;EACtE,OAAO,OAAO,gBAAgB,WAC1B,KAAK,cAAc,IAAI,aAAa,IAAI,IACxC,KAAK,cAAc,IAAI,aAAa,IAAI;CAC9C;CAiBA,cACE,aAC+D;EAC/D,IAAI,OAAO,gBAAgB,YAAY,gBAAgB,KAAA,GACrD,OAAO,KAAK,cAAc,KAAK,WAAW;EAE5C,OAAO,KAAK,cAAc,KAAK,WAAW;CAC5C;;;;;;;;;;;;;;;;CAiBA,MAAM,UAAU;EACd,IAAI,KAAK,UAAU;GACjB,KAAK,MAAM,SAAS;GAMpB,OAAM,MALa,KAAK,gBAAgB,EAAA,CAK7B,2BAA2B,KAAK,QAAQ;GACnD;EACF;EASA,MAAM,KAAK,IAAI,QAAQ,IAAI,qBAAqB,IAAI;EACpD,MAAM,KAAK,UAAU,cAAc;EAEnC,MAAM,KAAK,UAAU,QAAQ;EAC7B,KAAK,aAAa,QAAQ;EAC1B,MAAM,KAAK,IAAI,QAAQ,UAAU;EAEjC,KAAK,aAAa;EAOlB,iBAAiB;GACf,uBAAuB,KAAK,KAAK,WAAW;EAC9C,GAAG,CAAC;EAEJ,KAAK,MAAM,SAAS;CACtB;;;;;;;;;;;;;;;;;;;;CAqBA,MAAM,sBAAqC;EAYzC,MAAM,KAAK,2BAA2B;EACtC,IAAI,KAAK,UAAU;GAGjB,MAAM,KAAK,QAAQ;GACnB;EACF;EAIA,MAAM,YAAY,KAAK,IAAI,IAAI;EAC/B,MAAM,KAAK,IAAI,QAAQ,IAAI,qBAAqB,SAAS;EAGzD,MAAM,KAAK,UAAU,KAAK,KAAK;GAC7B,IAAI;GACJ,IAAI;GACJ,MAAM;GACN,WAAW;EACb,CAAC;CACH;;;;;;CAOA,MAAc,uBAA+C;EAC3D,MAAM,UAAU,MAAM,KAAK,IAAI,QAAQ,IACrC,mBACF;EACA,IAAI,OAAO,YAAY,UAAU,OAAO;EACxC,OAAO,YAAY,OAAO,KAAK,IAAI,IAAI;CACzC;CAEA,MAAc,qBAAuC;EACnD,OAAQ,MAAM,KAAK,qBAAqB,MAAO;CACjD;;;;;;CAOA,YAAoB,QAAyB;EAC3C,OAAO,iBAAiB,KAAK,OAAiC;CAChE;;;;;CAMA,qBAAoD;EAClD,OAAO,IAAI,IAAI,iBAAiB,IAAI,CAAC;CACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CA,MAAM,YACJ,cACA,QACA,SACiB;EAEjB,MAAM,WAAW,KAAK,2BAA2B,YAAY;EAC7D,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,2BACpC;EAKF,MAAM,cAAc,KAAK,gBAAgB,OAAO;EAChD,IAAI,CAAC,aACH,MAAM,IAAI,MACR,kGAEF;EAIF,MAAM,aAAa,SAAS,MAAM,MAAM,OAAO;EAG/C,MAAM,kBAAkB;GACtB,GAAG;GACH,aAAa,KAAK;GAClB,gBACE,YAAY,SAAS,UACjB,YAAY,UACZ,YAAY;GAClB,gBAAgB;GAChB,eAAe;EACjB;EAGA,MAAM,WAAW,MAAM,SAAS,OAAO;GACrC,IAAI;GACJ,QAAQ;GACR,WAAW,SAAS;EACtB,CAAC;EAGD,MAAM,KAAK,OAAO;EAClB,MAAM,eAAe,SAAS,WAC1B,KAAK,UAAU,QAAQ,QAAQ,IAC/B;EACJ,IAAI;GACF,KAAK,GAAG;;kBAEI,GAAG,IAAI,SAAS,GAAG,IAAI,aAAa,cAAc,aAAa;;EAE7E,SAAS,GAAG;GACV,IACE,aAAa,SACb,EAAE,QAAQ,SAAS,0BAA0B,GAE7C,MAAM,IAAI,MACR,qBAAqB,WAAW,2BAClC;GAEF,MAAM;EACR;EAEA,KAAK,MAAM,kBAAkB;GAAE,YAAY,SAAS;GAAI;EAAa,CAAC;EAEtE,OAAO,SAAS;CAClB;;;;;;;;;;;;;;;;;;CAmBA,MAAM,kBACJ,cACA,YACA,OACe;EACf,MAAM,WAAW,KAAK,2BAA2B,YAAY;EAC7D,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,2BACpC;EAGF,MAAM,WAAW,MAAM,SAAS,IAAI,UAAU;EAC9C,MAAM,KAAK,GAAG,YAAY,SAAS,UAAU,KAAK,GAAG;GACnD,aAAa;GACb,aAAa;GACb,YAAY;EACd,CAAC;EAED,KAAK,MAAM,kBAAkB;GAAE;GAAY,WAAW,MAAM;EAAK,CAAC;CACpE;;;;;;;;;;;;;;;;CAiBA,MAAM,gBACJ,YACA,MACe;EACf,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,KAAK,kBACT,aAAa,cACb,YACA;GACE,MAAM;GACN,SAAS;IACP,UAAU;IACV,QAAQ,MAAM;IACd,UAAU,MAAM;GAClB;EACF,CACF;EAEA,KAAK,MAAM,qBAAqB;GAAE;GAAY,QAAQ,MAAM;EAAO,CAAC;CACtE;;;;;;;;;;;;;;;CAgBA,MAAM,eACJ,YACA,MACe;EACf,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,KAAK,kBACT,aAAa,cACb,YACA;GACE,MAAM;GACN,SAAS;IACP,UAAU;IACV,QAAQ,MAAM;GAChB;EACF,CACF;EAEA,KAAK,MAAM,qBAAqB;GAAE;GAAY,QAAQ,MAAM;EAAO,CAAC;CACtE;;;;;;;;;;;;;;;CAgBA,MAAM,kBAAkB,YAAmC;EACzD,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,WAAW,KAAK,2BACpB,aAAa,YACf;EACA,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,aAAa,2BACjD;EAGF,MAAM,WAAW,MAAM,SAAS,IAAI,UAAU;EAC9C,MAAM,KAAK,GAAG,YAAY,SAAS,UAAU,GAAG;GAC9C,aAAa;GACb,aAAa;GACb,YAAY;EACd,CAAC;EAGD,MAAM,SAAS,MAAM,SAAS,OAAO;EACrC,KAAK,wBAAwB,YAAY,MAAM;EAE/C,KAAK,MAAM,uBAAuB;GAChC;GACA,cAAc,aAAa;EAC7B,CAAC;CACH;;;;;;;;;;;;;;;CAgBA,MAAM,cAAc,YAAmC;EACrD,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,WAAW,KAAK,2BACpB,aAAa,YACf;EACA,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,aAAa,2BACjD;EAGF,MAAM,WAAW,MAAM,SAAS,IAAI,UAAU;EAC9C,MAAM,KAAK,GAAG,YAAY,SAAS,MAAM,GAAG;GAC1C,aAAa;GACb,aAAa;GACb,YAAY;EACd,CAAC;EAED,MAAM,SAAS,MAAM,SAAS,OAAO;EACrC,KAAK,wBAAwB,YAAY,MAAM;EAE/C,KAAK,MAAM,mBAAmB;GAC5B;GACA,cAAc,aAAa;EAC7B,CAAC;CACH;;;;;;;;;;;;;;CAeA,MAAM,eAAe,YAAmC;EACtD,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,WAAW,KAAK,2BACpB,aAAa,YACf;EACA,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,aAAa,2BACjD;EAGF,MAAM,WAAW,MAAM,SAAS,IAAI,UAAU;EAC9C,MAAM,KAAK,GAAG,YAAY,SAAS,OAAO,GAAG;GAC3C,aAAa;GACb,aAAa;GACb,YAAY;EACd,CAAC;EAED,MAAM,SAAS,MAAM,SAAS,OAAO;EACrC,KAAK,wBAAwB,YAAY,MAAM;EAE/C,KAAK,MAAM,oBAAoB;GAC7B;GACA,cAAc,aAAa;EAC7B,CAAC;CACH;;;;;;;;;;;;;;;;;;;;;CAsBA,MAAM,gBACJ,YACA,UAAuC,CAAC,GACzB;EACf,MAAM,EAAE,gBAAgB,SAAS;EAEjC,MAAM,eAAe,KAAK,YAAY,UAAU;EAChD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,YAAY,WAAW,6BAA6B;EAGtE,MAAM,WAAW,KAAK,2BACpB,aAAa,YACf;EACA,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,aAAa,2BACjD;EAGF,MAAM,WAAW,MAAM,SAAS,IAAI,UAAU;EAC9C,MAAM,KAAK,GAAG,YAAY,SAAS,QAAQ,GAAG;GAC5C,aAAa;GACb,aAAa;GACb,YAAY;EACd,CAAC;EAED,IAAI,eAAe;GAEjB,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;GACxC,KAAK,GAAG;;;2BAGa,IAAI;2BACJ,IAAI;;;;8BAID,WAAW;;EAErC,OAAO;GAEL,MAAM,SAAS,MAAM,SAAS,OAAO;GACrC,KAAK,wBAAwB,YAAY,MAAM;EACjD;EAEA,KAAK,MAAM,sBAAsB;GAC/B;GACA,cAAc,aAAa;EAC7B,CAAC;CACH;;;;CAKA,2BACE,cACsB;EACtB,MAAM,UAAW,KAAK,IAAgC;EACtD,IACE,WACA,OAAO,YAAY,YACnB,YAAY,WACZ,SAAS,SAET,OAAO;CAGX;;;;CAKA,2BAA6C;EAC3C,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,KAAK,GACP,GACE,IACE,SACA,OAAO,UAAU,YACjB,YAAY,SACZ,SAAS,OAET,MAAM,KAAK,GAAG;EAGlB,OAAO;CACT;;;;;;;;CASA,MAAM,kBACJ,cACA,YACyB;EACzB,MAAM,WAAW,KAAK,2BAA2B,YAAY;EAC7D,IAAI,CAAC,UACH,MAAM,IAAI,MACR,qBAAqB,aAAa,2BACpC;EAIF,MAAM,SAAS,OAAM,MADE,SAAS,IAAI,UAAU,EAAA,CAChB,OAAO;EAGrC,KAAK,wBAAwB,YAAY,MAAM;EAE/C,OAAO;CACT;;;;;;;CAQA,YAAY,YAA8C;EACxD,MAAM,OAAO,KAAK,GAAwB;8DACgB,WAAW;;EAGrE,IAAI,CAAC,QAAQ,KAAK,WAAW,GAC3B;EAGF,OAAO,KAAK,mBAAmB,KAAK,EAAE;CACxC;;;;;;;;;;;;;;;;;;;;;;CAuBA,aAAa,WAAkC,CAAC,GAAiB;EAC/D,MAAM,QAAQ,KAAK,IAAI,SAAS,SAAS,IAAI,GAAG;EAChD,MAAM,QAAQ,SAAS,YAAY;EAGnC,MAAM,QAAQ,KAAK,gBAAgB,QAAQ;EAG3C,IAAI,QAAQ;EACZ,MAAM,SAAwC,CAAC;EAE/C,IAAI,SAAS,QAAQ;GACnB,MAAM,WAAW,MAAM,QAAQ,SAAS,MAAM,IAC1C,SAAS,SACT,CAAC,SAAS,MAAM;GACpB,MAAM,eAAe,SAAS,UAAU,GAAG,CAAC,CAAC,KAAK,IAAI;GACtD,SAAS,mBAAmB,aAAa;GACzC,OAAO,KAAK,GAAG,QAAQ;EACzB;EAEA,IAAI,SAAS,cAAc;GACzB,SAAS;GACT,OAAO,KAAK,SAAS,YAAY;EACnC;EAEA,IAAI,SAAS,UACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,QAAQ,GAAG;GAC5D,SAAS;GACT,OAAO,KAAK,KAAK,KAAK;EACxB;EAIF,IAAI,SAAS,QAAQ;GACnB,MAAM,SAAS,KAAK,cAAc,SAAS,MAAM;GACjD,IAAI,OAEF,SACE;QAGF,SACE;GAEJ,OAAO,KAAK,OAAO,WAAW,OAAO,WAAW,OAAO,UAAU;EACnE;EAGA,SAAS,wBAAwB,QAAQ,QAAQ,OAAO,gBAAgB,QAAQ,QAAQ;EAGxF,SAAS;EACT,OAAO,KAAK,QAAQ,CAAC;EAErB,MAAM,OAAO,KAAK,IAAI,QAAQ,IAC3B,KAAK,OAAO,GAAG,MAAM,CAAC,CACtB,QAAQ;EAEX,MAAM,UAAU,KAAK,SAAS;EAE9B,MAAM,aADa,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI,KAAA,CACvB,KAAK,QAAQ,KAAK,mBAAmB,GAAG,CAAC;EAQtE,OAAO;GAAE;GAAW;GAAO,YAJzB,WAAW,UAAU,SAAS,IAC1B,KAAK,cAAc,UAAU,UAAU,SAAS,EAAE,IAClD;EAEgC;CACxC;;;;CAKA,gBACE,UAGQ;EACR,IAAI,QAAQ;EACZ,MAAM,SAAwC,CAAC;EAE/C,IAAI,SAAS,QAAQ;GACnB,MAAM,WAAW,MAAM,QAAQ,SAAS,MAAM,IAC1C,SAAS,SACT,CAAC,SAAS,MAAM;GACpB,MAAM,eAAe,SAAS,UAAU,GAAG,CAAC,CAAC,KAAK,IAAI;GACtD,SAAS,mBAAmB,aAAa;GACzC,OAAO,KAAK,GAAG,QAAQ;EACzB;EAEA,IAAI,SAAS,cAAc;GACzB,SAAS;GACT,OAAO,KAAK,SAAS,YAAY;EACnC;EAEA,IAAI,SAAS,UACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,QAAQ,GAAG;GAC5D,SAAS;GACT,OAAO,KAAK,KAAK,KAAK;EACxB;EAGF,IAAI,SAAS,eAAe;GAC1B,SAAS;GACT,OAAO,KAAK,KAAK,MAAM,SAAS,cAAc,QAAQ,IAAI,GAAI,CAAC;EACjE;EAMA,OAJe,KAAK,IAAI,QAAQ,IAAI,KAAK,OAAO,GAAG,MAAM,CAAC,CAAC,QAI/C,CAAC,CAAC,EAAE,EAAE,SAAS;CAC7B;;;;;CAMA,cAAsB,UAAgC;EACpD,OAAO,KACL,KAAK,UAAU;GACb,GAAG,KAAK,MAAM,SAAS,UAAU,QAAQ,IAAI,GAAI;GACjD,GAAG,SAAS;EACd,CAAC,CACH;CACF;;;;;CAMA,cAAsB,QAGpB;EACA,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC;GACpC,IAAI,OAAO,KAAK,MAAM,YAAY,OAAO,KAAK,MAAM,UAClD,MAAM,IAAI,MAAM,0BAA0B;GAE5C,OAAO;IAAE,WAAW,KAAK;IAAG,YAAY,KAAK;GAAE;EACjD,QAAQ;GACN,MAAM,IAAI,MACR,sEACF;EACF;CACF;;;;;;;CAQA,eAAe,YAA6B;EAE1C,MAAM,WAAW,KAAK,GAAsB;8EAC8B,WAAW;;EAErF,IAAI,CAAC,SAAS,MAAM,SAAS,EAAE,CAAC,UAAU,GACxC,OAAO;EAET,KAAK,GAAG,uDAAuD;EAC/D,OAAO;CACT;;;;;;;;;;;;;;;;;;;;;;CAuBA,gBACE,WAEI,CAAC,GACG;EACR,IAAI,QAAQ;EACZ,MAAM,SAAwC,CAAC;EAE/C,IAAI,SAAS,QAAQ;GACnB,MAAM,WAAW,MAAM,QAAQ,SAAS,MAAM,IAC1C,SAAS,SACT,CAAC,SAAS,MAAM;GACpB,MAAM,eAAe,SAAS,UAAU,GAAG,CAAC,CAAC,KAAK,IAAI;GACtD,SAAS,mBAAmB,aAAa;GACzC,OAAO,KAAK,GAAG,QAAQ;EACzB;EAEA,IAAI,SAAS,cAAc;GACzB,SAAS;GACT,OAAO,KAAK,SAAS,YAAY;EACnC;EAEA,IAAI,SAAS,UACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,QAAQ,GAAG;GAC5D,SAAS;GACT,OAAO,KAAK,KAAK,KAAK;EACxB;EAGF,IAAI,SAAS,eAAe;GAC1B,SAAS;GACT,OAAO,KAAK,KAAK,MAAM,SAAS,cAAc,QAAQ,IAAI,GAAI,CAAC;EACjE;EAGA,OADe,KAAK,IAAI,QAAQ,IAAI,KAAK,OAAO,GAAG,MACvC,CAAC,CAAC;CAChB;;;;;;;;;;;;;;;;;CAkBA,uBAAuB,SAAiB,SAAyB;EAE/D,IAAI,CAAC,KAAK,2BAA2B,OAAO,GAC1C,MAAM,IAAI,MAAM,qBAAqB,QAAQ,2BAA2B;EAM1E,MAAM,QAAQ,KAHM,GAAsB;gFACkC,QAAQ;MAE/D,EAAE,EAAE,SAAS;EAElC,IAAI,QAAQ,GAAG;GACb,KACG,GAAG,kDAAkD,QAAQ,yBAAyB;GACzF,QAAQ,IACN,oBAAoB,MAAM,qBAAqB,QAAQ,QAAQ,QAAQ,EACzE;EACF;EAEA,OAAO;CACT;;;;CAKA,wBACE,YACA,QACM;EACN,MAAM,aAAa,OAAO;EAC1B,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;EAQxC,MAAM,cAAc;GAJlB;GACA;GACA;EAEkC,CAAC,CAAC,SAAS,UAAU,IAAI,MAAM;EAGnE,MAAM,YAAY,OAAO,OAAO,QAAQ;EACxC,MAAM,eAAe,OAAO,OAAO,WAAW;EAE9C,KAAK,GAAG;;qBAES,WAAW;yBACP,UAAU;4BACP,aAAa;yBAChB,IAAI;2BACF,YAAY;4BACX,WAAW;;CAErC;;;;CAKA,mBAA2B,KAAwC;EACjE,OAAO;GACL,IAAI,IAAI;GACR,YAAY,IAAI;GAChB,cAAc,IAAI;GAClB,QAAQ,IAAI;GACZ,UAAU,IAAI,WAAW,KAAK,MAAM,IAAI,QAAQ,IAAI;GACpD,OAAO,IAAI,aACP;IAAE,MAAM,IAAI;IAAY,SAAS,IAAI,iBAAiB;GAAG,IACzD;GACJ,2BAAW,IAAI,KAAK,IAAI,aAAa,GAAI;GACzC,2BAAW,IAAI,KAAK,IAAI,aAAa,GAAI;GACzC,aAAa,IAAI,+BAAe,IAAI,KAAK,IAAI,eAAe,GAAI,IAAI;EACtE;CACF;CAEA,gBACE,SACiC;EACjC,IAAI,KAAK,UAAU;GACjB,MAAM,OAAO,KAAK,YAAY;GAC9B,MAAM,kBACJ,SAAS,iBACR,OAAO,KAAK,8BAA8B,KAAK,SAAS,IAAI,KAAA;GAE/D,IAAI,CAAC,iBAAiB,OAAO,KAAA;GAE7B,OAAO;IACL,MAAM;IACN,SAAS;IACT,aAAa;IACb,MAAM,KAAK,SAAS,KAAK,UAAU,EAAE,GAAG,KAAK,EAAE;GACjD;EACF;EAEA,MAAM,mBACJ,SAAS,gBACT,KAAK,8BAA8B,KAAK,aAAa,IAAI;EAC3D,IAAI,CAAC,kBAAkB,OAAO,KAAA;EAE9B,OAAO;GACL,MAAM;GACN,SAAS;GACT,SAAS;GACT,MAAM,KAAK;EACb;CACF;CAEA,8BAAsC,WAAuC;EAC3E,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,KAAK,GACP,GACE,IACE,SACA,OAAO,UAAU,YACjB,gBAAgB,SAChB,OAAO,MAAM,eAAe;OAI1B,QAAQ,aACR,qBAAqB,GAAG,MAAM,qBAAqB,SAAS,GAE5D,OAAO;EAAA;CAKf;CAEA,6BACE,WACoB;EACpB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,KAAK,GACP,GACE,IAAI,UAAU,WACZ,OAAO;CAIb;;;;;;;;;;CAeA,MAAM,mBAAmB,UAA2C;EAClE,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;EAExC,QAAQ,SAAS,MAAjB;GACE,KAAK;IAGH,KAAK,GAAG;;iDAEiC,IAAI;gCACrB,SAAS,WAAW;;IAE5C,MAAM,KAAK,mBACT,SAAS,cACT,SAAS,YACT,SAAS,QACX;IACA;GACF,KAAK;IAGH,KAAK,GAAG;;kDAEkC,IAAI,mBAAmB,IAAI;gCAC7C,SAAS,WAAW;;;IAG5C,MAAM,KAAK,mBACT,SAAS,cACT,SAAS,YACT,SAAS,MACX;IACA;GACF,KAAK;IAGH,KAAK,GAAG;;iDAEiC,IAAI,mBAAmB,IAAI;8DACd,SAAS,MAAM;gCAC7C,SAAS,WAAW;;;IAG5C,MAAM,KAAK,gBACT,SAAS,cACT,SAAS,YACT,SAAS,KACX;IACA;GACF,KAAK;IAEH,MAAM,KAAK,gBACT,SAAS,cACT,SAAS,YACT,SAAS,KACX;IACA;EACJ;CACF;;;;;;;;;CAUA,MAAM,mBAEJ,cAEA,YAEA,UACe,CAEjB;;;;;;;;;CAUA,MAAM,mBAEJ,cAEA,YAEA,QACe,CAEjB;;;;;;;;;CAUA,MAAM,gBACJ,cACA,YACA,OACe;EACf,QAAQ,MACN,mBAAmB,aAAa,GAAG,WAAW,KAAK,MAAM,sEAE3D;CACF;;;;;;;;;CAUA,MAAM,gBAEJ,cAEA,YAEA,OACe,CAEjB;;;;;CAWA,MAAM,yBAAyB,UAA2C;EACxE,MAAM,KAAK,2BAA2B;EACtC,MAAM,KAAK,mBAAmB,QAAQ;CACxC;;;;;CAMA,MAAM,oBAAoB,SAAiC;EACzD,MAAM,KAAK,2BAA2B;EACtC,KAAK,UAAU,KAAK,UAAU,OAAO,CAAC;CACxC;;;;;CAMA,MAAM,sBACJ,QACA,OACe;EACf,MAAM,KAAK,2BAA2B;EACtC,IAAI,WAAW,OACb,KAAK,SAAS,KAAc;OACvB,IAAI,WAAW,SAAS;GAC7B,MAAM,eAAe,KAAK,SAAU,CAAC;GACrC,KAAK,SAAS;IACZ,GAAG;IACH,GAAI;GACN,CAAU;EACZ,OAAO,IAAI,WAAW,SACpB,KAAK,SAAS,KAAK,YAAY;CAEnC;CAyCA,MAAM,aACJ,YACA,cACA,uBAIA,cACA,SAYA;EACA,MAAM,kBAAkB,OAAO,iBAAiB;EAChD,MAAM,gBAAgB,kBAClB,IAAI,IAAI,YAAY,CAAC,CAAC,OACtB,KAAA;EAIJ,IAAI;EACJ,IACE,OAAO,0BAA0B,YACjC,0BAA0B,QAC1B,OAAQ,sBAA2C,OAAO,UAC1D;GACA,MAAM,QAAS,sBAAyC;GACxD,cAAc,kBAAkB,KAAK;EACvC;EAEA,MAAM,aAAa,KAAK,IAAI,YAAY;EAExC,MAAM,iBAAiB,WAAW,MAC/B,MACC,EAAE,SAAS,eACV,CAAC,mBAAmB,IAAI,IAAI,EAAE,UAAU,CAAC,CAAC,SAAS,cACxD;EAEA,IAAI,aAAa;GAIf,MAAM,aAAa,WAAW,MAAM,MAAM;IACxC,IAAI,EAAE,OAAO,aAAa,OAAO;IACjC,IAAI,EAAE,SAAS,YAAY,OAAO;IAClC,IAAI,iBACF,OAAO,IAAI,IAAI,EAAE,UAAU,CAAC,CAAC,SAAS;IAExC,OAAO;GACT,CAAC;GACD,IAAI,YACF,MAAM,IAAI,MACR,kBAAkB,YAAY,iCAAiC,WAAW,KAAK,KAAK,WAAW,WAAW,8CAE5G;GAUF,IAAI,kBAAkB,eAAe,OAAO,aAAa;IACvD,MAAM,KAAK,IAAI,gBACb,eAAe,IACf,aACA,KAAK,IACP;IACA,eAAe,KAAK;GACtB;EACF;EAEA,IAAI,kBAAkB,KAAK,IAAI,eAAe,eAAe,KAAK;GAChE,MAAM,OAAO,KAAK,IAAI,eAAe,eAAe;GACpD,IAAI,KAAK,oBAAoB,mBAAmB,gBAAgB;IAC9D,MAAM,eAAe,KAAK,QAAQ,UAAU;IAC5C,MAAM,UACH,MAAM,KAAK,mBACV,eAAe,IACf,cAAc,SACd,YACF,KACC,MAAM,KAAK,mBACV,eAAe,IACf,eAAe,UACf,YACF;IACF,IAAI,SACF,OAAO;KACL,IAAI,eAAe;KACnB,OAAO,mBAAmB;KAC1B;IACF;IAGF,MAAM,kBAAkB,MAAM,KAAK,IAAI,gBACrC,eAAe,EACjB;IACA,IAAI,gBAAgB,UAAU,mBAAmB,gBAAgB;KAC/D,IAAI,CAAC,gBAAgB,SACnB,MAAM,IAAI,MAAM,iDAAiD;KAEnE,OAAO;MACL,IAAI,eAAe;MACnB,OAAO,gBAAgB;MACvB,SAAS,gBAAgB;KAC3B;IACF;IACA,IAAI,gBAAgB,UAAU,mBAAmB,WAAW;KAC1D,MAAM,iBAAiB,MAAM,KAAK,IAAI,oBACpC,eAAe,EACjB;KACA,IAAI,CAAC,gBAAgB,SACnB,MAAM,IAAI,MACR,+CAA+C,gBAAgB,SAAS,wBAC1E;KAEF,OAAO;MACL,IAAI,eAAe;MACnB,OAAO,mBAAmB;KAC5B;IACF;IACA,MAAM,IAAI,MACR,sCAAsC,cAAc,IAAI,gBAAgB,OAC1E;GACF;GACA,IAAI,KAAK,oBAAoB,mBAAmB,QAC9C,MAAM,IAAI,MACR,eAAe,WAAW,wBAAwB,KAAK,iBACzD;GAEF,OAAO;IAAE,IAAI,eAAe;IAAI,OAAO,mBAAmB;GAAM;EAClE;EAGA,IAAI,OAAO,iBAAiB,UAAU;GACpC,MAAM,UAAU;GAIhB,MAAM,iBAAiB,WAAW,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG;GAInE,MAAM,cAAc,eAAe,gBAAgB;GACnD,MAAM,EAAE,OAAO,MAAM,KAAK,IAAI,QAC5B,GAAG,gBAAgB,kBACnB;IACE,WAAW,cAAc,EAAE,IAAI,YAAY,IAAI,KAAA;IAC/C,WAAW;KACT,MAAM;KACN,WACE;KACF,MAAM;KACN,OAAO,SAAS;IAClB;GACF,CACF;GAEA,MAAM,OAAO,KAAK,IAAI,eAAe;GACrC,IAAI,QAAQ,KAAK,oBAAoB,mBAAmB,WAAW;IACjE,MAAM,iBAAiB,MAAM,KAAK,IAAI,oBAAoB,EAAE;IAC5D,IAAI,kBAAkB,CAAC,eAAe,SACpC,MAAM,IAAI,MACR,+CAA+C,eAAe,OAChE;GAEJ,OAAO,IAAI,QAAQ,KAAK,oBAAoB,mBAAmB,QAC7D,MAAM,IAAI,MACR,oCAAoC,WAAW,aAAa,KAAK,iBACnE;GAGF,MAAM,cAAc,KAAK,6BACvB,YACF;GACA,IAAI,aACF,KAAK,IAAI,uBACP,IACA,YACA,gBACA,aACA,SAAS,KACX;GAGF,OAAO;IAAE;IAAI,OAAO,mBAAmB;GAAM;EAC/C;EAGA,MAAM,cAAc;EAKpB,IAAI;EACJ,IAAI;EACJ,IAAI;EAIJ,IAAI;EAEJ,IAAI,OAAO,gBAAgB,YAAY,gBAAgB,MAAM;GAC3D,uBAAuB,YAAY;GACnC,uBAAuB,YAAY;GACnC,uBAAuB,YAAY,gBAAgB;GACnD,kBAAkB;IAChB,QAAQ,YAAY;IACpB,WAAW,YAAY;IACvB,OAAO,YAAY;GACrB;EACF,OAAO;GACL,uBAAuB;GACvB,uBAAuB,gBAAgB;GACvC,kBAAkB;EACpB;EAGA,IACE,CAAC,KAAK,iBAAiB,yBACvB,wBACA,CAAC,sBAED,MAAM,IAAI,MACR,yOAGF;EAIF,IAAI,CAAC,sBAAsB;GACzB,MAAM,EAAE,SAAS,eAAe,gBAAgB;GAChD,IAAI,SAAS;IACX,MAAM,aAAa,IAAI,IAAI,QAAQ,GAAG;IACtC,uBAAuB,GAAG,WAAW,SAAS,IAAI,WAAW;GAC/D,OAAO,IAAI,YAAY,KAAK;IAC1B,MAAM,gBAAgB,IAAI,IAAI,WAAW,GAAG;IAC5C,uBAAuB,GAAG,cAAc,SAAS,IAAI,cAAc;GACrE;EACF;EAGA,IAAI;EACJ,IAAI,sBAAsB;GACxB,MAAM,iBAAiB,qBAAqB,QAAQ,OAAO,EAAE;GAC7D,cAAc,uBACV,GAAG,eAAe,GAAG,qBAAqB,QAAQ,OAAO,EAAE,MAC3D,GAAG,eAAe,GAAG,qBAAqB,GAAG,qBAAqB,KAAK,aAAa,IAAI,EAAE,GAAG,KAAK,KAAK;EAC7G;EAEA,MAAM,KAAK,eAAe,gBAAgB,MAAM,OAAO,CAAC;EAGxD,IAAI;EAGJ,IAAI,aAAa;GACf,eAAe,KAAK,uBAAuB,WAAW;GACtD,aAAa,WAAW;EAC1B;EAGA,MAAM,gBACJ,iBAAiB,WAAW,QAAQ;EAItC,IAAI,sBAAiD,CAAC;EACtD,IAAI,iBAAiB,WAAW,SAC9B,sBAAsB;GACpB,iBAAiB,EACf,QAAQ,KAAK,SACX,MAAM,KAAK;IACT,GAAG;IACH,SAAS,iBAAiB,WAAW;GACvC,CAAC,EACL;GACA,aAAa,EACX,SAAS,iBAAiB,WAAW,QACvC;EACF;EAIF,MAAM,KAAK,IAAI,eAAe,IAAI;GAChC,KAAK;GACL,MAAM;GACN;GACA,QAAQ,iBAAiB;GACzB,WAAW;IACT,GAAG;IACH;IACA,MAAM;IACN,8BACE,iBAAiB,WAAW;GAChC;GACA,OAAO,iBAAiB;EAC1B,CAAC;EAED,MAAM,SAAS,MAAM,KAAK,IAAI,gBAAgB,EAAE;EAEhD,IAAI,OAAO,UAAU,mBAAmB,QAEtC,MAAM,IAAI,MACR,sCAAsC,cAAc,IAAI,OAAO,OACjE;EAGF,IAAI,OAAO,UAAU,mBAAmB,gBAAgB;GACtD,IAAI,CAAC,aACH,MAAM,IAAI,MACR,uHAEF;GAEF,OAAO;IAAE;IAAI,OAAO,OAAO;IAAO,SAAS,OAAO;GAAQ;EAC5D;EAGA,MAAM,iBAAiB,MAAM,KAAK,IAAI,oBAAoB,EAAE;EAE5D,IAAI,kBAAkB,CAAC,eAAe,SAEpC,MAAM,IAAI,MACR,+CAA+C,eAAe,OAChE;EAGF,OAAO;GAAE;GAAI,OAAO,mBAAmB;EAAM;CAC/C;CAEA,MAAc,mBACZ,UACA,SACA,cAC6B;EAC7B,IAAI,CAAC,KAAK,mBAAmB,OAAO,KAAK,CAAC,cAAc;EACxD,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,CAAC,aAAa,IAAI,OAAO;EACvD,IAAI,CAAC,OAAO,OAAO;EAEnB,aAAa,WAAW;EACxB,IAAI;GACF,QAAQ,MAAM,aAAa,WAAW,KAAK,EAAA,CAAG,QAAQ,UAAU,KAAA;EAClE,QAAQ;GACN;EACF;CACF;CAEA,mBACE,OACiB;EACjB,IAAI,CAAC,OAAO,OAAO;EACnB,IAAI;GACF,MAAM,MAAM,IAAI,IAAI,KAAK;GACzB,OAAO,IAAI,aAAa,WAAW,IAAI,aAAa;EACtD,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,gBAAgB,IAAY;EAChC,MAAM,KAAK,IAAI,aAAa,EAAE;CAChC;CAEA,gBAAiC;EAC/B,MAAM,WAA4B;GAChC,SAAS,KAAK,IAAI,YAAY;GAC9B,WAAW,KAAK,IAAI,cAAc;GAClC,SAAS,CAAC;GACV,OAAO,KAAK,IAAI,UAAU;EAC5B;EAEA,MAAM,UAAU,KAAK,IAAI,YAAY;EAErC,IAAI,WAAW,MAAM,QAAQ,OAAO,KAAK,QAAQ,SAAS,GACxD,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,aAAa,KAAK,IAAI,eAAe,OAAO;GAGlD,IAAI,eAAmD;GACvD,IAAI,CAAC,cAAc,OAAO,UAExB,eAAe;GAGjB,SAAS,QAAQ,OAAO,MAAM;IAC5B,UAAU,OAAO;IACjB,cAAc,YAAY,sBAAsB;IAChD,OAAO,oBAAoB,YAAY,mBAAmB,IAAI;IAC9D,cAAc,YAAY,gBAAgB;IAC1C,MAAM,OAAO;IACb,YAAY,OAAO;IACnB,OAAO,YAAY,mBAAmB;GACxC;EACF;EAGF,OAAO;CACT;;;;;;;;;;;;;;;;;;;;;;;CAwBA,uBAAuB,aAA4C;EACjE,OAAO,IAAI,iCACT,KAAK,IAAI,SACT,KAAK,MACL,WACF;CACF;CAEA,sBAA8B;EAC5B,KAAK,mBACH,KAAK,UAAU;GACb,KAAK,KAAK,cAAc;GACxB,MAAA;EACF,CAAC,CACH;CACF;AACF;AA9/QE,MAAO,UAA8B,CAAC;AAigRxC,MAAM,iCAAiB,IAAI,IAAwC;;kBAoFhE,OAAO;AA/CV,IAAM,cAAN,cAA0B,UAAU;CAGlC,YAAY,OAAgC;EAC1C,MAAM;;EACN,uBAAA,QAAA,MAAc,KAAA;CAChB;CAEA,MAAM,SAA8B;EAClC,MAAM,SAAA,uBAAA,QAAS,IAAA,CAAA,CAAY,IAAI,UAAU;EACzC,MAAM,SAAuB,CAAC;EAC9B,IAAI,OAAO;EACX,OAAO,CAAC,MAAM;GACZ,MAAM,EAAE,OAAO,MAAM,eAAe,MAAM,OAAO,KAAK;GACtD,OAAO;GACP,IAAI,OACF,OAAO,KAAK,KAAK;EAErB;EACA,MAAM,cAAc,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;EACvE,MAAM,WAAW,IAAI,WAAW,WAAW;EAC3C,IAAI,SAAS;EACb,KAAK,MAAM,SAAS,QAAQ;GAC1B,SAAS,IAAI,OAAO,MAAM;GAC1B,UAAU,MAAM;EAClB;EACA,OAAO;CACT;CAEA,UAAU,QAAgB;EACxB,uBAAA,QAAA,IAAA,CAAA,CAAY,UAAU,MAAM;CAC9B;CAEA,QAAQ,QAAgB,SAA6C;EACnE,OAAA,uBAAA,QAAO,IAAA,CAAA,CAAY,QAAQ,QAAQ,OAAO;CAC5C;CAEA,MAAM,SAIuB;EAC3B,OAAA,uBAAA,QAAO,IAAA,CAAA,CAAY,MACjB,IAAI,aAAa,QAAQ,MAAM,QAAQ,IAAI,QAAQ,GAAG,CACxD;CACF;CAEA,CAAA,mBAAmB,CAInB;AACF;AAIA,MAAM,gCAAgB,IAAI,QAGxB;;;;;;;;AASF,eAAsB,gBAGpB,OACA,KACA,SACe;CACf,MAAM,cAAc,MAAM,QAAQ,SAAS,OAAO,GAAG;CAErD,IAAI,CAAC,aAAa;EAChB,IAAI,QAAQ,WACV,MAAM,QAAQ,UAAU,KAAK;OAE7B,QAAQ,KAAK,0DAA0D;EAEzE;CACF;CAGA,IAAI,CAAC,cAAc,IAAI,GAA8B,GAAG;EACtD,MAAM,MAA+B,CAAC;EACtC,MAAM,gBAA0B,CAAC;EACjC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAA8B,GACtE,IACE,SACA,OAAO,UAAU,YACjB,gBAAgB,SAChB,OAAO,MAAM,eAAe,YAC5B;GAEA,IAAI,OAAO;GACX,IAAI,qBAAqB,GAAG,KAAK;GACjC,IAAI,IAAI,YAAY,KAAK;GACzB,cAAc,KAAK,GAAG;EACxB;EAEF,cAAc,IAAI,KAAgC;GAChD;GACA;EACF,CAAC;CACH;CAEA,MAAM,SAAS,cAAc,IAAI,GAA8B;CAC/D,MAAM,YAAY,OAAO,IAAI,YAAY;CAEzC,IAAI,CAAC,WAAW;EAEd,MAAM,kBAAkB,OAAO,cAAc,KAAK,IAAI;EACtD,MAAM,IAAI,MACR,oBAAoB,YAAY,UAAU,gDAAgD,iBAC5F;CACF;CAEA,MAAM,QAAQ,MAAM,eAClB,WACA,YAAY,OACd;CAIA,MAAM,SAAS,IAAI,YAAY,KAAK;CAEpC,MAAM,MAAM,SAAS;EACnB,MAAM,MAAM;EACZ,IAAI,MAAM;EACV,SAAS,MAAM;EACf,SAAS,MAAM;EACf,eAAe,YAAY;EAC3B,SAAS;CACX,CAAC;AACH;;;;AAKA,IAAa,oBAAb,MAA+B;CAK7B,YAAY,YAAwB,IAAY;EAFhD,KAAQ,UAAU;EAGhB,KAAK,cAAc;EACnB,KAAK,MAAM;CACb;CAEA,MAAc,UAAgC;EAC5C,MAAM,YAAY,2BAA2B,MAAM,QAAQ;EAC3D,IAAI,cAAc,MAAM,OAAO;EAC/B,OAAO,sBAAsB,KAAK,aAAa,QAAQ;CACzD;;;;CAKA,IAAI,WAAoB;EACtB,OAAO,KAAK;CACd;;;;;;CAOA,KAAK,OAAyB;EAC5B,IAAI,KAAK,SAAS;GAChB,QAAQ,KACN,yEACF;GACA,OAAO;EACT;EACA,MAAM,WAAwB;GAC5B,MAAM;GACN,IAAI,KAAK;GACT,QAAQ;GACR,SAAS;GACT,MAAA;EACF;EACA,OAAO,KAAK,MAAM,QAAQ;CAC5B;;;;;;CAOA,IAAI,YAA+B;EACjC,IAAI,KAAK,SACP,OAAO;EAET,KAAK,UAAU;EACf,MAAM,WAAwB;GAC5B,MAAM;GACN,IAAI,KAAK;GACT,QAAQ;GACR,SAAS;GACT,MAAA;EACF;EACA,OAAO,KAAK,MAAM,QAAQ;CAC5B;;;;;;CAOA,MAAM,SAA0B;EAC9B,IAAI,KAAK,SACP,OAAO;EAET,KAAK,UAAU;EACf,MAAM,WAAwB;GAC5B,OAAO;GACP,IAAI,KAAK;GACT,SAAS;GACT,MAAA;EACF;EACA,OAAO,KAAK,MAAM,QAAQ;CAC5B;AACF"}