@probelabs/visor 0.1.181 → 0.1.182

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 (158) hide show
  1. package/defaults/code-talk.yaml +80 -14
  2. package/defaults/engineer.yaml +33 -15
  3. package/defaults/skills/code-explorer.yaml +5 -0
  4. package/dist/agent-protocol/a2a-frontend.d.ts +10 -0
  5. package/dist/agent-protocol/a2a-frontend.d.ts.map +1 -1
  6. package/dist/agent-protocol/task-evaluator.d.ts +52 -0
  7. package/dist/agent-protocol/task-evaluator.d.ts.map +1 -0
  8. package/dist/agent-protocol/task-store.d.ts +5 -3
  9. package/dist/agent-protocol/task-store.d.ts.map +1 -1
  10. package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
  11. package/dist/agent-protocol/tasks-tui.d.ts +34 -0
  12. package/dist/agent-protocol/tasks-tui.d.ts.map +1 -0
  13. package/dist/agent-protocol/trace-serializer.d.ts +90 -0
  14. package/dist/agent-protocol/trace-serializer.d.ts.map +1 -0
  15. package/dist/agent-protocol/track-execution.d.ts +2 -0
  16. package/dist/agent-protocol/track-execution.d.ts.map +1 -1
  17. package/dist/cli-main.d.ts.map +1 -1
  18. package/dist/defaults/code-talk.yaml +80 -14
  19. package/dist/defaults/engineer.yaml +33 -15
  20. package/dist/defaults/skills/code-explorer.yaml +5 -0
  21. package/dist/docs/commands.md +57 -14
  22. package/dist/docs/configuration.md +2 -0
  23. package/dist/docs/guides/graceful-restart.md +178 -0
  24. package/dist/docs/observability.md +69 -0
  25. package/dist/docs/production-deployment.md +17 -0
  26. package/dist/email/polling-runner.d.ts +4 -0
  27. package/dist/email/polling-runner.d.ts.map +1 -1
  28. package/dist/generated/config-schema.d.ts +70 -6
  29. package/dist/generated/config-schema.d.ts.map +1 -1
  30. package/dist/generated/config-schema.json +73 -6
  31. package/dist/index.js +5006 -886
  32. package/dist/output/traces/{run-2026-03-17T13-58-29-402Z.ndjson → run-2026-03-18T19-02-50-465Z.ndjson} +84 -84
  33. package/dist/{traces/run-2026-03-17T13-59-10-403Z.ndjson → output/traces/run-2026-03-18T19-03-30-428Z.ndjson} +2037 -2037
  34. package/dist/providers/mcp-custom-sse-server.d.ts +4 -0
  35. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
  36. package/dist/runners/graceful-restart.d.ts +46 -0
  37. package/dist/runners/graceful-restart.d.ts.map +1 -0
  38. package/dist/runners/mcp-server-runner.d.ts +12 -0
  39. package/dist/runners/mcp-server-runner.d.ts.map +1 -1
  40. package/dist/runners/runner-factory.d.ts.map +1 -1
  41. package/dist/runners/runner-host.d.ts +12 -0
  42. package/dist/runners/runner-host.d.ts.map +1 -1
  43. package/dist/runners/runner.d.ts +12 -0
  44. package/dist/runners/runner.d.ts.map +1 -1
  45. package/dist/sdk/{a2a-frontend-IWOUJOIZ.mjs → a2a-frontend-4LP3MLTS.mjs} +47 -5
  46. package/dist/sdk/a2a-frontend-4LP3MLTS.mjs.map +1 -0
  47. package/dist/sdk/a2a-frontend-5J3UNFY4.mjs +1718 -0
  48. package/dist/sdk/a2a-frontend-5J3UNFY4.mjs.map +1 -0
  49. package/dist/sdk/{a2a-frontend-BDACLGMA.mjs → a2a-frontend-MU5EO2HZ.mjs} +35 -1
  50. package/dist/sdk/a2a-frontend-MU5EO2HZ.mjs.map +1 -0
  51. package/dist/sdk/{check-provider-registry-4YKTEDKF.mjs → check-provider-registry-MHXQGUNN.mjs} +7 -7
  52. package/dist/sdk/{check-provider-registry-4YFVBGYU.mjs → check-provider-registry-RRWCXSTG.mjs} +3 -3
  53. package/dist/sdk/{check-provider-registry-67ZLGDDQ.mjs → check-provider-registry-Y33CRFVD.mjs} +7 -7
  54. package/dist/sdk/{chunk-DGIH6EX3.mjs → chunk-4AXAVXG5.mjs} +151 -281
  55. package/dist/sdk/chunk-4AXAVXG5.mjs.map +1 -0
  56. package/dist/sdk/{chunk-VMVIM4JB.mjs → chunk-4I3TJ7UJ.mjs} +37 -7
  57. package/dist/sdk/chunk-4I3TJ7UJ.mjs.map +1 -0
  58. package/dist/sdk/{chunk-VXC2XNQJ.mjs → chunk-5J3DNRF7.mjs} +3 -3
  59. package/dist/sdk/{chunk-7YZSSO4X.mjs → chunk-6DPPP7LD.mjs} +10 -10
  60. package/dist/sdk/chunk-7ERVRLDV.mjs +296 -0
  61. package/dist/sdk/chunk-7ERVRLDV.mjs.map +1 -0
  62. package/dist/sdk/{chunk-4DVP6KVC.mjs → chunk-7Z2WHX2J.mjs} +71 -30
  63. package/dist/sdk/chunk-7Z2WHX2J.mjs.map +1 -0
  64. package/dist/sdk/chunk-ANUT54HW.mjs +1502 -0
  65. package/dist/sdk/chunk-ANUT54HW.mjs.map +1 -0
  66. package/dist/sdk/{chunk-J73GEFPT.mjs → chunk-DHETLQIX.mjs} +2 -2
  67. package/dist/sdk/{chunk-QGBASDYP.mjs → chunk-JCOSKBMP.mjs} +71 -30
  68. package/dist/sdk/chunk-JCOSKBMP.mjs.map +1 -0
  69. package/dist/sdk/chunk-MK7ONH47.mjs +739 -0
  70. package/dist/sdk/chunk-MK7ONH47.mjs.map +1 -0
  71. package/dist/sdk/chunk-QXT47ZHR.mjs +390 -0
  72. package/dist/sdk/chunk-QXT47ZHR.mjs.map +1 -0
  73. package/dist/sdk/chunk-V75NEIXL.mjs +296 -0
  74. package/dist/sdk/chunk-V75NEIXL.mjs.map +1 -0
  75. package/dist/sdk/chunk-ZOF5QT6U.mjs +5943 -0
  76. package/dist/sdk/chunk-ZOF5QT6U.mjs.map +1 -0
  77. package/dist/sdk/{config-TSA5FUOM.mjs → config-2STD74CJ.mjs} +2 -2
  78. package/dist/sdk/config-JE4HKTWW.mjs +16 -0
  79. package/dist/sdk/{failure-condition-evaluator-HTPB5FYW.mjs → failure-condition-evaluator-5DZYMCGW.mjs} +4 -4
  80. package/dist/sdk/failure-condition-evaluator-R6DCDJAV.mjs +18 -0
  81. package/dist/sdk/{github-frontend-3SDFCCKI.mjs → github-frontend-3PSCKPAJ.mjs} +4 -4
  82. package/dist/sdk/github-frontend-L3F5JXPJ.mjs +1394 -0
  83. package/dist/sdk/github-frontend-L3F5JXPJ.mjs.map +1 -0
  84. package/dist/sdk/{host-QE4L7UXE.mjs → host-54CHV2LW.mjs} +3 -3
  85. package/dist/sdk/{host-VBBSLUWG.mjs → host-WAU6CT42.mjs} +3 -3
  86. package/dist/sdk/{host-CVH2CSHM.mjs → host-X5ZZCEWN.mjs} +2 -2
  87. package/dist/sdk/{routing-YVMTKFDZ.mjs → routing-CVQT4KHX.mjs} +5 -5
  88. package/dist/sdk/routing-EBAE5SSO.mjs +26 -0
  89. package/dist/sdk/{schedule-tool-Z5VG67JK.mjs → schedule-tool-POY3CDZL.mjs} +7 -7
  90. package/dist/sdk/{schedule-tool-ADUXTCY7.mjs → schedule-tool-R2OAATUS.mjs} +7 -7
  91. package/dist/sdk/{schedule-tool-ZMX3Y7LF.mjs → schedule-tool-Z6QYL2B3.mjs} +3 -3
  92. package/dist/sdk/{schedule-tool-handler-N7UNABOA.mjs → schedule-tool-handler-J4NUETJ6.mjs} +3 -3
  93. package/dist/sdk/{schedule-tool-handler-PCERK6ZZ.mjs → schedule-tool-handler-JMAKHPI7.mjs} +7 -7
  94. package/dist/sdk/{schedule-tool-handler-QOJVFRB4.mjs → schedule-tool-handler-MWFUIQKR.mjs} +7 -7
  95. package/dist/sdk/sdk.d.mts +33 -0
  96. package/dist/sdk/sdk.d.ts +33 -0
  97. package/dist/sdk/sdk.js +2058 -342
  98. package/dist/sdk/sdk.js.map +1 -1
  99. package/dist/sdk/sdk.mjs +6 -6
  100. package/dist/sdk/task-evaluator-HLNXKKVV.mjs +1278 -0
  101. package/dist/sdk/task-evaluator-HLNXKKVV.mjs.map +1 -0
  102. package/dist/sdk/{trace-helpers-KXDOJWBL.mjs → trace-helpers-HL5FBX65.mjs} +3 -3
  103. package/dist/sdk/trace-helpers-WJXYVV4S.mjs +29 -0
  104. package/dist/sdk/trace-helpers-WJXYVV4S.mjs.map +1 -0
  105. package/dist/sdk/trace-reader-ZY77OFNM.mjs +266 -0
  106. package/dist/sdk/trace-reader-ZY77OFNM.mjs.map +1 -0
  107. package/dist/sdk/track-execution-MKIQXP2C.mjs +136 -0
  108. package/dist/sdk/track-execution-MKIQXP2C.mjs.map +1 -0
  109. package/dist/sdk/track-execution-YUXQ6WQH.mjs +136 -0
  110. package/dist/sdk/track-execution-YUXQ6WQH.mjs.map +1 -0
  111. package/dist/sdk/{workflow-check-provider-NTHC5ZBF.mjs → workflow-check-provider-SE5I7EMA.mjs} +7 -7
  112. package/dist/sdk/workflow-check-provider-SE5I7EMA.mjs.map +1 -0
  113. package/dist/sdk/{workflow-check-provider-SRIMWKLQ.mjs → workflow-check-provider-VKYGI5GK.mjs} +3 -3
  114. package/dist/sdk/workflow-check-provider-VKYGI5GK.mjs.map +1 -0
  115. package/dist/sdk/{workflow-check-provider-CJXW2Z4F.mjs → workflow-check-provider-YDGZRI3Z.mjs} +7 -7
  116. package/dist/sdk/workflow-check-provider-YDGZRI3Z.mjs.map +1 -0
  117. package/dist/slack/socket-runner.d.ts +12 -0
  118. package/dist/slack/socket-runner.d.ts.map +1 -1
  119. package/dist/teams/webhook-runner.d.ts +4 -0
  120. package/dist/teams/webhook-runner.d.ts.map +1 -1
  121. package/dist/telegram/polling-runner.d.ts +2 -0
  122. package/dist/telegram/polling-runner.d.ts.map +1 -1
  123. package/dist/traces/{run-2026-03-17T13-58-29-402Z.ndjson → run-2026-03-18T19-02-50-465Z.ndjson} +84 -84
  124. package/dist/{output/traces/run-2026-03-17T13-59-10-403Z.ndjson → traces/run-2026-03-18T19-03-30-428Z.ndjson} +2037 -2037
  125. package/dist/types/config.d.ts +33 -0
  126. package/dist/types/config.d.ts.map +1 -1
  127. package/dist/whatsapp/webhook-runner.d.ts +4 -0
  128. package/dist/whatsapp/webhook-runner.d.ts.map +1 -1
  129. package/package.json +2 -2
  130. package/dist/sdk/a2a-frontend-BDACLGMA.mjs.map +0 -1
  131. package/dist/sdk/a2a-frontend-IWOUJOIZ.mjs.map +0 -1
  132. package/dist/sdk/chunk-4DVP6KVC.mjs.map +0 -1
  133. package/dist/sdk/chunk-DGIH6EX3.mjs.map +0 -1
  134. package/dist/sdk/chunk-QGBASDYP.mjs.map +0 -1
  135. package/dist/sdk/chunk-VMVIM4JB.mjs.map +0 -1
  136. /package/dist/sdk/{check-provider-registry-4YFVBGYU.mjs.map → check-provider-registry-MHXQGUNN.mjs.map} +0 -0
  137. /package/dist/sdk/{check-provider-registry-4YKTEDKF.mjs.map → check-provider-registry-RRWCXSTG.mjs.map} +0 -0
  138. /package/dist/sdk/{check-provider-registry-67ZLGDDQ.mjs.map → check-provider-registry-Y33CRFVD.mjs.map} +0 -0
  139. /package/dist/sdk/{chunk-VXC2XNQJ.mjs.map → chunk-5J3DNRF7.mjs.map} +0 -0
  140. /package/dist/sdk/{chunk-7YZSSO4X.mjs.map → chunk-6DPPP7LD.mjs.map} +0 -0
  141. /package/dist/sdk/{chunk-J73GEFPT.mjs.map → chunk-DHETLQIX.mjs.map} +0 -0
  142. /package/dist/sdk/{config-TSA5FUOM.mjs.map → config-2STD74CJ.mjs.map} +0 -0
  143. /package/dist/sdk/{failure-condition-evaluator-HTPB5FYW.mjs.map → config-JE4HKTWW.mjs.map} +0 -0
  144. /package/dist/sdk/{routing-YVMTKFDZ.mjs.map → failure-condition-evaluator-5DZYMCGW.mjs.map} +0 -0
  145. /package/dist/sdk/{schedule-tool-ADUXTCY7.mjs.map → failure-condition-evaluator-R6DCDJAV.mjs.map} +0 -0
  146. /package/dist/sdk/{github-frontend-3SDFCCKI.mjs.map → github-frontend-3PSCKPAJ.mjs.map} +0 -0
  147. /package/dist/sdk/{host-CVH2CSHM.mjs.map → host-54CHV2LW.mjs.map} +0 -0
  148. /package/dist/sdk/{host-QE4L7UXE.mjs.map → host-WAU6CT42.mjs.map} +0 -0
  149. /package/dist/sdk/{host-VBBSLUWG.mjs.map → host-X5ZZCEWN.mjs.map} +0 -0
  150. /package/dist/sdk/{schedule-tool-Z5VG67JK.mjs.map → routing-CVQT4KHX.mjs.map} +0 -0
  151. /package/dist/sdk/{schedule-tool-ZMX3Y7LF.mjs.map → routing-EBAE5SSO.mjs.map} +0 -0
  152. /package/dist/sdk/{schedule-tool-handler-N7UNABOA.mjs.map → schedule-tool-POY3CDZL.mjs.map} +0 -0
  153. /package/dist/sdk/{schedule-tool-handler-PCERK6ZZ.mjs.map → schedule-tool-R2OAATUS.mjs.map} +0 -0
  154. /package/dist/sdk/{schedule-tool-handler-QOJVFRB4.mjs.map → schedule-tool-Z6QYL2B3.mjs.map} +0 -0
  155. /package/dist/sdk/{trace-helpers-KXDOJWBL.mjs.map → schedule-tool-handler-J4NUETJ6.mjs.map} +0 -0
  156. /package/dist/sdk/{workflow-check-provider-CJXW2Z4F.mjs.map → schedule-tool-handler-JMAKHPI7.mjs.map} +0 -0
  157. /package/dist/sdk/{workflow-check-provider-NTHC5ZBF.mjs.map → schedule-tool-handler-MWFUIQKR.mjs.map} +0 -0
  158. /package/dist/sdk/{workflow-check-provider-SRIMWKLQ.mjs.map → trace-helpers-HL5FBX65.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/snapshot-store.ts","../../src/state-machine/states/routing.ts"],"sourcesContent":["/*\n * Internal snapshot store for incremental adoption of snapshot+scope execution.\n * Phase 0: journal only — no behavior change, used for future visibility work.\n */\n\nimport type { ReviewSummary } from './reviewer';\nimport type { EventTrigger } from './types/config';\n\nexport type ScopePath = Array<{ check: string; index: number }>;\n\nexport interface JournalEntry {\n commitId: number;\n sessionId: string;\n scope: ScopePath;\n checkId: string;\n event: EventTrigger | undefined;\n result: ReviewSummary & { output?: unknown; content?: string };\n}\n\nexport class ExecutionJournal {\n private commit = 0;\n private entries: JournalEntry[] = [];\n\n beginSnapshot(): number {\n return this.commit;\n }\n\n commitEntry(entry: {\n sessionId: string;\n scope: ScopePath;\n checkId: string;\n result: ReviewSummary & { output?: unknown; content?: string };\n event?: EventTrigger;\n }): JournalEntry {\n const committed: JournalEntry = {\n sessionId: entry.sessionId,\n scope: entry.scope,\n checkId: entry.checkId,\n result: entry.result,\n event: entry.event,\n commitId: ++this.commit,\n };\n this.entries.push(committed);\n return committed;\n }\n\n readVisible(sessionId: string, commitMax: number, event?: EventTrigger): JournalEntry[] {\n return this.entries.filter(\n e =>\n e.sessionId === sessionId && e.commitId <= commitMax && (event ? e.event === event : true)\n );\n }\n\n // Lightweight helpers for debugging/metrics\n size(): number {\n return this.entries.length;\n }\n}\n\nexport class ContextView {\n constructor(\n private journal: ExecutionJournal,\n private sessionId: string,\n private snapshotId: number,\n private scope: ScopePath,\n private event?: EventTrigger\n ) {}\n\n /** Return the nearest result for a check in this scope (exact item → ancestor → latest). */\n get(checkId: string): (ReviewSummary & { output?: unknown; content?: string }) | undefined {\n const visible = this.journal\n .readVisible(this.sessionId, this.snapshotId, this.event)\n .filter(e => e.checkId === checkId);\n if (visible.length === 0) return undefined;\n\n // exact scope match: prefer the most recent commit for this scope\n const exactMatches = visible.filter(e => this.sameScope(e.scope, this.scope));\n if (exactMatches.length > 0) {\n return exactMatches[exactMatches.length - 1].result;\n }\n\n // nearest ancestor (shortest distance)\n let best: { entry: JournalEntry; dist: number } | undefined;\n for (const e of visible) {\n const dist = this.ancestorDistance(e.scope, this.scope);\n if (dist >= 0 && (best === undefined || dist < best.dist)) {\n best = { entry: e, dist };\n }\n }\n if (best) return best.entry.result;\n\n // fallback to latest committed result\n return visible[visible.length - 1]?.result;\n }\n\n /** Return an aggregate (raw) result – the shallowest scope for this check. */\n getRaw(checkId: string): (ReviewSummary & { output?: unknown; content?: string }) | undefined {\n const visible = this.journal\n .readVisible(this.sessionId, this.snapshotId, this.event)\n .filter(e => e.checkId === checkId);\n if (visible.length === 0) return undefined;\n let shallow = visible[0];\n for (const e of visible) {\n if (e.scope.length < shallow.scope.length) shallow = e;\n }\n return shallow.result;\n }\n\n /** All results for a check up to this snapshot. */\n getHistory(checkId: string): Array<ReviewSummary & { output?: unknown; content?: string }> {\n return this.journal\n .readVisible(this.sessionId, this.snapshotId, this.event)\n .filter(e => e.checkId === checkId)\n .map(e => e.result);\n }\n\n private sameScope(a: ScopePath, b: ScopePath): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i].check !== b[i].check || a[i].index !== b[i].index) return false;\n }\n return true;\n }\n\n // distance from ancestor to current; -1 if not ancestor\n private ancestorDistance(ancestor: ScopePath, current: ScopePath): number {\n if (ancestor.length > current.length) return -1;\n // Treat root scope ([]) as non-ancestor for unrelated branches\n if (ancestor.length === 0 && current.length > 0) return -1;\n for (let i = 0; i < ancestor.length; i++) {\n if (ancestor[i].check !== current[i].check || ancestor[i].index !== current[i].index)\n return -1;\n }\n return current.length - ancestor.length;\n }\n}\n","/**\n * Routing State Handler\n *\n * Responsibilities:\n * - Evaluate fail_if conditions after check execution\n * - Process on_success, on_fail, on_finish triggers\n * - Enqueue ForwardRunRequested events for goto\n * - Enqueue WaveRetry events for routing loops\n * - Transition back to WavePlanning or Completed\n *\n * M2: Core routing logic implementation\n */\n\nimport type { EngineContext, RunState, EngineState, EngineEvent } from '../../types/engine';\nimport type { ReviewSummary, ReviewIssue } from '../../reviewer';\nimport type {\n CheckConfig,\n OnFailConfig,\n TransitionRule,\n OnSuccessRunItem,\n OnInitStepInvocation,\n OnInitWorkflowInvocation,\n} from '../../types/config';\nimport { logger } from '../../logger';\nimport { addEvent } from '../../telemetry/trace-helpers';\nimport { FailureConditionEvaluator } from '../../failure-condition-evaluator';\nimport { createSecureSandbox, compileAndRun } from '../../utils/sandbox';\nimport { MemoryStore } from '../../memory-store';\nimport { createExtendedLiquid } from '../../liquid-extensions';\n\n/**\n * Render Liquid template expressions in 'with' arguments for on_success.run.\n * This is called during routing, where we have access to the step's output.\n */\nasync function renderRouteArgs(\n args: Record<string, unknown> | undefined,\n output: unknown,\n dependencyResults: Record<string, unknown>,\n context: EngineContext\n): Promise<Record<string, unknown> | undefined> {\n if (!args || Object.keys(args).length === 0) {\n return args;\n }\n\n const liquid = createExtendedLiquid();\n const renderedArgs: Record<string, unknown> = {};\n\n // Build template context with output (current step) and outputs (all dependencies)\n const templateContext = {\n output: output, // Output of the step that triggered routing\n outputs: dependencyResults, // All dependency outputs\n env: process.env,\n inputs: (context.executionContext as any)?.workflowInputs || {},\n };\n\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && value.includes('{{')) {\n try {\n renderedArgs[key] = await liquid.parseAndRender(value, templateContext);\n } catch (error) {\n logger.warn(`[Routing] Failed to render template for arg ${key}: ${error}`);\n renderedArgs[key] = value;\n }\n } else {\n renderedArgs[key] = value;\n }\n }\n\n return renderedArgs;\n}\n\n/**\n * Helper to extract target name and args from an OnSuccessRunItem.\n * OnSuccessRunItem can be:\n * - string: plain step name\n * - OnInitStepInvocation: { step: string, with?: Record<string, unknown> }\n * - OnInitWorkflowInvocation: { workflow: string, with?: Record<string, unknown> }\n */\nfunction parseRunItem(item: OnSuccessRunItem): {\n target: string;\n args?: Record<string, unknown>;\n} {\n if (typeof item === 'string') {\n return { target: item };\n }\n if ('step' in item) {\n const stepItem = item as OnInitStepInvocation;\n return { target: stepItem.step, args: stepItem.with };\n }\n if ('workflow' in item) {\n const workflowItem = item as OnInitWorkflowInvocation;\n return { target: workflowItem.workflow, args: workflowItem.with };\n }\n // Fallback - shouldn't happen with proper typing\n return { target: String(item) };\n}\n\n/**\n * Check if any configured check depends (directly or via OR dependency) on the\n * given `checkId`. Used to decide whether a forEach parent has downstream\n * dependents, in which case its on_finish should defer to the LevelDispatch\n * post-children hook.\n */\n// hasDependents helper removed (unused)\n\n/**\n * Check if any dependent of `checkId` would execute with map fanout.\n * Used to decide whether a forEach parent's on_finish should be deferred to\n * the LevelDispatch post-children hook (only necessary when map-fanout children\n * will run per item).\n */\nfunction hasMapFanoutDependents(context: EngineContext, checkId: string): boolean {\n const checks = context.config.checks || {};\n const reduceProviders = new Set(['log', 'memory', 'script', 'workflow', 'noop']);\n\n for (const [cid, cfg] of Object.entries(checks)) {\n if (cid === checkId) continue;\n const rawDeps = (cfg as any).depends_on || [];\n const depList = Array.isArray(rawDeps) ? rawDeps : [rawDeps];\n // Does this check depend on our target?\n let depends = false;\n for (const dep of depList) {\n if (typeof dep !== 'string') continue;\n if (dep.includes('|')) {\n const opts = dep\n .split('|')\n .map(s => s.trim())\n .filter(Boolean);\n if (opts.includes(checkId)) {\n depends = true;\n break;\n }\n } else if (dep === checkId) {\n depends = true;\n break;\n }\n }\n if (!depends) continue;\n\n // Determine this dependent's fanout mode\n const explicit = (cfg as any).fanout as 'map' | 'reduce' | undefined;\n if (explicit === 'map') return true;\n if (explicit === 'reduce') continue;\n\n // Infer default based on provider type\n const providerType = context.checks[cid]?.providerType || (checks as any)[cid]?.type || '';\n const inferred: 'map' | 'reduce' = reduceProviders.has(providerType) ? 'reduce' : 'map';\n if (inferred === 'map') return true;\n }\n return false;\n}\n\n/** Classify failure type to inform retry policy mapping */\nfunction classifyFailure(result: ReviewSummary): 'none' | 'logical' | 'execution' {\n const issues = result?.issues || [];\n if (!issues || issues.length === 0) return 'none';\n // Heuristics:\n // - logical: fail_if, contract/guarantee_failed, explicit ruleIds ending with _fail_if\n // - execution: provider/command errors, timeouts, forEach/execution_error, sandbox_runner_error\n let hasLogical = false;\n let hasExecution = false;\n for (const iss of issues) {\n const id = String((iss as any).ruleId || '');\n const msg = String((iss as any).message || '');\n const msgLower = msg.toLowerCase();\n if (\n id.endsWith('_fail_if') ||\n id.includes('contract/guarantee_failed') ||\n id.includes('contract/schema_validation_failed')\n )\n hasLogical = true;\n if (\n id.endsWith('/error') ||\n id.includes('/execution_error') ||\n id.includes('timeout') ||\n msgLower.includes('timed out') ||\n msg.includes('Command execution failed')\n )\n hasExecution = true;\n if (id.includes('forEach/execution_error') || msg.includes('sandbox_runner_error'))\n hasExecution = true;\n }\n if (hasLogical && !hasExecution) return 'logical';\n if (hasExecution && !hasLogical) return 'execution';\n // Mixed or unknown: treat as execution to avoid suppressing retries unexpectedly\n return hasExecution ? 'execution' : 'logical';\n}\n\nfunction getCriticality(context: EngineContext, checkId: string): CheckConfig['criticality'] {\n const cfg = context.config.checks?.[checkId];\n return (cfg && (cfg as any).criticality) || 'policy';\n}\n\n/**\n * Context for a check that just completed and needs routing evaluation\n */\ninterface RoutingContext {\n checkId: string;\n scope: Array<{ check: string; index: number }>;\n result: ReviewSummary;\n checkConfig: CheckConfig;\n success: boolean; // true if no fatal issues\n}\n\n/**\n * Create memory helpers for sandbox context\n */\nfunction createMemoryHelpers() {\n const memoryStore = MemoryStore.getInstance();\n return {\n get: (key: string, ns?: string) => memoryStore.get(key, ns),\n has: (key: string, ns?: string) => memoryStore.has(key, ns),\n getAll: (ns?: string) => memoryStore.getAll(ns),\n set: (key: string, value: unknown, ns?: string) => {\n const nsName = ns || memoryStore.getDefaultNamespace();\n const data: Map<string, Map<string, unknown>> = (memoryStore as any)['data'];\n if (!data.has(nsName)) data.set(nsName, new Map());\n data.get(nsName)!.set(key, value);\n },\n clear: (ns?: string) => {\n const data: Map<string, Map<string, unknown>> = (memoryStore as any)['data'];\n if (ns) data.delete(ns);\n else data.clear();\n },\n increment: (key: string, amount = 1, ns?: string) => {\n const nsName = ns || memoryStore.getDefaultNamespace();\n const data: Map<string, Map<string, unknown>> = (memoryStore as any)['data'];\n if (!data.has(nsName)) data.set(nsName, new Map());\n const nsMap = data.get(nsName)!;\n const current = nsMap.get(key);\n const numCurrent = typeof current === 'number' ? current : 0;\n const newValue = numCurrent + amount;\n nsMap.set(key, newValue);\n return newValue;\n },\n };\n}\n\nfunction getHistoryLimit(): number | undefined {\n const raw = process.env.VISOR_TEST_HISTORY_LIMIT || process.env.VISOR_OUTPUT_HISTORY_LIMIT;\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n}\n\ntype RoutingTrigger = 'on_success' | 'on_fail' | 'on_finish';\ntype RoutingAction = 'run' | 'goto' | 'retry';\ntype RoutingSource = 'run' | 'run_js' | 'goto' | 'goto_js' | 'transitions' | 'retry';\n\nfunction formatScopeLabel(scope: Array<{ check: string; index: number }> | undefined): string {\n if (!scope || scope.length === 0) return '';\n return scope.map(item => `${item.check}:${item.index}`).join('|');\n}\n\nfunction recordRoutingEvent(args: {\n checkId: string;\n trigger: RoutingTrigger;\n action: RoutingAction;\n target?: string;\n source?: RoutingSource;\n scope?: Array<{ check: string; index: number }>;\n gotoEvent?: string;\n}): void {\n const attrs: Record<string, unknown> = {\n check_id: args.checkId,\n trigger: args.trigger,\n action: args.action,\n };\n if (args.target) attrs.target = args.target;\n if (args.source) attrs.source = args.source;\n const scopeLabel = formatScopeLabel(args.scope);\n if (scopeLabel) attrs.scope = scopeLabel;\n if (args.gotoEvent) attrs.goto_event = args.gotoEvent;\n addEvent('visor.routing', attrs);\n}\n\n/**\n * Handle routing state - evaluate conditions and decide next actions\n * @returns true if execution was halted (caller should stop processing)\n */\nexport async function handleRouting(\n context: EngineContext,\n state: RunState,\n transition: (newState: EngineState) => void,\n emitEvent: (event: EngineEvent) => void,\n routingContext: RoutingContext\n): Promise<boolean> {\n const { checkId, scope, result, checkConfig, success } = routingContext;\n\n // Always log routing entry for debugging E2E expectations\n logger.info(`[Routing] Evaluating routing for check: ${checkId}, success: ${success}`);\n\n // Step 1: Evaluate fail_if and failure_conditions\n const failureResult = await evaluateFailIf(checkId, result, checkConfig, context, state);\n\n // Step 1.5: Check if we need to halt execution immediately\n if (failureResult.haltExecution) {\n logger.error(\n `[Routing] HALTING EXECUTION due to critical failure in ${checkId}: ${failureResult.haltMessage}`\n );\n\n // Add halt issue to result for reporting\n const haltIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}_halt_execution`,\n message: `Execution halted: ${failureResult.haltMessage || 'Critical failure condition met'}`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), haltIssue];\n\n // Emit Shutdown event to stop the workflow\n emitEvent({\n type: 'Shutdown',\n error: {\n message: failureResult.haltMessage || `Execution halted by check ${checkId}`,\n name: 'HaltExecution',\n },\n });\n\n // Transition to Error state\n transition('Error');\n return true; // Signal that execution was halted\n }\n\n if (failureResult.failed) {\n if (context.debug) {\n logger.info(`[Routing] fail_if/failure_conditions triggered for ${checkId}`);\n }\n\n // Treat as failure for routing purposes\n await processOnFail(checkId, scope, result, checkConfig, context, state, emitEvent);\n } else if (success) {\n // Step 2: Process on_success routing\n await processOnSuccess(checkId, scope, result, checkConfig, context, state, emitEvent);\n } else {\n // Step 3: Process on_fail routing\n await processOnFail(checkId, scope, result, checkConfig, context, state, emitEvent);\n }\n\n // Step 4: on_finish\n // Process on_finish here for:\n // - non-forEach checks\n // - forEach parents that do NOT have map-fanout dependents\n // (reduce-only dependents don't need the post-children barrier)\n const shouldProcessOnFinishHere =\n !!checkConfig.on_finish &&\n (checkConfig.forEach !== true || !hasMapFanoutDependents(context, checkId));\n if (checkConfig.on_finish) {\n logger.info(\n `[Routing] on_finish decision for ${checkId}: forEach=${!!checkConfig.forEach}, processHere=${shouldProcessOnFinishHere}`\n );\n }\n if (shouldProcessOnFinishHere) {\n await processOnFinish(checkId, scope, result, checkConfig, context, state, emitEvent);\n }\n\n // Transition back to WavePlanning to process queued events\n transition('WavePlanning');\n return false; // Execution continues normally\n}\n\n/**\n * Process on_finish routing\n */\nasync function processOnFinish(\n checkId: string,\n scope: Array<{ check: string; index: number }>,\n result: ReviewSummary,\n checkConfig: CheckConfig,\n context: EngineContext,\n state: RunState,\n emitEvent: (event: EngineEvent) => void\n): Promise<void> {\n const onFinish = checkConfig.on_finish;\n\n if (!onFinish) {\n return; // No on_finish configuration\n }\n\n // Log at info level so it's visible in test output\n logger.info(`Processing on_finish for ${checkId}`);\n let queuedForward = false;\n // Process on_finish.run\n if (onFinish.run && onFinish.run.length > 0) {\n // Check if current check is a forEach parent with items\n const currentCheckIsForEach = checkConfig.forEach === true;\n const forEachItems = currentCheckIsForEach ? (result as any).forEachItems : undefined;\n const hasForEachItems = Array.isArray(forEachItems) && forEachItems.length > 0;\n\n for (const targetCheck of onFinish.run) {\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_finish', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_finish run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n // Handle fanout: check if target has fanout configuration\n const targetConfig = context.config.checks?.[targetCheck];\n const fanoutMode = targetConfig?.fanout || 'reduce'; // default to reduce\n\n if (context.debug) {\n logger.info(\n `[Routing] on_finish.run: scheduling ${targetCheck} with fanout=${fanoutMode}, hasForEachItems=${hasForEachItems}`\n );\n }\n\n // If current check has forEach items and target is map fanout, emit one event per item\n if (fanoutMode === 'map' && hasForEachItems) {\n // Map fanout: emit one ForwardRunRequested per forEach item\n for (let itemIndex = 0; itemIndex < forEachItems!.length; itemIndex++) {\n // Increment loop count for each item\n state.routingLoopCount++;\n\n const itemScope: Array<{ check: string; index: number }> = [\n { check: checkId, index: itemIndex },\n ];\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_finish',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope: itemScope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope: itemScope,\n origin: 'run',\n });\n queuedForward = true;\n }\n } else {\n // Reduce fanout (or no forEach context): emit with empty scope once\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_finish',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope: [],\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope: [],\n origin: 'run',\n });\n queuedForward = true;\n }\n }\n }\n\n // Process on_finish.run_js\n if (onFinish.run_js) {\n const dynamicTargets = await evaluateRunJs(\n onFinish.run_js,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n for (const runItem of dynamicTargets) {\n // Parse the run item to extract target and optional args\n const { target: targetCheck, args: runArgs } = parseRunItem(runItem);\n\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_finish', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_finish run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(\n `[Routing] on_finish.run_js: scheduling ${targetCheck}${runArgs ? ', args=' + JSON.stringify(runArgs) : ''}`\n );\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_finish',\n action: 'run',\n target: targetCheck,\n source: 'run_js',\n scope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope,\n origin: 'run_js',\n args: runArgs,\n });\n queuedForward = true;\n }\n }\n\n // Declarative transitions (override goto/goto_js when present)\n const finishTransTarget = await evaluateTransitions(\n onFinish.transitions,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n if (finishTransTarget !== undefined) {\n if (finishTransTarget) {\n if (checkLoopBudget(context, state, 'on_finish', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_finish goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n state.routingLoopCount++;\n recordRoutingEvent({\n checkId,\n trigger: 'on_finish',\n action: 'goto',\n target: finishTransTarget.to,\n source: 'transitions',\n scope,\n gotoEvent: finishTransTarget.goto_event,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: finishTransTarget.to,\n scope,\n origin: 'goto_js',\n gotoEvent: finishTransTarget.goto_event,\n });\n }\n return; // transitions override goto/goto_js\n }\n\n // Process on_finish.goto / goto_js\n const gotoTarget = await evaluateGoto(\n onFinish.goto_js,\n onFinish.goto,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n if (gotoTarget) {\n // Check loop budget before scheduling goto\n if (checkLoopBudget(context, state, 'on_finish', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_finish goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(`[Routing] on_finish.goto: ${gotoTarget}`);\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_finish',\n action: 'goto',\n target: gotoTarget,\n source: onFinish.goto_js ? 'goto_js' : 'goto',\n scope,\n });\n // Enqueue forward run event\n emitEvent({\n type: 'ForwardRunRequested',\n target: gotoTarget,\n scope,\n origin: 'goto_js',\n });\n\n // Mark that we've seen a forward run\n state.flags.forwardRunRequested = true;\n }\n\n // If we scheduled any forward-run targets via on_finish, request a wave retry so\n // dependent checks (with if conditions) can re-evaluate after the forward-run completes.\n // Guard: only enqueue once per originating check per wave to avoid loops.\n if (queuedForward) {\n const guardKey = `waveRetry:on_finish:${checkId}:wave:${state.wave}`;\n if (!(state as any).forwardRunGuards?.has(guardKey)) {\n (state as any).forwardRunGuards?.add(guardKey);\n emitEvent({ type: 'WaveRetry', reason: 'on_finish' });\n }\n }\n}\n\n/**\n * Result of evaluating failure conditions\n */\ninterface FailureEvaluationResult {\n /** Whether any failure condition was triggered */\n failed: boolean;\n /** Whether execution should halt immediately */\n haltExecution: boolean;\n /** Message describing the halt reason (if haltExecution is true) */\n haltMessage?: string;\n}\n\n/**\n * Evaluate fail_if and failure_conditions for a check\n */\n// Returns { failed, haltExecution } to indicate if check failed and if execution should halt.\n// Global fail_if records an issue for summary/reporting but MUST NOT gate routing.\n// failure_conditions with halt_execution: true will trigger workflow halt.\nasync function evaluateFailIf(\n checkId: string,\n result: ReviewSummary,\n checkConfig: CheckConfig,\n context: EngineContext,\n state: RunState\n): Promise<FailureEvaluationResult> {\n const config = context.config;\n\n // Check for fail_if at global or check level\n const globalFailIf = config.fail_if;\n const checkFailIf = checkConfig.fail_if;\n const globalFailureConditions = config.failure_conditions;\n const checkFailureConditions = checkConfig.failure_conditions;\n\n if (!globalFailIf && !checkFailIf && !globalFailureConditions && !checkFailureConditions) {\n return { failed: false, haltExecution: false }; // No failure conditions\n }\n\n const evaluator = new FailureConditionEvaluator();\n\n // Build outputs record from state\n const outputsRecord: Record<string, ReviewSummary> = {};\n for (const [key] of state.stats.entries()) {\n // Try to get the actual result from context.journal if available\n try {\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const journalResult = contextView.get(key);\n if (journalResult) {\n outputsRecord[key] = journalResult as ReviewSummary;\n }\n } catch {\n // Fallback to empty result\n outputsRecord[key] = { issues: [] };\n }\n }\n\n const checkSchema = typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema || '';\n const checkGroup = checkConfig.group || '';\n\n let anyFailed = false;\n let shouldHalt = false;\n let haltMessage: string | undefined;\n\n // Evaluate global fail_if (non-gating)\n if (globalFailIf) {\n try {\n const failed = await evaluator.evaluateSimpleCondition(\n checkId,\n checkSchema,\n checkGroup,\n result,\n globalFailIf,\n outputsRecord\n );\n\n if (failed) {\n logger.warn(`[Routing] Global fail_if triggered for ${checkId}: ${globalFailIf}`);\n\n // Add fail_if issue to result\n const failIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: 'global_fail_if',\n message: `Global failure condition met: ${globalFailIf}`,\n severity: 'error',\n category: 'logic',\n };\n\n result.issues = [...(result.issues || []), failIssue];\n // IMPORTANT: do not gate routing on global fail_if\n // This condition contributes to overall run status but should not\n // block dependents from executing when the producing check succeeded.\n // Continue evaluating check-level fail_if below.\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error evaluating global fail_if: ${msg}`);\n }\n }\n\n // Evaluate check-specific fail_if\n if (checkFailIf) {\n try {\n const failed = await evaluator.evaluateSimpleCondition(\n checkId,\n checkSchema,\n checkGroup,\n result,\n checkFailIf,\n outputsRecord\n );\n\n if (failed) {\n logger.warn(`[Routing] Check fail_if triggered for ${checkId}: ${checkFailIf}`);\n\n // Add fail_if issue to result\n const failIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}_fail_if`,\n message: `Check failure condition met: ${checkFailIf}`,\n severity: 'error',\n category: 'logic',\n };\n\n result.issues = [...(result.issues || []), failIssue];\n anyFailed = true;\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error evaluating check fail_if: ${msg}`);\n }\n }\n\n // Evaluate failure_conditions (both global and check-level)\n // These support halt_execution: true\n if (globalFailureConditions || checkFailureConditions) {\n try {\n const conditionResults = await evaluator.evaluateConditions(\n checkId,\n checkSchema,\n checkGroup,\n result,\n globalFailureConditions,\n checkFailureConditions,\n outputsRecord\n );\n\n // Check for triggered conditions\n for (const condResult of conditionResults) {\n if (condResult.failed) {\n logger.warn(\n `[Routing] Failure condition '${condResult.conditionName}' triggered for ${checkId}: ${condResult.expression}`\n );\n\n // Add issue to result\n const failIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}_${condResult.conditionName}`,\n message: condResult.message || `Failure condition met: ${condResult.expression}`,\n severity: condResult.severity || 'error',\n category: 'logic',\n };\n\n result.issues = [...(result.issues || []), failIssue];\n anyFailed = true;\n\n // Check if this condition requires halting execution\n if (condResult.haltExecution) {\n shouldHalt = true;\n haltMessage =\n condResult.message ||\n `Execution halted: condition '${condResult.conditionName}' triggered`;\n logger.error(\n `[Routing] HALT EXECUTION triggered by '${condResult.conditionName}' for ${checkId}`\n );\n }\n }\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error evaluating failure_conditions: ${msg}`);\n }\n }\n\n return { failed: anyFailed, haltExecution: shouldHalt, haltMessage };\n}\n\n/**\n * Check if routing loop budget is exceeded\n */\nexport function checkLoopBudget(\n context: EngineContext,\n state: RunState,\n origin: 'on_success' | 'on_fail' | 'on_finish',\n action: 'run' | 'goto'\n): boolean {\n const maxLoops = context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS;\n\n if (state.routingLoopCount >= maxLoops) {\n const msg = `Routing loop budget exceeded (max_loops=${maxLoops}) during ${origin} ${action}`;\n logger.error(`[Routing] ${msg}`);\n return true; // Budget exceeded\n }\n\n return false; // Budget OK\n}\n\n/**\n * Process on_success routing\n */\nasync function processOnSuccess(\n checkId: string,\n scope: Array<{ check: string; index: number }>,\n result: ReviewSummary,\n checkConfig: CheckConfig,\n context: EngineContext,\n state: RunState,\n emitEvent: (event: EngineEvent) => void\n): Promise<void> {\n const onSuccess = checkConfig.on_success;\n\n if (!onSuccess) {\n return; // No on_success configuration\n }\n\n if (context.debug) {\n logger.info(`[Routing] Processing on_success for ${checkId}`);\n }\n\n // Process on_success.run\n if (onSuccess.run && onSuccess.run.length > 0) {\n // Detect forEach context based on the actual result (aggregated map execution)\n const resForEachItems: any[] | undefined =\n (result && (result as any).forEachItems) || undefined;\n const hasForEachItems = Array.isArray(resForEachItems) && resForEachItems.length > 0;\n\n // Get the step's output for template rendering\n const stepOutput = (result as any)?.output;\n\n // Build dependency results from journal for template context\n const depResults: Record<string, unknown> = {};\n try {\n const snapshotId = context.journal.beginSnapshot();\n const allEntries = context.journal.readVisible(context.sessionId, snapshotId, context.event);\n for (const entry of allEntries) {\n if (entry.checkId && entry.result) {\n const r = entry.result as ReviewSummary & { output?: unknown };\n depResults[entry.checkId] = r.output !== undefined ? r.output : r;\n }\n }\n } catch (e) {\n logger.warn(`[Routing] Failed to build dependency results for template rendering: ${e}`);\n }\n\n for (const runItem of onSuccess.run) {\n // Parse the run item to extract target and optional args\n const { target: targetCheck, args: rawArgs } = parseRunItem(runItem);\n\n // Render Liquid templates in args if present\n const runArgs = rawArgs\n ? await renderRouteArgs(rawArgs, stepOutput, depResults, context)\n : undefined;\n\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_success', 'run')) {\n // Add error issue to result\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_success run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return; // Stop processing\n }\n\n // Handle fanout: check if target has fanout configuration\n const targetConfig = context.config.checks?.[targetCheck];\n const fanoutMode = targetConfig?.fanout || 'reduce'; // default to reduce\n\n if (context.debug) {\n logger.info(\n `[Routing] on_success.run: scheduling ${targetCheck} with fanout=${fanoutMode}, hasForEachItems=${hasForEachItems}${runArgs ? ', args=' + JSON.stringify(runArgs) : ''}`\n );\n }\n\n // If current check has forEach items and target is map fanout, emit one event per item\n if (fanoutMode === 'map' && hasForEachItems) {\n // Map fanout: emit one ForwardRunRequested per forEach item\n for (let itemIndex = 0; itemIndex < resForEachItems!.length; itemIndex++) {\n // Increment loop count for each item\n state.routingLoopCount++;\n\n const itemScope: Array<{ check: string; index: number }> = [\n { check: checkId, index: itemIndex },\n ];\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_success',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope: itemScope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope: itemScope,\n origin: 'run',\n args: runArgs,\n });\n }\n } else {\n // Reduce fanout (or no forEach context): emit with empty scope once\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_success',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope,\n origin: 'run',\n args: runArgs,\n });\n }\n }\n }\n\n // Process on_success.run_js\n if (onSuccess.run_js) {\n const dynamicTargets = await evaluateRunJs(\n onSuccess.run_js,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n for (const runItem of dynamicTargets) {\n // Parse the run item to extract target and optional args\n const { target: targetCheck, args: runArgs } = parseRunItem(runItem);\n\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_success', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_success run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(\n `[Routing] on_success.run_js: scheduling ${targetCheck}${runArgs ? ', args=' + JSON.stringify(runArgs) : ''}`\n );\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_success',\n action: 'run',\n target: targetCheck,\n source: 'run_js',\n scope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope,\n origin: 'run_js',\n args: runArgs,\n });\n }\n }\n\n // Declarative transitions for on_success (override goto/goto_js when present)\n const successTransTarget = await evaluateTransitions(\n onSuccess.transitions,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n if (successTransTarget !== undefined) {\n if (successTransTarget) {\n if (checkLoopBudget(context, state, 'on_success', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_success goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n state.routingLoopCount++;\n recordRoutingEvent({\n checkId,\n trigger: 'on_success',\n action: 'goto',\n target: successTransTarget.to,\n source: 'transitions',\n scope,\n gotoEvent: successTransTarget.goto_event,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: successTransTarget.to,\n scope,\n origin: 'goto_js',\n gotoEvent: successTransTarget.goto_event,\n });\n state.flags.forwardRunRequested = true;\n }\n return;\n }\n\n // Process on_success.goto / goto_js\n const gotoTarget = await evaluateGoto(\n onSuccess.goto_js,\n onSuccess.goto,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n if (gotoTarget) {\n // Check loop budget before scheduling goto\n if (checkLoopBudget(context, state, 'on_success', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_success goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(`[Routing] on_success.goto: ${gotoTarget}`);\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_success',\n action: 'goto',\n target: gotoTarget,\n source: onSuccess.goto_js ? 'goto_js' : 'goto',\n scope,\n gotoEvent: onSuccess.goto_event,\n });\n // Enqueue forward run event with optional event override\n emitEvent({\n type: 'ForwardRunRequested',\n target: gotoTarget,\n gotoEvent: onSuccess.goto_event,\n scope,\n origin: 'goto_js',\n });\n\n // Mark that we've seen a forward run\n state.flags.forwardRunRequested = true;\n }\n}\n\n/**\n * Process on_fail routing\n */\nasync function processOnFail(\n checkId: string,\n scope: Array<{ check: string; index: number }>,\n result: ReviewSummary,\n checkConfig: CheckConfig,\n context: EngineContext,\n state: RunState,\n emitEvent: (event: EngineEvent) => void\n): Promise<void> {\n // Merge defaults with check-specific on_fail\n const defaults = context.config.routing?.defaults?.on_fail || {};\n const onFail: OnFailConfig | undefined = checkConfig.on_fail\n ? { ...defaults, ...checkConfig.on_fail }\n : undefined;\n\n if (!onFail) {\n return; // No on_fail configuration\n }\n\n if (context.debug) {\n logger.info(`[Routing] Processing on_fail for ${checkId}`);\n }\n\n // Process on_fail.run\n if (onFail.run && onFail.run.length > 0) {\n // Detect forEach context based on the actual aggregated result\n const resForEachItems: any[] | undefined =\n (result && (result as any).forEachItems) || undefined;\n const hasForEachItems = Array.isArray(resForEachItems) && resForEachItems.length > 0;\n\n for (const targetCheck of onFail.run) {\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_fail', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_fail run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n // Handle fanout: check if target has fanout configuration\n const targetConfig = context.config.checks?.[targetCheck];\n const fanoutMode = targetConfig?.fanout || 'reduce'; // default to reduce\n\n if (context.debug) {\n logger.info(\n `[Routing] on_fail.run: scheduling ${targetCheck} with fanout=${fanoutMode}, hasForEachItems=${hasForEachItems}`\n );\n }\n\n // If current check ran in forEach context, schedule remediation per item\n if (hasForEachItems) {\n for (let itemIndex = 0; itemIndex < resForEachItems!.length; itemIndex++) {\n const itemOut = resForEachItems![itemIndex] as any;\n // Only remediate failed iterations if __failed is present; otherwise run for all\n if (\n itemOut &&\n typeof itemOut === 'object' &&\n itemOut.__failed !== true &&\n fanoutMode !== 'map'\n ) {\n // For reduce targets, skip successful iterations to avoid redundant runs\n continue;\n }\n\n state.routingLoopCount++;\n const itemScope: Array<{ check: string; index: number }> = [\n { check: checkId, index: itemIndex },\n ];\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope: itemScope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope: itemScope,\n origin: 'run',\n sourceCheck: checkId, // The failed check that triggered on_fail.run\n });\n }\n } else {\n // No forEach context: preserve current scope (if any)\n state.routingLoopCount++;\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'run',\n target: targetCheck,\n source: 'run',\n scope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope,\n origin: 'run',\n sourceCheck: checkId, // The failed check that triggered on_fail.run\n });\n }\n }\n }\n\n // Process on_fail.run_js\n if (onFail.run_js) {\n const dynamicTargets = await evaluateRunJs(\n onFail.run_js,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n for (const runItem of dynamicTargets) {\n // Parse the run item to extract target and optional args\n const { target: targetCheck, args: runArgs } = parseRunItem(runItem);\n\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_fail', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_fail run`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(\n `[Routing] on_fail.run_js: scheduling ${targetCheck}${runArgs ? ', args=' + JSON.stringify(runArgs) : ''}`\n );\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'run',\n target: targetCheck,\n source: 'run_js',\n scope,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope,\n origin: 'run_js',\n sourceCheck: checkId, // The failed check that triggered on_fail.run_js\n args: runArgs,\n });\n }\n }\n\n // Process on_fail.retry (schedule retry of the current check)\n if (onFail.retry && typeof onFail.retry.max === 'number' && onFail.retry.max > 0) {\n // Criticality mapping: for 'external' and 'internal', avoid automatic\n // retries for logical failures (fail_if/guarantee violations).\n const crit = getCriticality(context, checkId);\n const failureKind = classifyFailure(result);\n if ((crit === 'external' || crit === 'internal') && failureKind === 'logical') {\n if (context.debug) {\n logger.info(\n `[Routing] on_fail.retry suppressed for ${checkId} (criticality=${crit}, failure=logical)`\n );\n }\n // Skip retry scheduling\n } else {\n const max = Math.max(0, onFail.retry.max || 0);\n // Initialize retry attempt map on state\n if (!(state as any).retryAttempts) (state as any).retryAttempts = new Map<string, number>();\n const attemptsMap: Map<string, number> = (state as any).retryAttempts;\n\n const makeKey = (sc: Array<{ check: string; index: number }> | undefined) => {\n const keyScope = sc && sc.length > 0 ? JSON.stringify(sc) : 'root';\n return `${checkId}::${keyScope}`;\n };\n\n const scheduleRetryForScope = (sc: Array<{ check: string; index: number }> | undefined) => {\n const key = makeKey(sc);\n const used = attemptsMap.get(key) || 0;\n if (used >= max) return; // budget exhausted\n attemptsMap.set(key, used + 1);\n\n // Increment loop count and schedule forward run for the same check\n state.routingLoopCount++;\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'retry',\n source: 'retry',\n scope: sc || [],\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: checkId,\n scope: sc || [],\n origin: 'run',\n });\n };\n\n const resForEachItems: any[] | undefined =\n (result && (result as any).forEachItems) || undefined;\n const hasForEachItems = Array.isArray(resForEachItems) && resForEachItems.length > 0;\n\n if (hasForEachItems) {\n for (let i = 0; i < resForEachItems!.length; i++) {\n const itemOut = resForEachItems![i] as any;\n // Only retry failed iterations (marked by __failed)\n if (itemOut && typeof itemOut === 'object' && itemOut.__failed === true) {\n const sc: Array<{ check: string; index: number }> = [{ check: checkId, index: i }];\n scheduleRetryForScope(sc);\n }\n }\n } else {\n scheduleRetryForScope(scope);\n }\n\n // Note: backoff.delay_ms and mode are intentionally not awaited here; the\n // state-machine processes retries as subsequent waves. If needed later, we\n // can insert a timed wait in the orchestrator layer.\n }\n }\n\n // Declarative transitions for on_fail (override goto/goto_js when present)\n const failTransTarget = await evaluateTransitions(\n onFail.transitions,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n if (failTransTarget !== undefined) {\n if (failTransTarget) {\n if (checkLoopBudget(context, state, 'on_fail', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? DEFAULT_MAX_LOOPS}) during on_fail goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n state.routingLoopCount++;\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'goto',\n target: failTransTarget.to,\n source: 'transitions',\n scope,\n gotoEvent: failTransTarget.goto_event,\n });\n emitEvent({\n type: 'ForwardRunRequested',\n target: failTransTarget.to,\n scope,\n origin: 'goto_js',\n gotoEvent: failTransTarget.goto_event,\n });\n state.flags.forwardRunRequested = true;\n }\n return;\n }\n\n // Process on_fail.goto / goto_js\n const gotoTarget = await evaluateGoto(\n onFail.goto_js,\n onFail.goto,\n checkId,\n checkConfig,\n result,\n context,\n state\n );\n\n if (gotoTarget) {\n // Check loop budget before scheduling goto\n if (checkLoopBudget(context, state, 'on_fail', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_fail goto`,\n severity: 'error',\n category: 'logic',\n };\n result.issues = [...(result.issues || []), errorIssue];\n return;\n }\n\n if (context.debug) {\n logger.info(`[Routing] on_fail.goto: ${gotoTarget}`);\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n recordRoutingEvent({\n checkId,\n trigger: 'on_fail',\n action: 'goto',\n target: gotoTarget,\n source: onFail.goto_js ? 'goto_js' : 'goto',\n scope,\n gotoEvent: onFail.goto_event,\n });\n // Enqueue forward run event with optional event override\n emitEvent({\n type: 'ForwardRunRequested',\n target: gotoTarget,\n gotoEvent: onFail.goto_event,\n scope,\n origin: 'goto_js',\n });\n\n // Mark that we've seen a forward run\n state.flags.forwardRunRequested = true;\n }\n}\n\n/**\n * Evaluate run_js expression to get dynamic check targets\n */\n/**\n * Validate that an item is a valid OnSuccessRunItem (string or object with step/workflow)\n */\nfunction isValidRunItem(item: unknown): item is OnSuccessRunItem {\n if (typeof item === 'string' && item) return true;\n if (typeof item === 'object' && item !== null) {\n const obj = item as Record<string, unknown>;\n if (typeof obj.step === 'string' && obj.step) return true;\n if (typeof obj.workflow === 'string' && obj.workflow) return true;\n }\n return false;\n}\n\nasync function evaluateRunJs(\n runJs: string,\n checkId: string,\n checkConfig: CheckConfig,\n result: ReviewSummary,\n context: EngineContext,\n _state: RunState\n): Promise<OnSuccessRunItem[]> {\n try {\n const sandbox = createSecureSandbox();\n const historyLimit = getHistoryLimit();\n\n // Build outputs record and outputs_history\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n\n const outputsRecord: Record<string, any> = {};\n const outputsHistory: Record<string, any[]> = {};\n\n // Get all visible journal entries to build complete history\n const allEntries = context.journal.readVisible(context.sessionId, snapshotId, context.event);\n const uniqueCheckIds = new Set(allEntries.map(e => e.checkId));\n\n for (const checkIdFromJournal of uniqueCheckIds) {\n try {\n // Get current output for this check\n const journalResult = contextView.get(checkIdFromJournal);\n if (journalResult) {\n // Prefer the output field if present, otherwise use the full result\n outputsRecord[checkIdFromJournal] =\n journalResult.output !== undefined ? journalResult.output : journalResult;\n }\n } catch {\n outputsRecord[checkIdFromJournal] = { issues: [] };\n }\n\n // Build history for this check\n try {\n const history = contextView.getHistory(checkIdFromJournal);\n if (history && history.length > 0) {\n const trimmed =\n historyLimit && history.length > historyLimit\n ? history.slice(history.length - historyLimit)\n : history;\n // Extract outputs from history (prefer output field if available)\n outputsHistory[checkIdFromJournal] = trimmed.map((r: any) =>\n r.output !== undefined ? r.output : r\n );\n }\n } catch {\n // Ignore history errors\n }\n }\n\n // Add history as a property on outputs object for convenient access\n outputsRecord.history = outputsHistory;\n\n // Compute minimal forEach metadata for run_js parity\n let forEachMeta: any = undefined;\n try {\n const hist = outputsHistory[checkId] || [];\n const lastArr = (hist as any[])\n .slice()\n .reverse()\n .find((x: any) => Array.isArray(x));\n if (checkConfig.forEach === true && Array.isArray(lastArr)) {\n forEachMeta = {\n is_parent: true,\n last_wave_size: lastArr.length,\n last_items: lastArr,\n };\n }\n } catch {}\n\n const scopeObj: any = {\n step: {\n id: checkId,\n tags: checkConfig.tags || [],\n group: checkConfig.group,\n },\n outputs: outputsRecord,\n outputs_history: outputsHistory,\n output: (result as any)?.output,\n memory: createMemoryHelpers(),\n event: {\n name: context.event || 'manual',\n },\n forEach: forEachMeta,\n };\n\n const code = `\n const step = scope.step;\n const outputs = scope.outputs;\n const outputs_history = scope.outputs_history;\n const output = scope.output;\n const memory = scope.memory;\n const event = scope.event;\n const forEach = scope.forEach;\n const log = (...args) => console.log('🔍 Debug:', ...args);\n const __fn = () => {\n ${runJs}\n };\n const __res = __fn();\n // Return as-is; validation happens after sandbox execution\n return Array.isArray(__res) ? __res : [];\n `;\n\n try {\n const evalResult = compileAndRun<unknown[]>(\n sandbox,\n code,\n { scope: scopeObj },\n { injectLog: false, wrapFunction: false }\n );\n // Filter to valid run items (strings or objects with step/workflow)\n return Array.isArray(evalResult) ? evalResult.filter(isValidRunItem) : [];\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error in run_js sandbox evaluation: ${msg}`);\n return [];\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error evaluating run_js: ${msg}`);\n return [];\n }\n}\n\n/**\n * Evaluate goto_js or return static goto target\n */\nexport async function evaluateGoto(\n gotoJs: string | undefined,\n gotoStatic: string | undefined,\n checkId: string,\n checkConfig: CheckConfig,\n result: ReviewSummary,\n context: EngineContext,\n _state: RunState\n): Promise<string | null> {\n // Evaluate goto_js first\n if (gotoJs) {\n try {\n const sandbox = createSecureSandbox();\n const historyLimit = getHistoryLimit();\n\n // Build outputs record and outputs_history from the full session snapshot.\n // Do not filter by event here — on_finish (especially forEach post-children) may\n // need to see results committed under different event triggers within the same run.\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n undefined\n );\n\n const outputsRecord: Record<string, any> = {};\n const outputsHistory: Record<string, any[]> = {};\n\n // Get all visible journal entries to build complete history\n const allEntries = context.journal.readVisible(context.sessionId, snapshotId, undefined);\n const uniqueCheckIds = new Set(allEntries.map(e => e.checkId));\n\n for (const checkIdFromJournal of uniqueCheckIds) {\n try {\n // Get current output for this check\n const journalResult = contextView.get(checkIdFromJournal);\n if (journalResult) {\n // Prefer the output field if present, otherwise use the full result\n outputsRecord[checkIdFromJournal] =\n journalResult.output !== undefined ? journalResult.output : journalResult;\n }\n } catch {\n outputsRecord[checkIdFromJournal] = { issues: [] };\n }\n\n // Build history for this check\n try {\n const history = contextView.getHistory(checkIdFromJournal);\n if (history && history.length > 0) {\n const trimmed =\n historyLimit && history.length > historyLimit\n ? history.slice(history.length - historyLimit)\n : history;\n // Extract outputs from history (prefer output field if available)\n outputsHistory[checkIdFromJournal] = trimmed.map((r: any) =>\n r.output !== undefined ? r.output : r\n );\n }\n } catch {\n // Ignore history errors\n }\n }\n\n // Add history as a property on outputs object for convenient access\n outputsRecord.history = outputsHistory;\n\n // Compute minimal forEach metadata for convenience in goto_js\n // - last_wave_size: number of items in the latest root-scope array output\n // - last_items: the latest array output itself (if available)\n let forEachMeta: any = undefined;\n try {\n const hist = outputsHistory[checkId] || [];\n const lastArr = (hist as any[])\n .slice()\n .reverse()\n .find((x: any) => Array.isArray(x));\n if (checkConfig.forEach === true && Array.isArray(lastArr)) {\n forEachMeta = {\n is_parent: true,\n last_wave_size: lastArr.length,\n last_items: lastArr,\n };\n }\n } catch {}\n\n const scopeObj: any = {\n step: {\n id: checkId,\n tags: checkConfig.tags || [],\n group: checkConfig.group,\n },\n outputs: outputsRecord,\n outputs_history: outputsHistory,\n output: (result as any)?.output,\n memory: createMemoryHelpers(),\n event: {\n name: context.event || 'manual',\n },\n forEach: forEachMeta,\n };\n\n // Debug: Log outputs_history\n if (context.debug) {\n logger.info(\n `[Routing] evaluateGoto: checkId=${checkId}, outputs_history keys=${Object.keys(outputsHistory).join(',')}`\n );\n for (const [key, values] of Object.entries(outputsHistory)) {\n logger.info(`[Routing] ${key}: ${values.length} items`);\n }\n }\n\n const code = `\n const step = scope.step;\n const outputs = scope.outputs;\n const outputs_history = scope.outputs_history;\n const output = scope.output;\n const memory = scope.memory;\n const event = scope.event;\n const forEach = scope.forEach;\n const log = (...args) => console.log('🔍 Debug:', ...args);\n ${gotoJs}\n `;\n\n try {\n const evalResult = compileAndRun<string | null>(\n sandbox,\n code,\n { scope: scopeObj },\n { injectLog: false, wrapFunction: true }\n );\n\n if (context.debug) {\n logger.info(`[Routing] evaluateGoto result: ${evalResult}`);\n }\n\n if (typeof evalResult === 'string' && evalResult) {\n return evalResult;\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error in goto_js sandbox evaluation: ${msg}`);\n // Fall through to static goto\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[Routing] Error evaluating goto_js: ${msg}`);\n\n // Fall back to static goto if available\n if (gotoStatic) {\n logger.info(`[Routing] Falling back to static goto: ${gotoStatic}`);\n return gotoStatic;\n }\n }\n }\n\n // Return static goto\n return gotoStatic || null;\n}\n// Default values (used only when config is absent)\nconst DEFAULT_MAX_LOOPS = 10;\n\n/**\n * Evaluate declarative transitions. Returns:\n * - { to, goto_event } when a rule matches,\n * - null (explicit) when a rule matches with to=null,\n * - undefined when no rule matched or transitions is empty.\n */\nexport async function evaluateTransitions(\n transitions: TransitionRule[] | undefined,\n checkId: string,\n checkConfig: CheckConfig,\n result: ReviewSummary,\n context: EngineContext,\n _state: RunState\n): Promise<\n { to: string; goto_event?: import('../../types/config').EventTrigger } | null | undefined\n> {\n if (!transitions || transitions.length === 0) return undefined;\n try {\n const sandbox = createSecureSandbox();\n const historyLimit = getHistoryLimit();\n\n // Build outputs record and outputs_history from the full session snapshot\n const snapshotId = context.journal.beginSnapshot();\n const ContextView = (require('../../snapshot-store') as any).ContextView;\n const view = new ContextView(context.journal, context.sessionId, snapshotId, [], undefined);\n\n const outputsRecord: Record<string, any> = {};\n const outputsHistory: Record<string, any[]> = {};\n const allEntries = context.journal.readVisible(context.sessionId, snapshotId, undefined);\n const uniqueCheckIds = new Set(allEntries.map((e: any) => e.checkId));\n for (const cid of uniqueCheckIds) {\n try {\n const jr = view.get(cid);\n if (jr) outputsRecord[cid] = jr.output !== undefined ? jr.output : jr;\n } catch {}\n try {\n const hist = view.getHistory(cid);\n if (hist && hist.length > 0) {\n const trimmed =\n historyLimit && hist.length > historyLimit\n ? hist.slice(hist.length - historyLimit)\n : hist;\n outputsHistory[cid] = trimmed.map((r: any) => (r.output !== undefined ? r.output : r));\n }\n } catch {}\n }\n outputsRecord.history = outputsHistory;\n\n const scopeObj: any = {\n step: { id: checkId, tags: checkConfig.tags || [], group: checkConfig.group },\n outputs: outputsRecord,\n outputs_history: outputsHistory,\n output: (result as any)?.output,\n memory: createMemoryHelpers(),\n event: { name: context.event || 'manual' },\n };\n\n for (const rule of transitions) {\n const helpers = `\n const any = (arr, pred) => Array.isArray(arr) && arr.some(x => pred(x));\n const all = (arr, pred) => Array.isArray(arr) && arr.every(x => pred(x));\n const none = (arr, pred) => Array.isArray(arr) && !arr.some(x => pred(x));\n const count = (arr, pred) => Array.isArray(arr) ? arr.filter(x => pred(x)).length : 0;\n `;\n // Mirror the variable exposure pattern used in goto_js/run_js so that\n // `when:` expressions can reference `outputs`, `outputs_history`, `event`, etc.\n const code = `\n ${helpers}\n const step = scope.step;\n const outputs = scope.outputs;\n const outputs_history = scope.outputs_history;\n const output = scope.output;\n const memory = scope.memory;\n const event = scope.event;\n const __eval = () => { return (${rule.when}); };\n return __eval();\n `;\n let matched: boolean | undefined;\n try {\n matched = compileAndRun<boolean>(\n sandbox,\n code,\n { scope: scopeObj },\n { injectLog: false, wrapFunction: false }\n );\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.warn(`[Routing] Error evaluating transition 'when' clause: ${msg}`);\n matched = false;\n }\n if (matched) {\n if (rule.to === null) return null;\n if (typeof rule.to === 'string' && rule.to.length > 0) {\n return { to: rule.to, goto_event: (rule as any).goto_event };\n }\n return null;\n }\n }\n return undefined;\n } catch (err) {\n logger.error(\n `[Routing] Error evaluating transitions: ${err instanceof Error ? err.message : String(err)}`\n );\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmBa,kBAwCA;AA3Db;AAAA;AAAA;AAmBO,IAAM,mBAAN,MAAuB;AAAA,MACpB,SAAS;AAAA,MACT,UAA0B,CAAC;AAAA,MAEnC,gBAAwB;AACtB,eAAO,KAAK;AAAA,MACd;AAAA,MAEA,YAAY,OAMK;AACf,cAAM,YAA0B;AAAA,UAC9B,WAAW,MAAM;AAAA,UACjB,OAAO,MAAM;AAAA,UACb,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,UACd,OAAO,MAAM;AAAA,UACb,UAAU,EAAE,KAAK;AAAA,QACnB;AACA,aAAK,QAAQ,KAAK,SAAS;AAC3B,eAAO;AAAA,MACT;AAAA,MAEA,YAAY,WAAmB,WAAmB,OAAsC;AACtF,eAAO,KAAK,QAAQ;AAAA,UAClB,OACE,EAAE,cAAc,aAAa,EAAE,YAAY,cAAc,QAAQ,EAAE,UAAU,QAAQ;AAAA,QACzF;AAAA,MACF;AAAA;AAAA,MAGA,OAAe;AACb,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,IACF;AAEO,IAAM,cAAN,MAAkB;AAAA,MACvB,YACU,SACA,WACA,YACA,OACA,OACR;AALQ;AACA;AACA;AACA;AACA;AAAA,MACP;AAAA;AAAA,MAGH,IAAI,SAAuF;AACzF,cAAM,UAAU,KAAK,QAClB,YAAY,KAAK,WAAW,KAAK,YAAY,KAAK,KAAK,EACvD,OAAO,OAAK,EAAE,YAAY,OAAO;AACpC,YAAI,QAAQ,WAAW,EAAG,QAAO;AAGjC,cAAM,eAAe,QAAQ,OAAO,OAAK,KAAK,UAAU,EAAE,OAAO,KAAK,KAAK,CAAC;AAC5E,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO,aAAa,aAAa,SAAS,CAAC,EAAE;AAAA,QAC/C;AAGA,YAAI;AACJ,mBAAW,KAAK,SAAS;AACvB,gBAAM,OAAO,KAAK,iBAAiB,EAAE,OAAO,KAAK,KAAK;AACtD,cAAI,QAAQ,MAAM,SAAS,UAAa,OAAO,KAAK,OAAO;AACzD,mBAAO,EAAE,OAAO,GAAG,KAAK;AAAA,UAC1B;AAAA,QACF;AACA,YAAI,KAAM,QAAO,KAAK,MAAM;AAG5B,eAAO,QAAQ,QAAQ,SAAS,CAAC,GAAG;AAAA,MACtC;AAAA;AAAA,MAGA,OAAO,SAAuF;AAC5F,cAAM,UAAU,KAAK,QAClB,YAAY,KAAK,WAAW,KAAK,YAAY,KAAK,KAAK,EACvD,OAAO,OAAK,EAAE,YAAY,OAAO;AACpC,YAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,YAAI,UAAU,QAAQ,CAAC;AACvB,mBAAW,KAAK,SAAS;AACvB,cAAI,EAAE,MAAM,SAAS,QAAQ,MAAM,OAAQ,WAAU;AAAA,QACvD;AACA,eAAO,QAAQ;AAAA,MACjB;AAAA;AAAA,MAGA,WAAW,SAAgF;AACzF,eAAO,KAAK,QACT,YAAY,KAAK,WAAW,KAAK,YAAY,KAAK,KAAK,EACvD,OAAO,OAAK,EAAE,YAAY,OAAO,EACjC,IAAI,OAAK,EAAE,MAAM;AAAA,MACtB;AAAA,MAEQ,UAAU,GAAc,GAAuB;AACrD,YAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,iBAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,cAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAO,QAAO;AAAA,QACrE;AACA,eAAO;AAAA,MACT;AAAA;AAAA,MAGQ,iBAAiB,UAAqB,SAA4B;AACxE,YAAI,SAAS,SAAS,QAAQ,OAAQ,QAAO;AAE7C,YAAI,SAAS,WAAW,KAAK,QAAQ,SAAS,EAAG,QAAO;AACxD,iBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAI,SAAS,CAAC,EAAE,UAAU,QAAQ,CAAC,EAAE,SAAS,SAAS,CAAC,EAAE,UAAU,QAAQ,CAAC,EAAE;AAC7E,mBAAO;AAAA,QACX;AACA,eAAO,QAAQ,SAAS,SAAS;AAAA,MACnC;AAAA,IACF;AAAA;AAAA;;;ACrGA,eAAe,gBACb,MACA,QACA,mBACA,SAC8C;AAC9C,MAAI,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,qBAAqB;AACpC,QAAM,eAAwC,CAAC;AAG/C,QAAM,kBAAkB;AAAA,IACtB;AAAA;AAAA,IACA,SAAS;AAAA;AAAA,IACT,KAAK,QAAQ;AAAA,IACb,QAAS,QAAQ,kBAA0B,kBAAkB,CAAC;AAAA,EAChE;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,GAAG;AACrD,UAAI;AACF,qBAAa,GAAG,IAAI,MAAM,OAAO,eAAe,OAAO,eAAe;AAAA,MACxE,SAAS,OAAO;AACd,eAAO,KAAK,+CAA+C,GAAG,KAAK,KAAK,EAAE;AAC1E,qBAAa,GAAG,IAAI;AAAA,MACtB;AAAA,IACF,OAAO;AACL,mBAAa,GAAG,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,SAAS,aAAa,MAGpB;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AACA,MAAI,UAAU,MAAM;AAClB,UAAM,WAAW;AACjB,WAAO,EAAE,QAAQ,SAAS,MAAM,MAAM,SAAS,KAAK;AAAA,EACtD;AACA,MAAI,cAAc,MAAM;AACtB,UAAM,eAAe;AACrB,WAAO,EAAE,QAAQ,aAAa,UAAU,MAAM,aAAa,KAAK;AAAA,EAClE;AAEA,SAAO,EAAE,QAAQ,OAAO,IAAI,EAAE;AAChC;AAgBA,SAAS,uBAAuB,SAAwB,SAA0B;AAChF,QAAM,SAAS,QAAQ,OAAO,UAAU,CAAC;AACzC,QAAM,kBAAkB,oBAAI,IAAI,CAAC,OAAO,UAAU,UAAU,YAAY,MAAM,CAAC;AAE/E,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,QAAQ,QAAS;AACrB,UAAM,UAAW,IAAY,cAAc,CAAC;AAC5C,UAAM,UAAU,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO;AAE3D,QAAI,UAAU;AACd,eAAW,OAAO,SAAS;AACzB,UAAI,OAAO,QAAQ,SAAU;AAC7B,UAAI,IAAI,SAAS,GAAG,GAAG;AACrB,cAAM,OAAO,IACV,MAAM,GAAG,EACT,IAAI,OAAK,EAAE,KAAK,CAAC,EACjB,OAAO,OAAO;AACjB,YAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,oBAAU;AACV;AAAA,QACF;AAAA,MACF,WAAW,QAAQ,SAAS;AAC1B,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,QAAS;AAGd,UAAM,WAAY,IAAY;AAC9B,QAAI,aAAa,MAAO,QAAO;AAC/B,QAAI,aAAa,SAAU;AAG3B,UAAM,eAAe,QAAQ,OAAO,GAAG,GAAG,gBAAiB,OAAe,GAAG,GAAG,QAAQ;AACxF,UAAM,WAA6B,gBAAgB,IAAI,YAAY,IAAI,WAAW;AAClF,QAAI,aAAa,MAAO,QAAO;AAAA,EACjC;AACA,SAAO;AACT;AAGA,SAAS,gBAAgB,QAAyD;AAChF,QAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,MAAI,CAAC,UAAU,OAAO,WAAW,EAAG,QAAO;AAI3C,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,aAAW,OAAO,QAAQ;AACxB,UAAM,KAAK,OAAQ,IAAY,UAAU,EAAE;AAC3C,UAAM,MAAM,OAAQ,IAAY,WAAW,EAAE;AAC7C,UAAM,WAAW,IAAI,YAAY;AACjC,QACE,GAAG,SAAS,UAAU,KACtB,GAAG,SAAS,2BAA2B,KACvC,GAAG,SAAS,mCAAmC;AAE/C,mBAAa;AACf,QACE,GAAG,SAAS,QAAQ,KACpB,GAAG,SAAS,kBAAkB,KAC9B,GAAG,SAAS,SAAS,KACrB,SAAS,SAAS,WAAW,KAC7B,IAAI,SAAS,0BAA0B;AAEvC,qBAAe;AACjB,QAAI,GAAG,SAAS,yBAAyB,KAAK,IAAI,SAAS,sBAAsB;AAC/E,qBAAe;AAAA,EACnB;AACA,MAAI,cAAc,CAAC,aAAc,QAAO;AACxC,MAAI,gBAAgB,CAAC,WAAY,QAAO;AAExC,SAAO,eAAe,cAAc;AACtC;AAEA,SAAS,eAAe,SAAwB,SAA6C;AAC3F,QAAM,MAAM,QAAQ,OAAO,SAAS,OAAO;AAC3C,SAAQ,OAAQ,IAAY,eAAgB;AAC9C;AAgBA,SAAS,sBAAsB;AAC7B,QAAM,cAAc,YAAY,YAAY;AAC5C,SAAO;AAAA,IACL,KAAK,CAAC,KAAa,OAAgB,YAAY,IAAI,KAAK,EAAE;AAAA,IAC1D,KAAK,CAAC,KAAa,OAAgB,YAAY,IAAI,KAAK,EAAE;AAAA,IAC1D,QAAQ,CAAC,OAAgB,YAAY,OAAO,EAAE;AAAA,IAC9C,KAAK,CAAC,KAAa,OAAgB,OAAgB;AACjD,YAAM,SAAS,MAAM,YAAY,oBAAoB;AACrD,YAAM,OAA2C,YAAoB,MAAM;AAC3E,UAAI,CAAC,KAAK,IAAI,MAAM,EAAG,MAAK,IAAI,QAAQ,oBAAI,IAAI,CAAC;AACjD,WAAK,IAAI,MAAM,EAAG,IAAI,KAAK,KAAK;AAAA,IAClC;AAAA,IACA,OAAO,CAAC,OAAgB;AACtB,YAAM,OAA2C,YAAoB,MAAM;AAC3E,UAAI,GAAI,MAAK,OAAO,EAAE;AAAA,UACjB,MAAK,MAAM;AAAA,IAClB;AAAA,IACA,WAAW,CAAC,KAAa,SAAS,GAAG,OAAgB;AACnD,YAAM,SAAS,MAAM,YAAY,oBAAoB;AACrD,YAAM,OAA2C,YAAoB,MAAM;AAC3E,UAAI,CAAC,KAAK,IAAI,MAAM,EAAG,MAAK,IAAI,QAAQ,oBAAI,IAAI,CAAC;AACjD,YAAM,QAAQ,KAAK,IAAI,MAAM;AAC7B,YAAM,UAAU,MAAM,IAAI,GAAG;AAC7B,YAAM,aAAa,OAAO,YAAY,WAAW,UAAU;AAC3D,YAAM,WAAW,aAAa;AAC9B,YAAM,IAAI,KAAK,QAAQ;AACvB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,kBAAsC;AAC7C,QAAM,MAAM,QAAQ,IAAI,4BAA4B,QAAQ,IAAI;AAChE,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,SAAS,KAAK,EAAE;AAC1B,SAAO,OAAO,SAAS,CAAC,KAAK,IAAI,IAAI,IAAI;AAC3C;AAMA,SAAS,iBAAiB,OAAoE;AAC5F,MAAI,CAAC,SAAS,MAAM,WAAW,EAAG,QAAO;AACzC,SAAO,MAAM,IAAI,UAAQ,GAAG,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE,EAAE,KAAK,GAAG;AAClE;AAEA,SAAS,mBAAmB,MAQnB;AACP,QAAM,QAAiC;AAAA,IACrC,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,EACf;AACA,MAAI,KAAK,OAAQ,OAAM,SAAS,KAAK;AACrC,MAAI,KAAK,OAAQ,OAAM,SAAS,KAAK;AACrC,QAAM,aAAa,iBAAiB,KAAK,KAAK;AAC9C,MAAI,WAAY,OAAM,QAAQ;AAC9B,MAAI,KAAK,UAAW,OAAM,aAAa,KAAK;AAC5C,WAAS,iBAAiB,KAAK;AACjC;AAMA,eAAsB,cACpB,SACA,OACA,YACA,WACA,gBACkB;AAClB,QAAM,EAAE,SAAS,OAAO,QAAQ,aAAa,QAAQ,IAAI;AAGzD,SAAO,KAAK,2CAA2C,OAAO,cAAc,OAAO,EAAE;AAGrF,QAAM,gBAAgB,MAAM,eAAe,SAAS,QAAQ,aAAa,SAAS,KAAK;AAGvF,MAAI,cAAc,eAAe;AAC/B,WAAO;AAAA,MACL,0DAA0D,OAAO,KAAK,cAAc,WAAW;AAAA,IACjG;AAGA,UAAM,YAAyB;AAAA,MAC7B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ,GAAG,OAAO;AAAA,MAClB,SAAS,qBAAqB,cAAc,eAAe,gCAAgC;AAAA,MAC3F,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AACA,WAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,SAAS;AAGpD,cAAU;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,QACL,SAAS,cAAc,eAAe,6BAA6B,OAAO;AAAA,QAC1E,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAGD,eAAW,OAAO;AAClB,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,QAAQ;AACxB,QAAI,QAAQ,OAAO;AACjB,aAAO,KAAK,sDAAsD,OAAO,EAAE;AAAA,IAC7E;AAGA,UAAM,cAAc,SAAS,OAAO,QAAQ,aAAa,SAAS,OAAO,SAAS;AAAA,EACpF,WAAW,SAAS;AAElB,UAAM,iBAAiB,SAAS,OAAO,QAAQ,aAAa,SAAS,OAAO,SAAS;AAAA,EACvF,OAAO;AAEL,UAAM,cAAc,SAAS,OAAO,QAAQ,aAAa,SAAS,OAAO,SAAS;AAAA,EACpF;AAOA,QAAM,4BACJ,CAAC,CAAC,YAAY,cACb,YAAY,YAAY,QAAQ,CAAC,uBAAuB,SAAS,OAAO;AAC3E,MAAI,YAAY,WAAW;AACzB,WAAO;AAAA,MACL,oCAAoC,OAAO,aAAa,CAAC,CAAC,YAAY,OAAO,iBAAiB,yBAAyB;AAAA,IACzH;AAAA,EACF;AACA,MAAI,2BAA2B;AAC7B,UAAM,gBAAgB,SAAS,OAAO,QAAQ,aAAa,SAAS,OAAO,SAAS;AAAA,EACtF;AAGA,aAAW,cAAc;AACzB,SAAO;AACT;AAKA,eAAe,gBACb,SACA,OACA,QACA,aACA,SACA,OACA,WACe;AACf,QAAM,WAAW,YAAY;AAE7B,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AAGA,SAAO,KAAK,4BAA4B,OAAO,EAAE;AACjD,MAAI,gBAAgB;AAEpB,MAAI,SAAS,OAAO,SAAS,IAAI,SAAS,GAAG;AAE3C,UAAM,wBAAwB,YAAY,YAAY;AACtD,UAAM,eAAe,wBAAyB,OAAe,eAAe;AAC5E,UAAM,kBAAkB,MAAM,QAAQ,YAAY,KAAK,aAAa,SAAS;AAE7E,eAAW,eAAe,SAAS,KAAK;AAEtC,UAAI,gBAAgB,SAAS,OAAO,aAAa,KAAK,GAAG;AACvD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAGA,YAAM,eAAe,QAAQ,OAAO,SAAS,WAAW;AACxD,YAAM,aAAa,cAAc,UAAU;AAE3C,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,uCAAuC,WAAW,gBAAgB,UAAU,qBAAqB,eAAe;AAAA,QAClH;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,iBAAiB;AAE3C,iBAAS,YAAY,GAAG,YAAY,aAAc,QAAQ,aAAa;AAErE,gBAAM;AAEN,gBAAM,YAAqD;AAAA,YACzD,EAAE,OAAO,SAAS,OAAO,UAAU;AAAA,UACrC;AAEA,6BAAmB;AAAA,YACjB;AAAA,YACA,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,OAAO;AAAA,UACT,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,QAAQ;AAAA,UACV,CAAC;AACD,0BAAgB;AAAA,QAClB;AAAA,MACF,OAAO;AAGL,cAAM;AAEN,2BAAmB;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,OAAO,CAAC;AAAA,QACV,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,OAAO,CAAC;AAAA,UACR,QAAQ;AAAA,QACV,CAAC;AACD,wBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,QAAQ;AACnB,UAAM,iBAAiB,MAAM;AAAA,MAC3B,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,WAAW,gBAAgB;AAEpC,YAAM,EAAE,QAAQ,aAAa,MAAM,QAAQ,IAAI,aAAa,OAAO;AAGnE,UAAI,gBAAgB,SAAS,OAAO,aAAa,KAAK,GAAG;AACvD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAEA,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,0CAA0C,WAAW,GAAG,UAAU,YAAY,KAAK,UAAU,OAAO,IAAI,EAAE;AAAA,QAC5G;AAAA,MACF;AAGA,YAAM;AAEN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,MACR,CAAC;AACD,sBAAgB;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,oBAAoB,MAAM;AAAA,IAC9B,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,sBAAsB,QAAW;AACnC,QAAI,mBAAmB;AACrB,UAAI,gBAAgB,SAAS,OAAO,aAAa,MAAM,GAAG;AACxD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AACA,YAAM;AACN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,kBAAkB;AAAA,QAC1B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ,kBAAkB;AAAA,QAC1B;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAGA,QAAM,aAAa,MAAM;AAAA,IACvB,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AAEd,QAAI,gBAAgB,SAAS,OAAO,aAAa,MAAM,GAAG;AACxD,YAAM,aAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,GAAG,OAAO;AAAA,QAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,QAC1G,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AACA,aAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,IACF;AAEA,QAAI,QAAQ,OAAO;AACjB,aAAO,KAAK,6BAA6B,UAAU,EAAE;AAAA,IACvD;AAGA,UAAM;AAEN,uBAAmB;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ,SAAS,UAAU,YAAY;AAAA,MACvC;AAAA,IACF,CAAC;AAED,cAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,MAAM,sBAAsB;AAAA,EACpC;AAKA,MAAI,eAAe;AACjB,UAAM,WAAW,uBAAuB,OAAO,SAAS,MAAM,IAAI;AAClE,QAAI,CAAE,MAAc,kBAAkB,IAAI,QAAQ,GAAG;AACnD,MAAC,MAAc,kBAAkB,IAAI,QAAQ;AAC7C,gBAAU,EAAE,MAAM,aAAa,QAAQ,YAAY,CAAC;AAAA,IACtD;AAAA,EACF;AACF;AAoBA,eAAe,eACb,SACA,QACA,aACA,SACA,OACkC;AAClC,QAAM,SAAS,QAAQ;AAGvB,QAAM,eAAe,OAAO;AAC5B,QAAM,cAAc,YAAY;AAChC,QAAM,0BAA0B,OAAO;AACvC,QAAM,yBAAyB,YAAY;AAE3C,MAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,2BAA2B,CAAC,wBAAwB;AACxF,WAAO,EAAE,QAAQ,OAAO,eAAe,MAAM;AAAA,EAC/C;AAEA,QAAM,YAAY,IAAI,0BAA0B;AAGhD,QAAM,gBAA+C,CAAC;AACtD,aAAW,CAAC,GAAG,KAAK,MAAM,MAAM,QAAQ,GAAG;AAEzC,QAAI;AACF,YAAM,aAAa,QAAQ,QAAQ,cAAc;AACjD,YAAM,cAAc,IAAK,8DAAgC;AAAA,QACvD,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA,CAAC;AAAA,QACD,QAAQ;AAAA,MACV;AACA,YAAM,gBAAgB,YAAY,IAAI,GAAG;AACzC,UAAI,eAAe;AACjB,sBAAc,GAAG,IAAI;AAAA,MACvB;AAAA,IACF,QAAQ;AAEN,oBAAc,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,YAAY,WAAW,WAAW,WAAW,YAAY,UAAU;AAC9F,QAAM,aAAa,YAAY,SAAS;AAExC,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI;AAGJ,MAAI,cAAc;AAChB,QAAI;AACF,YAAM,SAAS,MAAM,UAAU;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,eAAO,KAAK,0CAA0C,OAAO,KAAK,YAAY,EAAE;AAGhF,cAAM,YAAyB;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS,iCAAiC,YAAY;AAAA,UACtD,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAEA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,SAAS;AAAA,MAKtD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,aAAO,MAAM,8CAA8C,GAAG,EAAE;AAAA,IAClE;AAAA,EACF;AAGA,MAAI,aAAa;AACf,QAAI;AACF,YAAM,SAAS,MAAM,UAAU;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,eAAO,KAAK,yCAAyC,OAAO,KAAK,WAAW,EAAE;AAG9E,cAAM,YAAyB;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,gCAAgC,WAAW;AAAA,UACpD,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAEA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,SAAS;AACpD,oBAAY;AAAA,MACd;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,aAAO,MAAM,6CAA6C,GAAG,EAAE;AAAA,IACjE;AAAA,EACF;AAIA,MAAI,2BAA2B,wBAAwB;AACrD,QAAI;AACF,YAAM,mBAAmB,MAAM,UAAU;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAGA,iBAAW,cAAc,kBAAkB;AACzC,YAAI,WAAW,QAAQ;AACrB,iBAAO;AAAA,YACL,gCAAgC,WAAW,aAAa,mBAAmB,OAAO,KAAK,WAAW,UAAU;AAAA,UAC9G;AAGA,gBAAM,YAAyB;AAAA,YAC7B,MAAM;AAAA,YACN,MAAM;AAAA,YACN,QAAQ,GAAG,OAAO,IAAI,WAAW,aAAa;AAAA,YAC9C,SAAS,WAAW,WAAW,0BAA0B,WAAW,UAAU;AAAA,YAC9E,UAAU,WAAW,YAAY;AAAA,YACjC,UAAU;AAAA,UACZ;AAEA,iBAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,SAAS;AACpD,sBAAY;AAGZ,cAAI,WAAW,eAAe;AAC5B,yBAAa;AACb,0BACE,WAAW,WACX,gCAAgC,WAAW,aAAa;AAC1D,mBAAO;AAAA,cACL,0CAA0C,WAAW,aAAa,SAAS,OAAO;AAAA,YACpF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,aAAO,MAAM,kDAAkD,GAAG,EAAE;AAAA,IACtE;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,WAAW,eAAe,YAAY,YAAY;AACrE;AAKO,SAAS,gBACd,SACA,OACA,QACA,QACS;AACT,QAAM,WAAW,QAAQ,OAAO,SAAS,aAAa;AAEtD,MAAI,MAAM,oBAAoB,UAAU;AACtC,UAAM,MAAM,2CAA2C,QAAQ,YAAY,MAAM,IAAI,MAAM;AAC3F,WAAO,MAAM,aAAa,GAAG,EAAE;AAC/B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,eAAe,iBACb,SACA,OACA,QACA,aACA,SACA,OACA,WACe;AACf,QAAM,YAAY,YAAY;AAE9B,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO;AACjB,WAAO,KAAK,uCAAuC,OAAO,EAAE;AAAA,EAC9D;AAGA,MAAI,UAAU,OAAO,UAAU,IAAI,SAAS,GAAG;AAE7C,UAAM,kBACH,UAAW,OAAe,gBAAiB;AAC9C,UAAM,kBAAkB,MAAM,QAAQ,eAAe,KAAK,gBAAgB,SAAS;AAGnF,UAAM,aAAc,QAAgB;AAGpC,UAAM,aAAsC,CAAC;AAC7C,QAAI;AACF,YAAM,aAAa,QAAQ,QAAQ,cAAc;AACjD,YAAM,aAAa,QAAQ,QAAQ,YAAY,QAAQ,WAAW,YAAY,QAAQ,KAAK;AAC3F,iBAAW,SAAS,YAAY;AAC9B,YAAI,MAAM,WAAW,MAAM,QAAQ;AACjC,gBAAM,IAAI,MAAM;AAChB,qBAAW,MAAM,OAAO,IAAI,EAAE,WAAW,SAAY,EAAE,SAAS;AAAA,QAClE;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,aAAO,KAAK,wEAAwE,CAAC,EAAE;AAAA,IACzF;AAEA,eAAW,WAAW,UAAU,KAAK;AAEnC,YAAM,EAAE,QAAQ,aAAa,MAAM,QAAQ,IAAI,aAAa,OAAO;AAGnE,YAAM,UAAU,UACZ,MAAM,gBAAgB,SAAS,YAAY,YAAY,OAAO,IAC9D;AAGJ,UAAI,gBAAgB,SAAS,OAAO,cAAc,KAAK,GAAG;AAExD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAGA,YAAM,eAAe,QAAQ,OAAO,SAAS,WAAW;AACxD,YAAM,aAAa,cAAc,UAAU;AAE3C,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,wCAAwC,WAAW,gBAAgB,UAAU,qBAAqB,eAAe,GAAG,UAAU,YAAY,KAAK,UAAU,OAAO,IAAI,EAAE;AAAA,QACxK;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,iBAAiB;AAE3C,iBAAS,YAAY,GAAG,YAAY,gBAAiB,QAAQ,aAAa;AAExE,gBAAM;AAEN,gBAAM,YAAqD;AAAA,YACzD,EAAE,OAAO,SAAS,OAAO,UAAU;AAAA,UACrC;AAEA,6BAAmB;AAAA,YACjB;AAAA,YACA,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,OAAO;AAAA,UACT,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AAGL,cAAM;AAEN,2BAAmB;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,QAAQ;AACpB,UAAM,iBAAiB,MAAM;AAAA,MAC3B,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,WAAW,gBAAgB;AAEpC,YAAM,EAAE,QAAQ,aAAa,MAAM,QAAQ,IAAI,aAAa,OAAO;AAGnE,UAAI,gBAAgB,SAAS,OAAO,cAAc,KAAK,GAAG;AACxD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,EAAE;AAAA,UAC3F,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAEA,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,2CAA2C,WAAW,GAAG,UAAU,YAAY,KAAK,UAAU,OAAO,IAAI,EAAE;AAAA,QAC7G;AAAA,MACF;AAGA,YAAM;AAEN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,qBAAqB,MAAM;AAAA,IAC/B,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,uBAAuB,QAAW;AACpC,QAAI,oBAAoB;AACtB,UAAI,gBAAgB,SAAS,OAAO,cAAc,MAAM,GAAG;AACzD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AACA,YAAM;AACN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,mBAAmB;AAAA,QAC3B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,mBAAmB;AAAA,MAChC,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ,mBAAmB;AAAA,QAC3B;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,mBAAmB;AAAA,MAChC,CAAC;AACD,YAAM,MAAM,sBAAsB;AAAA,IACpC;AACA;AAAA,EACF;AAGA,QAAM,aAAa,MAAM;AAAA,IACvB,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AAEd,QAAI,gBAAgB,SAAS,OAAO,cAAc,MAAM,GAAG;AACzD,YAAM,aAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,GAAG,OAAO;AAAA,QAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,EAAE;AAAA,QAC3F,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AACA,aAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,IACF;AAEA,QAAI,QAAQ,OAAO;AACjB,aAAO,KAAK,8BAA8B,UAAU,EAAE;AAAA,IACxD;AAGA,UAAM;AAEN,uBAAmB;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ,UAAU,UAAU,YAAY;AAAA,MACxC;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAED,cAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW,UAAU;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,MAAM,sBAAsB;AAAA,EACpC;AACF;AAKA,eAAe,cACb,SACA,OACA,QACA,aACA,SACA,OACA,WACe;AAEf,QAAM,WAAW,QAAQ,OAAO,SAAS,UAAU,WAAW,CAAC;AAC/D,QAAM,SAAmC,YAAY,UACjD,EAAE,GAAG,UAAU,GAAG,YAAY,QAAQ,IACtC;AAEJ,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO;AACjB,WAAO,KAAK,oCAAoC,OAAO,EAAE;AAAA,EAC3D;AAGA,MAAI,OAAO,OAAO,OAAO,IAAI,SAAS,GAAG;AAEvC,UAAM,kBACH,UAAW,OAAe,gBAAiB;AAC9C,UAAM,kBAAkB,MAAM,QAAQ,eAAe,KAAK,gBAAgB,SAAS;AAEnF,eAAW,eAAe,OAAO,KAAK;AAEpC,UAAI,gBAAgB,SAAS,OAAO,WAAW,KAAK,GAAG;AACrD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,EAAE;AAAA,UAC3F,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAGA,YAAM,eAAe,QAAQ,OAAO,SAAS,WAAW;AACxD,YAAM,aAAa,cAAc,UAAU;AAE3C,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,qCAAqC,WAAW,gBAAgB,UAAU,qBAAqB,eAAe;AAAA,QAChH;AAAA,MACF;AAGA,UAAI,iBAAiB;AACnB,iBAAS,YAAY,GAAG,YAAY,gBAAiB,QAAQ,aAAa;AACxE,gBAAM,UAAU,gBAAiB,SAAS;AAE1C,cACE,WACA,OAAO,YAAY,YACnB,QAAQ,aAAa,QACrB,eAAe,OACf;AAEA;AAAA,UACF;AAEA,gBAAM;AACN,gBAAM,YAAqD;AAAA,YACzD,EAAE,OAAO,SAAS,OAAO,UAAU;AAAA,UACrC;AACA,6BAAmB;AAAA,YACjB;AAAA,YACA,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,OAAO;AAAA,UACT,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AAEL,cAAM;AACN,2BAAmB;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ;AAAA,UACR,aAAa;AAAA;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,QAAQ;AACjB,UAAM,iBAAiB,MAAM;AAAA,MAC3B,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,WAAW,gBAAgB;AAEpC,YAAM,EAAE,QAAQ,aAAa,MAAM,QAAQ,IAAI,aAAa,OAAO;AAGnE,UAAI,gBAAgB,SAAS,OAAO,WAAW,KAAK,GAAG;AACrD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,EAAE;AAAA,UAC3F,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AAEA,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,wCAAwC,WAAW,GAAG,UAAU,YAAY,KAAK,UAAU,OAAO,IAAI,EAAE;AAAA,QAC1G;AAAA,MACF;AAGA,YAAM;AAEN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,aAAa;AAAA;AAAA,QACb,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,OAAO,OAAO,MAAM,QAAQ,YAAY,OAAO,MAAM,MAAM,GAAG;AAGhF,UAAM,OAAO,eAAe,SAAS,OAAO;AAC5C,UAAM,cAAc,gBAAgB,MAAM;AAC1C,SAAK,SAAS,cAAc,SAAS,eAAe,gBAAgB,WAAW;AAC7E,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,0CAA0C,OAAO,iBAAiB,IAAI;AAAA,QACxE;AAAA,MACF;AAAA,IAEF,OAAO;AACL,YAAM,MAAM,KAAK,IAAI,GAAG,OAAO,MAAM,OAAO,CAAC;AAE7C,UAAI,CAAE,MAAc,cAAe,CAAC,MAAc,gBAAgB,oBAAI,IAAoB;AAC1F,YAAM,cAAoC,MAAc;AAExD,YAAM,UAAU,CAAC,OAA4D;AAC3E,cAAM,WAAW,MAAM,GAAG,SAAS,IAAI,KAAK,UAAU,EAAE,IAAI;AAC5D,eAAO,GAAG,OAAO,KAAK,QAAQ;AAAA,MAChC;AAEA,YAAM,wBAAwB,CAAC,OAA4D;AACzF,cAAM,MAAM,QAAQ,EAAE;AACtB,cAAM,OAAO,YAAY,IAAI,GAAG,KAAK;AACrC,YAAI,QAAQ,IAAK;AACjB,oBAAY,IAAI,KAAK,OAAO,CAAC;AAG7B,cAAM;AACN,2BAAmB;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,OAAO,MAAM,CAAC;AAAA,QAChB,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,OAAO,MAAM,CAAC;AAAA,UACd,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAEA,YAAM,kBACH,UAAW,OAAe,gBAAiB;AAC9C,YAAM,kBAAkB,MAAM,QAAQ,eAAe,KAAK,gBAAgB,SAAS;AAEnF,UAAI,iBAAiB;AACnB,iBAAS,IAAI,GAAG,IAAI,gBAAiB,QAAQ,KAAK;AAChD,gBAAM,UAAU,gBAAiB,CAAC;AAElC,cAAI,WAAW,OAAO,YAAY,YAAY,QAAQ,aAAa,MAAM;AACvE,kBAAM,KAA8C,CAAC,EAAE,OAAO,SAAS,OAAO,EAAE,CAAC;AACjF,kCAAsB,EAAE;AAAA,UAC1B;AAAA,QACF;AAAA,MACF,OAAO;AACL,8BAAsB,KAAK;AAAA,MAC7B;AAAA,IAKF;AAAA,EACF;AAGA,QAAM,kBAAkB,MAAM;AAAA,IAC5B,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,oBAAoB,QAAW;AACjC,QAAI,iBAAiB;AACnB,UAAI,gBAAgB,SAAS,OAAO,WAAW,MAAM,GAAG;AACtD,cAAM,aAA0B;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,GAAG,OAAO;AAAA,UAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,iBAAiB;AAAA,UAC1G,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,MACF;AACA,YAAM;AACN,yBAAmB;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,gBAAgB;AAAA,QACxB,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,gBAAgB;AAAA,MAC7B,CAAC;AACD,gBAAU;AAAA,QACR,MAAM;AAAA,QACN,QAAQ,gBAAgB;AAAA,QACxB;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,gBAAgB;AAAA,MAC7B,CAAC;AACD,YAAM,MAAM,sBAAsB;AAAA,IACpC;AACA;AAAA,EACF;AAGA,QAAM,aAAa,MAAM;AAAA,IACvB,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AAEd,QAAI,gBAAgB,SAAS,OAAO,WAAW,MAAM,GAAG;AACtD,YAAM,aAA0B;AAAA,QAC9B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,GAAG,OAAO;AAAA,QAClB,SAAS,2CAA2C,QAAQ,OAAO,SAAS,aAAa,EAAE;AAAA,QAC3F,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AACA,aAAO,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,UAAU;AACrD;AAAA,IACF;AAEA,QAAI,QAAQ,OAAO;AACjB,aAAO,KAAK,2BAA2B,UAAU,EAAE;AAAA,IACrD;AAGA,UAAM;AAEN,uBAAmB;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ,OAAO,UAAU,YAAY;AAAA,MACrC;AAAA,MACA,WAAW,OAAO;AAAA,IACpB,CAAC;AAED,cAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW,OAAO;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,MAAM,sBAAsB;AAAA,EACpC;AACF;AAQA,SAAS,eAAe,MAAyC;AAC/D,MAAI,OAAO,SAAS,YAAY,KAAM,QAAO;AAC7C,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,UAAM,MAAM;AACZ,QAAI,OAAO,IAAI,SAAS,YAAY,IAAI,KAAM,QAAO;AACrD,QAAI,OAAO,IAAI,aAAa,YAAY,IAAI,SAAU,QAAO;AAAA,EAC/D;AACA,SAAO;AACT;AAEA,eAAe,cACb,OACA,SACA,aACA,QACA,SACA,QAC6B;AAC7B,MAAI;AACF,UAAM,UAAU,oBAAoB;AACpC,UAAM,eAAe,gBAAgB;AAGrC,UAAM,aAAa,QAAQ,QAAQ,cAAc;AACjD,UAAM,cAAc,IAAK,8DAAgC;AAAA,MACvD,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,CAAC;AAAA,MACD,QAAQ;AAAA,IACV;AAEA,UAAM,gBAAqC,CAAC;AAC5C,UAAM,iBAAwC,CAAC;AAG/C,UAAM,aAAa,QAAQ,QAAQ,YAAY,QAAQ,WAAW,YAAY,QAAQ,KAAK;AAC3F,UAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,OAAO,CAAC;AAE7D,eAAW,sBAAsB,gBAAgB;AAC/C,UAAI;AAEF,cAAM,gBAAgB,YAAY,IAAI,kBAAkB;AACxD,YAAI,eAAe;AAEjB,wBAAc,kBAAkB,IAC9B,cAAc,WAAW,SAAY,cAAc,SAAS;AAAA,QAChE;AAAA,MACF,QAAQ;AACN,sBAAc,kBAAkB,IAAI,EAAE,QAAQ,CAAC,EAAE;AAAA,MACnD;AAGA,UAAI;AACF,cAAM,UAAU,YAAY,WAAW,kBAAkB;AACzD,YAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,gBAAM,UACJ,gBAAgB,QAAQ,SAAS,eAC7B,QAAQ,MAAM,QAAQ,SAAS,YAAY,IAC3C;AAEN,yBAAe,kBAAkB,IAAI,QAAQ;AAAA,YAAI,CAAC,MAChD,EAAE,WAAW,SAAY,EAAE,SAAS;AAAA,UACtC;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,kBAAc,UAAU;AAGxB,QAAI,cAAmB;AACvB,QAAI;AACF,YAAM,OAAO,eAAe,OAAO,KAAK,CAAC;AACzC,YAAM,UAAW,KACd,MAAM,EACN,QAAQ,EACR,KAAK,CAAC,MAAW,MAAM,QAAQ,CAAC,CAAC;AACpC,UAAI,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,GAAG;AAC1D,sBAAc;AAAA,UACZ,WAAW;AAAA,UACX,gBAAgB,QAAQ;AAAA,UACxB,YAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAAC;AAET,UAAM,WAAgB;AAAA,MACpB,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM,YAAY,QAAQ,CAAC;AAAA,QAC3B,OAAO,YAAY;AAAA,MACrB;AAAA,MACA,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAS,QAAgB;AAAA,MACzB,QAAQ,oBAAoB;AAAA,MAC5B,OAAO;AAAA,QACL,MAAM,QAAQ,SAAS;AAAA,MACzB;AAAA,MACA,SAAS;AAAA,IACX;AAEA,UAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAUP,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAOX,QAAI;AACF,YAAM,aAAa;AAAA,QACjB;AAAA,QACA;AAAA,QACA,EAAE,OAAO,SAAS;AAAA,QAClB,EAAE,WAAW,OAAO,cAAc,MAAM;AAAA,MAC1C;AAEA,aAAO,MAAM,QAAQ,UAAU,IAAI,WAAW,OAAO,cAAc,IAAI,CAAC;AAAA,IAC1E,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,aAAO,MAAM,iDAAiD,GAAG,EAAE;AACnE,aAAO,CAAC;AAAA,IACV;AAAA,EACF,SAAS,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,WAAO,MAAM,sCAAsC,GAAG,EAAE;AACxD,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAsB,aACpB,QACA,YACA,SACA,aACA,QACA,SACA,QACwB;AAExB,MAAI,QAAQ;AACV,QAAI;AACF,YAAM,UAAU,oBAAoB;AACpC,YAAM,eAAe,gBAAgB;AAKrC,YAAM,aAAa,QAAQ,QAAQ,cAAc;AACjD,YAAM,cAAc,IAAK,8DAAgC;AAAA,QACvD,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA,CAAC;AAAA,QACD;AAAA,MACF;AAEA,YAAM,gBAAqC,CAAC;AAC5C,YAAM,iBAAwC,CAAC;AAG/C,YAAM,aAAa,QAAQ,QAAQ,YAAY,QAAQ,WAAW,YAAY,MAAS;AACvF,YAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,OAAO,CAAC;AAE7D,iBAAW,sBAAsB,gBAAgB;AAC/C,YAAI;AAEF,gBAAM,gBAAgB,YAAY,IAAI,kBAAkB;AACxD,cAAI,eAAe;AAEjB,0BAAc,kBAAkB,IAC9B,cAAc,WAAW,SAAY,cAAc,SAAS;AAAA,UAChE;AAAA,QACF,QAAQ;AACN,wBAAc,kBAAkB,IAAI,EAAE,QAAQ,CAAC,EAAE;AAAA,QACnD;AAGA,YAAI;AACF,gBAAM,UAAU,YAAY,WAAW,kBAAkB;AACzD,cAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,kBAAM,UACJ,gBAAgB,QAAQ,SAAS,eAC7B,QAAQ,MAAM,QAAQ,SAAS,YAAY,IAC3C;AAEN,2BAAe,kBAAkB,IAAI,QAAQ;AAAA,cAAI,CAAC,MAChD,EAAE,WAAW,SAAY,EAAE,SAAS;AAAA,YACtC;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAGA,oBAAc,UAAU;AAKxB,UAAI,cAAmB;AACvB,UAAI;AACF,cAAM,OAAO,eAAe,OAAO,KAAK,CAAC;AACzC,cAAM,UAAW,KACd,MAAM,EACN,QAAQ,EACR,KAAK,CAAC,MAAW,MAAM,QAAQ,CAAC,CAAC;AACpC,YAAI,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,GAAG;AAC1D,wBAAc;AAAA,YACZ,WAAW;AAAA,YACX,gBAAgB,QAAQ;AAAA,YACxB,YAAY;AAAA,UACd;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAAC;AAET,YAAM,WAAgB;AAAA,QACpB,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,MAAM,YAAY,QAAQ,CAAC;AAAA,UAC3B,OAAO,YAAY;AAAA,QACrB;AAAA,QACA,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,QAAS,QAAgB;AAAA,QACzB,QAAQ,oBAAoB;AAAA,QAC5B,OAAO;AAAA,UACL,MAAM,QAAQ,SAAS;AAAA,QACzB;AAAA,QACA,SAAS;AAAA,MACX;AAGA,UAAI,QAAQ,OAAO;AACjB,eAAO;AAAA,UACL,mCAAmC,OAAO,0BAA0B,OAAO,KAAK,cAAc,EAAE,KAAK,GAAG,CAAC;AAAA,QAC3G;AACA,mBAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC1D,iBAAO,KAAK,eAAe,GAAG,KAAK,OAAO,MAAM,QAAQ;AAAA,QAC1D;AAAA,MACF;AAEA,YAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAST,MAAM;AAAA;AAGV,UAAI;AACF,cAAM,aAAa;AAAA,UACjB;AAAA,UACA;AAAA,UACA,EAAE,OAAO,SAAS;AAAA,UAClB,EAAE,WAAW,OAAO,cAAc,KAAK;AAAA,QACzC;AAEA,YAAI,QAAQ,OAAO;AACjB,iBAAO,KAAK,kCAAkC,UAAU,EAAE;AAAA,QAC5D;AAEA,YAAI,OAAO,eAAe,YAAY,YAAY;AAChD,iBAAO;AAAA,QACT;AAAA,MACF,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,eAAO,MAAM,kDAAkD,GAAG,EAAE;AAAA,MAEtE;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,aAAO,MAAM,uCAAuC,GAAG,EAAE;AAGzD,UAAI,YAAY;AACd,eAAO,KAAK,0CAA0C,UAAU,EAAE;AAClE,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,SAAO,cAAc;AACvB;AAUA,eAAsB,oBACpB,aACA,SACA,aACA,QACA,SACA,QAGA;AACA,MAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO;AACrD,MAAI;AACF,UAAM,UAAU,oBAAoB;AACpC,UAAM,eAAe,gBAAgB;AAGrC,UAAM,aAAa,QAAQ,QAAQ,cAAc;AACjD,UAAMA,eAAe,8DAAwC;AAC7D,UAAM,OAAO,IAAIA,aAAY,QAAQ,SAAS,QAAQ,WAAW,YAAY,CAAC,GAAG,MAAS;AAE1F,UAAM,gBAAqC,CAAC;AAC5C,UAAM,iBAAwC,CAAC;AAC/C,UAAM,aAAa,QAAQ,QAAQ,YAAY,QAAQ,WAAW,YAAY,MAAS;AACvF,UAAM,iBAAiB,IAAI,IAAI,WAAW,IAAI,CAAC,MAAW,EAAE,OAAO,CAAC;AACpE,eAAW,OAAO,gBAAgB;AAChC,UAAI;AACF,cAAM,KAAK,KAAK,IAAI,GAAG;AACvB,YAAI,GAAI,eAAc,GAAG,IAAI,GAAG,WAAW,SAAY,GAAG,SAAS;AAAA,MACrE,QAAQ;AAAA,MAAC;AACT,UAAI;AACF,cAAM,OAAO,KAAK,WAAW,GAAG;AAChC,YAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,gBAAM,UACJ,gBAAgB,KAAK,SAAS,eAC1B,KAAK,MAAM,KAAK,SAAS,YAAY,IACrC;AACN,yBAAe,GAAG,IAAI,QAAQ,IAAI,CAAC,MAAY,EAAE,WAAW,SAAY,EAAE,SAAS,CAAE;AAAA,QACvF;AAAA,MACF,QAAQ;AAAA,MAAC;AAAA,IACX;AACA,kBAAc,UAAU;AAExB,UAAM,WAAgB;AAAA,MACpB,MAAM,EAAE,IAAI,SAAS,MAAM,YAAY,QAAQ,CAAC,GAAG,OAAO,YAAY,MAAM;AAAA,MAC5E,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAS,QAAgB;AAAA,MACzB,QAAQ,oBAAoB;AAAA,MAC5B,OAAO,EAAE,MAAM,QAAQ,SAAS,SAAS;AAAA,IAC3C;AAEA,eAAW,QAAQ,aAAa;AAC9B,YAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAQhB,YAAM,OAAO;AAAA,UACT,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAOwB,KAAK,IAAI;AAAA;AAAA;AAG5C,UAAI;AACJ,UAAI;AACF,kBAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA,EAAE,OAAO,SAAS;AAAA,UAClB,EAAE,WAAW,OAAO,cAAc,MAAM;AAAA,QAC1C;AAAA,MACF,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,eAAO,KAAK,wDAAwD,GAAG,EAAE;AACzE,kBAAU;AAAA,MACZ;AACA,UAAI,SAAS;AACX,YAAI,KAAK,OAAO,KAAM,QAAO;AAC7B,YAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,SAAS,GAAG;AACrD,iBAAO,EAAE,IAAI,KAAK,IAAI,YAAa,KAAa,WAAW;AAAA,QAC7D;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,2CAA2C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC7F;AACA,WAAO;AAAA,EACT;AACF;AA72DA,IAkwDM;AAlwDN;AAAA;AAuBA;AACA;AACA;AACA;AACA;AACA;AAsuDA,IAAM,oBAAoB;AAAA;AAAA;","names":["ContextView"]}
@@ -3,7 +3,7 @@ import {
3
3
  fallback_ndjson_exports,
4
4
  init_fallback_ndjson,
5
5
  init_trace_helpers
6
- } from "./chunk-DGIH6EX3.mjs";
6
+ } from "./chunk-7ERVRLDV.mjs";
7
7
  import {
8
8
  addFailIfTriggered,
9
9
  init_metrics
@@ -736,4 +736,4 @@ export {
736
736
  failure_condition_evaluator_exports,
737
737
  init_failure_condition_evaluator
738
738
  };
739
- //# sourceMappingURL=chunk-J73GEFPT.mjs.map
739
+ //# sourceMappingURL=chunk-DHETLQIX.mjs.map
@@ -58,7 +58,7 @@ import {
58
58
  import {
59
59
  config_exports,
60
60
  init_config
61
- } from "./chunk-VMVIM4JB.mjs";
61
+ } from "./chunk-ZOF5QT6U.mjs";
62
62
  import {
63
63
  ExecutionJournal,
64
64
  checkLoopBudget,
@@ -67,11 +67,11 @@ import {
67
67
  init_routing,
68
68
  init_snapshot_store,
69
69
  snapshot_store_exports
70
- } from "./chunk-VXC2XNQJ.mjs";
70
+ } from "./chunk-ANUT54HW.mjs";
71
71
  import {
72
72
  FailureConditionEvaluator,
73
73
  init_failure_condition_evaluator
74
- } from "./chunk-J73GEFPT.mjs";
74
+ } from "./chunk-DHETLQIX.mjs";
75
75
  import {
76
76
  addEvent,
77
77
  emitNdjsonFallback,
@@ -82,11 +82,11 @@ import {
82
82
  setSpanAttributes,
83
83
  trace_helpers_exports,
84
84
  withActiveSpan
85
- } from "./chunk-DGIH6EX3.mjs";
85
+ } from "./chunk-7ERVRLDV.mjs";
86
86
  import {
87
87
  generateHumanId,
88
88
  init_human_id
89
- } from "./chunk-6VVXKXTI.mjs";
89
+ } from "./chunk-QXT47ZHR.mjs";
90
90
  import {
91
91
  addDiagramBlock,
92
92
  init_metrics,
@@ -4295,7 +4295,7 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
4295
4295
  ...args,
4296
4296
  ...argsOverrides
4297
4297
  };
4298
- const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-NTHC5ZBF.mjs");
4298
+ const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-SE5I7EMA.mjs");
4299
4299
  const provider = new WorkflowCheckProvider2();
4300
4300
  const checkConfig = {
4301
4301
  type: "workflow",
@@ -10890,7 +10890,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10890
10890
  }
10891
10891
  }
10892
10892
  try {
10893
- const { evaluateTransitions } = await import("./routing-YVMTKFDZ.mjs");
10893
+ const { evaluateTransitions } = await import("./routing-CVQT4KHX.mjs");
10894
10894
  const transTarget = await evaluateTransitions(
10895
10895
  onFinish.transitions,
10896
10896
  forEachParent,
@@ -10950,7 +10950,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10950
10950
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
10951
10951
  );
10952
10952
  }
10953
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-YVMTKFDZ.mjs");
10953
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-CVQT4KHX.mjs");
10954
10954
  if (context2.debug) {
10955
10955
  logger.info(
10956
10956
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -14041,7 +14041,7 @@ var init_state_machine_execution_engine = __esm({
14041
14041
  try {
14042
14042
  const map = options?.webhookContext?.webhookData;
14043
14043
  if (map) {
14044
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-67ZLGDDQ.mjs");
14044
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-Y33CRFVD.mjs");
14045
14045
  const reg = CheckProviderRegistry2.getInstance();
14046
14046
  const p = reg.getProvider("http_input");
14047
14047
  if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
@@ -14154,7 +14154,7 @@ var init_state_machine_execution_engine = __esm({
14154
14154
  logger.info("[StateMachine] Using state machine engine");
14155
14155
  }
14156
14156
  if (!config) {
14157
- const { ConfigManager } = await import("./config-TSA5FUOM.mjs");
14157
+ const { ConfigManager } = await import("./config-JE4HKTWW.mjs");
14158
14158
  const configManager = new ConfigManager();
14159
14159
  config = await configManager.getDefaultConfig();
14160
14160
  logger.debug("[StateMachine] Using default configuration (no config provided)");
@@ -14164,7 +14164,7 @@ var init_state_machine_execution_engine = __esm({
14164
14164
  tag_filter: tagFilter
14165
14165
  } : config;
14166
14166
  try {
14167
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-67ZLGDDQ.mjs");
14167
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-Y33CRFVD.mjs");
14168
14168
  const registry = CheckProviderRegistry2.getInstance();
14169
14169
  registry.setCustomTools(configWithTagFilter.tools || {});
14170
14170
  } catch (error) {
@@ -14228,7 +14228,7 @@ var init_state_machine_execution_engine = __esm({
14228
14228
  try {
14229
14229
  const webhookData = this.executionContext?.webhookContext?.webhookData;
14230
14230
  if (webhookData instanceof Map) {
14231
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-QOJVFRB4.mjs");
14231
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-JMAKHPI7.mjs");
14232
14232
  const slackCtx = extractSlackContext2(webhookData);
14233
14233
  if (slackCtx) {
14234
14234
  const payload = Array.from(webhookData.values())[0];
@@ -14257,7 +14257,7 @@ var init_state_machine_execution_engine = __esm({
14257
14257
  if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
14258
14258
  try {
14259
14259
  const { EventBus } = await import("./event-bus-5K3Y2FCS.mjs");
14260
- const { FrontendsHost } = await import("./host-VBBSLUWG.mjs");
14260
+ const { FrontendsHost } = await import("./host-WAU6CT42.mjs");
14261
14261
  const bus = new EventBus();
14262
14262
  context2.eventBus = bus;
14263
14263
  frontendsHost = new FrontendsHost(bus, logger);
@@ -14609,9 +14609,9 @@ var init_state_machine_execution_engine = __esm({
14609
14609
  * @returns Array of failure condition evaluation results
14610
14610
  */
14611
14611
  async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
14612
- const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-HTPB5FYW.mjs");
14612
+ const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-5DZYMCGW.mjs");
14613
14613
  const evaluator = new FailureConditionEvaluator2();
14614
- const { addEvent: addEvent3 } = await import("./trace-helpers-KXDOJWBL.mjs");
14614
+ const { addEvent: addEvent3 } = await import("./trace-helpers-WJXYVV4S.mjs");
14615
14615
  const { addFailIfTriggered } = await import("./metrics-JTOG2HNO.mjs");
14616
14616
  const checkConfig = config.checks?.[checkName];
14617
14617
  if (!checkConfig) {
@@ -15447,7 +15447,7 @@ var init_scheduler = __esm({
15447
15447
  inputs: schedule.workflowInputs
15448
15448
  });
15449
15449
  if (this.taskStore) {
15450
- const { trackExecution } = await import("./track-execution-AMQQNXKE.mjs");
15450
+ const { trackExecution } = await import("./track-execution-MKIQXP2C.mjs");
15451
15451
  await trackExecution(
15452
15452
  {
15453
15453
  taskStore: this.taskStore,
@@ -15576,7 +15576,7 @@ Please provide an updated response based on the reminder above. You may referenc
15576
15576
  debug: process.env.VISOR_DEBUG === "true"
15577
15577
  });
15578
15578
  if (this.taskStore) {
15579
- const { trackExecution } = await import("./track-execution-AMQQNXKE.mjs");
15579
+ const { trackExecution } = await import("./track-execution-MKIQXP2C.mjs");
15580
15580
  await trackExecution(
15581
15581
  {
15582
15582
  taskStore: this.taskStore,
@@ -16795,6 +16795,7 @@ var init_mcp_custom_sse_server = __esm({
16795
16795
  workflowContext;
16796
16796
  keepaliveInterval = null;
16797
16797
  activeToolCalls = 0;
16798
+ inFlightToolCalls = /* @__PURE__ */ new Set();
16798
16799
  lastActivityAt = Date.now();
16799
16800
  gracefulStopRequested = false;
16800
16801
  static KEEPALIVE_INTERVAL_MS = 3e4;
@@ -16925,6 +16926,53 @@ var init_mcp_custom_sse_server = __esm({
16925
16926
  this.keepaliveInterval = null;
16926
16927
  }
16927
16928
  }
16929
+ beginToolCall(toolName, workspace) {
16930
+ if (workspace) {
16931
+ workspace.acquire();
16932
+ }
16933
+ const toolCall = {
16934
+ toolName,
16935
+ startedAt: Date.now(),
16936
+ workspace,
16937
+ counted: true,
16938
+ released: false
16939
+ };
16940
+ this.inFlightToolCalls.add(toolCall);
16941
+ this.activeToolCalls++;
16942
+ this.lastActivityAt = Date.now();
16943
+ return toolCall;
16944
+ }
16945
+ finalizeToolCall(toolCall, reason) {
16946
+ if (toolCall.counted) {
16947
+ this.activeToolCalls = Math.max(0, this.activeToolCalls - 1);
16948
+ toolCall.counted = false;
16949
+ }
16950
+ if (toolCall.workspace && !toolCall.released) {
16951
+ toolCall.workspace.release();
16952
+ toolCall.released = true;
16953
+ }
16954
+ this.inFlightToolCalls.delete(toolCall);
16955
+ this.lastActivityAt = Date.now();
16956
+ if (reason === "forced-stop") {
16957
+ logger.warn(
16958
+ `[CustomToolsSSEServer:${this.sessionId}] Force-released stranded tool call '${toolCall.toolName}' after ${Date.now() - toolCall.startedAt}ms`
16959
+ );
16960
+ }
16961
+ }
16962
+ forceDrainToolCalls() {
16963
+ if (this.inFlightToolCalls.size === 0) {
16964
+ if (this.activeToolCalls > 0) {
16965
+ logger.warn(
16966
+ `[CustomToolsSSEServer:${this.sessionId}] Resetting active tool counter with no in-flight records (${this.activeToolCalls})`
16967
+ );
16968
+ this.activeToolCalls = 0;
16969
+ }
16970
+ return;
16971
+ }
16972
+ for (const toolCall of Array.from(this.inFlightToolCalls)) {
16973
+ this.finalizeToolCall(toolCall, "forced-stop");
16974
+ }
16975
+ }
16928
16976
  /**
16929
16977
  * Stop the server and cleanup resources
16930
16978
  */
@@ -16955,6 +17003,7 @@ var init_mcp_custom_sse_server = __esm({
16955
17003
  logger.warn(
16956
17004
  `[CustomToolsSSEServer:${this.sessionId}] Drain timeout reached; stopping with ${this.activeToolCalls} active tool call(s)`
16957
17005
  );
17006
+ this.forceDrainToolCalls();
16958
17007
  }
16959
17008
  }
16960
17009
  if (this.debug) {
@@ -17339,11 +17388,7 @@ var init_mcp_custom_sse_server = __esm({
17339
17388
  */
17340
17389
  async handleToolCall(id, toolName, args) {
17341
17390
  const workspace = this.workflowContext?.workspace;
17342
- if (workspace) {
17343
- workspace.acquire();
17344
- }
17345
- this.activeToolCalls++;
17346
- this.lastActivityAt = Date.now();
17391
+ const toolCall = this.beginToolCall(toolName, workspace);
17347
17392
  try {
17348
17393
  if (this.debug) {
17349
17394
  logger.debug(
@@ -17630,11 +17675,7 @@ var init_mcp_custom_sse_server = __esm({
17630
17675
  }
17631
17676
  };
17632
17677
  } finally {
17633
- this.activeToolCalls = Math.max(0, this.activeToolCalls - 1);
17634
- this.lastActivityAt = Date.now();
17635
- if (workspace) {
17636
- workspace.release();
17637
- }
17678
+ this.finalizeToolCall(toolCall, "completed");
17638
17679
  }
17639
17680
  }
17640
17681
  /**
@@ -42425,8 +42466,8 @@ function buildBuiltinGlobals(opts) {
42425
42466
  const asyncFunctionNames = /* @__PURE__ */ new Set();
42426
42467
  const scheduleFn = async (args = {}) => {
42427
42468
  try {
42428
- const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-Z5VG67JK.mjs");
42429
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-QOJVFRB4.mjs");
42469
+ const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-POY3CDZL.mjs");
42470
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-JMAKHPI7.mjs");
42430
42471
  const parentCtx = opts.sessionInfo?._parentContext;
42431
42472
  const webhookData = parentCtx?.prInfo?.eventContext?.webhookData;
42432
42473
  const visorCfg = parentCtx?.config;
@@ -46150,4 +46191,4 @@ undici/lib/fetch/body.js:
46150
46191
  undici/lib/websocket/frame.js:
46151
46192
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
46152
46193
  */
46153
- //# sourceMappingURL=chunk-QGBASDYP.mjs.map
46194
+ //# sourceMappingURL=chunk-JCOSKBMP.mjs.map