nexus-agents 2.82.0 → 2.83.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/{child-mcp-config-BMSYR7VV.js → child-mcp-config-3ZW2UPKZ.js} +2 -2
  2. package/dist/{chunk-BQ4YXGGQ.js → chunk-3ACDP4E6.js} +124 -2
  3. package/dist/chunk-3ACDP4E6.js.map +1 -0
  4. package/dist/{chunk-S36LIUV2.js → chunk-4XSCU4B3.js} +8 -8
  5. package/dist/{chunk-HJUHDPXJ.js → chunk-5QJPM5CB.js} +3 -3
  6. package/dist/{chunk-633WH2ML.js → chunk-6T3EPABN.js} +1 -1
  7. package/dist/chunk-6T3EPABN.js.map +1 -0
  8. package/dist/{chunk-7VNVDFD5.js → chunk-6UI4NKT4.js} +44 -18
  9. package/dist/{chunk-7VNVDFD5.js.map → chunk-6UI4NKT4.js.map} +1 -1
  10. package/dist/{chunk-NTLJ3INA.js → chunk-6XRNFLPI.js} +2 -2
  11. package/dist/{chunk-U7JXQSEM.js → chunk-7V367KT4.js} +4 -4
  12. package/dist/{chunk-BL5IBHEY.js → chunk-A6WC5I7V.js} +3 -3
  13. package/dist/{chunk-OYDJ3C4N.js → chunk-BICIQYET.js} +3 -3
  14. package/dist/{chunk-SXL744NF.js → chunk-BUXXAN6V.js} +2 -2
  15. package/dist/{chunk-SHWGK7X6.js → chunk-DWOSFYI2.js} +2 -2
  16. package/dist/{chunk-2SQXJQTA.js → chunk-ELRNVADA.js} +16 -13
  17. package/dist/{chunk-2SQXJQTA.js.map → chunk-ELRNVADA.js.map} +1 -1
  18. package/dist/{chunk-2R5UUBGA.js → chunk-FHY7I736.js} +2 -2
  19. package/dist/{chunk-7J7PNOJQ.js → chunk-HFOQKCD2.js} +22 -5
  20. package/dist/chunk-HFOQKCD2.js.map +1 -0
  21. package/dist/{chunk-TXIUCEFT.js → chunk-HGPIHDC4.js} +3 -3
  22. package/dist/{chunk-X3JR3GMT.js → chunk-IM2B3FK2.js} +3 -3
  23. package/dist/{chunk-4XNVJS5A.js → chunk-J4ZBKE4B.js} +866 -892
  24. package/dist/chunk-J4ZBKE4B.js.map +1 -0
  25. package/dist/{chunk-SBZVRH4S.js → chunk-JA6ON2RP.js} +2 -2
  26. package/dist/{chunk-QHL4KGNB.js → chunk-LM2S2QWO.js} +2 -2
  27. package/dist/{chunk-QHL4KGNB.js.map → chunk-LM2S2QWO.js.map} +1 -1
  28. package/dist/{chunk-C7P2HLJX.js → chunk-MATFDJRW.js} +4 -4
  29. package/dist/{chunk-XGUDCUMB.js → chunk-O3XJLOEX.js} +2 -2
  30. package/dist/{chunk-FTT2IYYX.js → chunk-ODKIRXN7.js} +34 -43
  31. package/dist/chunk-ODKIRXN7.js.map +1 -0
  32. package/dist/{chunk-HMXQKDUV.js → chunk-SZZS57X7.js} +23 -7
  33. package/dist/chunk-SZZS57X7.js.map +1 -0
  34. package/dist/{chunk-W2AIGD35.js → chunk-TKGVRHEI.js} +3 -3
  35. package/dist/{chunk-HVZ52LOL.js → chunk-UFUR6RBP.js} +2 -2
  36. package/dist/{chunk-WUUEKFKG.js → chunk-VXIHHHLQ.js} +2 -2
  37. package/dist/{chunk-GNG7URCR.js → chunk-W6MLS2UL.js} +2 -2
  38. package/dist/{chunk-G2DZBEMU.js → chunk-XODXYOFN.js} +2 -2
  39. package/dist/{chunk-JM3R267Z.js → chunk-ZA6AZ7LK.js} +5 -5
  40. package/dist/{chunk-PZESEBD3.js → chunk-ZLGU7T6J.js} +2 -2
  41. package/dist/{cli-circuit-breaker-BIJUQRQI.js → cli-circuit-breaker-LC4NZUGD.js} +4 -4
  42. package/dist/cli.js +367 -345
  43. package/dist/cli.js.map +1 -1
  44. package/dist/codebase-search-ZFJUVMVR.js +8 -0
  45. package/dist/{composite-router-FB7P22L5.js → composite-router-GXQ25DO4.js} +2 -2
  46. package/dist/{consensus-vote-KKAIFULI.js → consensus-vote-MTLP6E72.js} +12 -12
  47. package/dist/{context-retriever-4JCGMWH7.js → context-retriever-GQRC2MVM.js} +6 -6
  48. package/dist/{doctor-deep-7YK4BZIJ.js → doctor-deep-T3UUJX2E.js} +3 -3
  49. package/dist/expert-bridge-7LPGCPPR.js +13 -0
  50. package/dist/{factory-DOWBGVAL.js → factory-3XB5CAAA.js} +5 -5
  51. package/dist/{factory-PK4EZL7K.js → factory-OKNCTJO6.js} +4 -4
  52. package/dist/index.d.ts +98 -194
  53. package/dist/index.js +90 -193
  54. package/dist/index.js.map +1 -1
  55. package/dist/{init-opencode-QP5CAMWN.js → init-opencode-KDTBKLXS.js} +5 -5
  56. package/dist/{issue-triage-T3SKNBH5.js → issue-triage-MURMDN2G.js} +4 -4
  57. package/dist/{registry-command-TH7U6UMC.js → registry-command-D56ROMFJ.js} +2 -2
  58. package/dist/{repo-analyze-D2OY2QSR.js → repo-analyze-JZEMBE6R.js} +2 -2
  59. package/dist/{repo-security-plan-V257RYTW.js → repo-security-plan-N3CDMW6L.js} +4 -4
  60. package/dist/{research-helpers-synthesize-Y3O76PY4.js → research-helpers-synthesize-36QBOKII.js} +3 -3
  61. package/dist/{routing-memory-AAH7NIHD.js → routing-memory-6IEPJ3EP.js} +2 -2
  62. package/dist/{session-memory-MY6YS2VX.js → session-memory-X6SCDFER.js} +3 -3
  63. package/dist/{setup-command-B6EC3OJA.js → setup-command-5AEO5A4Z.js} +11 -11
  64. package/dist/{setup-config-HVO6ZSLW.js → setup-config-RPSVIQJO.js} +3 -3
  65. package/dist/{setup-custom-api-UOIKUQL4.js → setup-custom-api-RBOJT3SS.js} +4 -4
  66. package/dist/{tool-memory-T7ZYIUJ2.js → tool-memory-EEHITQRJ.js} +5 -5
  67. package/dist/{weather-report-O3Z3BBAX.js → weather-report-6BC3JK5H.js} +2 -2
  68. package/package.json +1 -1
  69. package/dist/chunk-4XNVJS5A.js.map +0 -1
  70. package/dist/chunk-633WH2ML.js.map +0 -1
  71. package/dist/chunk-7J7PNOJQ.js.map +0 -1
  72. package/dist/chunk-AP2FD37C.js +0 -127
  73. package/dist/chunk-AP2FD37C.js.map +0 -1
  74. package/dist/chunk-BQ4YXGGQ.js.map +0 -1
  75. package/dist/chunk-ED6VQWNG.js +0 -63
  76. package/dist/chunk-ED6VQWNG.js.map +0 -1
  77. package/dist/chunk-FTT2IYYX.js.map +0 -1
  78. package/dist/chunk-HMXQKDUV.js.map +0 -1
  79. package/dist/codebase-search-PIBRTGBE.js +0 -9
  80. package/dist/expert-bridge-DJM5GAWZ.js +0 -11
  81. package/dist/shared-memory-CM6T2MYE.js +0 -8
  82. package/dist/symbol-extractor-WYXPJH65.js +0 -10
  83. package/dist/tool-memory-T7ZYIUJ2.js.map +0 -1
  84. package/dist/weather-report-O3Z3BBAX.js.map +0 -1
  85. /package/dist/{child-mcp-config-BMSYR7VV.js.map → child-mcp-config-3ZW2UPKZ.js.map} +0 -0
  86. /package/dist/{chunk-S36LIUV2.js.map → chunk-4XSCU4B3.js.map} +0 -0
  87. /package/dist/{chunk-HJUHDPXJ.js.map → chunk-5QJPM5CB.js.map} +0 -0
  88. /package/dist/{chunk-NTLJ3INA.js.map → chunk-6XRNFLPI.js.map} +0 -0
  89. /package/dist/{chunk-U7JXQSEM.js.map → chunk-7V367KT4.js.map} +0 -0
  90. /package/dist/{chunk-BL5IBHEY.js.map → chunk-A6WC5I7V.js.map} +0 -0
  91. /package/dist/{chunk-OYDJ3C4N.js.map → chunk-BICIQYET.js.map} +0 -0
  92. /package/dist/{chunk-SXL744NF.js.map → chunk-BUXXAN6V.js.map} +0 -0
  93. /package/dist/{chunk-SHWGK7X6.js.map → chunk-DWOSFYI2.js.map} +0 -0
  94. /package/dist/{chunk-2R5UUBGA.js.map → chunk-FHY7I736.js.map} +0 -0
  95. /package/dist/{chunk-TXIUCEFT.js.map → chunk-HGPIHDC4.js.map} +0 -0
  96. /package/dist/{chunk-X3JR3GMT.js.map → chunk-IM2B3FK2.js.map} +0 -0
  97. /package/dist/{chunk-SBZVRH4S.js.map → chunk-JA6ON2RP.js.map} +0 -0
  98. /package/dist/{chunk-C7P2HLJX.js.map → chunk-MATFDJRW.js.map} +0 -0
  99. /package/dist/{chunk-XGUDCUMB.js.map → chunk-O3XJLOEX.js.map} +0 -0
  100. /package/dist/{chunk-W2AIGD35.js.map → chunk-TKGVRHEI.js.map} +0 -0
  101. /package/dist/{chunk-HVZ52LOL.js.map → chunk-UFUR6RBP.js.map} +0 -0
  102. /package/dist/{chunk-WUUEKFKG.js.map → chunk-VXIHHHLQ.js.map} +0 -0
  103. /package/dist/{chunk-GNG7URCR.js.map → chunk-W6MLS2UL.js.map} +0 -0
  104. /package/dist/{chunk-G2DZBEMU.js.map → chunk-XODXYOFN.js.map} +0 -0
  105. /package/dist/{chunk-JM3R267Z.js.map → chunk-ZA6AZ7LK.js.map} +0 -0
  106. /package/dist/{chunk-PZESEBD3.js.map → chunk-ZLGU7T6J.js.map} +0 -0
  107. /package/dist/{cli-circuit-breaker-BIJUQRQI.js.map → cli-circuit-breaker-LC4NZUGD.js.map} +0 -0
  108. /package/dist/{codebase-search-PIBRTGBE.js.map → codebase-search-ZFJUVMVR.js.map} +0 -0
  109. /package/dist/{composite-router-FB7P22L5.js.map → composite-router-GXQ25DO4.js.map} +0 -0
  110. /package/dist/{consensus-vote-KKAIFULI.js.map → consensus-vote-MTLP6E72.js.map} +0 -0
  111. /package/dist/{context-retriever-4JCGMWH7.js.map → context-retriever-GQRC2MVM.js.map} +0 -0
  112. /package/dist/{doctor-deep-7YK4BZIJ.js.map → doctor-deep-T3UUJX2E.js.map} +0 -0
  113. /package/dist/{expert-bridge-DJM5GAWZ.js.map → expert-bridge-7LPGCPPR.js.map} +0 -0
  114. /package/dist/{factory-DOWBGVAL.js.map → factory-3XB5CAAA.js.map} +0 -0
  115. /package/dist/{factory-PK4EZL7K.js.map → factory-OKNCTJO6.js.map} +0 -0
  116. /package/dist/{init-opencode-QP5CAMWN.js.map → init-opencode-KDTBKLXS.js.map} +0 -0
  117. /package/dist/{issue-triage-T3SKNBH5.js.map → issue-triage-MURMDN2G.js.map} +0 -0
  118. /package/dist/{registry-command-TH7U6UMC.js.map → registry-command-D56ROMFJ.js.map} +0 -0
  119. /package/dist/{repo-analyze-D2OY2QSR.js.map → repo-analyze-JZEMBE6R.js.map} +0 -0
  120. /package/dist/{repo-security-plan-V257RYTW.js.map → repo-security-plan-N3CDMW6L.js.map} +0 -0
  121. /package/dist/{research-helpers-synthesize-Y3O76PY4.js.map → research-helpers-synthesize-36QBOKII.js.map} +0 -0
  122. /package/dist/{routing-memory-AAH7NIHD.js.map → routing-memory-6IEPJ3EP.js.map} +0 -0
  123. /package/dist/{session-memory-MY6YS2VX.js.map → session-memory-X6SCDFER.js.map} +0 -0
  124. /package/dist/{setup-command-B6EC3OJA.js.map → setup-command-5AEO5A4Z.js.map} +0 -0
  125. /package/dist/{setup-config-HVO6ZSLW.js.map → setup-config-RPSVIQJO.js.map} +0 -0
  126. /package/dist/{setup-custom-api-UOIKUQL4.js.map → setup-custom-api-RBOJT3SS.js.map} +0 -0
  127. /package/dist/{shared-memory-CM6T2MYE.js.map → tool-memory-EEHITQRJ.js.map} +0 -0
  128. /package/dist/{symbol-extractor-WYXPJH65.js.map → weather-report-6BC3JK5H.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/tools/consensus-vote.ts","../src/mcp/mcp-notifier.ts","../src/mcp/middleware/tool-wrapper.ts","../src/mcp/middleware/rate-limiter.ts","../src/mcp/middleware/validation.ts","../src/mcp/middleware/policy-types.ts","../src/mcp/middleware/policy-helpers.ts","../src/mcp/middleware/policy-rules.ts","../src/mcp/middleware/policy.ts","../src/mcp/middleware/timeout-guard.ts","../src/mcp/middleware/request-context.ts","../src/security/access-constraint-deriver/denylist.ts","../src/security/access-constraint-deriver/tool-risk.ts","../src/security/access-constraint-deriver/enforcer.ts","../src/security/access-constraint-deriver/mcp-guard.ts","../src/security/access-constraint-deriver/chain-adapter.ts","../src/mcp/error-envelope.ts","../src/mcp/tools/tool-result.ts","../src/mcp/middleware/middleware-chain.ts","../src/audit/secure-handler-audit.ts","../src/mcp/middleware/tool-input-sanitizer.ts","../src/mcp/middleware/secure-handler.ts","../src/cli/vote-types.ts","../src/cli-adapters/cli-to-model-adapter.ts","../src/adapters/claude-adapter.ts","../src/adapters/claude-adapter-types.ts","../src/adapters/claude-adapter-helpers.ts","../src/context/token-counter-helpers.ts","../src/adapters/prompt-utils.ts","../src/adapters/sdk/sdk-adapter.ts","../src/adapters/auto-adapter.ts","../src/agents/collaboration/event-bus-helpers.ts","../src/agents/collaboration/circular-buffer.ts","../src/agents/collaboration/event-bus.ts","../src/agents/collaboration/event-bus-topics.ts","../src/adapters/resilient-adapter.ts","../src/adapters/model-not-found-fallback.ts","../src/adapters/unified-registry.ts","../src/cli-adapters/codex-limits.ts","../src/cli/voter-prompts.ts","../src/cli/voter-response.ts","../src/cli/voter-execution.ts","../src/cli/voter-agents-deadline.ts","../src/cli/voter-agents.ts","../src/consensus/types-core.ts","../src/consensus/types-voting-protocol.ts","../src/consensus/types-weighted-voting.ts","../src/consensus/higher-order-types.ts","../src/consensus/higher-order-helpers.ts","../src/consensus/higher-order-voting.ts","../src/consensus/strategies.ts","../src/consensus/result-builder.ts","../src/consensus/helpers.ts","../src/consensus/incremental-quorum.ts","../src/consensus/engine.ts","../src/consensus/quorum-validator.ts","../src/consensus/voting-protocol-helpers.ts","../src/consensus/voting-protocol.ts","../src/agents/collaboration/byzantine-events.ts","../src/consensus/weighted-voting-helpers.ts","../src/consensus/weighted-voting.ts","../src/consensus/correlation-helpers.ts","../src/consensus/correlation-tracker.ts","../src/consensus/correlation-persistence.ts","../src/mcp/tools/consensus-vote-types.ts","../src/mcp/tools/consensus-vote-error-policy.ts","../src/orchestration/outcomes/outcome-store-persistence.ts","../src/mcp/tools/consensus-vote-recording.ts","../src/mcp/tools/simulation-guard.ts","../src/mcp/tool-annotations.ts"],"sourcesContent":["/* eslint-disable max-lines */ // Consensus voting — cohesive single module (governance: 400-600 OK)\n/**\n * nexus-agents/mcp - Consensus Vote Tool\n * @module mcp/tools/consensus-vote\n */\n\nimport { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ILogger } from '../../core/index.js';\nimport {\n createLogger,\n getErrorMessage,\n getTimeProvider,\n getRandomProvider,\n formatZodError,\n} from '../../core/index.js';\nimport type { IMcpNotifier } from '../mcp-notifier.js';\nimport { createMcpNotifier, NOOP_NOTIFIER, withProgressHeartbeat } from '../mcp-notifier.js';\nimport {\n wrapToolWithTimeout,\n toSdkCallbackWithBudgetCheck,\n getToolTimeout,\n} from '../middleware/tool-wrapper.js';\nimport { createSecureHandler, type HandlerContext } from '../middleware/secure-handler.js';\nimport {\n toolStructuredError,\n toolSuccess,\n type ToolResult,\n type BaseMcpToolDeps,\n} from './tool-result.js';\nimport type { ConsensusAlgorithm, Vote, ConsensusResult, Proposal } from '../../consensus/types.js';\nimport type { VoterRole, AgentVoteResult } from '../../cli/vote-types.js';\nimport { collectRealVotes } from '../../cli/voter-agents.js';\nimport { createConsensusEngine } from '../../consensus/engine.js';\nimport type {\n HigherOrderVotingResult,\n ICorrelationTracker,\n} from '../../consensus/higher-order-types.js';\nimport { HigherOrderVotingStrategy } from '../../consensus/index.js';\nimport {\n createPersistentCorrelationTracker,\n createPersistedProposal,\n saveCorrelationData,\n} from '../../consensus/correlation-persistence.js';\nimport {\n MAX_PROPOSAL_LENGTH,\n VotingStrategySchema,\n VoteThresholdSchema,\n ConsensusVoteInputSchema,\n buildResponse,\n getDefaultErrorPolicy,\n} from './consensus-vote-types.js';\nimport { applyErrorPolicy } from './consensus-vote-error-policy.js';\nimport { recordVoteSuccess, recordVoteError } from './consensus-vote-recording.js';\nimport { warnIfSimulatedOutsideTests } from './simulation-guard.js';\nimport { getToolAnnotations } from '../tool-annotations.js';\nimport type {\n VotingStrategy,\n ConsensusVoteInput,\n ConsensusVoteResponse,\n ExtendedVotingResult,\n} from './consensus-vote-types.js';\n\nexport type {\n VotingStrategy,\n ConsensusVoteInput,\n ConsensusVoteResponse,\n AgentVoteSummary,\n VoteDecisionStatus,\n HigherOrderMetadata,\n ExtendedVotingResult,\n} from './consensus-vote-types.js';\nexport { VotingStrategySchema, ConsensusVoteInputSchema } from './consensus-vote-types.js';\n\n// --- Correlation Tracker Singleton ---\nlet persistentCorrelationTracker: ICorrelationTracker | undefined;\n\n/** Gets or creates the persistent CorrelationTracker (Issue #517). */\nfunction getOrCreateCorrelationTracker(): ICorrelationTracker {\n persistentCorrelationTracker ??= createPersistentCorrelationTracker();\n return persistentCorrelationTracker;\n}\n\n/** Resets the persistent CorrelationTracker. @internal */\nexport function resetCorrelationTracker(): void {\n persistentCorrelationTracker = undefined;\n}\n\n// --- Dependencies ---\nexport interface ConsensusVoteDeps extends BaseMcpToolDeps {\n /** MCP notifier for client-visible logging (Issue #974) */\n notifier?: IMcpNotifier | undefined;\n}\n\n// --- Strategy Resolution ---\nfunction resolveStrategy(input: ConsensusVoteInput): VotingStrategy {\n if (input.strategy !== undefined) return input.strategy;\n if (input.threshold !== undefined) {\n switch (input.threshold) {\n case 'majority':\n return 'simple_majority';\n case 'supermajority':\n return 'supermajority';\n case 'unanimous':\n return 'unanimous';\n }\n }\n return 'simple_majority';\n}\n\nfunction strategyToAlgorithm(strategy: VotingStrategy): ConsensusAlgorithm {\n if (strategy === 'higher_order') return 'higher_order';\n if (strategy === 'opinion_wise') return 'opinion_wise';\n return strategy;\n}\n\nfunction getVoterRoles(quickMode: boolean): readonly VoterRole[] {\n // Default panel expanded to 7 roles 2026-04-25 — scope_steward added to\n // catch build-vs-buy blind spots (#2185). QuickMode substitutes\n // scope_steward for pm so fast triage covers existence-justification.\n return quickMode\n ? ['architect', 'security', 'scope_steward']\n : ['architect', 'security', 'devex', 'ai_ml', 'pm', 'catfish', 'scope_steward'];\n}\n\n// --- Voting Execution ---\n/** Creates a synthetic ConsensusResult when all votes are errors (Issue #815). */\nfunction createEmptyConsensusResult(\n proposal: string,\n algorithm: ConsensusAlgorithm\n): ConsensusResult {\n const now = new Date().toISOString();\n return {\n proposalId: 'no-valid-votes',\n proposal: { title: 'MCP Consensus Vote', description: proposal, algorithm },\n outcome: 'rejected',\n votes: new Map<string, Vote>(),\n voteCounts: { approve: 0, reject: 0, abstain: 0, total: 0 },\n approvalPercentage: 0,\n quorumReached: false,\n startedAt: now,\n closedAt: now,\n durationMs: 0,\n };\n}\n\n/**\n * Creates a synthetic ConsensusResult for an error-policy short-circuit\n * (#2630). Reused for both the hard floor (errors > 50%) and `fail_closed`.\n * Mirrors `createEmptyConsensusResult` but stamps the reason on the\n * proposal title so downstream `mapOutcomeToDecision` / `buildResponse`\n * surface a human-readable failure mode.\n */\nfunction createPolicyFailedResult(\n proposal: string,\n algorithm: ConsensusAlgorithm,\n reason: string\n): ConsensusResult {\n const now = new Date().toISOString();\n return {\n proposalId: 'error-policy-short-circuit',\n proposal: { title: `MCP Consensus Vote — ${reason}`, description: proposal, algorithm },\n outcome: 'rejected',\n votes: new Map<string, Vote>(),\n voteCounts: { approve: 0, reject: 0, abstain: 0, total: 0 },\n approvalPercentage: 0,\n quorumReached: false,\n startedAt: now,\n closedAt: now,\n durationMs: 0,\n };\n}\n\n/** Thresholds per algorithm for cascade detection. */\nconst CASCADE_THRESHOLDS: Record<string, number> = {\n majority: 0.5,\n supermajority: 0.67,\n unanimous: 1.0,\n};\n\n/** Detect if vote outcome is mathematically decided (#1765). */\nfunction detectEarlyCascade(\n algorithm: string,\n approvals: number,\n rejections: number,\n total: number\n): { decided: boolean; reason: string } {\n const threshold = CASCADE_THRESHOLDS[algorithm] ?? 0.5;\n if (total === 0) return { decided: false, reason: '' };\n\n // Unanimous: any rejection decides\n if (algorithm === 'unanimous' && rejections > 0) {\n return { decided: true, reason: `Unanimous rejected: ${String(rejections)} rejection(s)` };\n }\n // Approval locked: even if all remaining vote reject, approval holds\n if (approvals / total > threshold) {\n return {\n decided: true,\n reason: `Approval locked: ${String(approvals)}/${String(total)} > ${String(threshold)}`,\n };\n }\n // Rejection locked: even if all remaining vote approve, rejection holds\n const remaining = total - approvals - rejections;\n if ((approvals + remaining) / total < threshold) {\n return {\n decided: true,\n reason: `Rejection locked: max possible ${String(approvals + remaining)}/${String(total)} < ${String(threshold)}`,\n };\n }\n return { decided: false, reason: '' };\n}\n\n/**\n * Run the consensus engine over already-policy-applied votes.\n *\n * Callers MUST pass `engineVotes` produced by `applyErrorPolicy` (#2630)\n * — under `reduce_denominator` that means errors are already filtered;\n * under `count_as_abstain` errors have been converted to abstain\n * decisions but kept in the array. This function does no further\n * filtering on `source`.\n */\nasync function processVotesThroughEngine(\n engineVotes: readonly AgentVoteResult[],\n proposal: string,\n algorithm: ConsensusAlgorithm\n): Promise<ConsensusResult> {\n if (engineVotes.length === 0) return createEmptyConsensusResult(proposal, algorithm);\n\n const engine = createConsensusEngine();\n const engineProposal: Proposal = {\n title: 'MCP Consensus Vote',\n description: proposal,\n algorithm,\n };\n const proposalResult = await engine.propose(engineProposal);\n if (!proposalResult.ok)\n throw new Error(`Failed to create proposal: ${proposalResult.error.message}`, {\n cause: proposalResult.error,\n });\n\n const proposalId = proposalResult.value;\n for (const { role, vote } of engineVotes) await engine.vote(proposalId, role, vote);\n\n const resultRes = await engine.close(proposalId);\n if (!resultRes.ok)\n throw new Error(`Failed to close proposal: ${resultRes.error.message}`, {\n cause: resultRes.error,\n });\n return resultRes.value;\n}\n\nfunction runHigherOrderVoting(\n strategy: VotingStrategy,\n voteMap: Map<string, Vote>,\n logger: ILogger\n): HigherOrderVotingResult | undefined {\n if (strategy !== 'higher_order') return undefined;\n const hovStrategy = new HigherOrderVotingStrategy();\n const tracker = getOrCreateCorrelationTracker();\n const result = hovStrategy.aggregate(voteMap, tracker);\n logger.info('Higher-Order Voting complete', {\n method: result.method,\n decision: result.decision,\n posteriorApproval: result.posteriorApproval.toFixed(3),\n });\n return result;\n}\n\nfunction recordVotesToTracker(\n votes: readonly AgentVoteResult[],\n voteMap: Map<string, Vote>,\n outcome: 'approved' | 'rejected',\n logger: ILogger\n): void {\n const allVotesReal = votes.every((v) => v.source === 'llm');\n if (!allVotesReal) {\n logger.warn('Skipping correlation recording due to non-LLM votes', {\n count: votes.filter((v) => v.source !== 'llm').length,\n });\n return;\n }\n const tracker = getOrCreateCorrelationTracker();\n const id = `consensus-${String(getTimeProvider().now())}-${getRandomProvider().random().toString(36).slice(2, 9)}`;\n tracker.recordProposalVotes(id, voteMap, outcome);\n logger.debug('Recorded votes to tracker', { proposalId: id, outcome });\n\n try {\n const persisted = createPersistedProposal(id, voteMap, outcome);\n const saveResult = saveCorrelationData([persisted]);\n if (!saveResult.ok) {\n logger.warn('Failed to persist correlation data', { error: saveResult.error.message });\n }\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n logger.warn('Error persisting correlation data', { error: message });\n }\n}\n\n/** Process votes with cascade detection — extracted for max-lines-per-function (#1765). */\n/**\n * Run the engine + cascade-detection + higher-order voting against\n * already-policy-applied votes (#2630).\n *\n * Callers MUST pass `engineVotes` produced by `applyErrorPolicy` — no\n * filtering on `source` happens inside this function. Cascade-detection\n * counts and the higher-order voteMap are both built directly from\n * `engineVotes`.\n */\nasync function processVotesWithCascade(\n engineVotes: readonly AgentVoteResult[],\n opts: {\n totalRoles: number;\n proposal: string;\n algorithm: ConsensusAlgorithm;\n strategy: VotingStrategy;\n log: ILogger;\n }\n): Promise<{\n engineResult: ConsensusResult;\n voteMap: Map<string, Vote>;\n higherOrderResult: ReturnType<typeof runHigherOrderVoting>;\n outcome: 'approved' | 'rejected';\n cascaded: boolean;\n}> {\n const approvals = engineVotes.filter((v) => v.vote.decision === 'approve').length;\n const rejections = engineVotes.filter((v) => v.vote.decision === 'reject').length;\n const cascadeInfo = detectEarlyCascade(opts.algorithm, approvals, rejections, opts.totalRoles);\n\n if (cascadeInfo.decided) {\n opts.log.info('Vote cascade: outcome decided early', {\n approvals,\n rejections,\n total: opts.totalRoles,\n reason: cascadeInfo.reason,\n });\n }\n\n const engineResult = await processVotesThroughEngine(engineVotes, opts.proposal, opts.algorithm);\n const voteMap = new Map<string, Vote>();\n for (const { role, vote } of engineVotes) voteMap.set(role, vote);\n\n const higherOrderResult = cascadeInfo.decided\n ? undefined\n : runHigherOrderVoting(opts.strategy, voteMap, opts.log);\n const outcome: 'approved' | 'rejected' =\n engineResult.outcome === 'approved' ? 'approved' : 'rejected';\n\n return { engineResult, voteMap, higherOrderResult, outcome, cascaded: cascadeInfo.decided };\n}\n\n/** Execute a consensus vote with full strategy support. Exported for pipeline DRY (#1694). */\n/** Confidence threshold above which a contrarian rejection triggers escalation (#1799). */\nconst CONTRARIAN_ESCALATION_THRESHOLD = 0.8;\n\n/** Run a single contrarian agent to check for YAGNI/MISALIGNED/SECURITY_RISK (#1799). */\nasync function runContrarianCheck(\n proposal: string,\n log: ILogger\n): Promise<{ shouldEscalate: boolean; reason: string; confidence: number }> {\n try {\n const { executeExpert } = await import('../../pipeline/expert-bridge.js');\n const prompt = [\n 'You are a contrarian analyst. Your job is to find reasons this proposal should be REJECTED.',\n 'Look for: YAGNI (not needed), MISALIGNED (wrong tech/architecture), SECURITY_RISK, SCOPE_CREEP.',\n '',\n `Proposal: ${proposal.slice(0, 2000)}`,\n '',\n 'If you find a strong reason to reject, respond with JSON:',\n '{\"decision\":\"reject\",\"confidence\":0.0-1.0,\"reasoning\":\"your concern\"}',\n 'If the proposal is sound, respond with:',\n '{\"decision\":\"approve\",\"confidence\":0.0-1.0,\"reasoning\":\"why it is acceptable\"}',\n ].join('\\n');\n\n const result = await executeExpert('architecture', prompt);\n if (!result.success) return { shouldEscalate: false, reason: '', confidence: 0 };\n\n const jsonMatch = result.text.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch === null) return { shouldEscalate: false, reason: '', confidence: 0 };\n\n const parsed = JSON.parse(jsonMatch[0]) as {\n decision?: string;\n confidence?: number;\n reasoning?: string;\n };\n\n const isRejection = parsed.decision === 'reject';\n const confidence = typeof parsed.confidence === 'number' ? parsed.confidence : 0;\n const reasoning = typeof parsed.reasoning === 'string' ? parsed.reasoning : '';\n\n if (isRejection && confidence >= CONTRARIAN_ESCALATION_THRESHOLD) {\n log.info('Contrarian rejected with high confidence', {\n confidence,\n reasoning: reasoning.slice(0, 200),\n });\n return { shouldEscalate: true, reason: reasoning, confidence };\n }\n\n return { shouldEscalate: false, reason: '', confidence };\n } catch (error: unknown) {\n // Closes #2952 (medium): pre-fix the bare `catch {}` swallowed\n // `executeExpert` failures, JSON parse errors, and expert-bridge\n // import errors identically — the escalation guardrail silently\n // disabled itself with no log trail. Log + return the default\n // \"no escalation\" envelope so a contrarian-check infrastructure\n // bug is at least visible in operator logs.\n const message = error instanceof Error ? error.message : String(error);\n log.warn('Contrarian check failed; defaulting to no escalation', { error: message });\n return { shouldEscalate: false, reason: '', confidence: 0 };\n }\n}\n\n/**\n * Build a short-circuit result for the error-policy gate (#2630). Called\n * when the hard floor (>50% errors) trips or `fail_closed` matches.\n * Logs the warning and returns the synthetic `ExtendedVotingResult` that\n * `executeVoting` propagates to the response builder.\n */\nfunction buildPolicyShortCircuitResult(args: {\n input: ConsensusVoteInput;\n strategy: VotingStrategy;\n algorithm: ConsensusAlgorithm;\n votes: readonly AgentVoteResult[];\n errorPolicy: ConsensusVoteInput['errorPolicy'];\n reason: string;\n startTime: number;\n logger: ILogger;\n}): ExtendedVotingResult {\n args.logger.warn('Consensus vote short-circuited by error policy', {\n errorPolicy: args.errorPolicy,\n reason: args.reason,\n });\n const totalTimeMs = getTimeProvider().now() - args.startTime;\n return {\n proposal: args.input.proposal,\n threshold: args.algorithm,\n result: createPolicyFailedResult(args.input.proposal, args.algorithm, args.reason),\n votes: args.votes,\n totalTimeMs,\n simulateVotes: args.input.simulateVotes,\n strategy: args.strategy,\n };\n}\n\n/**\n * Contrarian-escalation gate for `quickMode` approvals (#1799).\n *\n * When `quickMode` voted approve, run a single contrarian agent to\n * catch YAGNI / SECURITY_RISK / SCOPE_CREEP. If it rejects with high\n * confidence, escalate by re-running `executeVoting` with the full\n * voter panel. Returns the escalated result, or `undefined` to signal\n * \"no escalation, continue with the quickMode result.\"\n */\nasync function maybeEscalateContrarian(\n input: ConsensusVoteInput,\n outcome: 'approved' | 'rejected',\n logger: ILogger,\n opts?: { voteTimeoutMs?: number }\n): Promise<ExtendedVotingResult | undefined> {\n if (!input.quickMode || outcome !== 'approved' || input.simulateVotes) return undefined;\n const escalation = await runContrarianCheck(input.proposal, logger);\n if (!escalation.shouldEscalate) return undefined;\n logger.warn('Contrarian escalation: re-running with full vote', {\n reason: escalation.reason,\n confidence: escalation.confidence,\n });\n return executeVoting({ ...input, quickMode: false }, logger, opts);\n}\n\n/*\n * Top-level voting flow: vote collection → error-policy gate → engine +\n * cascade → contrarian escalation → finalize. Further extraction\n * obscures control flow more than it helps; helpers already extracted\n * are applyErrorPolicy, buildPolicyShortCircuitResult,\n * maybeEscalateContrarian, finalizeVotingResult.\n */\n// eslint-disable-next-line max-lines-per-function -- see block comment above\nexport async function executeVoting(\n input: ConsensusVoteInput,\n logger: ILogger,\n opts?: { voteTimeoutMs?: number }\n): Promise<ExtendedVotingResult> {\n const strategy = resolveStrategy(input);\n const algorithm = strategyToAlgorithm(strategy);\n const roles = getVoterRoles(input.quickMode);\n const startTime = getTimeProvider().now();\n const errorPolicy = input.errorPolicy ?? getDefaultErrorPolicy(strategy);\n\n logger.info('Starting consensus vote', {\n strategy,\n algorithm,\n roleCount: roles.length,\n errorPolicy,\n });\n const votes = await collectRealVotes({\n roles,\n proposal: input.proposal,\n simulate: input.simulateVotes,\n ...(opts?.voteTimeoutMs !== undefined && { timeoutMs: opts.voteTimeoutMs }),\n });\n\n // Error-policy gate (#2630): hard floor + fail_closed + reduce_denominator /\n // count_as_abstain transformation. Engine sees the resulting shape.\n const policyDecision = applyErrorPolicy(votes, errorPolicy);\n if (policyDecision.shortCircuit) {\n return buildPolicyShortCircuitResult({\n input,\n strategy,\n algorithm,\n votes,\n errorPolicy,\n reason: policyDecision.reason ?? 'error policy short-circuit',\n startTime,\n logger,\n });\n }\n\n // Check for early cascade and process votes (#1765)\n const { engineResult, voteMap, higherOrderResult, outcome, cascaded } =\n await processVotesWithCascade(policyDecision.engineVotes, {\n totalRoles: roles.length,\n proposal: input.proposal,\n algorithm,\n strategy,\n log: logger,\n });\n\n recordVotesToTracker(votes, voteMap, outcome, logger);\n\n const escalated = await maybeEscalateContrarian(input, outcome, logger, opts);\n if (escalated !== undefined) return escalated;\n\n return finalizeVotingResult({\n input,\n strategy,\n algorithm,\n engineResult,\n higherOrderResult,\n votes,\n outcome,\n cascaded,\n startTime,\n logger,\n });\n}\n\n/** Build the final `ExtendedVotingResult` once the engine + cascade settle. */\nfunction finalizeVotingResult(args: {\n input: ConsensusVoteInput;\n strategy: VotingStrategy;\n algorithm: ConsensusAlgorithm;\n engineResult: ConsensusResult;\n higherOrderResult: ReturnType<typeof runHigherOrderVoting>;\n votes: readonly AgentVoteResult[];\n outcome: 'approved' | 'rejected';\n cascaded: boolean;\n startTime: number;\n logger: ILogger;\n}): ExtendedVotingResult {\n const totalTimeMs = getTimeProvider().now() - args.startTime;\n args.logger.info('Consensus vote completed', {\n strategy: args.strategy,\n outcome: args.outcome,\n durationMs: totalTimeMs,\n cascaded: args.cascaded,\n });\n const result: ExtendedVotingResult = {\n proposal: args.input.proposal,\n threshold: args.algorithm,\n result: args.engineResult,\n votes: args.votes,\n totalTimeMs,\n simulateVotes: args.input.simulateVotes,\n strategy: args.strategy,\n };\n if (args.higherOrderResult !== undefined) result.higherOrderResult = args.higherOrderResult;\n return result;\n}\n\n// --- Handler & Registration ---\nasync function handleConsensusVote(\n deps: ConsensusVoteDeps,\n args: ConsensusVoteInput\n): Promise<{ ok: true; value: ConsensusVoteResponse } | { ok: false; error: string }> {\n const logger = deps.logger ?? createLogger({ tool: 'consensus_vote' });\n if (args.simulateVotes) warnIfSimulatedOutsideTests('consensus_vote', logger);\n try {\n const result = await executeVoting(args, logger);\n const strategy = args.strategy ?? 'simple_majority';\n\n // Detect all-error votes: return structured error instead of fake \"rejected\" (#1552)\n const errorVotes = result.votes.filter((v) => v.source === 'error');\n if (errorVotes.length === result.votes.length && result.votes.length > 0) {\n const failures = errorVotes.map((v) => `${v.role}: ${v.error ?? 'unknown error'}`).join('; ');\n logger.warn('All voters failed', { failureCount: errorVotes.length, failures });\n recordVoteError(args.proposal, `All ${String(errorVotes.length)} voters failed: ${failures}`);\n return {\n ok: false,\n error: `All ${String(errorVotes.length)} voters failed. Failures: ${failures}`,\n };\n }\n\n recordVoteSuccess(\n args.proposal,\n strategy,\n result.result.outcome,\n result.totalTimeMs,\n result.votes\n );\n return { ok: true, value: buildResponse(args, result) };\n } catch (error) {\n const message = getErrorMessage(error);\n const cause = error instanceof Error ? error : new Error(message);\n logger.error('Consensus vote failed', cause);\n recordVoteError(args.proposal, message);\n return { ok: false, error: `Voting failed: ${message}` };\n }\n}\n\ntype ConsensusVoteToolResponse = ToolResult;\n\nfunction createConsensusVoteHandler(deps: ConsensusVoteDeps) {\n const notifier = deps.notifier ?? NOOP_NOTIFIER;\n return async (args: unknown, ctx: HandlerContext): Promise<ConsensusVoteToolResponse> => {\n const validationResult = ConsensusVoteInputSchema.safeParse(args);\n if (!validationResult.success) {\n return toolStructuredError({\n errorCategory: 'validation',\n message: `Validation error: ${formatZodError(validationResult.error)}`,\n });\n }\n\n const strategy = validationResult.data.strategy ?? 'simple_majority';\n ctx.logger.debug('Starting consensus vote', {\n strategy,\n quickMode: validationResult.data.quickMode,\n });\n notifier.info('consensus_vote', {\n event: 'vote_start',\n proposalLength: validationResult.data.proposal.length,\n strategy,\n });\n\n const result = await withProgressHeartbeat('consensus_vote', notifier, () =>\n handleConsensusVote(deps, validationResult.data)\n );\n if (!result.ok) {\n return toolStructuredError({ errorCategory: 'internal', message: result.error });\n }\n\n for (const vote of result.value.votes) {\n notifier.debug('consensus_vote', {\n event: 'vote_collected',\n role: vote.role,\n decision: vote.decision,\n });\n }\n notifier.info('consensus_vote', {\n event: 'vote_complete',\n decision: result.value.decision,\n approvalPercentage: result.value.approvalPercentage,\n voteCount: result.value.votes.length,\n });\n const data = result.value as unknown as Record<string, unknown>;\n return {\n ...toolSuccess(JSON.stringify(result.value, null, 2)),\n structuredContent: data,\n };\n };\n}\n\n/** Output schema for consensus_vote tool (Issue #1117, #1246). */\nexport const CONSENSUS_VOTE_OUTPUT_SCHEMA = {\n proposal: z.string(),\n strategy: VotingStrategySchema,\n decision: z.enum(['approved', 'rejected', 'no_quorum']),\n approvalPercentage: z.number(),\n voteCounts: z.object({\n approve: z.number(),\n reject: z.number(),\n abstain: z.number(),\n error: z.number(),\n }),\n votes: z.array(\n z.object({\n role: z.string().max(100),\n decision: z.enum(['approve', 'reject', 'abstain']),\n confidence: z.number(),\n reasoning: z.string().max(4000),\n simulated: z.boolean(),\n error: z.boolean(),\n modelUsed: z.string().max(100).optional(),\n rejectionCategories: z\n .array(\n z.enum([\n 'YAGNI',\n 'DRY_VIOLATION',\n 'OVER_ENGINEERING',\n 'SCOPE_CREEP',\n 'SECURITY_RISK',\n 'MISALIGNED',\n 'INSUFFICIENT_EVIDENCE',\n ])\n )\n .optional(),\n })\n ),\n threshold: VoteThresholdSchema.optional(),\n durationMs: z.number(),\n simulateVotes: z.boolean(),\n higherOrderMetadata: z\n .object({\n posteriorApproval: z.number(),\n posteriorRejection: z.number(),\n effectiveVoteCount: z.number(),\n method: z.enum(['ow', 'isp', 'simple']),\n usedCorrelationData: z.boolean(),\n improvementOverBaseline: z.number(),\n downweightedAgents: z.array(z.string().max(100)).max(10),\n reasoning: z.string().max(2000),\n })\n .optional(),\n};\n\n/**\n * Registers the consensus_vote tool with the MCP server.\n * Uses createSecureHandler (Issue #531) with timeout protection (Issue #271).\n * @category MCP\n */\nexport function registerConsensusVoteTool(server: McpServer, deps: ConsensusVoteDeps): void {\n const logger = deps.logger ?? createLogger({ tool: 'consensus_vote' });\n const notifier = deps.notifier ?? createMcpNotifier(server);\n const depsWithNotifier = { ...deps, notifier };\n const toolSchema = {\n proposal: z.string().min(1).max(MAX_PROPOSAL_LENGTH).describe('Proposal text to vote on'),\n threshold: z\n .enum(['majority', 'supermajority', 'unanimous'])\n .optional()\n .describe('Voting threshold (legacy). Use strategy instead.'),\n strategy: VotingStrategySchema.optional().describe(\n 'Voting strategy: simple_majority (default), supermajority, unanimous, proof_of_learning, or higher_order'\n ),\n quickMode: z.boolean().optional().default(false).describe('Use 3 agents instead of 7'),\n simulateVotes: z\n .boolean()\n .optional()\n .default(false)\n .describe('TESTS ONLY — random output, must not be used for real decisions (#2319)'),\n };\n\n const description =\n 'Execute multi-model consensus voting on a proposal. ' +\n 'Uses 7 specialized agent roles (architect, security, devex, ai_ml, pm, catfish, scope_steward) ' +\n 'to vote on proposals with configurable strategies. ' +\n 'Supports higher_order strategy for Bayesian-optimal aggregation with correlation awareness (Issue #514).';\n\n const secureHandler = createSecureHandler(createConsensusVoteHandler(depsWithNotifier), {\n toolName: 'consensus_vote',\n rateLimiter: deps.rateLimiter,\n logger,\n });\n\n const timeoutMs = getToolTimeout('consensus_vote', deps.security);\n const wrappedHandler = wrapToolWithTimeout('consensus_vote', secureHandler, {\n timeoutMs,\n logger,\n });\n\n server.registerTool(\n 'consensus_vote',\n {\n description,\n inputSchema: toolSchema,\n outputSchema: CONSENSUS_VOTE_OUTPUT_SCHEMA,\n annotations: getToolAnnotations('consensus_vote'),\n },\n toSdkCallbackWithBudgetCheck(wrappedHandler, 'consensus_vote', timeoutMs, logger)\n );\n logger.info('Registered consensus_vote tool with secure handler and timeout protection');\n}\n","/**\n * nexus-agents/mcp - MCP Notification Helper\n *\n * Sends structured logging notifications to MCP clients via\n * the `notifications/message` protocol method.\n * Clients (e.g., Claude Code) can display these for real-time\n * observability of orchestration events.\n *\n * Also provides progress notification support via AsyncLocalStorage\n * for resetting client-side request timeouts (MCP SDK resetTimeoutOnProgress).\n *\n * @module mcp/mcp-notifier\n * (Source: Issue #973, #974 — Claude Code Observability)\n * (Source: Issue #1108 — Progress heartbeat timeout reset)\n * (Source: MCP Protocol 2025-11-25, Logging Specification)\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createLogger, getErrorMessage } from '../core/index.js';\n\n/**\n * Logging levels for MCP notifications (RFC 5424 syslog).\n */\nexport type McpLogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error';\n\n/**\n * MCP notifier for sending structured log events to clients.\n */\nexport interface IMcpNotifier {\n /** Send info-level notification (key orchestration events) */\n info(logger: string, data: Record<string, unknown>): void;\n /** Send debug-level notification (detailed execution steps) */\n debug(logger: string, data: Record<string, unknown>): void;\n /** Send warning-level notification */\n warn(logger: string, data: Record<string, unknown>): void;\n}\n\nconst internalLogger = createLogger({ component: 'mcp-notifier' });\n\n/**\n * Creates an MCP notifier that sends logging notifications to connected clients.\n *\n * Notifications are fire-and-forget — failures are logged but never\n * propagate to callers. This ensures observability never breaks tool execution.\n */\nexport function createMcpNotifier(server: McpServer): IMcpNotifier {\n function send(level: McpLogLevel, logger: string, data: Record<string, unknown>): void {\n try {\n server.sendLoggingMessage({ level, logger, data }).catch((error: unknown) => {\n internalLogger.debug('Failed to send MCP notification', {\n level,\n logger,\n error: getErrorMessage(error),\n });\n });\n } catch (error: unknown) {\n internalLogger.debug('Failed to send MCP notification', {\n level,\n logger,\n error: getErrorMessage(error),\n });\n }\n }\n\n return {\n info: (logger, data) => {\n send('info', logger, data);\n },\n debug: (logger, data) => {\n send('debug', logger, data);\n },\n warn: (logger, data) => {\n send('warning', logger, data);\n },\n };\n}\n\n/**\n * No-op notifier for when MCP server is not available.\n */\nexport const NOOP_NOTIFIER: IMcpNotifier = {\n info: () => undefined,\n debug: () => undefined,\n warn: () => undefined,\n};\n\n// ============================================================================\n// Progress Notification Support (MCP SDK resetTimeoutOnProgress)\n// ============================================================================\n\n/**\n * Callback to send a progress notification to the MCP client.\n * When the client sets resetTimeoutOnProgress=true, each notification\n * resets the client's 60s request timeout.\n */\nexport type ProgressSender = (progress: number, total?: number) => void;\n\n/**\n * Progress context stored via AsyncLocalStorage.\n * Set by toSdkCallbackWithProgress when a progressToken is available.\n */\nexport interface ProgressContext {\n readonly progressToken: string | number;\n readonly sendNotification: ProgressSender;\n}\n\n/**\n * AsyncLocalStorage for MCP progress context.\n * Allows withProgressHeartbeat to access the progress sender without\n * threading it through the entire middleware chain.\n */\nexport const progressContextStorage = new AsyncLocalStorage<ProgressContext>();\n\n// ============================================================================\n// Abort Signal Support (MCP SDK cancellation)\n// ============================================================================\n\n/**\n * AsyncLocalStorage for MCP abort signal.\n * Set by toSdkCallback when the SDK provides an AbortSignal.\n * Allows middleware (e.g., TimeoutGuard) to race client cancellation\n * alongside server-side timeouts.\n */\nexport const abortSignalStorage = new AsyncLocalStorage<AbortSignal>();\n\n/**\n * Wraps an async operation with periodic heartbeat notifications.\n *\n * When a progressToken is available (via AsyncLocalStorage from the MCP\n * request handler), sends real `notifications/progress` that reset the\n * client's request timeout (MCP SDK resetTimeoutOnProgress feature).\n *\n * Always sends logging notifications for observability regardless.\n *\n * @param toolName - Name of the tool for notification context\n * @param notifier - MCP notifier instance\n * @param operation - The async operation to wrap\n * @param intervalMs - Heartbeat interval (default: 15000ms)\n * @returns The operation result\n */\nexport async function withProgressHeartbeat<T>(\n toolName: string,\n notifier: IMcpNotifier,\n operation: () => Promise<T>,\n intervalMs = 15_000\n): Promise<T> {\n const startTime = Date.now();\n let beatCount = 0;\n const progressCtx = progressContextStorage.getStore();\n\n const timer = setInterval(() => {\n beatCount++;\n const elapsed = Math.round((Date.now() - startTime) / 1000);\n\n // Send real progress notification if client provided progressToken\n if (progressCtx !== undefined) {\n progressCtx.sendNotification(beatCount);\n }\n\n // Always send logging notification for observability\n notifier.debug(toolName, {\n event: 'heartbeat',\n elapsedSeconds: elapsed,\n beatCount,\n hasProgressToken: progressCtx !== undefined,\n });\n }, intervalMs);\n\n try {\n return await operation();\n } finally {\n clearInterval(timer);\n }\n}\n","/**\n * nexus-agents/mcp - Tool Wrapper Helper\n *\n * Provides a convenient wrapper for MCP tools that automatically applies\n * the middleware chain with timeout protection (CVE-2026-0621 mitigation).\n *\n * @module mcp/middleware/tool-wrapper\n * (Source: Issue #271, CVE-2026-0621 mitigation)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport type { ILogger } from '../../core/index.js';\nimport type { TimeoutConfig, SecurityConfig } from '../../config/schemas.js';\nimport type { IPolicyFirewall, ExecutionMode } from './policy.js';\nimport type { RateLimiterConfig } from './rate-limiter.js';\nimport { RateLimiter } from './rate-limiter.js';\nimport {\n withMiddleware,\n createMiddlewareFactory,\n type ToolHandler,\n type ContextAwareToolHandler,\n type MiddlewareChainConfig,\n} from './middleware-chain.js';\nimport { MCP_TIMEOUTS } from '../../config/timeouts.js';\nimport {\n progressContextStorage,\n abortSignalStorage,\n type ProgressContext,\n} from '../mcp-notifier.js';\nimport { createLogger as createInternalLogger, getErrorMessage } from '../../core/index.js';\nimport { getNexusDataDir } from '../../config/nexus-data-dir.js';\n\n/**\n * Default timeout configuration.\n * Values sourced from config/timeouts.ts (Issue #984).\n */\nexport const DEFAULT_TIMEOUT_CONFIG: TimeoutConfig = {\n defaultTimeoutMs: MCP_TIMEOUTS.defaultMs,\n maxTimeoutMs: MCP_TIMEOUTS.maxMs,\n enableLogging: true,\n uriValidation: true,\n};\n\n/**\n * Default per-tool timeout overrides.\n * Sourced from config/timeouts.ts (Issue #984).\n */\nexport const DEFAULT_TOOL_TIMEOUTS: Record<string, number> = {\n ...MCP_TIMEOUTS.perTool,\n};\n\n/**\n * Resolves the timeout for a specific tool.\n * Priority: explicit override > security config perToolTimeout > DEFAULT_TOOL_TIMEOUTS > global default.\n * (Issue #657 - Per-tool timeout configuration)\n */\nexport function getToolTimeout(\n toolName: string,\n security?: SecurityConfig,\n explicitMs?: number\n): number {\n // Explicit override takes highest priority\n if (explicitMs !== undefined) {\n return explicitMs;\n }\n // Check security config per-tool overrides\n const perToolConfig = security?.timeout?.perToolTimeout;\n const perToolMs = perToolConfig?.[toolName];\n if (perToolMs !== undefined) {\n return perToolMs;\n }\n // Check built-in per-tool defaults\n const builtInDefault = DEFAULT_TOOL_TIMEOUTS[toolName];\n if (builtInDefault !== undefined) {\n return builtInDefault;\n }\n // Fall back to global default\n return security?.timeout?.defaultTimeoutMs ?? DEFAULT_TIMEOUT_CONFIG.defaultTimeoutMs;\n}\n\n/**\n * Configuration for creating a tool factory.\n */\nexport interface ToolFactoryConfig {\n /** Logger instance */\n logger?: ILogger | undefined;\n /** Security configuration (includes timeout config) */\n security?: SecurityConfig | undefined;\n /** Policy firewall instance */\n policyFirewall?: IPolicyFirewall | undefined;\n /** Rate limiter configuration */\n rateLimiter?: RateLimiterConfig | RateLimiter | undefined;\n /** Allowed paths for file operations */\n allowedPaths?: readonly string[] | undefined;\n}\n\n/**\n * Per-tool configuration options.\n */\nexport interface ToolWrapperOptions {\n /** Execution mode for policy evaluation (default: 'read-only') */\n executionMode?: ExecutionMode | undefined;\n /** Custom timeout in ms (overrides default) */\n timeoutMs?: number | undefined;\n /** Skip timeout protection (use sparingly) */\n skipTimeout?: boolean | undefined;\n /** Skip rate limiting */\n skipRateLimit?: boolean | undefined;\n}\n\n/**\n * Gets timeout configuration from security config or uses defaults.\n */\nfunction getTimeoutConfig(\n security?: SecurityConfig,\n overrideMs?: number\n): MiddlewareChainConfig['timeout'] {\n const timeoutConfig = security?.timeout ?? DEFAULT_TIMEOUT_CONFIG;\n\n return {\n defaultTimeoutMs: overrideMs ?? timeoutConfig.defaultTimeoutMs,\n maxTimeoutMs: timeoutConfig.maxTimeoutMs,\n enableLogging: timeoutConfig.enableLogging,\n };\n}\n\n/**\n * Creates a tool factory with shared configuration.\n *\n * This factory produces wrapped handlers that include timeout protection,\n * rate limiting, and other middleware as configured.\n *\n * @example\n * ```typescript\n * const wrapTool = createToolFactory({\n * security: appConfig.security,\n * rateLimiter: { capacity: 100, refillRate: 10 },\n * });\n *\n * const handler = wrapTool('my_tool', async (args) => {\n * // Your tool logic here\n * return { content: [{ type: 'text', text: 'Done' }] };\n * });\n * ```\n */\nexport function createToolFactory(\n config: ToolFactoryConfig\n): (\n toolName: string,\n handler: ContextAwareToolHandler | ToolHandler,\n options?: ToolWrapperOptions\n) => ToolHandler {\n const { security, policyFirewall, rateLimiter, allowedPaths, logger } = config;\n\n return (toolName, handler, options) => {\n const skip = {\n timeout: options?.skipTimeout,\n rateLimit: options?.skipRateLimit,\n };\n\n const chainConfig: Omit<MiddlewareChainConfig, 'toolName'> = {\n logger,\n policyFirewall,\n executionMode: options?.executionMode ?? 'read-only',\n allowedPaths,\n rateLimiter,\n timeout: skip.timeout === true ? undefined : getTimeoutConfig(security, options?.timeoutMs),\n skip,\n };\n\n return withMiddleware(toolName, handler, chainConfig);\n };\n}\n\n/**\n * Wraps a single tool handler with timeout protection.\n *\n * This is a convenience function for simple cases where you don't need\n * the full factory setup.\n *\n * @example\n * ```typescript\n * const handler = wrapToolWithTimeout('my_tool', async (args) => {\n * return { content: [{ type: 'text', text: 'Done' }] };\n * });\n * ```\n */\nexport function wrapToolWithTimeout(\n toolName: string,\n handler: ContextAwareToolHandler | ToolHandler,\n options?: {\n timeoutMs?: number;\n logger?: ILogger;\n }\n): ToolHandler {\n return withMiddleware(toolName, handler, {\n timeout: getTimeoutConfig(undefined, options?.timeoutMs),\n logger: options?.logger,\n });\n}\n\n/** Shape of the MCP SDK's extra._meta for progress tokens. */\ninterface SdkMeta {\n readonly progressToken?: string | number;\n}\n\n/** Shape of the MCP SDK's extra object passed to tool handlers. */\ninterface SdkExtra {\n readonly _meta?: SdkMeta;\n readonly signal?: AbortSignal;\n readonly sendNotification?: (notification: {\n method: string;\n params?: Record<string, unknown>;\n }) => Promise<void>;\n}\n\nconst wrapperLogger = createInternalLogger({ component: 'tool-wrapper' });\n\n/** Extract progress context from MCP SDK extra if progressToken present. */\nfunction extractProgressContext(extra: unknown): ProgressContext | undefined {\n const sdk = extra as SdkExtra | undefined;\n const token = sdk?._meta?.progressToken;\n const sendFn = sdk?.sendNotification;\n if (token === undefined || sendFn === undefined) return undefined;\n\n return {\n progressToken: token,\n sendNotification: (progress: number, total?: number) => {\n const params: Record<string, unknown> = {\n progressToken: token,\n progress,\n };\n if (total !== undefined) params['total'] = total;\n sendFn({ method: 'notifications/progress', params }).catch((err: unknown) => {\n wrapperLogger.debug('Failed to send progress notification', {\n error: getErrorMessage(err),\n });\n });\n },\n };\n}\n\n/**\n * Runs handler within nested AsyncLocalStorage contexts for progress + abort.\n */\n/** SDK-compatible tool result with optional structuredContent (Issue #1117). */\ntype SdkToolResult = {\n content: Array<{ type: 'text'; text: string }>;\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n // Post-#2649: the structured error envelope lives in `_meta` under\n // `nexus-agents/error` (not in `structuredContent`, which is validated\n // against `outputSchema` even on error results).\n _meta?: Record<string, unknown>;\n};\n\nfunction runWithContexts(\n handler: ToolHandler,\n args: unknown,\n progressCtx: ProgressContext | undefined,\n signal: AbortSignal | undefined\n): Promise<SdkToolResult> {\n const run = (): Promise<SdkToolResult> => handler(args);\n\n // Nest contexts: abort signal outer, progress inner\n if (signal !== undefined && progressCtx !== undefined) {\n return abortSignalStorage.run(signal, () => progressContextStorage.run(progressCtx, run));\n }\n if (signal !== undefined) {\n return abortSignalStorage.run(signal, run);\n }\n if (progressCtx !== undefined) {\n return progressContextStorage.run(progressCtx, run);\n }\n return run();\n}\n\n/**\n * Adapts a ToolHandler to the MCP SDK's expected callback signature.\n *\n * Extracts progressToken and AbortSignal from extra, runs the handler\n * within AsyncLocalStorage contexts so middleware can access them.\n *\n * @param handler - Our internal ToolHandler\n * @returns SDK-compatible callback function\n */\nexport function toSdkCallback(\n handler: ToolHandler\n): (args: unknown, extra: unknown) => Promise<SdkToolResult> {\n return (args: unknown, extra: unknown) => {\n const progressCtx = extractProgressContext(extra);\n const signal = (extra as SdkExtra | undefined)?.signal;\n return runWithContexts(handler, args, progressCtx, signal);\n };\n}\n\n/**\n * MCP SDK client default request timeout. Matches `DEFAULT_REQUEST_TIMEOUT_MSEC`\n * in `@modelcontextprotocol/sdk` (`shared/protocol.js`). If a tool's\n * configured server-side budget exceeds this and the client did not send a\n * `progressToken` (i.e. did not pass `onprogress` to its `request()` call),\n * the client kills the request at this threshold regardless of what the\n * server is doing — heartbeats fire but go nowhere.\n *\n * (Source: audit on #2619 / #2631 — root cause of \"MCP error -32001 at 60010ms\")\n */\nexport const MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS = 60_000;\n\n/**\n * Relative path under `$NEXUS_DATA_DIR` for the timeout-mismatch event log.\n * The #2632 WARN was log-only — useful in tail but not queryable. #2703\n * records each mismatch event as a JSONL row keyed by a correlation\n * `eventId` shared with the log entry, so \"did mismatch cause this\n * timeout?\" can be answered by joining the warning's eventId against the\n * recorded outcome — not just counted in aggregate.\n *\n * Schema lives at `docs/architecture/MCP_PROTOCOL.md` (Timeout-mismatch\n * telemetry section).\n */\nexport const TIMEOUT_MISMATCH_TELEMETRY_REL_PATH = 'mcp-telemetry/timeout-mismatch-events.jsonl';\n\n/** A single timeout-mismatch event recorded to the telemetry JSONL. */\nexport interface TimeoutMismatchEvent {\n readonly eventId: string;\n readonly toolName: string;\n readonly configuredTimeoutMs: number;\n readonly mcpSdkDefaultMs: number;\n readonly startedAt: string;\n readonly endedAt: string;\n readonly durationMs: number;\n readonly outcome: 'success' | 'error';\n /** From the post-#2649 structured error envelope when present. */\n readonly errorCategory?: string;\n readonly errorMessage?: string;\n}\n\n/**\n * Cache the \"dir ensured\" flag so we don't re-`existsSync` on every call\n * (closes #2955 site 3, partial). Cached per `dirname(path)` so an\n * operator changing `NEXUS_DATA_DIR` between calls (test/dev only)\n * still works after a process restart. The full async-write part of\n * the perf fix is deferred — `tool-wrapper-budget-check.test.ts` reads\n * the JSONL synchronously after `await callback(...)` and expects the\n * write to be visible, so switching to `fs.promises.appendFile` broke\n * those tests. The dir-cache is the cheaper part of the perf win\n * (skipping 1 existsSync per call); the appendFileSync vs appendFile\n * win can ship later behind a test-helper that awaits pending writes.\n */\nconst ensuredDirs = new Set<string>();\n\n/** Best-effort append — telemetry recording must never fail the user's tool call. */\nfunction appendTimeoutMismatchEvent(event: TimeoutMismatchEvent): void {\n try {\n const path = join(getNexusDataDir(), TIMEOUT_MISMATCH_TELEMETRY_REL_PATH);\n const dir = dirname(path);\n if (!ensuredDirs.has(dir)) {\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n ensuredDirs.add(dir);\n }\n appendFileSync(path, JSON.stringify(event) + '\\n', 'utf-8');\n } catch (err) {\n wrapperLogger.debug('Best-effort timeout-mismatch event recording failed', {\n error: getErrorMessage(err),\n });\n }\n}\n\n/** Pull the post-#2649 errorCategory off an error result's `_meta` envelope. */\nfunction extractErrorCategoryFromResult(result: SdkToolResult): string | undefined {\n const envelope = result._meta?.['nexus-agents/error'];\n if (envelope !== null && typeof envelope === 'object' && 'errorCategory' in envelope) {\n const cat = (envelope as { errorCategory?: unknown }).errorCategory;\n if (typeof cat === 'string') return cat;\n }\n return undefined;\n}\n\n/** First text-content line of an error result, truncated for logging. */\nfunction extractErrorMessageFromResult(result: SdkToolResult): string | undefined {\n const first = result.content[0];\n if (first?.type === 'text' && typeof first.text === 'string') {\n return first.text.slice(0, 500);\n }\n return undefined;\n}\n\ninterface MismatchCallContext {\n readonly log: ILogger;\n readonly handler: ToolHandler;\n readonly args: unknown;\n readonly progressCtx: ProgressContext | undefined;\n readonly signal: AbortSignal | undefined;\n readonly toolName: string;\n readonly configuredTimeoutMs: number;\n}\n\ninterface MismatchOutcome {\n readonly outcome: 'success' | 'error';\n readonly errorCategory?: string;\n readonly errorMessage?: string;\n}\n\n/** Build a complete event record from a finished mismatched call. */\nfunction buildMismatchEvent(\n ctx: MismatchCallContext,\n eventId: string,\n t0: number,\n outcome: MismatchOutcome\n): TimeoutMismatchEvent {\n const t1 = Date.now();\n return {\n eventId,\n toolName: ctx.toolName,\n configuredTimeoutMs: ctx.configuredTimeoutMs,\n mcpSdkDefaultMs: MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS,\n startedAt: new Date(t0).toISOString(),\n endedAt: new Date(t1).toISOString(),\n durationMs: t1 - t0,\n outcome: outcome.outcome,\n ...(outcome.errorCategory !== undefined ? { errorCategory: outcome.errorCategory } : {}),\n ...(outcome.errorMessage !== undefined ? { errorMessage: outcome.errorMessage } : {}),\n };\n}\n\n/** Classify a tool result into a MismatchOutcome (success or structured error). */\nfunction classifyResult(result: SdkToolResult): MismatchOutcome {\n if (result.isError !== true) return { outcome: 'success' };\n const errorCategory = extractErrorCategoryFromResult(result);\n const errorMessage = extractErrorMessageFromResult(result);\n return {\n outcome: 'error',\n ...(errorCategory !== undefined ? { errorCategory } : {}),\n ...(errorMessage !== undefined ? { errorMessage } : {}),\n };\n}\n\n/** Run a mismatched call, recording its outcome to the JSONL. */\nasync function runMismatchedCall(ctx: MismatchCallContext): Promise<SdkToolResult> {\n const eventId = randomUUID();\n const t0 = Date.now();\n ctx.log.warn(\n 'MCP tool budget exceeds client default and no progressToken received — request likely to be killed by client before server-side deadline',\n {\n tool: ctx.toolName,\n eventId,\n configuredTimeoutMs: ctx.configuredTimeoutMs,\n mcpSdkDefaultMs: MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS,\n remediation:\n 'Client should pass `onprogress` and `resetTimeoutOnProgress: true` when calling, or extend `options.timeout`. See docs/architecture/MCP_PROTOCOL.md.',\n }\n );\n try {\n const result = await runWithContexts(ctx.handler, ctx.args, ctx.progressCtx, ctx.signal);\n appendTimeoutMismatchEvent(buildMismatchEvent(ctx, eventId, t0, classifyResult(result)));\n return result;\n } catch (err) {\n appendTimeoutMismatchEvent(\n buildMismatchEvent(ctx, eventId, t0, {\n outcome: 'error',\n errorMessage: getErrorMessage(err).slice(0, 500),\n })\n );\n throw err;\n }\n}\n\n/**\n * Like `toSdkCallback`, but emits a one-shot WARN at invocation start when\n * the configured per-tool budget exceeds the MCP SDK client default AND the\n * client did not send a `progressToken`. The call is almost certainly going\n * to die at the client default (~60s) regardless of server-side timeout\n * config or progress heartbeats — surface that at the moment of invocation\n * so operators can spot the mismatch in logs without waiting for the\n * timeout to fire.\n *\n * Wrap a long-running tool (`orchestrate`, `consensus_vote`,\n * `execute_expert`, `run_workflow`) with this instead of plain\n * `toSdkCallback`. Tools whose budget already fits within\n * `MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS` should keep using `toSdkCallback`.\n *\n * Each mismatch is **also recorded** to\n * `$NEXUS_DATA_DIR/mcp-telemetry/timeout-mismatch-events.jsonl` with a\n * correlation `eventId` (also surfaced in the WARN log entry) and the\n * call's eventual outcome (`success` / `error` + post-#2649 errorCategory\n * if present). This lets the Epic #2631 gate be answered with data —\n * \"of N mismatches, what fraction ended in a timeout?\" — not just counted\n * in aggregate (#2703).\n *\n * (Source: audit on #2619 / #2631 — observability for client-timeout mismatch)\n */\nexport function toSdkCallbackWithBudgetCheck(\n handler: ToolHandler,\n toolName: string,\n configuredTimeoutMs: number,\n logger?: ILogger\n): (args: unknown, extra: unknown) => Promise<SdkToolResult> {\n const log = logger ?? wrapperLogger;\n return (args: unknown, extra: unknown) => {\n const progressCtx = extractProgressContext(extra);\n const signal = (extra as SdkExtra | undefined)?.signal;\n const isMismatch =\n configuredTimeoutMs > MCP_SDK_DEFAULT_REQUEST_TIMEOUT_MS && progressCtx === undefined;\n if (!isMismatch) return runWithContexts(handler, args, progressCtx, signal);\n return runMismatchedCall({\n log,\n handler,\n args,\n progressCtx,\n signal,\n toolName,\n configuredTimeoutMs,\n });\n };\n}\n\n/**\n * Re-export middleware factory for advanced use cases.\n */\nexport { createMiddlewareFactory, withMiddleware };\n","/**\n * nexus-agents/mcp - Rate Limiter Middleware\n *\n * Token bucket implementation for rate limiting MCP tool calls.\n * Prevents abuse and ensures fair resource usage.\n *\n * (Source: Token Bucket Algorithm, RFC 6585)\n */\n\nimport { createLogger, type ILogger, getTimeProvider } from '../../core/index.js';\n\n/**\n * Configuration for the token bucket rate limiter.\n */\nexport interface RateLimiterConfig {\n /** Maximum number of tokens in the bucket */\n readonly capacity: number;\n /** Number of tokens added per interval */\n readonly refillRate: number;\n /** Interval in milliseconds between token refills (default: 1000ms) */\n readonly refillIntervalMs?: number;\n /** Optional logger instance */\n readonly logger?: ILogger;\n /** Optional identifier for logging */\n readonly name?: string;\n}\n\n/**\n * Current state of the rate limiter.\n */\nexport interface RateLimiterState {\n /** Current number of available tokens */\n readonly tokens: number;\n /** Capacity of the bucket */\n readonly capacity: number;\n /** Time until next token is available (0 if tokens available) */\n readonly nextTokenMs: number;\n}\n\n// Canonical source: config/timeouts.ts (Issue #1046)\nimport { CACHE_TIMEOUTS } from '../../config/timeouts.js';\n\nconst DEFAULT_REFILL_INTERVAL_MS = CACHE_TIMEOUTS.rateLimitRefillMs;\n\n/**\n * Token bucket rate limiter implementation.\n *\n * The token bucket algorithm allows for bursting up to the capacity,\n * while maintaining a steady-state rate equal to the refill rate.\n *\n * @example\n * ```typescript\n * const limiter = new RateLimiter({\n * capacity: 100,\n * refillRate: 10,\n * refillIntervalMs: 1000,\n * });\n *\n * if (limiter.tryAcquire()) {\n * // Proceed with operation\n * } else {\n * // Rate limited, reject or queue\n * }\n * ```\n */\nexport class RateLimiter {\n private tokens: number;\n private readonly capacity: number;\n private readonly refillRate: number;\n private readonly refillIntervalMs: number;\n private lastRefillTime: number;\n private readonly logger: ILogger;\n private readonly name: string;\n\n constructor(config: RateLimiterConfig) {\n this.capacity = config.capacity;\n this.refillRate = config.refillRate;\n this.refillIntervalMs = config.refillIntervalMs ?? DEFAULT_REFILL_INTERVAL_MS;\n this.tokens = this.capacity;\n this.lastRefillTime = getTimeProvider().now();\n this.name = config.name ?? 'rate-limiter';\n this.logger = config.logger ?? createLogger({ component: this.name });\n\n this.logger.debug('Rate limiter initialized', {\n capacity: this.capacity,\n refillRate: this.refillRate,\n refillIntervalMs: this.refillIntervalMs,\n });\n }\n\n /**\n * Refills tokens based on elapsed time.\n * Called automatically before each acquire attempt.\n */\n private refill(): void {\n const now = getTimeProvider().now();\n const elapsed = now - this.lastRefillTime;\n const intervals = Math.floor(elapsed / this.refillIntervalMs);\n\n if (intervals > 0) {\n const tokensToAdd = intervals * this.refillRate;\n this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);\n this.lastRefillTime = now - (elapsed % this.refillIntervalMs);\n\n if (tokensToAdd > 0) {\n this.logger.debug('Tokens refilled', {\n added: tokensToAdd,\n current: this.tokens,\n });\n }\n }\n }\n\n /**\n * Attempts to acquire a token.\n *\n * @param count - Number of tokens to acquire (default: 1)\n * @returns True if tokens were acquired, false if rate limited\n */\n tryAcquire(count = 1): boolean {\n this.refill();\n\n if (this.tokens >= count) {\n this.tokens -= count;\n this.logger.debug('Token acquired', {\n requested: count,\n remaining: this.tokens,\n });\n return true;\n }\n\n this.logger.warn('Rate limit exceeded', {\n requested: count,\n available: this.tokens,\n });\n return false;\n }\n\n /**\n * Gets the current state of the rate limiter.\n *\n * @returns The current rate limiter state\n */\n getState(): RateLimiterState {\n this.refill();\n\n const nextTokenMs =\n this.tokens > 0 ? 0 : this.refillIntervalMs - (getTimeProvider().now() - this.lastRefillTime);\n\n return {\n tokens: this.tokens,\n capacity: this.capacity,\n nextTokenMs: Math.max(0, nextTokenMs),\n };\n }\n\n /**\n * Resets the rate limiter to full capacity.\n * Useful for testing or after configuration changes.\n */\n reset(): void {\n this.tokens = this.capacity;\n this.lastRefillTime = getTimeProvider().now();\n this.logger.debug('Rate limiter reset', { tokens: this.tokens });\n }\n}\n\n/**\n * Creates a rate limiter with default settings suitable for MCP tools.\n *\n * Default configuration:\n * - Capacity: 100 tokens\n * - Refill rate: 10 tokens per second\n *\n * @param name - Optional name for the rate limiter\n * @param logger - Optional logger instance\n * @returns A configured RateLimiter instance\n */\nexport function createDefaultRateLimiter(name?: string, logger?: ILogger): RateLimiter {\n const config: RateLimiterConfig = {\n capacity: 100,\n refillRate: 10,\n refillIntervalMs: 1000,\n };\n if (name !== undefined) {\n (config as { name?: string }).name = name;\n }\n if (logger !== undefined) {\n (config as { logger?: ILogger }).logger = logger;\n }\n return new RateLimiter(config);\n}\n","/**\n * nexus-agents/mcp - Validation Middleware\n *\n * Input validation helper using Zod schemas.\n * All tool inputs must be validated at the boundary.\n *\n * (Source: MCP Protocol 2025-11-25, Zod Documentation)\n */\n\nimport type { ZodType } from 'zod';\n\nimport { type Result, ok, err, ValidationError, formatZodError } from '../../core/index.js';\n\n// Re-export isZodError for backward compatibility\nexport { isZodError } from '../../core/index.js';\n\n/**\n * Validates tool input against a Zod schema.\n *\n * This function should be called at the start of every tool handler\n * to validate incoming arguments before processing.\n *\n * @template T - The expected type after validation\n * @param schema - The Zod schema to validate against\n * @param args - The unknown input to validate\n * @returns Result containing validated data or a ValidationError\n *\n * @example\n * ```typescript\n * const InputSchema = z.object({\n * task: z.string().min(1),\n * context: z.record(z.string(), z.unknown()).optional(),\n * });\n *\n * server.tool('my_tool', InputSchema.shape, async (args) => {\n * const result = validateToolInput(InputSchema, args);\n * if (!result.ok) {\n * return toolStructuredError({ errorCategory: 'validation', message: result.error.message });\n * }\n * const { task, context } = result.value;\n * // Process validated input...\n * });\n * ```\n */\nexport function validateToolInput<T>(\n schema: ZodType<T>,\n args: unknown\n): Result<T, ValidationError> {\n const parsed = schema.safeParse(args);\n\n if (parsed.success) {\n return ok(parsed.data);\n }\n\n const message = formatZodError(parsed.error);\n const validationError = new ValidationError(`Invalid tool input: ${message}`, {\n context: {\n issues: parsed.error.issues,\n receivedType: typeof args,\n },\n });\n\n return err(validationError);\n}\n\n/**\n * Creates a validation function bound to a specific schema.\n *\n * Useful for reusing the same schema across multiple tools.\n *\n * @template T - The expected type after validation\n * @param schema - The Zod schema to bind\n * @returns A validation function for the schema\n *\n * @example\n * ```typescript\n * const validateTask = createValidator(TaskSchema);\n *\n * // Later in tool handlers:\n * const result = validateTask(args);\n * ```\n */\nexport function createValidator<T>(\n schema: ZodType<T>\n): (args: unknown) => Result<T, ValidationError> {\n return (args: unknown) => validateToolInput(schema, args);\n}\n\n// `validateToolOutput` and `createOutputValidator` (Issue #547 sibling of\n// `validateToolInput` / `createValidator`) removed in #3022 — no MCP tool\n// ever called the output-validation path; every tool returns its result\n// without schema-validating first. If output validation comes back as a\n// real requirement, reintroduce alongside the per-tool wiring in the same\n// PR (activate-or-delete YAGNI — #2937, #2938, #2939, #2940, #3018, #3022).\n","/**\n * nexus-agents/mcp - Policy Firewall Types\n *\n * Type definitions for the authorization layer of MCP tool calls.\n *\n * (Source: OWASP ASVS 4.0, Authorization Controls)\n */\n\nimport { z } from 'zod';\n\nimport { SecurityError, type ILogger } from '../../core/index.js';\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Artifact type for policy context.\n * Artifacts are resources that can be referenced in policy decisions.\n */\nexport interface Artifact<T = unknown> {\n readonly id: string;\n readonly type: string;\n readonly value: T;\n readonly createdAt: Date;\n}\n\n/**\n * Execution mode for tool operations.\n * - 'read-only': Only read operations allowed (default)\n * - 'read-write': Both read and write operations allowed\n */\nexport type ExecutionMode = 'read-only' | 'read-write';\n\n/**\n * Policy enforcement mode.\n * - 'enforce': Block denied operations\n * - 'warn': Log denials but allow execution (for migration)\n */\nexport type PolicyMode = 'enforce' | 'warn';\n\n/**\n * Result of a policy evaluation.\n */\nexport interface PolicyDecision {\n readonly allowed: boolean;\n readonly reason: string;\n readonly requiredArtifact?: string;\n readonly ruleName?: string;\n}\n\n/**\n * Context provided to policy rules for evaluation.\n */\nexport interface PolicyContext {\n readonly toolName: string;\n readonly args: unknown;\n readonly mode: ExecutionMode;\n readonly artifacts?: Map<string, Artifact>;\n readonly workflowId?: string;\n readonly allowedPaths?: readonly string[];\n}\n\n/**\n * A single policy rule that can approve or deny operations.\n */\nexport interface PolicyRule {\n readonly name: string;\n readonly description: string;\n check(ctx: PolicyContext): PolicyDecision;\n}\n\n/**\n * Interface for the policy firewall.\n */\nexport interface IPolicyFirewall {\n evaluate(ctx: PolicyContext): PolicyDecision;\n addRule(rule: PolicyRule): void;\n removeRule(name: string): boolean;\n getRules(): readonly PolicyRule[];\n setMode(mode: PolicyMode): void;\n getMode(): PolicyMode;\n}\n\n/**\n * Configuration for the policy firewall.\n */\nexport interface PolicyFirewallConfig {\n /** Enforcement mode (default: 'enforce') */\n readonly mode?: PolicyMode;\n /** Logger instance */\n readonly logger?: ILogger;\n /** Initial rules to register */\n readonly rules?: readonly PolicyRule[];\n}\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Policy error for authorization failures.\n */\nexport class PolicyError extends SecurityError {\n readonly decision: PolicyDecision;\n\n constructor(message: string, decision: PolicyDecision) {\n super(message, {\n context: {\n allowed: decision.allowed,\n reason: decision.reason,\n ruleName: decision.ruleName,\n requiredArtifact: decision.requiredArtifact,\n },\n });\n this.name = 'PolicyError';\n this.decision = decision;\n }\n}\n\n// =============================================================================\n// Zod Schemas for Configuration\n// =============================================================================\n\n/**\n * Schema for policy configuration.\n */\nexport const PolicyConfigSchema = z.object({\n defaultMode: z.enum(['read-only', 'read-write']).default('read-only'),\n policyMode: z.enum(['enforce', 'warn']).default('enforce'),\n allowedPaths: z.array(z.string()).default(['./']),\n});\n\nexport type PolicyConfig = z.infer<typeof PolicyConfigSchema>;\n","/**\n * nexus-agents/mcp - Policy Firewall Helpers\n *\n * Utility functions for path validation and argument extraction.\n *\n * (Source: OWASP ASVS 4.0, Authorization Controls)\n */\n\n// =============================================================================\n// Path Utility Functions\n// =============================================================================\n\n/**\n * Validates a path against allowed roots.\n *\n * @param targetPath - The path to validate\n * @param allowedPaths - Array of allowed root paths\n * @returns True if the path is within an allowed root\n */\nexport function isPathSafe(targetPath: string, allowedPaths: readonly string[]): boolean {\n // Normalize the target path\n const normalizedTarget = normalizePath(targetPath);\n\n // Check if any allowed path is a prefix of the target\n for (const allowed of allowedPaths) {\n const normalizedAllowed = normalizePath(allowed);\n if (normalizedTarget.startsWith(normalizedAllowed)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Normalizes a path by removing trailing slashes and handling relative paths.\n */\nexport function normalizePath(p: string): string {\n // Remove trailing slashes\n let normalized = p.replace(/\\/{1,100}$/, '');\n\n // Handle relative paths\n if (normalized === '.') {\n normalized = '';\n } else if (normalized.startsWith('./')) {\n normalized = normalized.slice(2);\n }\n\n // Ensure absolute-like comparison\n if (!normalized.startsWith('/')) {\n normalized = '/' + normalized;\n }\n\n return normalized;\n}\n\n/**\n * Extracts path from tool arguments if present.\n */\nexport function extractPathFromArgs(args: unknown): string | undefined {\n if (args === null || typeof args !== 'object') {\n return undefined;\n }\n\n const argsObj = args as Record<string, unknown>;\n\n // Common path field names\n const pathFields = ['path', 'filePath', 'file_path', 'directory', 'dir', 'target'];\n\n for (const field of pathFields) {\n const value = argsObj[field];\n if (typeof value === 'string') {\n return value;\n }\n }\n\n return undefined;\n}\n","/**\n * nexus-agents/mcp - Policy Firewall Rules\n *\n * Default policy rules and constants for the authorization layer.\n *\n * (Source: OWASP ASVS 4.0, Authorization Controls)\n */\n\nimport type { PolicyContext, PolicyDecision, PolicyRule } from './policy-types.js';\nimport { isPathSafe, extractPathFromArgs } from './policy-helpers.js';\n\n// =============================================================================\n// Tool Classification Constants\n// =============================================================================\n\n/**\n * Tools that are considered write/mutation operations.\n */\nexport const MUTATION_TOOLS = new Set([\n 'write_file',\n 'edit_file',\n 'delete_file',\n 'create_directory',\n 'remove_directory',\n 'execute_command',\n 'run_shell',\n 'bash',\n 'create_expert',\n 'run_workflow',\n]);\n\n/**\n * Tools that are considered read-only operations.\n */\nexport const READ_ONLY_TOOLS = new Set([\n 'read_file',\n 'list_directory',\n 'search_files',\n 'get_status',\n 'orchestrate',\n 'delegate_to_model',\n]);\n\n// =============================================================================\n// Tool Classification Functions\n// =============================================================================\n\n/**\n * Checks if a tool is a mutation operation.\n */\nexport function isMutationTool(toolName: string): boolean {\n // Check explicit mutation tools\n if (MUTATION_TOOLS.has(toolName)) {\n return true;\n }\n\n // Check explicit read-only tools\n if (READ_ONLY_TOOLS.has(toolName)) {\n return false;\n }\n\n // Default to treating unknown tools as mutations (safe default)\n return true;\n}\n\n// =============================================================================\n// Default Policy Rules\n// =============================================================================\n\n/**\n * Policy rule that denies mutation operations when mode is 'read-only'.\n *\n * This ensures that write operations are only allowed when explicitly\n * enabled via the 'read-write' mode.\n */\nexport const denyMutationsWithoutModeRule: PolicyRule = {\n name: 'deny-mutations-without-mode',\n description: 'Blocks write operations unless mode is read-write',\n check(ctx: PolicyContext): PolicyDecision {\n // If mode is read-write, allow all operations\n if (ctx.mode === 'read-write') {\n return { allowed: true, reason: 'Read-write mode enabled' };\n }\n\n // Check if this is a mutation tool\n if (isMutationTool(ctx.toolName)) {\n return {\n allowed: false,\n reason: `Tool '${ctx.toolName}' is a mutation operation but mode is '${ctx.mode}'. Set mode to 'read-write' to enable.`,\n };\n }\n\n // Read-only tool in read-only mode is allowed\n return { allowed: true, reason: 'Read-only operation allowed' };\n },\n};\n\n/**\n * Policy rule that validates paths against allowed roots.\n *\n * Prevents path traversal attacks by ensuring all file operations\n * target paths within configured allowed directories.\n */\nexport const safePathsRule: PolicyRule = {\n name: 'safe-paths',\n description: 'Validates paths against allowed root directories',\n check(ctx: PolicyContext): PolicyDecision {\n // Extract path from arguments\n const targetPath = extractPathFromArgs(ctx.args);\n\n // If no path in args, allow (not a file operation)\n if (targetPath === undefined) {\n return { allowed: true, reason: 'No path argument found' };\n }\n\n // Check for obvious path traversal attempts\n if (targetPath.includes('..')) {\n return {\n allowed: false,\n reason: `Path contains '..' which may indicate path traversal: ${targetPath}`,\n };\n }\n\n // Get allowed paths from context or use default\n const allowedPaths = ctx.allowedPaths ?? ['./'];\n\n // Validate path is within allowed roots\n if (!isPathSafe(targetPath, allowedPaths)) {\n return {\n allowed: false,\n reason: `Path '${targetPath}' is outside allowed directories: ${allowedPaths.join(', ')}`,\n };\n }\n\n return { allowed: true, reason: 'Path is within allowed directories' };\n },\n};\n","/**\n * nexus-agents/mcp - Policy Firewall Middleware\n *\n * Authorization layer for MCP tool calls. Evaluates policy rules\n * to determine whether operations should be allowed or denied.\n *\n * This is separate from validation - validation checks if input is well-formed,\n * policy checks if the operation is authorized.\n *\n * (Source: OWASP ASVS 4.0, Authorization Controls)\n */\n\nimport { createLogger, type ILogger, type Result, ok, err } from '../../core/index.js';\n\nimport type {\n Artifact,\n ExecutionMode,\n PolicyMode,\n PolicyDecision,\n PolicyContext,\n PolicyRule,\n IPolicyFirewall,\n PolicyFirewallConfig,\n} from './policy-types.js';\nimport { PolicyError } from './policy-types.js';\nimport { denyMutationsWithoutModeRule, safePathsRule } from './policy-rules.js';\n\n// =============================================================================\n// PolicyFirewall Implementation\n// =============================================================================\n\n/**\n * Policy firewall that evaluates rules to authorize or deny operations.\n *\n * Rules are evaluated in order. The first rule that denies the operation\n * stops evaluation and returns the denial. If all rules pass, the operation\n * is allowed.\n *\n * @example\n * ```typescript\n * const firewall = new PolicyFirewall({ mode: 'enforce' });\n *\n * // Add rules\n * firewall.addRule(denyMutationsWithoutModeRule);\n * firewall.addRule(safePathsRule);\n *\n * // Evaluate\n * const decision = firewall.evaluate({\n * toolName: 'write_file',\n * args: { path: '/etc/passwd' },\n * mode: 'read-only',\n * });\n *\n * if (!decision.allowed) {\n * console.error(`Denied: ${decision.reason}`);\n * }\n * ```\n */\nexport class PolicyFirewall implements IPolicyFirewall {\n private readonly rules: PolicyRule[] = [];\n private mode: PolicyMode;\n private readonly logger: ILogger;\n\n constructor(config?: PolicyFirewallConfig) {\n this.mode = config?.mode ?? 'enforce';\n this.logger = config?.logger ?? createLogger({ component: 'policy-firewall' });\n\n // Register initial rules if provided\n if (config?.rules) {\n for (const rule of config.rules) {\n this.rules.push(rule);\n }\n }\n\n this.logger.debug('Policy firewall initialized', {\n mode: this.mode,\n ruleCount: this.rules.length,\n });\n }\n\n /**\n * Evaluates all policy rules against the given context.\n *\n * Rules are evaluated in order. The first rule that denies stops\n * evaluation and returns the denial decision.\n *\n * @param ctx - The policy context to evaluate\n * @returns The policy decision\n */\n evaluate(ctx: PolicyContext): PolicyDecision {\n this.logger.debug('Evaluating policy', {\n toolName: ctx.toolName,\n mode: ctx.mode,\n ruleCount: this.rules.length,\n });\n\n // If no rules, allow by default\n if (this.rules.length === 0) {\n return this.allowWithReason(ctx, 'No policy rules configured');\n }\n\n // Evaluate each rule in order\n for (const rule of this.rules) {\n const decision = rule.check(ctx);\n\n if (!decision.allowed) {\n return this.handleDenial(ctx, rule, decision);\n }\n }\n\n // All rules passed\n return this.allowWithReason(ctx, 'All policy rules passed');\n }\n\n /**\n * Creates an allow decision with the given reason and logs it.\n */\n private allowWithReason(ctx: PolicyContext, reason: string): PolicyDecision {\n const decision: PolicyDecision = { allowed: true, reason };\n this.logDecision(ctx, decision);\n return decision;\n }\n\n /**\n * Handles a rule denial, respecting warn mode if configured.\n */\n private handleDenial(\n ctx: PolicyContext,\n rule: PolicyRule,\n decision: PolicyDecision\n ): PolicyDecision {\n const denialDecision: PolicyDecision = {\n ...decision,\n ruleName: rule.name,\n };\n\n this.logDecision(ctx, denialDecision);\n\n // In warn mode, log but still allow\n if (this.mode === 'warn') {\n this.logger.warn('Policy denial overridden by warn mode', {\n toolName: ctx.toolName,\n ruleName: rule.name,\n reason: decision.reason,\n });\n return {\n allowed: true,\n reason: `[WARN MODE] Would be denied: ${decision.reason}`,\n ruleName: rule.name,\n };\n }\n\n return denialDecision;\n }\n\n /**\n * Adds a policy rule to the firewall.\n *\n * @param rule - The rule to add\n */\n addRule(rule: PolicyRule): void {\n // Prevent duplicate rules\n const existingIndex = this.rules.findIndex((r) => r.name === rule.name);\n if (existingIndex >= 0) {\n this.logger.warn('Replacing existing policy rule', { ruleName: rule.name });\n this.rules[existingIndex] = rule;\n } else {\n this.rules.push(rule);\n this.logger.debug('Policy rule added', { ruleName: rule.name });\n }\n }\n\n /**\n * Removes a policy rule by name.\n *\n * @param name - The name of the rule to remove\n * @returns True if the rule was found and removed\n */\n removeRule(name: string): boolean {\n const index = this.rules.findIndex((r) => r.name === name);\n if (index >= 0) {\n this.rules.splice(index, 1);\n this.logger.debug('Policy rule removed', { ruleName: name });\n return true;\n }\n return false;\n }\n\n /**\n * Gets all registered policy rules.\n *\n * @returns A readonly array of policy rules\n */\n getRules(): readonly PolicyRule[] {\n return [...this.rules];\n }\n\n /**\n * Sets the policy enforcement mode.\n *\n * @param mode - The new enforcement mode\n */\n setMode(mode: PolicyMode): void {\n const previousMode = this.mode;\n this.mode = mode;\n this.logger.info('Policy mode changed', { from: previousMode, to: mode });\n }\n\n /**\n * Gets the current policy enforcement mode.\n *\n * @returns The current mode\n */\n getMode(): PolicyMode {\n return this.mode;\n }\n\n /**\n * Logs a policy decision for audit purposes.\n */\n private logDecision(ctx: PolicyContext, decision: PolicyDecision): void {\n const logData = {\n toolName: ctx.toolName,\n mode: ctx.mode,\n workflowId: ctx.workflowId,\n allowed: decision.allowed,\n reason: decision.reason,\n ruleName: decision.ruleName,\n };\n\n if (decision.allowed) {\n this.logger.debug('Policy decision: ALLOWED', logData);\n } else {\n this.logger.warn('Policy decision: DENIED', logData);\n }\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates a policy firewall with default rules.\n *\n * Default rules included:\n * - deny-mutations-without-mode\n * - safe-paths\n *\n * @param config - Optional configuration\n * @returns A configured PolicyFirewall instance\n */\nexport function createDefaultPolicyFirewall(config?: PolicyFirewallConfig): PolicyFirewall {\n const firewall = new PolicyFirewall(config);\n\n // Add default rules\n firewall.addRule(denyMutationsWithoutModeRule);\n firewall.addRule(safePathsRule);\n\n return firewall;\n}\n\n/**\n * Evaluates a policy context and returns a Result.\n *\n * This is a convenience function that wraps the firewall evaluation\n * in a Result type for easier error handling.\n *\n * @param firewall - The policy firewall to use\n * @param ctx - The policy context to evaluate\n * @returns Result containing void on success or PolicyError on denial\n */\nexport function evaluatePolicy(\n firewall: IPolicyFirewall,\n ctx: PolicyContext\n): Result<void, PolicyError> {\n const decision = firewall.evaluate(ctx);\n\n if (decision.allowed) {\n return ok(undefined);\n }\n\n return err(new PolicyError(`Policy denied: ${decision.reason}`, decision));\n}\n\n/**\n * Creates a policy context from tool invocation parameters.\n *\n * @param toolName - Name of the tool being invoked\n * @param args - Tool arguments\n * @param options - Additional context options\n * @returns A PolicyContext object\n */\nexport function createPolicyContext(\n toolName: string,\n args: unknown,\n options?: {\n mode?: ExecutionMode;\n artifacts?: Map<string, Artifact>;\n workflowId?: string;\n allowedPaths?: readonly string[];\n }\n): PolicyContext {\n // Build base context with required properties\n const base = {\n toolName,\n args,\n mode: options?.mode ?? 'read-only',\n };\n\n // Use Object.assign to build result, only adding optional properties\n // when they are actually defined (to satisfy exactOptionalPropertyTypes)\n const result: Record<string, unknown> = { ...base };\n\n if (options?.artifacts !== undefined) {\n result['artifacts'] = options.artifacts;\n }\n if (options?.workflowId !== undefined) {\n result['workflowId'] = options.workflowId;\n }\n if (options?.allowedPaths !== undefined) {\n result['allowedPaths'] = options.allowedPaths;\n }\n\n return result as unknown as PolicyContext;\n}\n\n// =============================================================================\n// Re-exports for backward compatibility\n// =============================================================================\n\nexport * from './policy-types.js';\nexport * from './policy-rules.js';\nexport * from './policy-helpers.js';\n","/**\n * nexus-agents/mcp - Timeout Guard Middleware\n *\n * Provides timeout protection for MCP operations to mitigate ReDoS and\n * other denial-of-service vectors. Implements configurable timeouts with\n * proper cleanup and error handling.\n *\n * (Source: CVE-2026-0621, GHSA-8r9q-7v3j-jr4g)\n * (Source: Issue #107)\n *\n * @module mcp/middleware/timeout-guard\n */\n\nimport {\n getErrorMessage,\n createLogger,\n type ILogger,\n type Result,\n ok,\n err,\n getTimeProvider,\n} from '../../core/index.js';\n\n/**\n * Error codes for timeout-related failures.\n */\nexport type TimeoutErrorCode =\n | 'OPERATION_TIMEOUT'\n | 'OPERATION_CANCELLED'\n | 'INVALID_TIMEOUT'\n | 'GUARD_ERROR';\n\n/**\n * Timeout guard error.\n */\nexport interface TimeoutError {\n readonly code: TimeoutErrorCode;\n readonly message: string;\n readonly operation?: string;\n readonly timeoutMs?: number;\n readonly cause?: Error;\n}\n\n/**\n * Configuration for timeout guard.\n */\nexport interface TimeoutGuardConfig {\n /** Default timeout in milliseconds (default: 30000) */\n readonly defaultTimeoutMs?: number;\n /** Maximum allowed timeout in milliseconds (default: 300000) */\n readonly maxTimeoutMs?: number;\n /** Whether to log timeout events (default: true) */\n readonly enableLogging?: boolean;\n /** Logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Result of a guarded operation.\n */\nexport interface GuardedResult<T> {\n /** The operation result */\n readonly value: T;\n /** Execution duration in milliseconds */\n readonly durationMs: number;\n /** Whether the operation was near timeout */\n readonly nearTimeout: boolean;\n}\n\n/** Execution options for guarded operations. */\nexport interface ExecuteOptions {\n /** Custom timeout for this operation */\n readonly timeoutMs?: number;\n /** Name for logging/debugging */\n readonly operationName?: string;\n /** Cleanup function to call on timeout */\n readonly onTimeout?: () => void;\n /** AbortSignal for client-initiated cancellation */\n readonly signal?: AbortSignal;\n}\n\n// Canonical source: config/timeouts.ts (Issue #1046)\nimport { TIMEOUT_GUARD } from '../../config/timeouts.js';\n\nconst DEFAULT_TIMEOUT_MS = TIMEOUT_GUARD.defaultMs;\nconst MAX_TIMEOUT_MS = TIMEOUT_GUARD.maxMs;\nconst NEAR_TIMEOUT_THRESHOLD = TIMEOUT_GUARD.nearTimeoutThreshold;\n\n/** Internal state for tracking timeout. */\ninterface TimeoutState {\n timeoutId: ReturnType<typeof setTimeout> | undefined;\n timedOut: boolean;\n}\n\n/**\n * Creates a timeout error for operation timeout.\n */\nfunction createTimeoutError(operationName: string, timeoutMs: number): TimeoutError {\n return {\n code: 'OPERATION_TIMEOUT',\n message: `Operation '${operationName}' timed out after ${String(timeoutMs)}ms`,\n operation: operationName,\n timeoutMs,\n };\n}\n\n/**\n * Creates a guard error from a caught exception.\n */\nfunction createGuardError(error: unknown, operationName: string): TimeoutError {\n const guardError: TimeoutError = {\n code: 'GUARD_ERROR',\n message: getErrorMessage(error),\n operation: operationName,\n };\n if (error instanceof Error) {\n return { ...guardError, cause: error };\n }\n return guardError;\n}\n\n/**\n * Timeout guard for protecting async operations from hanging.\n *\n * Provides protection against:\n * - ReDoS attacks (CVE-2026-0621)\n * - Slow/hanging external services\n * - Resource exhaustion\n *\n * @example\n * ```typescript\n * const guard = new TimeoutGuard({ defaultTimeoutMs: 5000 });\n *\n * const result = await guard.execute(\n * () => someAsyncOperation(),\n * { operationName: 'process-uri' }\n * );\n *\n * if (result.ok) {\n * console.log('Completed in', result.value.durationMs, 'ms');\n * }\n * ```\n */\nexport class TimeoutGuard {\n private readonly defaultTimeoutMs: number;\n private readonly maxTimeoutMs: number;\n private readonly enableLogging: boolean;\n private readonly logger: ILogger;\n\n constructor(config?: TimeoutGuardConfig) {\n this.defaultTimeoutMs = config?.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.maxTimeoutMs = config?.maxTimeoutMs ?? MAX_TIMEOUT_MS;\n this.enableLogging = config?.enableLogging ?? true;\n this.logger = config?.logger ?? createLogger({ component: 'timeout-guard' });\n }\n\n /** Resolves effective timeout and operation name from options. */\n private resolveOptions(options?: ExecuteOptions): {\n timeoutMs: number;\n operationName: string;\n } {\n return {\n timeoutMs: Math.min(options?.timeoutMs ?? this.defaultTimeoutMs, this.maxTimeoutMs),\n operationName: options?.operationName ?? 'unknown',\n };\n }\n\n /**\n * Executes an async operation with timeout protection.\n */\n async execute<T>(\n operation: () => Promise<T>,\n options?: ExecuteOptions\n ): Promise<Result<GuardedResult<T>, TimeoutError>> {\n const { timeoutMs, operationName } = this.resolveOptions(options);\n\n const validationError = this.validateTimeout(timeoutMs, operationName);\n if (validationError !== null) {\n return err(validationError);\n }\n\n return this.runGuarded(operation, timeoutMs, operationName, options);\n }\n\n /** Runs the operation with timeout and optional abort signal. */\n private async runGuarded<T>(\n operation: () => Promise<T>,\n timeoutMs: number,\n operationName: string,\n options?: ExecuteOptions\n ): Promise<Result<GuardedResult<T>, TimeoutError>> {\n this.logStart(operationName, timeoutMs);\n const startTime = getTimeProvider().now();\n const state: TimeoutState = { timeoutId: undefined, timedOut: false };\n\n try {\n const result = await this.runWithTimeout(\n operation,\n timeoutMs,\n state,\n options?.onTimeout,\n options?.signal\n );\n return this.handleSuccess(result, startTime, timeoutMs, operationName);\n } catch {\n const cancelled = options?.signal?.aborted === true && !state.timedOut;\n return err(\n this.handleFailure(state.timedOut, operationName, timeoutMs, startTime, cancelled)\n );\n } finally {\n if (state.timeoutId !== undefined) {\n clearTimeout(state.timeoutId);\n }\n }\n }\n\n private validateTimeout(timeoutMs: number, operationName: string): TimeoutError | null {\n if (timeoutMs <= 0) {\n return {\n code: 'INVALID_TIMEOUT',\n message: `Invalid timeout: ${String(timeoutMs)}ms`,\n operation: operationName,\n };\n }\n return null;\n }\n\n private logStart(operationName: string, timeoutMs: number): void {\n if (this.enableLogging) {\n this.logger.debug('Starting guarded operation', { operation: operationName, timeoutMs });\n }\n }\n\n private async runWithTimeout<T>(\n operation: () => Promise<T>,\n timeoutMs: number,\n state: TimeoutState,\n onTimeout?: () => void,\n signal?: AbortSignal\n ): Promise<T> {\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n state.timeoutId = setTimeout(() => {\n state.timedOut = true;\n onTimeout?.();\n reject(new Error(`Operation timed out after ${String(timeoutMs)}ms`));\n }, timeoutMs);\n });\n\n const promises: Array<Promise<T>> = [operation(), timeoutPromise];\n\n // Race against client AbortSignal if provided\n if (signal !== undefined && !signal.aborted) {\n const abortPromise = new Promise<never>((_resolve, reject) => {\n signal.addEventListener(\n 'abort',\n () => {\n reject(new Error('Operation cancelled by client'));\n },\n { once: true }\n );\n });\n promises.push(abortPromise);\n }\n\n return Promise.race(promises);\n }\n\n private handleSuccess<T>(\n result: T,\n startTime: number,\n timeoutMs: number,\n operationName: string\n ): Result<GuardedResult<T>, TimeoutError> {\n const durationMs = getTimeProvider().now() - startTime;\n const nearTimeout = durationMs > timeoutMs * NEAR_TIMEOUT_THRESHOLD;\n\n if (nearTimeout && this.enableLogging) {\n this.logger.warn('Operation completed near timeout threshold', {\n operation: operationName,\n durationMs,\n timeoutMs,\n thresholdPercent: Math.round((durationMs / timeoutMs) * 100),\n });\n }\n\n if (this.enableLogging) {\n this.logger.debug('Guarded operation completed', { operation: operationName, durationMs });\n }\n\n return ok({ value: result, durationMs, nearTimeout });\n }\n\n private handleFailure(\n timedOut: boolean,\n operationName: string,\n timeoutMs: number,\n startTime: number,\n cancelled = false\n ): TimeoutError {\n const durationMs = getTimeProvider().now() - startTime;\n\n if (cancelled) {\n this.logger.info('Operation cancelled by client', {\n operation: operationName,\n durationMs,\n });\n return {\n code: 'OPERATION_CANCELLED',\n message: `Operation '${operationName}' cancelled by client`,\n operation: operationName,\n };\n }\n\n if (timedOut) {\n this.logger.error('Operation timed out', undefined, {\n operation: operationName,\n timeoutMs,\n durationMs,\n });\n return createTimeoutError(operationName, timeoutMs);\n }\n\n return createGuardError(new Error('Unknown error'), operationName);\n }\n\n /**\n * Creates a guarded version of an async function.\n */\n guard<TArgs extends unknown[], TResult>(\n fn: (...args: TArgs) => Promise<TResult>,\n options?: { readonly timeoutMs?: number; readonly operationName?: string }\n ): (...args: TArgs) => Promise<Result<GuardedResult<TResult>, TimeoutError>> {\n return async (...args: TArgs): Promise<Result<GuardedResult<TResult>, TimeoutError>> => {\n return this.execute(() => fn(...args), options);\n };\n }\n}\n\n/**\n * URI validation utilities to complement timeout protection.\n */\nexport const UriValidation = {\n MAX_URI_LENGTH: 8192,\n MAX_TEMPLATE_DEPTH: 3,\n SUSPICIOUS_PATTERN: /\\{[+#./;?&]?[^}]*\\*\\}.*\\{[+#./;?&]?[^}]*\\*\\}|\\{(?:[^{}]*\\{){3,}/,\n\n validate(uri: string): Result<string, TimeoutError> {\n if (uri.length > this.MAX_URI_LENGTH) {\n return err({\n code: 'GUARD_ERROR',\n message: `URI exceeds maximum length: ${String(uri.length)} > ${String(this.MAX_URI_LENGTH)}`,\n operation: 'uri-validation',\n });\n }\n\n if (this.SUSPICIOUS_PATTERN.test(uri)) {\n return err({\n code: 'GUARD_ERROR',\n message: 'URI contains suspicious patterns that may cause performance issues',\n operation: 'uri-validation',\n });\n }\n\n return ok(uri);\n },\n\n sanitize(uri: string): string {\n const sanitized = uri.slice(0, this.MAX_URI_LENGTH);\n let depth = 0;\n let result = '';\n\n for (const char of sanitized) {\n if (char === '{') {\n depth++;\n if (depth > this.MAX_TEMPLATE_DEPTH) continue;\n } else if (char === '}') {\n if (depth > this.MAX_TEMPLATE_DEPTH) {\n depth--;\n continue;\n }\n depth--;\n }\n result += char;\n }\n\n return result;\n },\n};\n\n/**\n * Creates a timeout guard with default MCP-appropriate settings.\n */\nexport function createDefaultTimeoutGuard(logger?: ILogger): TimeoutGuard {\n const config: TimeoutGuardConfig = {\n defaultTimeoutMs: DEFAULT_TIMEOUT_MS,\n maxTimeoutMs: MAX_TIMEOUT_MS,\n enableLogging: true,\n };\n if (logger !== undefined) {\n return new TimeoutGuard({ ...config, logger });\n }\n return new TimeoutGuard(config);\n}\n","/**\n * nexus-agents/mcp - Request Context Middleware\n *\n * Provides request ID generation and caller context tracking for MCP tools.\n * (Source: Issue #185 Phase 1 - Request context & PolicyFirewall integration)\n *\n * @module mcp/middleware/request-context\n */\n\nimport { randomBytes } from 'node:crypto';\nimport { getTimeProvider } from '../../core/index.js';\nimport type { TrustTier } from '../../security/trust-types.js';\n\n/**\n * Authenticated user information.\n * (Source: Issue #739 - MCP authentication)\n */\nexport interface AuthenticatedUser {\n /** Unique user/client identifier */\n readonly id: string;\n /** Human-readable name (optional) */\n readonly name?: string;\n /** Granted permissions/scopes (optional) */\n readonly permissions?: readonly string[];\n}\n\n/**\n * Caller identification for audit trails.\n */\nexport interface CallerInfo {\n /** Client identifier (e.g., 'claude-cli', 'gemini-cli') */\n readonly clientId?: string;\n /** User agent string if available */\n readonly userAgent?: string;\n /** Session ID for request correlation */\n readonly sessionId?: string;\n /** IP address or transport identifier */\n readonly transport?: string;\n /** Whether the request is authenticated (Issue #739) */\n readonly authenticated?: boolean;\n /** Authenticated user information (Issue #739) */\n readonly authenticatedUser?: AuthenticatedUser;\n}\n\n/**\n * Request context for MCP tool invocations.\n * Immutable once created.\n */\nexport interface RequestContext {\n /** Unique request identifier (format: req_<16 hex chars>) */\n readonly requestId: string;\n /** Timestamp when request was received (ISO 8601, ET) */\n readonly timestamp: string;\n /** Tool being invoked */\n readonly toolName: string;\n /** Caller information for audit */\n readonly caller: CallerInfo;\n /**\n * Trust tier for this request (Issue #828).\n * Derived from caller authentication state:\n * - '1' = Authenticated + known client, or stdio (local-only)\n * - '2' = Authenticated via network\n * - '3' = Unauthenticated network request\n * - '4' = Request with detected injection patterns (set by sanitizer)\n */\n readonly trustTier: TrustTier;\n /** Trace ID for distributed tracing correlation */\n readonly traceId?: string;\n /** Parent span ID if part of a larger trace */\n readonly parentSpanId?: string;\n}\n\n/**\n * Options for creating a request context.\n */\nexport interface CreateContextOptions {\n /** Tool name being invoked */\n toolName: string;\n /** Optional caller information */\n caller?: CallerInfo;\n /** Optional explicit trust tier override (defaults to derived from caller) */\n trustTier?: TrustTier;\n /** Optional trace ID for correlation */\n traceId?: string;\n /** Optional parent span ID */\n parentSpanId?: string;\n}\n\n/**\n * Generates a cryptographically secure request ID.\n * Format: req_<16 hex characters>\n *\n * @returns Unique request identifier\n */\nexport function generateRequestId(): string {\n const bytes = randomBytes(8);\n return `req_${bytes.toString('hex')}`;\n}\n\n/**\n * Generates a session ID for request correlation.\n * Format: sess_<12 hex characters>\n *\n * @returns Unique session identifier\n */\nexport function generateSessionId(): string {\n const bytes = randomBytes(6);\n return `sess_${bytes.toString('hex')}`;\n}\n\n/**\n * Formats timestamp in ISO 8601 format with ET timezone.\n * (Source: CLAUDE.md - Time Authority section)\n */\nfunction formatTimestamp(): string {\n const now = new Date(getTimeProvider().now());\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: 'America/New_York',\n timeZoneName: 'shortOffset',\n });\n const parts = formatter.formatToParts(now);\n const offset = parts.find((p) => p.type === 'timeZoneName')?.value ?? '-05:00';\n const base = now.toLocaleString('sv-SE', {\n timeZone: 'America/New_York',\n hour12: false,\n });\n return base.replace(' ', 'T') + offset.replace('GMT', '');\n}\n\n/**\n * Derives trust tier from caller authentication state (Issue #828).\n *\n * - Authenticated + known CLI client (claude, gemini, codex) → Tier 1\n * - stdio transport (local-only, no network) → Tier 1\n * - Authenticated via network → Tier 2\n * - Unauthenticated → Tier 3\n */\nexport function deriveTrustTier(caller: CallerInfo): TrustTier {\n const knownClients = ['claude-cli', 'gemini-cli', 'codex-cli'];\n\n if (caller.transport === 'stdio') return '1';\n\n if (caller.authenticated === true) {\n if (caller.clientId !== undefined && knownClients.includes(caller.clientId)) {\n return '1';\n }\n return '2';\n }\n\n return '3';\n}\n\n/**\n * Creates an immutable request context for an MCP tool invocation.\n *\n * @param options - Context creation options\n * @returns Immutable request context\n */\nexport function createRequestContext(options: CreateContextOptions): RequestContext {\n const caller = options.caller ?? {};\n const context: RequestContext = {\n requestId: generateRequestId(),\n timestamp: formatTimestamp(),\n toolName: options.toolName,\n caller,\n trustTier: options.trustTier ?? deriveTrustTier(caller),\n ...(options.traceId !== undefined && { traceId: options.traceId }),\n ...(options.parentSpanId !== undefined && { parentSpanId: options.parentSpanId }),\n };\n\n // Freeze to ensure immutability\n return Object.freeze(context);\n}\n\n/**\n * Extracts caller info from MCP transport metadata.\n * Currently supports extracting from request headers or environment.\n *\n * @param metadata - Optional transport metadata\n * @returns Caller information\n */\nexport function extractCallerInfo(metadata?: Record<string, unknown>): CallerInfo {\n const caller: CallerInfo = {};\n\n if (metadata !== undefined) {\n // Extract all available fields from metadata\n const extracted: CallerInfo = {\n ...caller,\n ...(typeof metadata['clientId'] === 'string' ? { clientId: metadata['clientId'] } : {}),\n ...(typeof metadata['userAgent'] === 'string' ? { userAgent: metadata['userAgent'] } : {}),\n ...(typeof metadata['sessionId'] === 'string' ? { sessionId: metadata['sessionId'] } : {}),\n };\n\n // If any metadata was extracted, return it directly\n if (\n typeof metadata['clientId'] === 'string' ||\n typeof metadata['userAgent'] === 'string' ||\n typeof metadata['sessionId'] === 'string'\n ) {\n return extracted;\n }\n }\n\n // Fallback to environment variables for known CLI tools\n const claudeSession = process.env['CLAUDE_SESSION_ID'];\n if (claudeSession !== undefined) {\n return { ...caller, clientId: 'claude-cli', sessionId: claudeSession };\n }\n\n const geminiSession = process.env['GEMINI_SESSION_ID'];\n if (geminiSession !== undefined) {\n return { ...caller, clientId: 'gemini-cli', sessionId: geminiSession };\n }\n\n return caller;\n}\n\n/**\n * Formats request context for logging.\n * Extracts essential fields for log context.\n *\n * @param ctx - Request context\n * @returns Log-friendly context object\n */\nexport function contextForLogging(ctx: RequestContext): Record<string, unknown> {\n return {\n requestId: ctx.requestId,\n toolName: ctx.toolName,\n trustTier: ctx.trustTier,\n ...(ctx.caller.clientId !== undefined && { clientId: ctx.caller.clientId }),\n ...(ctx.traceId !== undefined && { traceId: ctx.traceId }),\n };\n}\n\n/**\n * Type guard to check if a value is a valid RequestContext.\n */\nexport function isRequestContext(value: unknown): value is RequestContext {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const obj = value as Record<string, unknown>;\n return (\n typeof obj['requestId'] === 'string' &&\n obj['requestId'].startsWith('req_') &&\n typeof obj['timestamp'] === 'string' &&\n typeof obj['toolName'] === 'string' &&\n typeof obj['caller'] === 'object' &&\n typeof obj['trustTier'] === 'string' &&\n ['1', '2', '3', '4'].includes(obj['trustTier'])\n );\n}\n","/**\n * Access Constraint Deriver — Unbypassable denylist (#1977 condition 3).\n *\n * Hardcoded patterns that no LLM-derived policy may override. Applied FIRST\n * in the enforcer, before checking the per-task policy. If the LLM (or a\n * malicious user objective) produces a policy that would allow access to\n * `.env`, SSH keys, cloud credentials, or similar, the denylist still wins.\n *\n * This exists because the LLM deriver is the weakest link — a user objective\n * that says \"I need to view my AWS credentials to debug\" would otherwise\n * produce a policy allowing `~/.aws/**`. The denylist refuses regardless.\n *\n * @module security/access-constraint-deriver/denylist\n */\n\n/**\n * File-path patterns that are unconditionally denied. Glob-style wildcards.\n * All matching is case-insensitive to catch `~/.SSH` and similar.\n */\nexport const UNBYPASSABLE_PATH_PATTERNS: readonly string[] = [\n // Environment files\n '.env',\n '.env.*',\n '**/.env',\n '**/.env.*',\n\n // SSH credentials\n '~/.ssh/**',\n '**/ssh/id_*',\n '**/*_rsa',\n '**/*_ed25519',\n '**/*.pem',\n\n // Cloud credentials\n '~/.aws/**',\n '~/.azure/**',\n '~/.gcp/**',\n '~/.config/gcloud/**',\n '~/.kube/config',\n\n // Unix secret files\n '/etc/shadow',\n '/etc/sudoers',\n '/etc/sudoers.d/**',\n\n // Common secret file patterns\n '**/secrets.*',\n '**/credentials.*',\n '**/private_key.*',\n '**/id_rsa*',\n];\n\n/**\n * Tool names that are unconditionally denied regardless of derived policy.\n * These are tools that should never be callable during automated agent\n * dispatch — they require explicit human action.\n */\nexport const UNBYPASSABLE_TOOL_NAMES: readonly string[] = [\n // Destructive git operations\n 'git_push_force',\n 'git_reset_hard',\n 'git_branch_delete_force',\n 'git_clean_force',\n\n // Destructive filesystem\n 'rm_recursive_force',\n 'chmod_recursive',\n\n // Identity / auth mutations\n 'ssh_add_key',\n 'gpg_add_key',\n 'npm_publish_force',\n\n // Remote destruction\n 'github_repo_delete',\n 'github_org_transfer',\n 'aws_account_close',\n];\n\n/**\n * Compiles a glob pattern to a regex at module-load time.\n * Supports: `**` (any path segments), `*` (any non-separator chars),\n * `~/` (home-anchor prefix). All other regex metachars escaped.\n *\n * Regexes built here come from the hardcoded `UNBYPASSABLE_PATH_PATTERNS`\n * constant — never from user input — so they are ReDoS-safe by construction.\n */\nfunction compileGlobToRegex(pattern: string): RegExp {\n const pat = pattern.toLowerCase();\n // Escape regex metacharacters INCLUDING backslash (per CodeQL — without\n // backslash in the class, a `\\` in input would leak into the regex output\n // unescaped). Do NOT escape `*` here — it's a glob wildcard that the\n // subsequent replaces expand into regex wildcards.\n const escaped = pat\n .replace(/[\\\\.+^$()|[\\]{}]/g, '\\\\$&')\n .replace(/\\*\\*/g, '__DOUBLESTAR__')\n .replace(/\\*/g, '[^/]*')\n .replace(/__DOUBLESTAR__/g, '.*');\n const anchored = escaped.startsWith('~/')\n ? `(^|/)${escaped.slice(2)}$`\n : escaped.startsWith('/')\n ? `^${escaped}$`\n : `(^|/)${escaped}$`;\n return new RegExp(anchored);\n}\n\n/**\n * Precompiled regexes for every unbypassable path pattern, computed once\n * at module load. Static inputs → no ReDoS surface.\n */\nconst COMPILED_PATH_PATTERNS: ReadonlyArray<{\n readonly pattern: string;\n readonly regex: RegExp;\n}> = UNBYPASSABLE_PATH_PATTERNS.map((pattern) => ({\n pattern,\n regex: compileGlobToRegex(pattern),\n}));\n\n/**\n * Returns true if a lowercased file path matches the given pattern.\n * Exported for tests; production code should use `isPathDenied`.\n */\nexport function matchDenyPattern(path: string, pattern: string): boolean {\n const normalized = path.toLowerCase();\n const compiled = COMPILED_PATH_PATTERNS.find((c) => c.pattern === pattern);\n if (compiled !== undefined) return compiled.regex.test(normalized);\n // Fallback for ad-hoc test patterns not in the static list.\n return compileGlobToRegex(pattern).test(normalized);\n}\n\n/** Returns true if the path hits any unbypassable pattern. */\nexport function isPathDenied(path: string): boolean {\n const normalized = path.toLowerCase();\n return COMPILED_PATH_PATTERNS.some((c) => c.regex.test(normalized));\n}\n\n/** Returns true if the tool name is unconditionally denied. */\nexport function isToolDenied(toolName: string): boolean {\n return UNBYPASSABLE_TOOL_NAMES.includes(toolName);\n}\n","/**\n * Tool risk classification for `confirm_risky` access-policy mode (#2279).\n *\n * Classifies each registered MCP tool as `read-only` (safe — log-and-allow\n * under confirm_risky) or `risky` (write/exec/network — block under\n * confirm_risky). Used by the policy enforcer to differentiate which\n * violations a human would have wanted to review.\n *\n * Classification policy:\n *\n * - **Read-only**: tool exclusively reads existing state — no file writes,\n * no subprocess execution, no network requests beyond a single bounded\n * read of project-internal data. `query_*`, `list_*`, `search_*`,\n * `*_query`, `*_analyze` patterns by default.\n * - **Risky**: tool writes files, runs subprocesses, posts to external\n * services, calls LLM APIs, or has any side effect that a human reviewer\n * would want to see before approving in confirm_risky mode.\n *\n * If a tool is unknown, it is treated as risky (default-deny) — same\n * principle as the unbypassable denylist: the security layer fails closed\n * on a misclassification.\n *\n * Update path: when adding a new MCP tool, classify it explicitly here.\n * The `inject-governance.ts check` CI gate ensures the registry list is\n * still the source of truth; this file is the risk overlay.\n *\n * @module security/access-constraint-deriver/tool-risk\n */\n\n/**\n * Tools that exclusively read state. Violations on these are log-and-allow\n * under `confirm_risky` mode — same as `audit` mode.\n */\nexport const READ_ONLY_TOOLS: ReadonlySet<string> = new Set([\n // Discovery / listing\n 'list_experts',\n 'list_workflows',\n // Research reads\n 'research_query',\n 'research_analyze',\n 'research_catalog_review',\n 'research_synthesize',\n // Memory reads\n 'memory_query',\n 'memory_stats',\n // Observability\n 'weather_report',\n 'query_trace',\n 'query_task_state',\n // Codebase intelligence (read-only over local files)\n 'search_codebase',\n 'extract_symbols',\n // Repo analysis (read-only)\n 'repo_analyze',\n 'repo_security_plan',\n // Routing recommendation (no side effects — returns recommendation)\n 'delegate_to_model',\n // Registry import (returns a draft template — does not write)\n 'registry_import',\n]);\n\n/**\n * Returns true if the tool is risky under confirm_risky mode (default-deny\n * for unknown tools — security layer fails closed).\n */\nexport function isRiskyTool(toolName: string): boolean {\n return !READ_ONLY_TOOLS.has(toolName);\n}\n","/**\n * Access Constraint Deriver — Policy enforcement (#1977, #2279).\n *\n * Pure function that checks a proposed tool call against a derived policy\n * and returns an AccessDecision. Enforcement depends on the policy's mode:\n * - `off` and `audit` never block\n * - `confirm_risky` (#2279) blocks violations on risky tools (write/exec/\n * network) and log-and-allows violations on read-only tools\n * - `enforce` blocks every violation regardless of risk classification\n *\n * @module security/access-constraint-deriver/enforcer\n */\n\nimport { isPathDenied, isToolDenied } from './denylist.js';\nimport { isRiskyTool } from './tool-risk.js';\nimport type { AccessDecision, TaskAccessPolicy } from './types.js';\n\n/**\n * Checks a proposed tool call against the unbypassable denylist AND the\n * task's derived access policy.\n *\n * Order of operations (important — the denylist is FIRST and unbypassable):\n * 1. If the tool is on the hardcoded deny-tool list → deny regardless\n * of policy. This is unbypassable even in `off` mode.\n * 2. If a file-path argument is provided and matches an unbypassable path\n * pattern (e.g. `~/.ssh/**`, `/etc/shadow`) → deny regardless.\n * 3. Otherwise, fall back to the per-task policy (bypass in skeleton).\n *\n * The denylist check runs before the policy check so a malicious LLM-derived\n * policy cannot grant access to secrets/credentials by listing the tool in\n * `allowedTools`.\n */\nexport function checkAccess(\n toolName: string,\n policy: TaskAccessPolicy,\n args?: { readonly path?: string }\n): AccessDecision {\n // 1. Unbypassable tool denylist — applies in all modes.\n if (isToolDenied(toolName)) {\n return {\n decision: 'deny',\n reason: `tool \"${toolName}\" is on the unbypassable deny-tool list`,\n matchedRule: 'unbypassable:tool',\n };\n }\n\n // 2. Unbypassable path denylist — applies when a path argument is given.\n if (typeof args?.path === 'string' && args.path.length > 0 && isPathDenied(args.path)) {\n return {\n decision: 'deny',\n reason: `path \"${args.path}\" is on the unbypassable deny-path list`,\n matchedRule: 'unbypassable:path',\n };\n }\n\n // 3. Per-task policy check.\n if (policy.allowedTools === '*') return { decision: 'allow' };\n\n if (policy.allowedTools.includes(toolName)) return { decision: 'allow' };\n\n return decideOnViolation(toolName, policy.mode);\n}\n\n/**\n * Mode-specific behavior when a tool is not in the per-task allowlist.\n * Extracted so checkAccess stays under the complexity-10 cap.\n */\nfunction decideOnViolation(toolName: string, mode: TaskAccessPolicy['mode']): AccessDecision {\n if (mode === 'audit') {\n return {\n decision: 'log-and-allow',\n warning: `tool \"${toolName}\" not in derived policy (audit mode)`,\n };\n }\n // confirm_risky: split by tool risk classification (#2279). Read-only\n // violations are log-and-allow (audit-like); risky violations are denied\n // with a structured reason that surfaces \"would-have-required-approval\"\n // semantics. Operators add the tool to the allowlist after review, or\n // graduate to `enforce` once the violation rate is acceptable.\n if (mode === 'confirm_risky') {\n if (!isRiskyTool(toolName)) {\n return {\n decision: 'log-and-allow',\n warning: `tool \"${toolName}\" not in derived policy (confirm_risky mode, read-only — would have required human approval, allowed because read-only)`,\n };\n }\n return {\n decision: 'deny',\n reason: `tool \"${toolName}\" not in derived policy (confirm_risky mode, risky — would have required human approval; denied for now, add to allowedTools or run in audit mode to allow)`,\n matchedRule: 'allowedTools:confirm_risky',\n };\n }\n return {\n decision: 'deny',\n reason: `tool \"${toolName}\" not in derived policy`,\n matchedRule: 'allowedTools',\n };\n}\n","/**\n * Access Constraint Deriver — MCP tool dispatch guard (#1977 final wiring).\n *\n * Per-call helper and middleware factory that plugs the access-constraint\n * enforcer into the MCP tool dispatch path. Runs AFTER policy derivation\n * (deriver.ts owns that) and BEFORE the tool handler executes.\n *\n * Behavior matrix:\n * - mode=off → no-op, allows every call (this is the default; runtime\n * behavior is unchanged from pre-#1977)\n * - mode=audit → checks against the policy; on violation, logs a warning\n * and still forwards to the handler\n * - mode=enforce → checks against the policy; on violation, returns an\n * MCP-format isError result without invoking the handler\n *\n * The enforcer's hardcoded denylist (denylist.ts) runs FIRST regardless\n * of mode. Even `off` mode denies destructive tools and secret paths.\n *\n * @module security/access-constraint-deriver/mcp-guard\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { checkAccess } from './enforcer.js';\nimport type { AccessDecision, TaskAccessPolicy } from './types.js';\n\n/** AsyncLocalStorage holding the active task's access policy. */\nconst accessPolicyStorage = new AsyncLocalStorage<TaskAccessPolicy>();\n\n/**\n * Run `fn` with `policy` available to any nested MCP tool dispatch.\n *\n * Orchestrators (orchestrate, execute_expert, etc.) derive a policy at\n * task start and wrap downstream work in this helper. Tool handlers that\n * use `guardMcpToolCall` will read the policy from ALS.\n */\nexport function withAccessPolicy<T>(policy: TaskAccessPolicy, fn: () => Promise<T>): Promise<T> {\n return accessPolicyStorage.run(policy, fn);\n}\n\n/**\n * Returns the active access policy, or undefined if no wrapping `withAccessPolicy`\n * is in scope. When undefined, `guardMcpToolCall` treats the request as\n * mode=off (permissive) since no task context has been established.\n */\nexport function getActivePolicy(): TaskAccessPolicy | undefined {\n return accessPolicyStorage.getStore();\n}\n\n/**\n * Input-hints a tool handler can surface so the guard can reason about\n * file-path arguments. Tools with a `path` arg should pass it; tools\n * without can omit.\n */\nexport interface GuardArgs {\n readonly path?: string;\n}\n\n/**\n * Check a proposed MCP tool call against the active access policy.\n *\n * Pure function — does not mutate the policy or the storage. Returns an\n * AccessDecision the caller interprets:\n *\n * - `allow`: invoke the handler\n * - `deny`: do not invoke; return a RefuseAction / isError result upstream\n * - `log-and-allow`: log a warning, then invoke the handler (audit mode)\n *\n * When no policy is in ALS (no wrapping `withAccessPolicy`), this returns\n * `allow` — the guard is opt-in at the orchestrator layer.\n */\nexport function guardMcpToolCall(toolName: string, args?: GuardArgs): AccessDecision {\n const policy = getActivePolicy();\n if (policy === undefined) return { decision: 'allow' };\n return checkAccess(toolName, policy, args);\n}\n\n/**\n * Shape of the logger the middleware uses. Minimal to avoid coupling.\n */\ninterface MiddlewareLogger {\n warn: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n}\n\n/**\n * Formats a deny decision as an MCP-compliant isError ToolResult shape.\n * The MCP server's middleware chain recognizes `{ isError, content }` and\n * surfaces it as a tool error to the caller.\n */\nexport function denyToToolResult(\n decision: Extract<AccessDecision, { decision: 'deny' }>,\n requestId: string\n): { isError: true; content: Array<{ type: 'text'; text: string }> } {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `access denied: ${decision.reason} (rule: ${decision.matchedRule}, request: ${requestId})`,\n },\n ],\n };\n}\n\n/**\n * Create an access-policy middleware that plugs into the MCP middleware\n * chain. Reads the active policy from ALS. When no policy is active OR\n * the policy is in `off` mode, this middleware is a no-op pass-through.\n */\nexport function createAccessPolicyMiddleware(config: {\n readonly toolName: string;\n readonly logger: MiddlewareLogger;\n}): (\n args: unknown,\n ctx: { readonly requestContext: { readonly requestId: string } },\n next: (args: unknown, ctx: unknown) => Promise<unknown>\n) => Promise<unknown> {\n return async (args, ctx, next) => {\n const policy = getActivePolicy();\n if (policy === undefined || policy.mode === 'off') {\n return next(args, ctx);\n }\n\n const guardArgs = toGuardArgs(args);\n const decision = checkAccess(config.toolName, policy, guardArgs);\n\n if (decision.decision === 'allow') {\n return next(args, ctx);\n }\n if (decision.decision === 'log-and-allow') {\n config.logger.warn('access-policy: audit violation', {\n tool: config.toolName,\n warning: decision.warning,\n policySource: policy.source,\n requestId: ctx.requestContext.requestId,\n });\n return next(args, ctx);\n }\n // decision.decision === 'deny'\n config.logger.info('access-policy: tool call denied', {\n tool: config.toolName,\n reason: decision.reason,\n matchedRule: decision.matchedRule,\n policySource: policy.source,\n mode: policy.mode,\n requestId: ctx.requestContext.requestId,\n });\n return denyToToolResult(decision, ctx.requestContext.requestId);\n };\n}\n\n/** Extract path from a typed tool-arg record, if present and a string. */\nfunction toGuardArgs(args: unknown): GuardArgs | undefined {\n if (typeof args !== 'object' || args === null) return undefined;\n const path = (args as Record<string, unknown>)['path'];\n return typeof path === 'string' && path.length > 0 ? { path } : undefined;\n}\n","/**\n * Access Constraint Deriver — MCP middleware-chain adapter (#1977 activation).\n *\n * Bridges `createAccessPolicyMiddleware` (which returns a generic\n * `Promise<unknown>`-shaped middleware) to the strongly-typed `Middleware`\n * contract used by `mcp/middleware/middleware-chain.ts`.\n *\n * Mounted into the standard middleware stack so every tool call passes\n * through the ClawGuard enforcer. When no orchestrator has wrapped the\n * call with `withAccessPolicy(...)`, this adapter is a no-op pass-through\n * — runtime behavior is unchanged for callers that don't set up a policy.\n *\n * @module security/access-constraint-deriver/chain-adapter\n */\n\nimport { checkAccess } from './enforcer.js';\nimport { denyToToolResult, getActivePolicy } from './mcp-guard.js';\nimport type { GuardArgs } from './mcp-guard.js';\n// Type-only import: no runtime cycle with mcp/middleware/middleware-chain.ts.\nimport type { Middleware } from '../../mcp/middleware/middleware-chain.js';\n\nfunction toGuardArgs(args: unknown): GuardArgs | undefined {\n if (typeof args !== 'object' || args === null) return undefined;\n const path = (args as Record<string, unknown>)['path'];\n return typeof path === 'string' && path.length > 0 ? { path } : undefined;\n}\n\n/**\n * Builds a middleware-chain-compatible access-policy middleware for\n * `toolName`. Reads the active `TaskAccessPolicy` from `AsyncLocalStorage`\n * (populated by `withAccessPolicy`). When no policy is active OR the\n * policy is in `off` mode, the middleware is a no-op pass-through.\n */\nexport function createAccessPolicyChainMiddleware(toolName: string): Middleware {\n return async (args, ctx, next) => {\n const policy = getActivePolicy();\n if (policy === undefined || policy.mode === 'off') {\n return next(args, ctx);\n }\n\n const decision = checkAccess(toolName, policy, toGuardArgs(args));\n\n if (decision.decision === 'allow') {\n return next(args, ctx);\n }\n if (decision.decision === 'log-and-allow') {\n ctx.logger.warn('access-policy: audit violation', {\n tool: toolName,\n warning: decision.warning,\n policySource: policy.source,\n requestId: ctx.requestContext.requestId,\n });\n return next(args, ctx);\n }\n ctx.logger.info('access-policy: tool call denied', {\n tool: toolName,\n reason: decision.reason,\n matchedRule: decision.matchedRule,\n policySource: policy.source,\n mode: policy.mode,\n requestId: ctx.requestContext.requestId,\n });\n return denyToToolResult(decision, ctx.requestContext.requestId);\n };\n}\n","/**\n * nexus-agents/mcp - Structured Tool Error Envelope\n *\n * Caller-facing error contract for MCP tools. Replaces the opaque\n * `{ isError: true, content: [{ text }] }` string shape with a structured\n * envelope so callers (other tools, voter panels, the Claude/Codex/Gemini/\n * OpenCode harnesses) can reason about retry-safety and recovery path\n * instead of string-matching arbitrary text.\n *\n * SCOPE — this envelope is caller-facing ONLY. The routing/circuit-breaker\n * layer classifies adapter subprocess failures through its own\n * `categorizeOutcomeError()` path (orchestration/outcomes/outcome-types.ts)\n * and never reads this envelope. `coarsenFailureCategory()` is a one-way\n * convenience for the rare tool that internally catches an\n * `OutcomeFailureCategory`-classified error and wants to surface it to its\n * caller — it is not, and must not become, a routing input. The two\n * taxonomies serve different layers; this is the single authoritative\n * projection between them.\n *\n * @module mcp/error-envelope\n * @see Issue #2649\n */\n\nimport { z } from 'zod';\nimport type { OutcomeFailureCategory } from '../orchestration/outcomes/outcome-types.js';\n\n// ============================================================================\n// Schema\n// ============================================================================\n\n/**\n * Caller-facing error category. Deliberately coarser than the routing\n * layer's 11-value `OutcomeFailureCategory` — a tool's caller only needs\n * enough resolution to choose a recovery path:\n *\n * - `transient` — network blip, rate limit, timeout. Retry is safe.\n * - `validation` — input shape/values wrong. Caller must fix its args.\n * - `permission` — auth / authorization / sandbox / access-policy denial.\n * - `business` — domain-logic refusal (dedup hit, precondition not met).\n * An expected, non-bug outcome — not a failure to retry.\n * - `internal` — unexpected, bug-class. Not retry-class; escalate.\n */\nexport const ErrorCategorySchema = z.enum([\n 'transient',\n 'validation',\n 'permission',\n 'business',\n 'internal',\n]);\n\nexport type ErrorCategory = z.infer<typeof ErrorCategorySchema>;\n\n/**\n * Structured error envelope returned by MCP tools. Carried in the tool\n * result's `structuredContent` under the `error` key; the human-readable\n * `message` is also mirrored into `content[].text` for display.\n */\nexport const ToolErrorEnvelopeSchema = z.object({\n errorCategory: ErrorCategorySchema,\n /** Whether retrying the same call could succeed without caller changes. */\n isRetryable: z.boolean(),\n /** Human-readable summary. Bounded to keep stack traces out of results. */\n message: z.string().min(1).max(2000),\n /**\n * Optional structured context. MUST NOT carry secrets, credentials,\n * absolute filesystem paths, or raw Error/response objects — those are\n * an information-disclosure risk (this field is not output-sanitized).\n */\n detail: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ToolErrorEnvelope = z.infer<typeof ToolErrorEnvelopeSchema>;\n\n/**\n * `_meta` key the envelope is carried under on a tool result. It lives in\n * `_meta` — NOT `structuredContent` — because the MCP client validates\n * `structuredContent` against the tool's `outputSchema` even on error\n * results (SDK `client/index.js`: it only guards on presence, not on\n * `isError`), so an envelope in `structuredContent` breaks every tool\n * that has an `outputSchema`. `_meta` is the spec's out-of-band metadata\n * channel and is never schema-validated. Namespaced to avoid collisions.\n */\nexport const ERROR_ENVELOPE_META_KEY = 'nexus-agents/error';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Default retry-safety for a category. Only `transient` errors are\n * retry-safe by default; callers can override per-call when a specific\n * `internal` or `business` error is known to be retryable.\n */\nexport function defaultRetryable(category: ErrorCategory): boolean {\n return category === 'transient';\n}\n\n/**\n * The single authoritative projection from the routing layer's 11-value\n * `OutcomeFailureCategory` down to the 5-value caller-facing\n * `ErrorCategory`. A `Record` over every key — adding a 12th\n * `OutcomeFailureCategory` value without extending this map is a compile\n * error, which is the drift safeguard.\n *\n * One-way only: there is no `un-coarsen`, by design — the routing layer\n * keeps its own granular classification and never round-trips through here.\n */\nconst FAILURE_CATEGORY_COARSENING: Record<OutcomeFailureCategory, ErrorCategory> = {\n timeout: 'transient',\n rate_limit: 'transient',\n connection: 'transient',\n authentication: 'permission',\n validation: 'validation',\n parse: 'validation',\n crash: 'internal',\n adapter_unavailable: 'internal',\n execution: 'internal',\n generic: 'internal',\n unknown: 'internal',\n};\n\n/**\n * Coarsen a routing-layer `OutcomeFailureCategory` to a caller-facing\n * `ErrorCategory`. Use this only when a tool has caught an error already\n * classified by the routing layer and wants to surface it in its envelope.\n */\nexport function coarsenFailureCategory(category: OutcomeFailureCategory): ErrorCategory {\n return FAILURE_CATEGORY_COARSENING[category];\n}\n\n/**\n * Extract and validate a `ToolErrorEnvelope` from a tool result's `_meta`\n * object. Returns `null` when `_meta` is absent or does not carry a\n * parseable envelope under {@link ERROR_ENVELOPE_META_KEY}. Used by\n * envelope-aware callers.\n */\nexport function parseToolErrorEnvelope(meta: unknown): ToolErrorEnvelope | null {\n if (meta === null || typeof meta !== 'object') {\n return null;\n }\n const candidate = (meta as Record<string, unknown>)[ERROR_ENVELOPE_META_KEY];\n const result = ToolErrorEnvelopeSchema.safeParse(candidate);\n return result.success ? result.data : null;\n}\n","/**\n * nexus-agents/mcp - Tool Result Helpers\n *\n * Canonical type and factory functions for MCP tool results.\n * Extracted from index.ts to allow tool implementations to import\n * without circular dependencies.\n *\n * @module mcp/tools/tool-result\n */\n\nimport type { ILogger } from '../../core/index.js';\nimport type { RateLimiter } from '../middleware/rate-limiter.js';\nimport type { SecurityConfig } from '../../config/schemas.js';\nimport {\n defaultRetryable,\n ERROR_ENVELOPE_META_KEY,\n type ErrorCategory,\n type ToolErrorEnvelope,\n} from '../error-envelope.js';\n\n// ============================================================================\n// Base Dependencies\n// ============================================================================\n\n/**\n * Common dependency interface shared by all MCP tool handlers.\n *\n * Tool-specific deps interfaces should extend this base.\n * (Source: Issue #1439 — DRY extraction of 25 duplicated Deps interfaces)\n */\nexport interface BaseMcpToolDeps {\n /** Optional logger */\n logger?: ILogger;\n /** Rate limiter for throttling tool calls (required) */\n rateLimiter: RateLimiter;\n /** Security configuration (includes timeout settings) */\n security?: SecurityConfig | undefined;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * MCP tool content types.\n */\nexport interface TextContent {\n type: 'text';\n text: string;\n}\n\n/**\n * MCP tool result.\n *\n * Uses mutable properties for compatibility with secure-handler\n * sanitization (which rewrites `text` in-place).\n */\nexport interface ToolResult {\n content: Array<TextContent>;\n isError?: boolean;\n /** Structured output for SDK outputSchema validation (Issue #1117) */\n structuredContent?: Record<string, unknown>;\n /**\n * Out-of-band metadata, never validated against `outputSchema`. The\n * structured error envelope (#2649) is carried here under\n * `ERROR_ENVELOPE_META_KEY`.\n */\n _meta?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates a successful tool result.\n *\n * @param text - The result text\n * @returns A ToolResult with the text content\n *\n * @example\n * ```typescript\n * return toolSuccess(JSON.stringify({ status: 'ok', data: result }));\n * ```\n */\nexport function toolSuccess(text: string): ToolResult {\n return {\n content: [{ type: 'text', text }],\n };\n}\n\n/**\n * Creates a successful tool result with structured content for outputSchema validation.\n *\n * When a tool is registered with outputSchema, the SDK validates structuredContent\n * against the schema. This helper returns both text (for display) and structured data.\n *\n * @param data - The structured result data (must match the tool's outputSchema)\n * @returns A ToolResult with both text content and structuredContent\n *\n * @example\n * ```typescript\n * return toolSuccessStructured({ experts: [...], count: 10 });\n * ```\n */\nexport function toolSuccessStructured(data: Record<string, unknown>): ToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n structuredContent: data,\n };\n}\n\n/**\n * Input for {@link toolStructuredError}. `isRetryable` is optional — when\n * omitted it is derived from the category via `defaultRetryable()`.\n */\nexport interface ToolStructuredErrorInput {\n errorCategory: ErrorCategory;\n message: string;\n isRetryable?: boolean;\n detail?: Record<string, unknown>;\n}\n\n/**\n * Creates a structured error tool result (#2649). The envelope is carried\n * in `_meta` (under `ERROR_ENVELOPE_META_KEY`) — NOT `structuredContent`,\n * which the MCP client validates against the tool's `outputSchema` even\n * on error results. `message` is mirrored into `content[].text` for\n * display.\n *\n * @example\n * ```typescript\n * if (!validated.success) {\n * return toolStructuredError({\n * errorCategory: 'validation',\n * message: `Validation error: ${formatZodError(validated.error)}`,\n * });\n * }\n * ```\n */\nexport function toolStructuredError(input: ToolStructuredErrorInput): ToolResult {\n const envelope: ToolErrorEnvelope = {\n errorCategory: input.errorCategory,\n isRetryable: input.isRetryable ?? defaultRetryable(input.errorCategory),\n message: input.message,\n ...(input.detail !== undefined ? { detail: input.detail } : {}),\n };\n return {\n isError: true,\n content: [{ type: 'text', text: envelope.message }],\n _meta: { [ERROR_ENVELOPE_META_KEY]: envelope },\n };\n}\n\n/**\n * Creates an error tool result.\n *\n * Back-compat alias for {@link toolStructuredError} — maps to the\n * conservative `internal` / non-retryable envelope. New code should call\n * `toolStructuredError` directly with the correct category; this alias\n * exists so the ~64 legacy call sites keep working during the #2649\n * migration sweep.\n *\n * @param message - The error message\n * @returns A ToolResult with isError set to true and an `internal` envelope\n */\nexport function toolError(message: string): ToolResult {\n return toolStructuredError({ errorCategory: 'internal', message });\n}\n","/**\n * nexus-agents/mcp - Centralized Middleware Chain\n *\n * Provides a composable middleware chain for MCP tools with guaranteed\n * execution order: auth → validation → policy → rate-limit → timeout → audit\n *\n * @module mcp/middleware/middleware-chain\n * (Source: Issue #189 - Centralized MCP middleware chain)\n */\n\nimport type { z } from 'zod';\nimport type { ILogger } from '../../core/index.js';\nimport { createLogger, getTimeProvider } from '../../core/index.js';\nimport { validateToolInput } from './validation.js';\nimport { RateLimiter, type RateLimiterConfig } from './rate-limiter.js';\nimport { type IPolicyFirewall, type ExecutionMode, createPolicyContext } from './policy.js';\nimport { TimeoutGuard, type TimeoutGuardConfig } from './timeout-guard.js';\nimport { createRequestContext, contextForLogging, type RequestContext } from './request-context.js';\nimport { createMetricsMiddleware } from './tool-metrics.js';\nimport { abortSignalStorage } from '../mcp-notifier.js';\nimport { createAccessPolicyChainMiddleware } from '../../security/access-constraint-deriver/chain-adapter.js';\nimport { toolStructuredError } from '../tools/tool-result.js';\nimport type { ErrorCategory } from '../error-envelope.js';\n\n/**\n * MCP tool result type.\n *\n * This interface is structurally compatible with the MCP SDK's CallToolResult.\n * The content array accepts text content for simplicity, while remaining\n * compatible with the SDK's broader ContentBlock type at runtime.\n */\nexport interface ToolResult {\n /** Content blocks returned by the tool (text content) */\n content: Array<{ type: 'text'; text: string }>;\n /** Whether this represents an error result */\n isError?: boolean;\n /** Structured output for SDK outputSchema validation (Issue #1117) */\n structuredContent?: Record<string, unknown>;\n /** Out-of-band metadata — carries the #2649 error envelope on errors. */\n _meta?: Record<string, unknown>;\n}\n\n/**\n * Middleware context passed through the chain.\n */\nexport interface MiddlewareContext {\n /** Unique request ID for tracing */\n readonly requestContext: RequestContext;\n /** Logger with request context */\n readonly logger: ILogger;\n /** Validated arguments (set after validation middleware) */\n validatedArgs?: unknown;\n}\n\n/**\n * Middleware function signature.\n * Each middleware receives the context and a next function to call.\n */\nexport type Middleware = (\n args: unknown,\n ctx: MiddlewareContext,\n next: (args: unknown, ctx: MiddlewareContext) => Promise<ToolResult>\n) => Promise<ToolResult>;\n\n/**\n * Configuration for the middleware chain.\n */\nexport interface MiddlewareChainConfig {\n /** Tool name for logging and policy evaluation */\n toolName: string;\n /** Zod schema for input validation (optional) */\n schema?: z.ZodType;\n /** Policy firewall instance (optional) */\n policyFirewall?: IPolicyFirewall | undefined;\n /** Execution mode for policy evaluation */\n executionMode?: ExecutionMode | undefined;\n /** Allowed paths for file operations */\n allowedPaths?: readonly string[] | undefined;\n /** Rate limiter configuration (optional) */\n rateLimiter?: RateLimiterConfig | RateLimiter | undefined;\n /** Timeout configuration (optional) */\n timeout?: TimeoutGuardConfig | undefined;\n /** Logger instance (optional) */\n logger?: ILogger | undefined;\n /** Skip specific middleware steps */\n skip?: MiddlewareSkipConfig | undefined;\n}\n\n/**\n * Configuration for skipping middleware steps.\n */\nexport interface MiddlewareSkipConfig {\n validation?: boolean | undefined;\n policy?: boolean | undefined;\n rateLimit?: boolean | undefined;\n timeout?: boolean | undefined;\n audit?: boolean | undefined;\n /** Skip the ClawGuard access-policy middleware (#1977). */\n accessPolicy?: boolean | undefined;\n}\n\n/**\n * Tool handler function signature.\n */\nexport type ToolHandler = (args: unknown) => Promise<ToolResult>;\n\n/**\n * Context-aware handler that receives middleware context.\n */\nexport type ContextAwareToolHandler = (\n args: unknown,\n ctx: MiddlewareContext\n) => Promise<ToolResult>;\n\n/**\n * Creates an error result with the structured error envelope (#2649).\n * Each middleware passes the category that matches its failure mode.\n */\nfunction errorResult(category: ErrorCategory, message: string, requestId: string): ToolResult {\n return toolStructuredError({\n errorCategory: category,\n message: `${message} (request: ${requestId})`,\n });\n}\n\n/**\n * Creates validation middleware.\n */\nfunction createValidationMiddleware(schema: z.ZodType): Middleware {\n return async (args, ctx, next) => {\n const result = validateToolInput(schema, args);\n if (!result.ok) {\n ctx.logger.warn('Validation failed', {\n error: result.error.message,\n });\n return errorResult(\n 'validation',\n `Validation error: ${result.error.message}`,\n ctx.requestContext.requestId\n );\n }\n ctx.validatedArgs = result.value;\n return next(result.value, ctx);\n };\n}\n\n/**\n * Creates policy middleware.\n */\nfunction createPolicyMiddleware(\n firewall: IPolicyFirewall,\n toolName: string,\n mode: ExecutionMode,\n allowedPaths?: readonly string[]\n): Middleware {\n return async (args, ctx, next) => {\n const policyCtx = createPolicyContext(toolName, args, {\n mode,\n ...(allowedPaths !== undefined && { allowedPaths }),\n });\n const decision = firewall.evaluate(policyCtx);\n\n if (!decision.allowed) {\n ctx.logger.warn('Policy denied', {\n reason: decision.reason,\n ruleName: decision.ruleName,\n });\n return errorResult(\n 'permission',\n `Policy denied: ${decision.reason}`,\n ctx.requestContext.requestId\n );\n }\n ctx.logger.debug('Policy check passed', { reason: decision.reason });\n return next(args, ctx);\n };\n}\n\n/**\n * Creates rate limit middleware.\n */\nfunction createRateLimitMiddleware(limiter: RateLimiter): Middleware {\n return async (args, ctx, next) => {\n const acquired = limiter.tryAcquire();\n if (!acquired) {\n const state = limiter.getState();\n ctx.logger.warn('Rate limit exceeded', {\n nextTokenMs: state.nextTokenMs,\n });\n return errorResult(\n 'transient',\n `Rate limit exceeded. Try again in ${String(state.nextTokenMs)}ms`,\n ctx.requestContext.requestId\n );\n }\n return next(args, ctx);\n };\n}\n\n/**\n * Creates timeout middleware.\n * Reads AbortSignal from AsyncLocalStorage for client cancellation support.\n */\nfunction createTimeoutMiddleware(guard: TimeoutGuard, toolName: string): Middleware {\n return async (args, ctx, next) => {\n const signal = abortSignalStorage.getStore();\n const result = await guard.execute(() => next(args, ctx), {\n operationName: toolName,\n ...(signal !== undefined ? { signal } : {}),\n });\n\n if (!result.ok) {\n ctx.logger.error('Operation timed out', undefined, {\n code: result.error.code,\n timeoutMs: result.error.timeoutMs,\n });\n // Timeout — transient, a retry with more headroom may succeed.\n return errorResult('transient', result.error.message, ctx.requestContext.requestId);\n }\n\n if (result.value.nearTimeout) {\n ctx.logger.warn('Operation completed near timeout threshold', {\n durationMs: result.value.durationMs,\n });\n }\n\n return result.value.value;\n };\n}\n\n/**\n * Creates audit middleware that logs start/end of request.\n */\nfunction createAuditMiddleware(): Middleware {\n return async (args, ctx, next) => {\n const startTime = getTimeProvider().now();\n ctx.logger.info('Tool invocation started');\n\n try {\n const result = await next(args, ctx);\n const durationMs = getTimeProvider().now() - startTime;\n\n if (result.isError === true) {\n ctx.logger.warn('Tool execution completed with error', { durationMs });\n } else {\n ctx.logger.info('Tool execution completed', { durationMs });\n }\n return result;\n } catch (error) {\n const durationMs = getTimeProvider().now() - startTime;\n const message = error instanceof Error ? error.message : 'Unknown error';\n ctx.logger.error('Tool execution failed', error instanceof Error ? error : undefined, {\n durationMs,\n });\n return errorResult('internal', `Internal error: ${message}`, ctx.requestContext.requestId);\n }\n };\n}\n\n/**\n * Composes multiple middleware functions into a single chain.\n */\nfunction composeMiddleware(middlewares: Middleware[]): Middleware {\n return (args, ctx, finalHandler) => {\n const dispatch = (index: number, currentArgs: unknown): Promise<ToolResult> => {\n if (index >= middlewares.length) {\n return finalHandler(currentArgs, ctx);\n }\n const middleware = middlewares[index];\n if (middleware === undefined) {\n return finalHandler(currentArgs, ctx);\n }\n return middleware(currentArgs, ctx, (nextArgs) => dispatch(index + 1, nextArgs));\n };\n return dispatch(0, args);\n };\n}\n\n/** Helper: adds audit middleware if not skipped */\nfunction addAuditMiddleware(middlewares: Middleware[], skip: MiddlewareSkipConfig): void {\n if (skip.audit !== true) {\n middlewares.push(createAuditMiddleware());\n }\n}\n\n/** Helper: adds rate limit middleware if configured */\nfunction addRateLimitMiddleware(\n middlewares: Middleware[],\n config: MiddlewareChainConfig,\n skip: MiddlewareSkipConfig\n): void {\n if (skip.rateLimit !== true && config.rateLimiter !== undefined) {\n const limiter =\n config.rateLimiter instanceof RateLimiter\n ? config.rateLimiter\n : new RateLimiter(config.rateLimiter);\n middlewares.push(createRateLimitMiddleware(limiter));\n }\n}\n\n/** Helper: adds validation middleware if schema provided */\nfunction addValidationMiddleware(\n middlewares: Middleware[],\n config: MiddlewareChainConfig,\n skip: MiddlewareSkipConfig\n): void {\n if (skip.validation !== true && config.schema !== undefined) {\n middlewares.push(createValidationMiddleware(config.schema));\n }\n}\n\n/** Helper: adds policy middleware if configured */\nfunction addPolicyMiddleware(\n middlewares: Middleware[],\n config: MiddlewareChainConfig,\n skip: MiddlewareSkipConfig\n): void {\n if (skip.policy !== true && config.policyFirewall !== undefined) {\n const mode = config.executionMode ?? 'read-only';\n middlewares.push(\n createPolicyMiddleware(config.policyFirewall, config.toolName, mode, config.allowedPaths)\n );\n }\n}\n\n/** Helper: adds timeout middleware if configured */\nfunction addTimeoutMiddleware(\n middlewares: Middleware[],\n config: MiddlewareChainConfig,\n skip: MiddlewareSkipConfig\n): void {\n if (skip.timeout !== true && config.timeout !== undefined) {\n const guard = new TimeoutGuard(config.timeout);\n middlewares.push(createTimeoutMiddleware(guard, config.toolName));\n }\n}\n\n/**\n * Helper: adds the ClawGuard access-policy middleware (#1977).\n *\n * Always added unless explicitly skipped. The middleware is ALS-backed\n * and a no-op pass-through when no orchestrator has called\n * `withAccessPolicy(...)` — so runtime behavior is unchanged for callers\n * that haven't opted in.\n */\nfunction addAccessPolicyMiddleware(\n middlewares: Middleware[],\n config: MiddlewareChainConfig,\n skip: MiddlewareSkipConfig\n): void {\n if (skip.accessPolicy !== true) {\n middlewares.push(createAccessPolicyChainMiddleware(config.toolName));\n }\n}\n\n/** Helper: builds the middleware stack */\nfunction buildMiddlewareStack(config: MiddlewareChainConfig): Middleware[] {\n const skip = config.skip ?? {};\n const middlewares: Middleware[] = [];\n\n middlewares.push(createMetricsMiddleware()); // Tool usage analytics (#1022)\n addAuditMiddleware(middlewares, skip);\n addRateLimitMiddleware(middlewares, config, skip);\n addValidationMiddleware(middlewares, config, skip);\n addPolicyMiddleware(middlewares, config, skip);\n addAccessPolicyMiddleware(middlewares, config, skip); // #1977 ClawGuard\n addTimeoutMiddleware(middlewares, config, skip);\n\n return middlewares;\n}\n\n/**\n * Creates a middleware chain with the standard execution order.\n *\n * Order: audit → rate-limit → validation → policy → timeout → handler\n *\n * Audit wraps everything to capture timing. Rate limit is checked early\n * to reject requests before expensive validation. Timeout wraps the\n * actual handler execution.\n *\n * @param config - Chain configuration\n * @returns A function that wraps handlers with the middleware chain\n */\nexport function createMiddlewareChain(\n config: MiddlewareChainConfig\n): (handler: ContextAwareToolHandler) => ToolHandler {\n const logger = config.logger ?? createLogger({ tool: config.toolName });\n const middlewares = buildMiddlewareStack(config);\n const composed = composeMiddleware(middlewares);\n\n return (handler: ContextAwareToolHandler): ToolHandler => {\n return async (args: unknown): Promise<ToolResult> => {\n const requestContext = createRequestContext({ toolName: config.toolName });\n const requestLogger = logger.child(contextForLogging(requestContext));\n const ctx: MiddlewareContext = { requestContext, logger: requestLogger };\n return composed(args, ctx, (finalArgs, finalCtx) => handler(finalArgs, finalCtx));\n };\n };\n}\n\n/**\n * Convenience function to wrap a handler with default middleware.\n *\n * @param toolName - Name of the tool\n * @param handler - The tool handler\n * @param options - Optional middleware configuration\n * @returns Wrapped handler with middleware\n */\nexport function withMiddleware(\n toolName: string,\n handler: ContextAwareToolHandler | ToolHandler,\n options?: Partial<Omit<MiddlewareChainConfig, 'toolName'>>\n): ToolHandler {\n // Note: Policy firewall is NOT added by default - must be explicitly configured\n // This follows the principle of minimal defaults with explicit opt-in for security\n const config: MiddlewareChainConfig = {\n toolName,\n ...options,\n };\n\n const chain = createMiddlewareChain(config);\n\n // Wrap handler to support both signatures\n const wrappedHandler: ContextAwareToolHandler = (args, ctx) => {\n // Check if handler expects context (2 params)\n if (handler.length >= 2) {\n return handler(args, ctx);\n }\n return (handler as ToolHandler)(args);\n };\n\n return chain(wrappedHandler);\n}\n\n/**\n * Creates a middleware chain factory with shared configuration.\n *\n * @param sharedConfig - Configuration shared across all tools\n * @returns Factory function for creating wrapped handlers\n */\nexport function createMiddlewareFactory(\n sharedConfig: Omit<MiddlewareChainConfig, 'toolName' | 'schema'>\n): (\n toolName: string,\n handler: ContextAwareToolHandler | ToolHandler,\n schema?: z.ZodType\n) => ToolHandler {\n return (toolName, handler, schema) => {\n const options = schema !== undefined ? { ...sharedConfig, schema } : sharedConfig;\n return withMiddleware(toolName, handler, options);\n };\n}\n","/**\n * nexus-agents/audit - SecureHandler Audit Integration\n *\n * Integration helper to add audit logging to SecureHandler middleware.\n *\n * (Source: Issue #193 - Phase 3 structured audit logging)\n *\n * @module audit/secure-handler-audit\n */\n\nimport type { IAuditLogger, AuditActor, AuditOutcome } from './audit-types.js';\nimport type { RequestContext } from '../mcp/middleware/request-context.js';\n\n/**\n * Configuration for audit-enabled secure handler.\n */\nexport interface AuditHandlerConfig {\n /** Audit logger instance */\n auditLogger: IAuditLogger;\n /** Default actor for requests without caller info */\n defaultActor?: AuditActor | undefined;\n}\n\n/**\n * Creates an AuditActor from RequestContext.\n */\nexport function actorFromContext(ctx: RequestContext, fallback?: AuditActor): AuditActor {\n const caller = ctx.caller;\n const clientId = caller.clientId;\n if (clientId !== undefined && clientId.length > 0) {\n return {\n type: clientId.includes('api') ? 'external' : clientId.includes('cli') ? 'agent' : 'user',\n id: clientId,\n name: caller.userAgent,\n };\n }\n return fallback ?? { type: 'system', id: 'unknown', name: 'Unknown Caller' };\n}\n\n/**\n * Maps tool result to audit outcome.\n */\nexport function resultToOutcome(\n isError: boolean | undefined,\n isPolicyDenied: boolean\n): AuditOutcome {\n if (isPolicyDenied) return 'denied';\n if (isError === true) return 'failure';\n return 'success';\n}\n\n/** Options for logging tool invocation audit */\nexport interface LogToolInvocationOpts {\n auditLogger: IAuditLogger;\n toolName: string;\n outcome: AuditOutcome;\n actor: AuditActor;\n requestId: string;\n durationMs?: number | undefined;\n errorMessage?: string | undefined;\n}\n\n/**\n * Logs tool invocation to audit logger.\n */\nexport function logToolInvocationAudit(opts: LogToolInvocationOpts): void {\n opts.auditLogger.logToolInvocation({\n toolName: opts.toolName,\n outcome: opts.outcome,\n actor: opts.actor,\n requestId: opts.requestId,\n durationMs: opts.durationMs,\n errorMessage: opts.errorMessage,\n });\n}\n\n/** Options for logging policy audit */\nexport interface LogPolicyAuditOpts {\n auditLogger: IAuditLogger;\n policyName: string;\n decision: 'allow' | 'deny';\n reason: string;\n toolName: string;\n actor: AuditActor;\n requestId: string;\n}\n\n/**\n * Logs policy decision to audit logger.\n */\nexport function logPolicyAudit(opts: LogPolicyAuditOpts): void {\n opts.auditLogger.logPolicyDecision({\n policyName: opts.policyName,\n decision: opts.decision,\n reason: opts.reason,\n toolName: opts.toolName,\n actor: opts.actor,\n requestId: opts.requestId,\n });\n}\n\n/** Options for logging rate limit audit */\nexport interface LogRateLimitAuditOpts {\n auditLogger: IAuditLogger;\n toolName: string;\n actor: AuditActor;\n currentRate: number;\n limitRate: number;\n requestId: string;\n}\n\n/**\n * Logs rate limit violation to audit logger.\n */\nexport function logRateLimitAudit(opts: LogRateLimitAuditOpts): void {\n opts.auditLogger.logRateLimitViolation({\n toolName: opts.toolName,\n actor: opts.actor,\n currentRate: opts.currentRate,\n limitRate: opts.limitRate,\n requestId: opts.requestId,\n });\n}\n","/**\n * nexus-agents/mcp - Tool Input Sanitizer Middleware\n *\n * Lightweight sanitization for MCP tool arguments. Strips XML-like\n * conversation injection tags and detects prompt injection patterns\n * in all string values within tool arguments.\n *\n * Defense-in-depth layer that protects against prompt injection\n * through tool arguments containing external content.\n *\n * @module mcp/middleware/tool-input-sanitizer\n * (Source: Issue #828 — Wire security modules into production pipeline)\n */\n\nimport type { ILogger } from '../../core/index.js';\n\n/**\n * Result of sanitizing tool input.\n */\nexport interface SanitizeToolInputResult {\n /** Sanitized arguments (XML tags stripped from string values) */\n readonly sanitized: unknown;\n /** Whether any modification was made */\n readonly wasModified: boolean;\n /** Count of strings that were modified */\n readonly modifiedCount: number;\n /** Injection patterns detected (for logging) */\n readonly detectedPatterns: readonly string[];\n}\n\n/**\n * XML-like tags that mimic conversation structure or system prompts.\n * Stripping these prevents prompt injection through tool arguments.\n */\nconst XML_INJECTION_PATTERN =\n /<\\/?(system|human|assistant|instructions|user|prompt|context|tool_use|tool_result)\\b[^>]*>/gi;\n\n/**\n * Patterns that indicate attempted prompt injection.\n * These are logged but not necessarily stripped (detection only).\n */\nconst INJECTION_DETECTORS: ReadonlyArray<{ name: string; pattern: RegExp }> = [\n { name: 'system_prompt_override', pattern: /ignore (?:all )?previous (?:instructions|rules)/i },\n { name: 'role_impersonation', pattern: /i(?:'m| am) the (?:repo |project )?(?:owner|admin)/i },\n { name: 'hidden_instruction', pattern: /<!--[\\s\\S]*?(?:execute|delete|merge|apply)[\\s\\S]*?-->/i },\n];\n\n/**\n * Sanitizes a single string value by stripping XML injection tags.\n * Returns the cleaned string and whether it was modified.\n */\nfunction sanitizeString(value: string): { cleaned: string; modified: boolean } {\n XML_INJECTION_PATTERN.lastIndex = 0;\n const cleaned = value.replace(XML_INJECTION_PATTERN, '');\n return { cleaned, modified: cleaned !== value };\n}\n\n/**\n * Detects injection patterns in a string without modifying it.\n */\nfunction detectPatterns(value: string): string[] {\n const detected: string[] = [];\n for (const { name, pattern } of INJECTION_DETECTORS) {\n pattern.lastIndex = 0;\n if (pattern.test(value)) {\n detected.push(name);\n }\n }\n return detected;\n}\n\n/**\n * Recursively sanitizes all string values in an object/array.\n * Returns a deep copy with XML injection tags stripped from strings.\n */\nfunction sanitizeValue(value: unknown, stats: { count: number; patterns: string[] }): unknown {\n if (typeof value === 'string') {\n const patterns = detectPatterns(value);\n if (patterns.length > 0) {\n stats.patterns.push(...patterns);\n }\n const { cleaned, modified } = sanitizeString(value);\n if (modified) stats.count++;\n return cleaned;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => sanitizeValue(item, stats));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = sanitizeValue(val, stats);\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Sanitizes MCP tool arguments by stripping XML injection tags\n * from all string values and detecting injection patterns.\n *\n * @param args - Tool arguments to sanitize\n * @returns Sanitized result with modification tracking\n */\nexport function sanitizeToolInput(args: unknown): SanitizeToolInputResult {\n if (args === undefined || args === null) {\n return { sanitized: args, wasModified: false, modifiedCount: 0, detectedPatterns: [] };\n }\n\n const stats = { count: 0, patterns: [] as string[] };\n const sanitized = sanitizeValue(args, stats);\n const uniquePatterns = [...new Set(stats.patterns)];\n\n return {\n sanitized,\n wasModified: stats.count > 0,\n modifiedCount: stats.count,\n detectedPatterns: uniquePatterns,\n };\n}\n\n/**\n * Logs sanitization results when modifications or detections occur.\n */\nexport function logSanitizationResult(\n result: SanitizeToolInputResult,\n logger: ILogger,\n toolName: string\n): void {\n if (result.wasModified) {\n logger.warn('Tool input sanitized — XML injection tags stripped', {\n tool: toolName,\n modifiedFields: result.modifiedCount,\n });\n }\n if (result.detectedPatterns.length > 0) {\n logger.warn('Injection patterns detected in tool input', {\n tool: toolName,\n patterns: result.detectedPatterns,\n });\n }\n}\n","/**\n * nexus-agents/mcp - Secure Handler Middleware\n *\n * Higher-order function that wraps MCP tool handlers with security middleware:\n * - RequestContext creation and tracking\n * - PolicyFirewall evaluation\n * - Logging with request context\n *\n * (Source: Issue #185 Phase 1 - PolicyFirewall integration)\n *\n * @module mcp/middleware/secure-handler\n */\n\nimport type { ILogger } from '../../core/index.js';\nimport { createLogger, getTimeProvider } from '../../core/index.js';\nimport {\n createRequestContext,\n contextForLogging,\n type RequestContext,\n type CallerInfo,\n} from './request-context.js';\nimport { type IPolicyFirewall, type ExecutionMode, createPolicyContext } from './policy.js';\nimport type { RateLimiter } from './rate-limiter.js';\nimport type { IAuditLogger } from '../../audit/audit-types.js';\nimport { actorFromContext, resultToOutcome } from '../../audit/secure-handler-audit.js';\nimport {\n sanitizeToolInput,\n logSanitizationResult,\n type SanitizeToolInputResult,\n} from './tool-input-sanitizer.js';\nimport { toolStructuredError, type ToolResult } from '../tools/tool-result.js';\n\nexport type { ToolResult };\n\n/**\n * Tool handler function signature.\n */\nexport type ToolHandler = (args: unknown) => Promise<ToolResult>;\n\n/**\n * Security tier for MCP tools. Controls input validation strictness.\n *\n * - 'standard': Default. XML injection tag stripping only (existing behavior).\n * - 'user-facing': Accepts user task descriptions. Rejects known injection patterns.\n * - 'external': Processes external URLs/content. Strictest validation.\n *\n * @see Issue #1586 — Tiered security validation\n */\nexport type SecurityTier = 'standard' | 'user-facing' | 'external';\n\n/**\n * Configuration for the secure handler wrapper.\n */\nexport interface SecureHandlerConfig {\n /** Tool name for logging and policy evaluation */\n toolName: string;\n /** Security tier controlling input validation strictness (default: 'standard') */\n securityTier?: SecurityTier;\n /** Policy firewall instance (optional - if not provided, policy checks are skipped) */\n policyFirewall?: IPolicyFirewall;\n /** Execution mode for policy evaluation */\n executionMode?: ExecutionMode;\n /** Allowed paths for file operations */\n allowedPaths?: readonly string[];\n /** Rate limiter instance (optional) */\n rateLimiter?: RateLimiter;\n /** Logger instance (optional - creates default if not provided) */\n logger?: ILogger;\n /** Caller information extractor (optional) */\n callerInfo?: CallerInfo;\n /** Audit logger for structured audit trail (Issue #740 Phase 2) */\n auditLogger?: IAuditLogger;\n}\n\n/**\n * Extended handler context passed to the wrapped handler.\n */\nexport interface HandlerContext {\n /** Request context for this invocation */\n requestContext: RequestContext;\n /** Logger with request context attached */\n logger: ILogger;\n}\n\n/**\n * Tool handler with context signature.\n */\nexport type ContextAwareHandler = (args: unknown, ctx: HandlerContext) => Promise<ToolResult>;\n\n/**\n * Creates a rate limit error response. Rate limits are transient — the\n * structured envelope marks it retryable (#2649).\n */\nfunction rateLimitError(nextTokenMs: number): ToolResult {\n return toolStructuredError({\n errorCategory: 'transient',\n message: `Rate limit exceeded. Try again in ${String(nextTokenMs)}ms.`,\n });\n}\n\n/**\n * Creates a policy denial error response — an access-control denial,\n * categorized `permission` (#2649).\n */\nfunction policyDeniedError(reason: string, requestId: string): ToolResult {\n return toolStructuredError({\n errorCategory: 'permission',\n message: `Policy denied: ${reason} (request: ${requestId})`,\n });\n}\n\n/**\n * Creates an internal error response (#2649).\n */\nfunction internalError(message: string, requestId: string): ToolResult {\n return toolStructuredError({\n errorCategory: 'internal',\n message: `Internal error: ${message} (request: ${requestId})`,\n });\n}\n\n/**\n * Maximum input size for tool arguments (10MB).\n * Prevents memory exhaustion from oversized payloads.\n * (Source: Issue #740 - MCP security hardening)\n */\nconst MAX_INPUT_SIZE_BYTES = 10 * 1024 * 1024;\n\n/**\n * Patterns that indicate leaked secrets in tool output.\n * Each pattern is tested against tool response text.\n */\nconst SECRET_PATTERNS: readonly RegExp[] = [\n // API keys with common prefixes\n /\\b(sk-[a-zA-Z0-9]{20,})\\b/,\n /\\b(pk-[a-zA-Z0-9]{20,})\\b/,\n // AWS-style keys\n /\\b(AKIA[A-Z0-9]{16})\\b/,\n // Bearer tokens in output\n /Bearer\\s+[a-zA-Z0-9_\\-.~+/]+=*/,\n // Generic long hex secrets (40+ chars)\n /\\b[0-9a-f]{40,}\\b/i,\n // password= or token= in output\n /(?:password|token|secret|apikey|api_key)\\s*[=:]\\s*\\S{8,}/i,\n];\n\n/** Redact detected secrets from tool output text. */\nfunction sanitizeOutput(text: string, logger: ILogger): string {\n let sanitized = text;\n for (const pattern of SECRET_PATTERNS) {\n if (pattern.test(sanitized)) {\n logger.warn('Potential secret detected in tool output, redacting', {\n pattern: pattern.source.slice(0, 30),\n });\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n }\n return sanitized;\n}\n\n/** Sanitize all text content in a tool result (Issue #740). */\nfunction sanitizeToolResult(result: ToolResult, logger: ILogger): void {\n for (const item of result.content) {\n item.text = sanitizeOutput(item.text, logger);\n }\n}\n\n/** Validates input size and returns error if too large. */\nfunction checkInputSize(args: unknown, logger: ILogger, requestId: string): ToolResult | null {\n if (args === undefined) return null;\n const inputSize = JSON.stringify(args).length;\n if (inputSize > MAX_INPUT_SIZE_BYTES) {\n logger.warn('Input size exceeds limit', { inputSize, limit: MAX_INPUT_SIZE_BYTES });\n return internalError('Input too large', requestId);\n }\n return null;\n}\n\n/**\n * Checks rate limiter and returns error if exceeded.\n */\nfunction checkRateLimit(rateLimiter: RateLimiter, logger: ILogger): ToolResult | null {\n const acquired = rateLimiter.tryAcquire();\n if (!acquired) {\n const state = rateLimiter.getState();\n logger.warn('Rate limit exceeded');\n return rateLimitError(state.nextTokenMs);\n }\n return null;\n}\n\n/** Options for policy check */\ninterface PolicyCheckOptions {\n firewall: IPolicyFirewall;\n toolName: string;\n args: unknown;\n mode: ExecutionMode;\n allowedPaths?: readonly string[] | undefined;\n logger: ILogger;\n requestId: string;\n}\n\n/**\n * Evaluates policy firewall and returns error if denied.\n */\nfunction checkPolicy(opts: PolicyCheckOptions): ToolResult | null {\n const ctxOpts = {\n mode: opts.mode,\n ...(opts.allowedPaths && { allowedPaths: opts.allowedPaths }),\n };\n const decision = opts.firewall.evaluate(createPolicyContext(opts.toolName, opts.args, ctxOpts));\n\n if (!decision.allowed) {\n opts.logger.warn('Policy denied tool execution', {\n reason: decision.reason,\n ruleName: decision.ruleName,\n });\n return policyDeniedError(decision.reason, opts.requestId);\n }\n opts.logger.debug('Policy check passed', { reason: decision.reason });\n return null;\n}\n\n/**\n * Executes handler and logs result.\n */\nasync function executeHandler(\n handler: ToolHandler | ContextAwareHandler,\n args: unknown,\n ctx: HandlerContext,\n logger: ILogger\n): Promise<ToolResult> {\n const startTime = getTimeProvider().now();\n const result =\n handler.length >= 2 ? await handler(args, ctx) : await (handler as ToolHandler)(args);\n\n const durationMs = getTimeProvider().now() - startTime;\n if (result.isError === true) {\n logger.warn('Tool execution completed with error', { durationMs });\n } else {\n logger.info('Tool execution completed', { durationMs });\n }\n return result;\n}\n\n/** Emits an audit event for a completed tool invocation. */\nfunction emitToolAudit(\n auditLogger: IAuditLogger,\n toolName: string,\n ctx: RequestContext,\n result: ToolResult,\n durationMs: number\n): void {\n const actor = actorFromContext(ctx);\n const outcome = resultToOutcome(result.isError, false);\n auditLogger.logToolInvocation({\n toolName,\n outcome,\n actor,\n requestId: ctx.requestId,\n durationMs,\n });\n}\n\n/**\n * Emits an audit event when a tool handler throws (or returns a rejected\n * Promise) — closes the audit-trail gap where unexpected exceptions left\n * no auditor record (security-review fallout from #2191).\n */\nfunction emitToolAuditException(\n auditLogger: IAuditLogger,\n toolName: string,\n ctx: RequestContext,\n durationMs: number\n): void {\n const actor = actorFromContext(ctx);\n auditLogger.logToolInvocation({\n toolName,\n outcome: 'error',\n actor,\n requestId: ctx.requestId,\n durationMs,\n });\n}\n\n/** Emits an audit event for a policy denial. */\nfunction emitPolicyAudit(\n auditLogger: IAuditLogger,\n toolName: string,\n ctx: RequestContext,\n reason: string\n): void {\n const actor = actorFromContext(ctx);\n auditLogger.logPolicyDecision({\n policyName: 'default',\n decision: 'deny',\n reason,\n toolName,\n actor,\n requestId: ctx.requestId,\n });\n}\n\n/** Emits an audit event for a rate limit violation. */\nfunction emitRateLimitAudit(\n auditLogger: IAuditLogger,\n toolName: string,\n ctx: RequestContext\n): void {\n const actor = actorFromContext(ctx);\n auditLogger.logRateLimitViolation({\n toolName,\n actor,\n currentRate: 0,\n limitRate: 0,\n requestId: ctx.requestId,\n });\n}\n\n/** Reject inputs with detected injection patterns for elevated security tiers. */\nfunction checkSecurityTier(\n config: SecureHandlerConfig,\n sanitizeResult: SanitizeToolInputResult,\n logger: ILogger\n): ToolResult | null {\n const tier = config.securityTier ?? 'standard';\n if (tier === 'standard' || sanitizeResult.detectedPatterns.length === 0) {\n return null;\n }\n logger.warn('Input rejected by security tier validation', {\n tier,\n patterns: sanitizeResult.detectedPatterns,\n });\n // Security-tier rejection of suspected injection patterns — an\n // access-control denial, categorized `permission` (#2649).\n return toolStructuredError({\n errorCategory: 'permission',\n message:\n `Input validation failed: detected patterns [${sanitizeResult.detectedPatterns.join(', ')}]. ` +\n 'Remove prompt injection patterns and retry.',\n });\n}\n\n/** Pre-execution checks: input size, input sanitization, rate limit, policy. */\nfunction runPreChecks(\n config: SecureHandlerConfig,\n args: unknown,\n mode: ExecutionMode,\n requestContext: RequestContext,\n logger: ILogger\n): { error: ToolResult | null; sanitizedArgs: unknown } {\n const sizeResult = checkInputSize(args, logger, requestContext.requestId);\n if (sizeResult) return { error: sizeResult, sanitizedArgs: args };\n\n // Sanitize tool input: strip XML injection tags, detect injection patterns (Issue #828)\n const sanitizeResult = sanitizeToolInput(args);\n logSanitizationResult(sanitizeResult, logger, config.toolName);\n const sanitizedArgs = sanitizeResult.wasModified ? sanitizeResult.sanitized : args;\n\n // Tiered validation: reject (not strip) for user-facing/external tools (Issue #1586)\n const tierError = checkSecurityTier(config, sanitizeResult, logger);\n if (tierError !== null) return { error: tierError, sanitizedArgs };\n\n if (config.rateLimiter) {\n const rlResult = checkRateLimit(config.rateLimiter, logger);\n if (rlResult) {\n if (config.auditLogger)\n emitRateLimitAudit(config.auditLogger, config.toolName, requestContext);\n return { error: rlResult, sanitizedArgs };\n }\n }\n\n if (config.policyFirewall) {\n const pResult = checkPolicy({\n firewall: config.policyFirewall,\n toolName: config.toolName,\n args: sanitizedArgs,\n mode,\n allowedPaths: config.allowedPaths,\n logger,\n requestId: requestContext.requestId,\n });\n if (pResult) {\n if (config.auditLogger)\n emitPolicyAudit(config.auditLogger, config.toolName, requestContext, 'policy denied');\n return { error: pResult, sanitizedArgs };\n }\n }\n\n return { error: null, sanitizedArgs };\n}\n\n/**\n * Wraps a tool handler with security middleware.\n *\n * @param handler - The original tool handler or context-aware handler\n * @param config - Security configuration\n * @returns Wrapped handler with security middleware\n */\nexport function createSecureHandler(\n handler: ToolHandler | ContextAwareHandler,\n config: SecureHandlerConfig\n): ToolHandler {\n const logger = config.logger ?? createLogger({ tool: config.toolName });\n const mode = config.executionMode ?? 'read-only';\n\n return async (args: unknown): Promise<ToolResult> => {\n const ctxOpts = {\n toolName: config.toolName,\n ...(config.callerInfo && { caller: config.callerInfo }),\n };\n const requestContext = createRequestContext(ctxOpts);\n const requestLogger = logger.child(contextForLogging(requestContext));\n requestLogger.info('Tool invocation started');\n\n const { error: preCheckError, sanitizedArgs } = runPreChecks(\n config,\n args,\n mode,\n requestContext,\n requestLogger\n );\n if (preCheckError) return preCheckError;\n\n return executeAndAudit(handler, sanitizedArgs, requestContext, requestLogger, config);\n };\n}\n\n/**\n * Executes the wrapped handler with audit emission on both the success and\n * exception paths. Extracted from `createSecureHandler` to keep that\n * function within the 50-line budget.\n */\nasync function executeAndAudit(\n handler: ToolHandler | ContextAwareHandler,\n sanitizedArgs: unknown,\n requestContext: RequestContext,\n requestLogger: ILogger,\n config: SecureHandlerConfig\n): Promise<ToolResult> {\n const execStartTime = getTimeProvider().now();\n try {\n const result = await executeHandler(\n handler,\n sanitizedArgs,\n { requestContext, logger: requestLogger },\n requestLogger\n );\n sanitizeToolResult(result, requestLogger);\n if (config.auditLogger) {\n emitToolAudit(\n config.auditLogger,\n config.toolName,\n requestContext,\n result,\n getTimeProvider().now() - execStartTime\n );\n }\n return result;\n } catch (error) {\n const rawMessage = error instanceof Error ? error.message : 'Unknown error';\n requestLogger.error('Tool execution failed', error instanceof Error ? error : undefined);\n if (config.auditLogger) {\n emitToolAuditException(\n config.auditLogger,\n config.toolName,\n requestContext,\n getTimeProvider().now() - execStartTime\n );\n }\n // Closes a secret-leak path: adapter SDKs commonly echo offending\n // credentials in their error messages (e.g. Anthropic's\n // AuthenticationError carries `sk-ant-api03-…` substrings; fetch\n // wrappers can echo Authorization headers). The success branch above\n // runs sanitizeToolResult; the exception path must too.\n const sanitized = sanitizeOutput(rawMessage, requestLogger);\n return internalError(sanitized, requestContext.requestId);\n }\n}\n\n/**\n * Creates a secure handler factory with shared configuration.\n * Useful for registering multiple tools with the same security settings.\n *\n * @param sharedConfig - Shared security configuration\n * @returns Factory function for creating secure handlers\n */\nexport function createSecureHandlerFactory(\n sharedConfig: Omit<SecureHandlerConfig, 'toolName'>\n): (toolName: string, handler: ToolHandler | ContextAwareHandler) => ToolHandler {\n return (toolName: string, handler: ToolHandler | ContextAwareHandler) =>\n createSecureHandler(handler, { ...sharedConfig, toolName });\n}\n","/**\n * nexus-agents vote command types\n *\n * Type definitions for the consensus voting CLI command.\n *\n * (Source: Issue #212, Process Automation Epic #209)\n */\n\nimport type { ConsensusAlgorithm, Vote, ConsensusResult } from '../consensus/types.js';\nimport type { ErrorPolicy, VoteThreshold } from '../mcp/tools/consensus-vote-types.js';\n\n/**\n * Options for the vote command.\n */\nexport interface VoteCommandOptions {\n readonly proposal: string;\n readonly threshold?: VoteThreshold;\n /** Use simulated votes instead of LLM execution (maps from --dry-run CLI flag) */\n readonly dryRun?: boolean;\n readonly quick?: boolean;\n readonly verbose?: boolean;\n readonly createIssue?: boolean;\n readonly issueNumber?: number;\n /** Timeout per vote in milliseconds (default: 90000 per Issue #607) */\n readonly timeoutMs?: number;\n /**\n * How to treat voters that errored or timed out (#2630). When undefined,\n * the same per-strategy default `executeVoting` uses applies:\n * `fail_closed` for unanimous, `reduce_denominator` otherwise.\n */\n readonly errorPolicy?: ErrorPolicy;\n}\n\n/**\n * Voter agent role definitions.\n *\n * `scope_steward` (#2185) was added 2026-04-25 to address a build-vs-buy\n * blind spot in the original 6-role panel: the panel approved a proposal\n * to build a USB-flasher CLI without flagging that Rufus already solves\n * the problem. The scope-steward role explicitly checks for existing tools\n * + biases toward \"don't build.\"\n */\nexport type VoterRole =\n | 'architect'\n | 'security'\n | 'devex'\n | 'ai_ml'\n | 'pm'\n | 'catfish'\n | 'scope_steward';\n\n/**\n * Agent role descriptions for prompt generation.\n */\nexport const VOTER_ROLES: Record<VoterRole, string> = {\n architect: 'Software Architect - evaluates technical design, scalability, and maintainability',\n security:\n 'Security Engineer - evaluates security implications, vulnerabilities, and attack vectors',\n devex: 'Developer Experience - evaluates usability, documentation, and developer workflow',\n ai_ml: 'AI/ML Engineer - evaluates AI/ML aspects, model selection, and learning capabilities',\n pm: 'Product Manager - evaluates business value, user impact, and resource allocation',\n catfish:\n 'Contrarian Analyst - deliberately challenges proposals to prevent agreement bias (arXiv:2505.21503)',\n scope_steward:\n 'Scope Steward - asks whether to build at all; checks existing tools, biases toward kill-the-feature (#2185)',\n};\n\n/**\n * Individual agent vote with metadata.\n */\nexport interface AgentVoteResult {\n readonly role: VoterRole;\n readonly vote: Vote;\n readonly processingTimeMs: number;\n /**\n * Source of the vote:\n * - 'llm': Real LLM execution\n * - 'simulation': Fallback simulation (opt-in only)\n * - 'error': Error during execution (Issue #523)\n */\n readonly source: 'llm' | 'simulation' | 'error';\n /** CLI that executed this vote (for adaptive routing feedback). */\n readonly cli?: string | undefined;\n /** Error message if vote fell back to simulation or encountered an error */\n readonly error?: string;\n}\n\n/**\n * Full voting result.\n */\nexport interface VotingResult {\n readonly proposal: string;\n readonly threshold: ConsensusAlgorithm;\n readonly result: ConsensusResult;\n readonly votes: readonly AgentVoteResult[];\n readonly totalTimeMs: number;\n /** Whether simulated votes were used instead of LLM execution */\n readonly simulateVotes: boolean;\n}\n\n/**\n * Vote verification hash for audit trail.\n */\nexport interface VoteHash {\n readonly role: VoterRole;\n readonly hash: string;\n readonly timestamp: string;\n}\n","/**\n * CLI-to-Model Adapter Bridge\n *\n * Wraps an ICliAdapter to implement IModelAdapter, enabling CLI tools\n * (claude, gemini, codex) to be used where model adapters are expected.\n *\n * @module cli-adapters/cli-to-model-adapter\n */\n\nimport type {\n Result,\n IModelAdapter,\n CompletionRequest,\n CompletionResponse,\n ModelCapability,\n} from '../core/index.js';\nimport { ModelCapability as MC, ok, err, ModelError, ConfigError } from '../core/index.js';\nimport { estimateTokens } from '../core/token-estimator.js';\nimport type { ICliAdapter, CliTask, CliResponse, CliError, ExecutionOptions } from './types.js';\nimport type { StreamChunk } from '../core/types/model.js';\n\n/** Configuration for CliToModelAdapter. */\nexport interface CliToModelAdapterConfig {\n /** Default timeout for CLI calls (ms). Overrides auto-detection. */\n readonly defaultTimeoutMs?: number;\n}\n\n/**\n * Bridge adapter that wraps ICliAdapter to implement IModelAdapter.\n *\n * This enables using CLI tools (claude, gemini, codex) in contexts\n * that expect IModelAdapter.\n *\n * @example\n * ```typescript\n * const cliAdapter = createCliAdapter({ cli: 'claude' });\n * const modelAdapter = new CliToModelAdapter(cliAdapter);\n *\n * // Now use modelAdapter where IModelAdapter is expected\n * const result = await modelAdapter.complete({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * });\n * ```\n */\nexport class CliToModelAdapter implements IModelAdapter {\n readonly providerId: string;\n readonly modelId: string;\n readonly capabilities: readonly ModelCapability[];\n\n private readonly cliAdapter: ICliAdapter;\n private readonly defaultTimeoutMs: number | undefined;\n\n /**\n * Creates a bridge from CLI adapter to model adapter.\n *\n * @param cliAdapter - The CLI adapter to wrap\n * @param config - Optional configuration (e.g. timeout override)\n */\n constructor(cliAdapter: ICliAdapter, config?: CliToModelAdapterConfig) {\n this.cliAdapter = cliAdapter;\n this.defaultTimeoutMs = config?.defaultTimeoutMs;\n this.providerId = `cli-${cliAdapter.name}`;\n this.modelId = cliAdapter.getModelInfo().id;\n this.capabilities = this.deriveCapabilities();\n }\n\n /**\n * Derives ModelCapability from CLI capabilities.\n */\n private deriveCapabilities(): readonly ModelCapability[] {\n const caps: ModelCapability[] = [MC.COMPLETION, MC.TOOL_USE];\n\n // Claude CLI has extended thinking capability\n if (this.cliAdapter.name === 'claude') {\n caps.push(MC.EXTENDED_THINKING);\n }\n\n return caps;\n }\n\n /**\n * Converts CompletionRequest to CliTask.\n */\n private toCliTask(request: CompletionRequest): CliTask {\n // Build content from messages\n const content = request.messages\n .map((msg) => {\n const text =\n typeof msg.content === 'string'\n ? msg.content\n : msg.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('\\n');\n return `[${msg.role}]: ${text}`;\n })\n .join('\\n\\n');\n\n // Build task with conditional optional properties\n const task: CliTask = { content };\n\n if (request.systemPrompt !== undefined) {\n (task as { systemPrompt: string }).systemPrompt = request.systemPrompt;\n }\n if (request.maxTokens !== undefined) {\n (task as { maxTokens: number }).maxTokens = request.maxTokens;\n }\n\n return task;\n }\n\n /**\n * Converts CliResponse to CompletionResponse.\n */\n private toCompletionResponse(response: CliResponse): CompletionResponse {\n return {\n content: [{ type: 'text', text: response.text }],\n usage: {\n inputTokens: response.usage?.inputTokens ?? 0,\n outputTokens: response.usage?.outputTokens ?? 0,\n totalTokens: response.usage?.totalTokens ?? 0,\n },\n stopReason: 'end_turn',\n model: response.model ?? this.modelId,\n };\n }\n\n /**\n * Converts CliError to ModelError.\n */\n private toModelError(cliError: CliError): ModelError {\n const options = cliError.cause !== undefined ? { cause: cliError.cause } : {};\n return new ModelError(cliError.message, options);\n }\n\n /**\n * Send a completion request via CLI.\n */\n async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n const task = this.toCliTask(request);\n const opts: ExecutionOptions | undefined =\n this.defaultTimeoutMs !== undefined ? { timeoutMs: this.defaultTimeoutMs } : undefined;\n const result = await this.cliAdapter.execute(task, opts);\n\n if (!result.ok) {\n return err(this.toModelError(result.error));\n }\n\n return ok(this.toCompletionResponse(result.value));\n }\n\n /**\n * Streaming is not supported via CLI adapters.\n * Falls back to non-streaming and yields single chunk.\n */\n async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n const result = await this.complete(request);\n\n if (!result.ok) {\n throw result.error;\n }\n\n const response = result.value;\n\n yield { type: 'message_start', message: { model: response.model } };\n\n yield {\n type: 'content_block_start',\n index: 0,\n contentBlock: response.content[0] ?? { type: 'text', text: '' },\n };\n\n const firstBlock = response.content[0];\n const text = firstBlock?.type === 'text' ? firstBlock.text : '';\n yield { type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text } };\n\n yield { type: 'content_block_stop', index: 0 };\n\n yield {\n type: 'message_delta',\n delta: { stop_reason: response.stopReason },\n usage: response.usage,\n };\n\n yield { type: 'message_stop' };\n }\n\n /**\n * Token count via canonical estimator (DRY consolidation Issue #1596).\n */\n countTokens(text: string): Promise<number> {\n return Promise.resolve(estimateTokens(text));\n }\n\n /**\n * Validate configuration by running health check.\n */\n validateConfig(): Result<void, ConfigError> {\n // CLI adapters validate via health check\n return ok(undefined);\n }\n\n /**\n * Initialize the underlying CLI adapter.\n */\n async initialize(): Promise<void> {\n await this.cliAdapter.initialize();\n }\n\n /**\n * Dispose the underlying CLI adapter.\n */\n async dispose(): Promise<void> {\n await this.cliAdapter.dispose();\n }\n}\n\n/**\n * Creates a model adapter from a CLI adapter.\n *\n * @param cliAdapter - The CLI adapter to wrap\n * @returns IModelAdapter implementation\n */\nexport function createCliToModelAdapter(\n cliAdapter: ICliAdapter,\n config?: CliToModelAdapterConfig\n): CliToModelAdapter {\n return new CliToModelAdapter(cliAdapter, config);\n}\n","/**\n * nexus-agents/adapters - Claude/Anthropic Model Adapter\n *\n * Adapter for Anthropic's Claude models (claude-opus-4, claude-sonnet-4, claude-haiku-3).\n * Implements the IModelAdapter interface with streaming support, rate limiting,\n * and proper error handling.\n *\n * Verified 2026-01-03: @anthropic-ai/sdk@0.71.2 is current stable\n * (Source: npm registry)\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages';\nimport type {\n Result,\n CompletionRequest,\n CompletionResponse,\n ModelMetadata,\n StreamChunk,\n ContentBlock,\n TokenUsage,\n} from '../core/index.js';\nimport { ok, err, ModelError, ConfigError, getTokenEstimator } from '../core/index.js';\nimport {\n BaseAdapter,\n type BaseAdapterConfig,\n requireApiKey,\n validateApiKeyPresence,\n} from './base-adapter.js';\nimport { createStream } from './streaming.js';\nimport type { ClaudeAdapterConfig } from './claude-adapter-types.js';\nimport { DEFAULT_MAX_TOKENS } from './claude-adapter-types.js';\nimport {\n mapStopReason,\n mapContentBlock,\n mapMessage,\n mapTool,\n resolveModelId,\n getModelCapabilities,\n} from './claude-adapter-helpers.js';\nimport { extractRequestSystemPrompt } from './prompt-utils.js';\n\n// Re-export types and constants for backward compatibility\nexport type { ClaudeAdapterConfig } from './claude-adapter-types.js';\nexport { CLAUDE_MODELS, CLAUDE_MODEL_ALIASES } from './claude-adapter-types.js';\n\n/**\n * Claude/Anthropic model adapter.\n *\n * Provides a unified interface for interacting with Anthropic's Claude models.\n * Supports completion, streaming, tool use, and vision capabilities.\n *\n * @example\n * ```typescript\n * const adapter = new ClaudeAdapter({\n * modelId: 'claude-sonnet-4',\n * apiKey: process.env.ANTHROPIC_API_KEY,\n * });\n *\n * const result = await adapter.complete({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * maxTokens: 1024,\n * });\n *\n * if (result.ok) {\n * console.log(result.value.content);\n * }\n * ```\n */\nexport class ClaudeAdapter extends BaseAdapter {\n private readonly client: Anthropic;\n private readonly resolvedModelId: string;\n\n /**\n * Creates a new ClaudeAdapter instance.\n *\n * @param config - Claude adapter configuration\n * @throws {ConfigError} If API key is missing\n */\n constructor(config: ClaudeAdapterConfig) {\n const resolvedModelId = resolveModelId(config.modelId);\n\n // Build baseConfig conditionally to satisfy exactOptionalPropertyTypes\n const baseConfig: BaseAdapterConfig = {\n providerId: 'anthropic',\n modelId: resolvedModelId,\n capabilities: getModelCapabilities(config.modelId),\n apiKey: config.apiKey,\n };\n\n // Only set optional properties if defined\n if (config.baseUrl !== undefined) {\n baseConfig.baseUrl = config.baseUrl;\n }\n if (config.timeout !== undefined) {\n baseConfig.timeout = config.timeout;\n }\n if (config.maxRetries !== undefined) {\n baseConfig.maxRetries = config.maxRetries;\n }\n\n super(baseConfig);\n\n this.resolvedModelId = resolvedModelId;\n\n // Validate API key presence\n requireApiKey(config.apiKey, 'Anthropic', config.modelId);\n\n // Create Anthropic client\n this.client = new Anthropic({\n apiKey: config.apiKey,\n baseURL: config.baseUrl,\n timeout: config.timeout,\n maxRetries: config.maxRetries ?? 2,\n });\n }\n\n /**\n * Validates adapter configuration.\n * Extends base validation with Claude-specific checks.\n */\n override validateConfig(): Result<void, ConfigError> {\n const baseResult = super.validateConfig();\n if (!baseResult.ok) {\n return baseResult;\n }\n\n // Validate API key is present\n const keyResult = validateApiKeyPresence(this.config.apiKey, this.providerId, this.modelId);\n if (!keyResult.ok) return keyResult;\n\n return ok(undefined);\n }\n\n /**\n * Send a completion request to Claude.\n *\n * @param request - The completion request\n * @returns Result with response or ModelError\n */\n async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n this.logRequest(request);\n\n try {\n const response = await this.executeCompletion(request);\n this.logResponse(response);\n return ok(response);\n } catch (error) {\n return err(this.transformError(error));\n }\n }\n\n /**\n * Stream a completion request from Claude.\n *\n * @param request - The completion request\n * @yields StreamChunk objects as they arrive\n */\n async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n this.logRequest(request);\n\n const [controller, iterable] = createStream<StreamChunk>();\n\n // Start streaming in the background\n this.executeStream(request, controller).catch((error: unknown) => {\n const modelError = this.transformError(error);\n controller.error(modelError);\n });\n\n yield* iterable;\n }\n\n /**\n * Count tokens in text using Claude-specific estimation.\n *\n * Claude uses a custom tokenizer. This provides a more accurate estimate\n * than the base adapter's generic calculation.\n *\n * @param text - Text to count tokens for\n * @returns Approximate token count\n */\n override countTokens(text: string): Promise<number> {\n // Use unified TokenEstimator with Claude-specific ratio (~3.5 chars/token)\n return Promise.resolve(getTokenEstimator().estimateText(text, 'claude'));\n }\n\n /**\n * Executes the completion request against the Anthropic API.\n */\n private async executeCompletion(request: CompletionRequest): Promise<CompletionResponse> {\n const params = this.buildRequestParams(request);\n const response = await this.client.messages.create(params);\n\n return this.mapResponse(response);\n }\n\n /**\n * Executes streaming completion and pushes chunks to the controller.\n */\n private async executeStream(\n request: CompletionRequest,\n controller: {\n push: (chunk: StreamChunk) => Result<void, Error>;\n complete: () => void;\n error: (error: Error) => void;\n }\n ): Promise<void> {\n try {\n const params = this.buildRequestParams(request);\n const stream = this.client.messages.stream(params);\n\n for await (const event of stream) {\n const chunk = this.mapStreamEvent(event);\n if (chunk) {\n controller.push(chunk);\n }\n }\n\n controller.complete();\n } catch (error) {\n const modelError = this.transformError(error);\n controller.error(modelError);\n }\n }\n\n /**\n * Builds Anthropic API request parameters from our CompletionRequest.\n */\n private buildRequestParams(\n request: CompletionRequest\n ): Anthropic.MessageCreateParamsNonStreaming {\n // Filter out system messages and map the rest\n const messages = request.messages.filter((m) => m.role !== 'system').map(mapMessage);\n\n const params: Anthropic.MessageCreateParamsNonStreaming = {\n model: this.resolvedModelId,\n messages,\n max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,\n };\n\n // Add system prompt if provided\n const systemPrompt = extractRequestSystemPrompt(request);\n if (systemPrompt !== undefined) {\n params.system = systemPrompt;\n }\n\n // Apply optional parameters\n this.applyOptionalParams(params, request);\n\n return params;\n }\n\n /**\n * Applies optional parameters to the request params.\n */\n private applyOptionalParams(\n params: Anthropic.MessageCreateParamsNonStreaming,\n request: CompletionRequest\n ): void {\n if (request.temperature !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- SDK 0.88 deprecated `temperature` for post-Opus-4.6 models; kept for backward compat with older Anthropic models and value 1.0\n params.temperature = request.temperature;\n }\n\n if (request.stop !== undefined && request.stop.length > 0) {\n params.stop_sequences = request.stop;\n }\n\n if (request.tools !== undefined && request.tools.length > 0) {\n params.tools = request.tools.map(mapTool);\n }\n\n // Issue #470: Log warning when responseFormat is requested but not supported\n if (request.responseFormat !== undefined && request.responseFormat.type !== 'text') {\n this.logger.warn('responseFormat is not supported by Claude adapter', {\n requestedFormat: request.responseFormat.type,\n suggestion: 'Use tool use or prompt engineering for structured output',\n });\n }\n }\n\n /**\n * Maps Anthropic API response to our CompletionResponse format.\n */\n private mapResponse(response: Anthropic.Message): CompletionResponse {\n const content: ContentBlock[] = response.content.map(mapContentBlock);\n\n const usage: TokenUsage = {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n totalTokens: response.usage.input_tokens + response.usage.output_tokens,\n };\n\n return {\n content,\n usage,\n stopReason: mapStopReason(response.stop_reason),\n model: response.model,\n };\n }\n\n /**\n * Maps Anthropic stream events to our StreamChunk format.\n */\n private mapStreamEvent(event: MessageStreamEvent): StreamChunk | null {\n switch (event.type) {\n case 'message_start':\n return {\n type: 'message_start',\n message: { model: event.message.model },\n };\n\n case 'content_block_start':\n return {\n type: 'content_block_start',\n index: event.index,\n contentBlock: mapContentBlock(event.content_block),\n };\n\n case 'content_block_delta':\n if (event.delta.type === 'text_delta') {\n return {\n type: 'content_block_delta',\n index: event.index,\n delta: { type: 'text_delta', text: event.delta.text },\n };\n }\n return null;\n\n case 'content_block_stop':\n return {\n type: 'content_block_stop',\n index: event.index,\n };\n\n case 'message_delta':\n return {\n type: 'message_delta',\n delta: { stop_reason: mapStopReason(event.delta.stop_reason ?? null) },\n usage: {\n inputTokens: 0, // Not available in delta\n outputTokens: event.usage.output_tokens,\n totalTokens: event.usage.output_tokens,\n },\n };\n\n case 'message_stop':\n return { type: 'message_stop' };\n\n default:\n return null;\n }\n }\n\n /**\n * (#2540) List models the Anthropic API currently exposes.\n * Wraps `client.models.list()`. Cached for 5 min, in-flight promise\n * shared across concurrent callers, throws on non-2xx so the\n * harness-side identity resolver knows to fall back.\n */\n async listModels(): Promise<readonly ModelMetadata[]> {\n const now = Date.now();\n if (this.modelsCache !== null && now - this.modelsCache.fetchedAt < CLAUDE_LIST_MODELS_TTL_MS) {\n return this.modelsCache.value;\n }\n if (this.modelsInFlight !== null) return this.modelsInFlight;\n const inFlight = this.fetchModels();\n this.modelsInFlight = inFlight;\n try {\n const value = await inFlight;\n this.modelsCache = { value, fetchedAt: Date.now() };\n return value;\n } finally {\n this.modelsInFlight = null;\n }\n }\n\n private modelsCache: { value: readonly ModelMetadata[]; fetchedAt: number } | null = null;\n private modelsInFlight: Promise<readonly ModelMetadata[]> | null = null;\n\n private async fetchModels(): Promise<readonly ModelMetadata[]> {\n const list = await this.client.models.list();\n const out: ModelMetadata[] = [];\n for (const m of list.data) {\n const entry: ModelMetadata = { id: m.id };\n if (typeof m.created_at === 'string') {\n const ts = Date.parse(m.created_at);\n if (!Number.isNaN(ts)) {\n out.push({ ...entry, ownedBy: 'anthropic', createdAt: Math.floor(ts / 1000) });\n continue;\n }\n }\n out.push({ ...entry, ownedBy: 'anthropic' });\n }\n return out;\n }\n}\n\nconst CLAUDE_LIST_MODELS_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Creates a ClaudeAdapter with the specified configuration.\n * Factory function for cleaner API.\n *\n * @param config - Claude adapter configuration\n * @returns A configured ClaudeAdapter instance\n *\n * @example\n * ```typescript\n * const adapter = createClaudeAdapter({\n * modelId: 'claude-sonnet-4',\n * apiKey: process.env.ANTHROPIC_API_KEY!,\n * });\n * ```\n */\nexport function createClaudeAdapter(config: ClaudeAdapterConfig): ClaudeAdapter {\n return new ClaudeAdapter(config);\n}\n","/**\n * nexus-agents/adapters - Claude Adapter Types\n *\n * Type definitions and constants for the Claude/Anthropic adapter.\n *\n * @module adapters/claude-adapter-types\n */\n\nimport { getCliModelName } from '../config/model-config-helpers.js';\n\n/**\n * Supported Claude model identifiers.\n *\n * Derived from `config/in-tree-data.ts` via `getCliModelName()` (which reads\n * the ModelRegistry — see `config/model-registry.ts`). Do not hardcode\n * model-version strings here; update the registry.\n */\nexport const CLAUDE_MODELS = {\n OPUS_4: getCliModelName('claude-opus'),\n SONNET_4: getCliModelName('claude-sonnet'),\n HAIKU_4: getCliModelName('claude-haiku'),\n} as const;\n\n/**\n * Legacy version-suffix aliases mapped to the current registry cliModelName.\n *\n * Values come from `CLAUDE_MODELS` so they stay in sync with the canonical\n * registry. Add legacy entries here, never the version strings themselves.\n */\nexport const CLAUDE_MODEL_ALIASES: Record<string, string> = {\n 'claude-opus-4': CLAUDE_MODELS.OPUS_4,\n 'claude-sonnet-4': CLAUDE_MODELS.SONNET_4,\n 'claude-haiku-4': CLAUDE_MODELS.HAIKU_4,\n // Legacy alias — pre-4.x users routed to the current haiku.\n 'claude-haiku-3': CLAUDE_MODELS.HAIKU_4,\n} as const;\n\n/**\n * Configuration specific to ClaudeAdapter.\n */\nexport interface ClaudeAdapterConfig {\n /** Model ID (e.g., 'claude-sonnet-4' or full model identifier) */\n modelId: string;\n /** API key for Anthropic API (required) */\n apiKey: string;\n /** Base URL for API (optional, defaults to Anthropic's API) */\n baseUrl?: string;\n /** Request timeout in milliseconds (optional) */\n timeout?: number;\n /** Maximum retries for failed requests (optional) */\n maxRetries?: number;\n}\n\n// Note: Token estimation moved to core/token-estimator.ts (unified TokenEstimator)\n\n/**\n * Default maximum tokens for Claude models.\n */\nexport const DEFAULT_MAX_TOKENS = 4096;\n","/**\n * nexus-agents/adapters - Claude Adapter Helpers\n *\n * Helper functions for mapping between nexus-agents types and Anthropic SDK types.\n *\n * @module adapters/claude-adapter-helpers\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type {\n MessageParam,\n ContentBlock as AnthropicContentBlock,\n} from '@anthropic-ai/sdk/resources/messages';\nimport type { ContentBlock, Message, ToolDefinition, StopReason } from '../core/index.js';\nimport { ModelCapability } from '../core/index.js';\nimport { getCliModelName, resolveCliAlias } from '../config/model-config-helpers.js';\n\n/**\n * Maps Anthropic stop reasons to our StopReason type.\n */\nexport function mapStopReason(anthropicReason: string | null): StopReason {\n switch (anthropicReason) {\n case 'end_turn':\n return 'end_turn';\n case 'max_tokens':\n return 'max_tokens';\n case 'stop_sequence':\n return 'stop_sequence';\n case 'tool_use':\n return 'tool_use';\n default:\n return 'end_turn';\n }\n}\n\n/**\n * Maps Anthropic content blocks to our ContentBlock type.\n */\nexport function mapContentBlock(block: AnthropicContentBlock): ContentBlock {\n if (block.type === 'text') {\n return { type: 'text', text: block.text };\n }\n if (block.type === 'tool_use') {\n const toolBlock = block;\n return {\n type: 'tool_use',\n id: toolBlock.id,\n name: toolBlock.name,\n input: toolBlock.input,\n };\n }\n // Handle unexpected block types gracefully\n return { type: 'text', text: '' };\n}\n\n/**\n * Maps our Message format to Anthropic's MessageParam format.\n */\nexport function mapMessage(message: Message): MessageParam {\n const role = message.role === 'user' ? 'user' : 'assistant';\n\n if (typeof message.content === 'string') {\n return { role, content: message.content };\n }\n\n // Map content blocks\n const content = message.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: block.text };\n }\n if (block.type === 'tool_use') {\n return {\n type: 'tool_use' as const,\n id: block.id,\n name: block.name,\n input: block.input,\n };\n }\n if (block.type === 'tool_result') {\n const toolResult: {\n type: 'tool_result';\n tool_use_id: string;\n content: string;\n is_error?: boolean;\n } = {\n type: 'tool_result' as const,\n tool_use_id: block.tool_use_id,\n content: block.content,\n };\n // Only set is_error if explicitly defined (exactOptionalPropertyTypes)\n if (block.is_error !== undefined) {\n toolResult.is_error = block.is_error;\n }\n return toolResult;\n }\n // Image type is the remaining possibility\n // Cast source to match Anthropic's expected type\n return {\n type: 'image' as const,\n source: block.source as Anthropic.ImageBlockParam['source'],\n };\n });\n\n return { role, content };\n}\n\n/**\n * Maps our ToolDefinition to Anthropic's tool format.\n */\nexport function mapTool(tool: ToolDefinition): Anthropic.Tool {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.inputSchema as Anthropic.Tool.InputSchema,\n };\n}\n\n/**\n * Resolves a Claude model alias to the full identifier the SDK expects.\n *\n * `resolveCliAlias` consults the canonical registry — both the cliAlias /\n * id columns AND the `aliases` array (#2199 Child 5 migration). Unknown\n * ids pass through (e.g., custom Bedrock identifiers).\n *\n * The canonical model strings live in `config/in-tree-data.ts` and are\n * resolved through the ModelRegistry; this function never holds them\n * directly (issue #2186 Child 1).\n */\nexport function resolveModelId(modelId: string): string {\n const registryId = resolveCliAlias(modelId);\n if (registryId !== undefined) return getCliModelName(registryId);\n return modelId;\n}\n\n/**\n * Determines capabilities based on model ID.\n */\nexport function getModelCapabilities(modelId: string): readonly ModelCapability[] {\n const capabilities: ModelCapability[] = [\n ModelCapability.COMPLETION,\n ModelCapability.STREAMING,\n ModelCapability.TOOL_USE,\n ModelCapability.VISION,\n ];\n\n // Extended thinking is available on Opus and Sonnet 4\n const resolvedId = resolveModelId(modelId);\n if (resolvedId.includes('opus') || resolvedId.includes('sonnet-4')) {\n capabilities.push(ModelCapability.EXTENDED_THINKING);\n }\n\n return capabilities;\n}\n","/**\n * nexus-agents/context - Token Counter Helpers\n *\n * Internal helper functions for token counting.\n *\n * @module context/token-counter-helpers\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Message } from '../core/index.js';\nimport type { TokenCounterProvider } from './token-counter-types.js';\n\n/**\n * Generates a cache key from content.\n */\nexport function generateCacheKey(\n content: string | Message[],\n provider: TokenCounterProvider | 'estimate',\n model?: string\n): string {\n const contentStr = typeof content === 'string' ? content : JSON.stringify(content);\n return `${provider}:${model ?? 'default'}:${contentStr}`;\n}\n\n/**\n * Converts Message[] to Anthropic MessageParam[] format.\n */\nexport function messagesToAnthropicFormat(messages: Message[]): Anthropic.MessageParam[] {\n return messages\n .filter((m) => m.role !== 'system')\n .map((m) => {\n const role = m.role === 'user' ? 'user' : 'assistant';\n if (typeof m.content === 'string') {\n return { role, content: m.content };\n }\n // Map content blocks\n const content = m.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: block.text };\n }\n if (block.type === 'tool_use') {\n return {\n type: 'tool_use' as const,\n id: block.id,\n name: block.name,\n input: block.input,\n };\n }\n if (block.type === 'tool_result') {\n return {\n type: 'tool_result' as const,\n tool_use_id: block.tool_use_id,\n content: block.content,\n };\n }\n // Image type - handle source type properly\n return {\n type: 'image' as const,\n source: block.source as Anthropic.ImageBlockParam['source'],\n };\n });\n return { role, content };\n });\n}\n\n/**\n * Extracts system prompt from messages if present.\n */\nexport function extractSystemPrompt(messages: Message[]): string | undefined {\n const systemMsg = messages.find((m) => m.role === 'system');\n if (systemMsg === undefined) {\n return undefined;\n }\n if (typeof systemMsg.content === 'string') {\n return systemMsg.content;\n }\n return systemMsg.content\n .filter((b): b is { type: 'text'; text: string } => b.type === 'text')\n .map((b) => b.text)\n .join('\\n');\n}\n","/**\n * Shared prompt extraction utilities for model adapters.\n *\n * Consolidates the duplicated extractSystemPrompt logic from\n * claude-adapter, gemini-adapter, and ollama-adapter into a single\n * implementation.\n *\n * @module adapters/prompt-utils\n * (Source: Issue #1596 — DRY adapter standardization)\n */\n\nimport type { CompletionRequest } from '../core/index.js';\nimport { extractSystemPrompt } from '../context/token-counter-helpers.js';\n\n/**\n * Extracts the system prompt from a CompletionRequest.\n *\n * Checks the explicit `systemPrompt` field first, then falls back to\n * searching the messages array for a system-role message.\n */\nexport function extractRequestSystemPrompt(request: CompletionRequest): string | undefined {\n if (request.systemPrompt !== undefined && request.systemPrompt !== '') {\n return request.systemPrompt;\n }\n return extractSystemPrompt(request.messages);\n}\n","/**\n * nexus-agents/adapters/sdk - Base SDK Adapter\n *\n * Implements IModelAdapter using the Vercel AI SDK's generateText/streamText\n * APIs. Provides a unified adapter for any AI SDK-supported provider.\n *\n * @module adapters/sdk/sdk-adapter\n * (Source: Issue #1123 — AI SDK provider layer)\n */\n\nimport type {\n CompletionRequest,\n CompletionResponse,\n ContentBlock,\n StreamChunk,\n Result,\n ILogger,\n} from '../../core/index.js';\nimport {\n ok,\n ModelError,\n ModelCapability,\n createLogger,\n getErrorMessage,\n} from '../../core/index.js';\nimport { BaseAdapter, AdapterModelError } from '../base-adapter.js';\nimport { ErrorCode } from '../../core/index.js';\nimport { isRateLimitLikeError } from '../rate-limit-detector.js';\nimport { sanitizeOutput } from '../../security/output-sanitizer.js';\nimport type { SdkAdapterConfig, SdkProviderId } from './types.js';\nimport { PROVIDER_ENV_KEYS, CUSTOM_API_BASE_URL_ENV } from './types.js';\nimport { validateCustomApiBaseUrl } from './custom-api-validation.js';\n\n/** Minimal AI SDK model interface (duck-typed for optional dependency). */\ninterface AiSdkModel {\n readonly modelId: string;\n}\n\n/** AI SDK generateText result shape (duck-typed). */\ninterface GenerateTextResult {\n text: string;\n finishReason: string;\n usage: {\n inputTokens: number | undefined;\n outputTokens: number | undefined;\n totalTokens: number | undefined;\n };\n response: { modelId: string };\n}\n\n/** AI SDK streamText result shape (duck-typed). */\ninterface StreamTextResult {\n textStream: AsyncIterable<string>;\n}\n\n/** Function signatures for AI SDK entry points (loaded dynamically). */\ninterface AiSdkFunctions {\n generateText: (options: Record<string, unknown>) => Promise<GenerateTextResult>;\n streamText: (options: Record<string, unknown>) => StreamTextResult;\n}\n\n/** AI SDK provider factory: creates a provider instance that is callable as a model factory. */\ntype ProviderFactory = (opts: Record<string, unknown>) => ProviderInstance;\n\n/** AI SDK provider instance: callable to create a model. */\ntype ProviderInstance = (id: string) => AiSdkModel;\n\n/**\n * Extracts a named provider factory from a dynamically-imported AI SDK module.\n *\n * AI SDK provider modules export factory functions (e.g., createAnthropic, createOpenAI)\n * that return callable provider instances. Since these are optional peer dependencies\n * loaded via dynamic import, we validate the shape at runtime rather than relying on\n * compile-time types.\n */\nfunction extractProviderFactory(\n mod: Record<string, unknown>,\n factoryName: string\n): ProviderFactory {\n const factory = mod[factoryName];\n if (typeof factory !== 'function') {\n throw new Error(`AI SDK module missing expected export: ${factoryName}`);\n }\n return factory as ProviderFactory;\n}\n\n/**\n * Validates a dynamically-imported AI SDK module has the expected generateText/streamText exports.\n *\n * The 'ai' package is an optional peer dependency loaded via dynamic import.\n * We validate the shape at runtime to avoid unsafe casts.\n */\nfunction extractAiSdkFunctions(mod: Record<string, unknown>): AiSdkFunctions {\n const generateText = mod['generateText'];\n const streamText = mod['streamText'];\n if (typeof generateText !== 'function') {\n throw new Error(\"AI SDK module missing expected export: 'generateText'\");\n }\n if (typeof streamText !== 'function') {\n throw new Error(\"AI SDK module missing expected export: 'streamText'\");\n }\n return {\n generateText: generateText as AiSdkFunctions['generateText'],\n streamText: streamText as AiSdkFunctions['streamText'],\n };\n}\n\n/**\n * Resolves the API key for a given provider.\n * Priority: explicit config > environment variable.\n */\nfunction resolveApiKey(providerId: SdkProviderId, configKey?: string): string | undefined {\n if (configKey !== undefined) return configKey;\n const envVar = PROVIDER_ENV_KEYS[providerId];\n return process.env[envVar];\n}\n\n/**\n * For the `custom-openai` provider only: resolve the base URL (config >\n * env) and run it through the SSRF guard. Returns `undefined` for every\n * other provider (the AI SDK's built-in factories handle their own\n * endpoints). Throws `ConfigError` at construction time for invalid\n * custom-openai setups — catching misconfiguration immediately rather\n * than on the first request.\n */\nfunction resolveAndValidateCustomBaseUrl(config: SdkAdapterConfig): string | undefined {\n if (config.providerId !== 'custom-openai') return undefined;\n const raw = config.baseUrl ?? process.env[CUSTOM_API_BASE_URL_ENV];\n const validated = validateCustomApiBaseUrl(raw);\n if (!validated.ok) throw validated.error;\n return validated.value.toString();\n}\n\n/**\n * Maps AI SDK finish reasons to our StopReason type.\n */\nfunction mapFinishReason(reason: string): CompletionResponse['stopReason'] {\n switch (reason) {\n case 'stop':\n case 'end-turn':\n return 'end_turn';\n case 'length':\n return 'max_tokens';\n case 'tool-calls':\n return 'tool_use';\n default:\n return 'end_turn';\n }\n}\n\n/**\n * Categorizes an error into an ErrorCode for the circuit breaker.\n */\nfunction categorizeError(error: unknown): ErrorCode {\n if (isRateLimitLikeError(error)) {\n return ErrorCode.MODEL_RATE_LIMITED;\n }\n const message = getErrorMessage(error).toLowerCase();\n if (message.includes('timeout') || message.includes('timed out')) {\n return ErrorCode.MODEL_TIMEOUT;\n }\n if (message.includes('401') || message.includes('unauthorized') || message.includes('api key')) {\n return ErrorCode.CONFIG_INVALID;\n }\n return ErrorCode.MODEL_ERROR;\n}\n\n/**\n * AI SDK adapter implementing IModelAdapter.\n *\n * Uses Vercel AI SDK (npm: ai) for model interaction instead of\n * CLI subprocess spawning. Supports any provider that has an\n * `@ai-sdk/*` package.\n */\nexport class SdkAdapter extends BaseAdapter {\n private readonly sdkProviderId: SdkProviderId;\n private model: AiSdkModel | undefined;\n private sdkFunctions: AiSdkFunctions | undefined;\n private readonly sdkConfig: SdkAdapterConfig;\n /** Validated base URL for custom-openai provider; undefined for built-ins. */\n private readonly customBaseUrl: string | undefined;\n /** Inflight init promise for coalescing concurrent calls (Issue #1438). */\n private initPromise: Promise<void> | undefined;\n\n constructor(config: SdkAdapterConfig, logger?: ILogger) {\n const apiKey = resolveApiKey(config.providerId, config.apiKey);\n super({\n providerId: `sdk-${config.providerId}`,\n modelId: config.modelId,\n capabilities: [ModelCapability.COMPLETION, ModelCapability.STREAMING],\n logger: logger ?? createLogger({ adapter: `sdk-${config.providerId}` }),\n ...(apiKey !== undefined ? { apiKey } : {}),\n ...(config.timeout !== undefined ? { timeout: config.timeout } : {}),\n ...(config.maxRetries !== undefined ? { maxRetries: config.maxRetries } : {}),\n });\n this.sdkProviderId = config.providerId;\n this.sdkConfig = config;\n this.customBaseUrl = resolveAndValidateCustomBaseUrl(config);\n }\n\n /**\n * Lazily initialize the AI SDK model and functions.\n * This allows the adapter to be created without the AI SDK installed,\n * failing only when actually used.\n */\n private async ensureInitialized(): Promise<void> {\n if (this.model !== undefined) return;\n // Coalesce concurrent init calls into a single load (Issue #1438)\n if (this.initPromise !== undefined) {\n await this.initPromise;\n return;\n }\n this.initPromise = this.doInitialize();\n try {\n await this.initPromise;\n } finally {\n this.initPromise = undefined;\n }\n }\n\n private async doInitialize(): Promise<void> {\n const apiKey = resolveApiKey(this.sdkProviderId, this.sdkConfig.apiKey);\n if (apiKey === undefined) {\n throw new AdapterModelError(`No API key for ${this.sdkProviderId}`, {\n code: ErrorCode.CONFIG_INVALID,\n });\n }\n\n // Dynamic import — AI SDK is an optional peer dependency\n const providerModule = await this.loadProvider(apiKey);\n this.model = providerModule.model;\n\n // AI SDK is an optional peer dependency — validate shape at runtime\n const aiModule = await import('ai');\n this.sdkFunctions = extractAiSdkFunctions(aiModule);\n }\n\n /**\n * Loads the provider-specific AI SDK module.\n *\n * Each @ai-sdk/* package exports a factory function (e.g., createAnthropic)\n * that returns a callable provider instance. We use extractProviderFactory()\n * to validate the export exists at runtime, since these are optional peer deps.\n */\n private async loadProvider(apiKey: string): Promise<{ model: AiSdkModel }> {\n switch (this.sdkProviderId) {\n case 'anthropic': {\n const mod = await import('@ai-sdk/anthropic');\n const factory = extractProviderFactory(mod, 'createAnthropic');\n const provider = factory({ apiKey });\n return { model: provider(this.modelId) };\n }\n case 'openai': {\n const mod = await import('@ai-sdk/openai');\n const factory = extractProviderFactory(mod, 'createOpenAI');\n const provider = factory({ apiKey });\n return { model: provider(this.modelId) };\n }\n case 'google': {\n const mod = await import('@ai-sdk/google');\n const factory = extractProviderFactory(mod, 'createGoogleGenerativeAI');\n const provider = factory({ apiKey });\n return { model: provider(this.modelId) };\n }\n case 'custom-openai': {\n // OpenAI-compatible gateway (multi-vendor proxies, self-hosted servers,\n // corporate LLM gateways). Reuses @ai-sdk/openai with a configurable\n // baseURL. See custom-api-validation.ts for the SSRF guard; the\n // adapter constructor validates before this method is reached.\n const mod = await import('@ai-sdk/openai');\n const factory = extractProviderFactory(mod, 'createOpenAI');\n const opts: Record<string, unknown> = { apiKey };\n if (this.customBaseUrl !== undefined) opts['baseURL'] = this.customBaseUrl;\n const provider = factory(opts);\n return { model: provider(this.modelId) };\n }\n }\n }\n\n /**\n * Maps our CompletionRequest to AI SDK generateText options.\n */\n private buildSdkOptions(request: CompletionRequest): Record<string, unknown> {\n const options: Record<string, unknown> = {\n model: this.model,\n messages: request.messages.map((m) => ({\n role: m.role === 'system' ? 'system' : m.role,\n content:\n typeof m.content === 'string'\n ? m.content\n : m.content.map((c: ContentBlock) => {\n if (c.type === 'text') return { type: 'text' as const, text: c.text };\n return c;\n }),\n })),\n };\n\n if (request.systemPrompt !== undefined) {\n options['system'] = request.systemPrompt;\n }\n if (request.temperature !== undefined) {\n options['temperature'] = request.temperature;\n }\n if (request.maxTokens !== undefined) {\n options['maxTokens'] = request.maxTokens;\n }\n if (request.stop !== undefined) {\n options['stopSequences'] = request.stop;\n }\n\n return options;\n }\n\n async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n try {\n await this.ensureInitialized();\n this.logRequest(request);\n\n const sdk = this.sdkFunctions;\n if (sdk === undefined) {\n throw new Error(\n `SDK not initialized for model '${this.sdkConfig.modelId}' (provider: ${this.sdkProviderId}). ` +\n 'Ensure ensureInitialized() completes before calling complete().'\n );\n }\n const options = this.buildSdkOptions(request);\n const result = await sdk.generateText(options);\n\n const response: CompletionResponse = {\n content: [{ type: 'text', text: result.text }],\n usage: {\n inputTokens: result.usage.inputTokens ?? 0,\n outputTokens: result.usage.outputTokens ?? 0,\n totalTokens: result.usage.totalTokens ?? 0,\n },\n stopReason: mapFinishReason(result.finishReason),\n model: result.response.modelId,\n };\n\n this.logResponse(response);\n return ok(response);\n } catch (error: unknown) {\n const code = categorizeError(error);\n return this.toErrorResult(error, code);\n }\n }\n\n async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n // Ensure initialization and SDK readiness before entering the generator body.\n // Errors thrown before the first yield in an async generator bypass for-await-of\n // try/catch in callers, so we validate eagerly and wrap the body in try/catch.\n await this.ensureInitialized();\n this.logRequest(request);\n\n const sdk = this.sdkFunctions;\n if (sdk === undefined) {\n throw new AdapterModelError('SDK not initialized after ensureInitialized()', {\n code: ErrorCode.CONFIG_INVALID,\n });\n }\n\n const options = this.buildSdkOptions(request);\n\n // First yield establishes the generator — errors after this point are\n // properly caught by callers using for-await-of with try/catch.\n yield { type: 'message_start', message: { model: this.modelId } };\n\n const result = sdk.streamText(options);\n let index = 0;\n yield { type: 'content_block_start', index, contentBlock: { type: 'text', text: '' } };\n\n for await (const text of result.textStream) {\n yield {\n type: 'content_block_delta',\n index,\n delta: { type: 'text_delta', text },\n };\n }\n\n yield { type: 'content_block_stop', index };\n index++;\n yield {\n type: 'message_delta',\n delta: { stop_reason: 'end_turn' },\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n };\n yield { type: 'message_stop' };\n }\n\n /**\n * Converts a caught error into a Result error with categorized ErrorCode.\n */\n private toErrorResult(error: unknown, code: ErrorCode): Result<CompletionResponse, ModelError> {\n const message = getErrorMessage(error);\n // Scrub API keys + bearer tokens out of upstream SDK error messages\n // before they hit logs or the surfaced ModelError. Parity with the\n // subprocess-adapter path. Audit #2824.\n const safeMessage = sanitizeOutput(message);\n const errorObj = error instanceof Error ? error : new Error(safeMessage);\n this.logger.error(`SDK adapter error (${this.sdkProviderId})`, errorObj);\n // AdapterModelError extends ModelError — no cast needed\n const modelError = new AdapterModelError(`${this.sdkProviderId} SDK error: ${safeMessage}`, {\n code,\n });\n return { ok: false, error: modelError };\n }\n}\n","/**\n * Auto-Selecting Model Adapter Factory\n *\n * Automatically selects the best available adapter:\n * 1. CLI adapters (claude/gemini/codex) - OAuth, no API keys needed\n * The CLIs handle model selection internally.\n * 2. API adapters (Anthropic/OpenAI) - requires API keys (fallback)\n *\n * Supports optional caching to avoid repeated CLI health checks.\n *\n * @module adapters/auto-adapter\n * (Source: Issue #165 - CLI detection cache)\n */\n\nimport type { IModelAdapter, ILogger } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\nimport { createCliAdapter, isCliAvailable, getAvailableClis } from '../cli-adapters/factory.js';\nimport { createCliToModelAdapter } from '../cli-adapters/cli-to-model-adapter.js';\nimport { createClaudeAdapter } from './claude-adapter.js';\nimport { SdkAdapter } from './sdk/index.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport type { ICliDetectionCache } from '../cli-adapters/cli-detection-cache.js';\nimport { createCliDetectionCache } from '../cli-adapters/cli-detection-cache.js';\nimport { CUSTOM_API_DEFAULT_MODEL } from '../config/defaults.js';\nimport { getCliModelName, getDefaultModelForCli } from '../config/model-config-helpers.js';\n\n/**\n * Adapter selection priority.\n */\nexport type AdapterPriority = 'cli-first' | 'api-first' | 'cli-only' | 'api-only';\n\n/**\n * Configuration for auto-selecting adapters.\n */\nexport interface AutoAdapterConfig {\n /** Selection priority (default: 'cli-first') */\n readonly priority?: AdapterPriority;\n /** Preferred CLI if multiple available (optional) */\n readonly preferredCli?: CliName;\n /** API key for Anthropic (optional, for fallback) */\n readonly anthropicApiKey?: string;\n /** API key for OpenAI (optional, for fallback via AI SDK) */\n readonly openaiApiKey?: string;\n /** API key for Google AI (optional, for fallback via AI SDK) */\n readonly googleApiKey?: string;\n /** Logger instance */\n readonly logger?: ILogger;\n /** CLI detection cache (optional, creates new if not provided) */\n readonly cache?: ICliDetectionCache;\n /** Whether to create and use cache if not provided (default: true) */\n readonly enableCache?: boolean;\n /** Default timeout for CLI subprocess calls (ms). Overrides auto-detection. */\n readonly defaultCliTimeoutMs?: number;\n}\n\n/**\n * Result of adapter selection.\n */\nexport interface AdapterSelection {\n /** The selected adapter */\n readonly adapter: IModelAdapter;\n /** Source of the adapter */\n readonly source: 'cli' | 'api';\n /** Which CLI or API was selected */\n readonly name: string;\n /** Why this adapter was selected */\n readonly reason: string;\n /** The cache used for CLI detection (for reuse) */\n readonly cache?: ICliDetectionCache | undefined;\n}\n\nconst defaultLogger = createLogger({ component: 'auto-adapter' });\n\n/**\n * Resolves the cache to use based on configuration.\n */\nfunction resolveCache(config: AutoAdapterConfig, logger: ILogger): ICliDetectionCache | undefined {\n if (config.cache !== undefined) {\n return config.cache;\n }\n const enableCache = config.enableCache ?? true;\n return enableCache ? createCliDetectionCache({ logger }) : undefined;\n}\n\n/**\n * Attempts to create a CLI-based model adapter.\n * The CLI tools (claude, gemini, codex) handle their own model selection.\n * Uses cache to avoid repeated health checks.\n */\nasync function tryCliAdapter(\n config: AutoAdapterConfig,\n logger: ILogger,\n cache?: ICliDetectionCache\n): Promise<AdapterSelection | null> {\n const preferredCli = config.preferredCli;\n\n const bridgeConfig =\n config.defaultCliTimeoutMs !== undefined\n ? { defaultTimeoutMs: config.defaultCliTimeoutMs }\n : undefined;\n\n // If preferred CLI specified, try that first\n if (preferredCli !== undefined && (await isCliAvailable(preferredCli, cache))) {\n logger.info('Using preferred CLI', { cli: preferredCli });\n const cliAdapter = createCliAdapter({ cli: preferredCli, logger });\n await cliAdapter.initialize();\n return {\n adapter: createCliToModelAdapter(cliAdapter, bridgeConfig),\n source: 'cli',\n name: preferredCli,\n reason: `Preferred CLI '${preferredCli}' is available (model selection handled by CLI)`,\n cache,\n };\n }\n\n // Otherwise, get all available CLIs and use the first one found\n const availableClis = await getAvailableClis(cache);\n\n if (availableClis.length === 0) {\n logger.info('No CLI adapters available');\n return null;\n }\n\n // Use first available CLI - each CLI handles its own model selection\n const selectedCli = availableClis[0];\n\n if (selectedCli === undefined) {\n return null;\n }\n\n logger.info('Auto-selected CLI', { cli: selectedCli, available: availableClis });\n const cliAdapter = createCliAdapter({ cli: selectedCli, logger });\n await cliAdapter.initialize();\n\n return {\n adapter: createCliToModelAdapter(cliAdapter, bridgeConfig),\n source: 'cli',\n name: selectedCli,\n reason: `Using '${selectedCli}' CLI (model selection handled by CLI)`,\n cache,\n };\n}\n\n/**\n * Resolves an API key from config or environment variable.\n */\nfunction resolveApiKeyFromEnv(configKey: string | undefined, envVar: string): string | undefined {\n const key = configKey ?? process.env[envVar];\n return key !== undefined && key.length > 0 ? key : undefined;\n}\n\n/**\n * Attempts to create an API-based model adapter.\n * Tries providers in order: Anthropic (native), OpenAI (SDK), Google (SDK).\n * This is a fallback when no CLIs are available.\n */\nfunction tryApiAdapter(config: AutoAdapterConfig, logger: ILogger): AdapterSelection | null {\n // Derive default model IDs from canonical registry instead of hardcoding\n const claudeModelId = getCliModelName(getDefaultModelForCli('claude'));\n const codexModelId = getCliModelName(getDefaultModelForCli('codex'));\n const geminiModelId = getCliModelName(getDefaultModelForCli('gemini'));\n\n // 1. Anthropic — use native ClaudeAdapter (battle-tested)\n const anthropicKey = resolveApiKeyFromEnv(config.anthropicApiKey, 'ANTHROPIC_API_KEY');\n if (anthropicKey !== undefined) {\n logger.info('Using Anthropic API adapter', { model: claudeModelId });\n return {\n adapter: createClaudeAdapter({ modelId: claudeModelId, apiKey: anthropicKey }),\n source: 'api',\n name: 'anthropic',\n reason: `Using Anthropic API (native adapter, model: ${claudeModelId})`,\n };\n }\n\n // 2. OpenAI — use AI SDK adapter\n const openaiKey = resolveApiKeyFromEnv(config.openaiApiKey, 'OPENAI_API_KEY');\n if (openaiKey !== undefined) {\n logger.info('Using OpenAI API adapter (AI SDK)', { model: codexModelId });\n return {\n adapter: new SdkAdapter({ providerId: 'openai', modelId: codexModelId, apiKey: openaiKey }),\n source: 'api',\n name: 'openai',\n reason: `Using OpenAI API via AI SDK (model: ${codexModelId})`,\n };\n }\n\n // 3. Google — use AI SDK adapter\n const googleKey = resolveApiKeyFromEnv(config.googleApiKey, 'GOOGLE_AI_API_KEY');\n if (googleKey !== undefined) {\n logger.info('Using Google AI API adapter (AI SDK)', { model: geminiModelId });\n return {\n adapter: new SdkAdapter({\n providerId: 'google',\n modelId: geminiModelId,\n apiKey: googleKey,\n }),\n source: 'api',\n name: 'google',\n reason: `Using Google AI API via AI SDK (model: ${geminiModelId})`,\n };\n }\n\n // 4. Custom OpenAI-compatible gateway (multi-vendor proxies, self-hosted\n // LLM servers, corporate gateways). Extracted for line limit.\n const custom = tryCustomOpenAiAdapter(logger);\n if (custom !== null) return custom;\n\n logger.info('No API keys available for any provider');\n return null;\n}\n\n/**\n * Tries the custom-openai SDK adapter if `NEXUS_CUSTOM_API_KEY` and\n * `NEXUS_CUSTOM_API_BASE_URL` are both set. The adapter constructor\n * runs the base URL through an SSRF guard (see\n * adapters/sdk/custom-api-validation.ts). Epic #2119.\n */\nfunction tryCustomOpenAiAdapter(logger: ILogger): AdapterSelection | null {\n const customKey = resolveApiKeyFromEnv(undefined, 'NEXUS_CUSTOM_API_KEY');\n const customBaseUrl = process.env['NEXUS_CUSTOM_API_BASE_URL'];\n if (customKey === undefined || customBaseUrl === undefined || customBaseUrl === '') {\n return null;\n }\n const customModelId = process.env['NEXUS_CUSTOM_MODEL'] ?? CUSTOM_API_DEFAULT_MODEL;\n logger.info('Using custom-openai SDK adapter', {\n model: customModelId,\n baseUrl: customBaseUrl,\n });\n return {\n adapter: new SdkAdapter({\n providerId: 'custom-openai',\n modelId: customModelId,\n apiKey: customKey,\n baseUrl: customBaseUrl,\n }),\n source: 'api',\n name: 'custom-openai',\n reason: `Using custom OpenAI-compatible gateway at ${customBaseUrl} (model: ${customModelId})`,\n };\n}\n\n/** Try CLI first, then API as fallback. */\nasync function selectCliFirst(\n config: AutoAdapterConfig,\n logger: ILogger,\n cache?: ICliDetectionCache\n): Promise<AdapterSelection> {\n const cliResult = await tryCliAdapter(config, logger, cache);\n if (cliResult !== null) return cliResult;\n const apiResult = tryApiAdapter(config, logger);\n if (apiResult !== null) return apiResult;\n throw new Error(\n 'No adapters available. Install a CLI (claude/gemini/codex) or set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY.'\n );\n}\n\n/** Try API first, then CLI as fallback. */\nasync function selectApiFirst(\n config: AutoAdapterConfig,\n logger: ILogger,\n cache?: ICliDetectionCache\n): Promise<AdapterSelection> {\n const apiResult = tryApiAdapter(config, logger);\n if (apiResult !== null) return apiResult;\n const cliResult = await tryCliAdapter(config, logger, cache);\n if (cliResult !== null) return cliResult;\n throw new Error(\n 'No adapters available. Set ANTHROPIC_API_KEY/OPENAI_API_KEY/GOOGLE_AI_API_KEY or install a CLI (claude/gemini/codex).'\n );\n}\n\n/** CLI only - no API fallback. */\nasync function selectCliOnly(\n config: AutoAdapterConfig,\n logger: ILogger,\n cache?: ICliDetectionCache\n): Promise<AdapterSelection> {\n const cliResult = await tryCliAdapter(config, logger, cache);\n if (cliResult !== null) return cliResult;\n throw new Error(\n 'No CLI adapters available. Install and authenticate claude, gemini, or codex CLI.'\n );\n}\n\n/** API only - no CLI fallback. */\nfunction selectApiOnly(config: AutoAdapterConfig, logger: ILogger): AdapterSelection {\n const apiResult = tryApiAdapter(config, logger);\n if (apiResult !== null) return apiResult;\n throw new Error(\n 'No API key available. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY.'\n );\n}\n\n/**\n * Auto-selects the best available model adapter.\n * Uses caching to avoid repeated CLI health checks.\n *\n * @param config - Configuration options\n * @returns Selected adapter or throws if none available\n *\n * @example\n * ```typescript\n * // Use CLI if available, fall back to API\n * const { adapter, source, reason, cache } = await createAutoAdapter();\n * console.log(`Using ${source} adapter: ${reason}`);\n *\n * // Reuse cache for subsequent selections\n * const { adapter: adapter2 } = await createAutoAdapter({ cache });\n *\n * // Force CLI only\n * const { adapter } = await createAutoAdapter({ priority: 'cli-only' });\n * ```\n */\nexport async function createAutoAdapter(config: AutoAdapterConfig = {}): Promise<AdapterSelection> {\n const logger = config.logger ?? defaultLogger;\n const priority = config.priority ?? 'cli-first';\n const cache = resolveCache(config, logger);\n\n logger.info('Auto-selecting adapter', { priority, cacheEnabled: cache !== undefined });\n\n switch (priority) {\n case 'cli-first':\n return selectCliFirst(config, logger, cache);\n case 'api-first':\n return selectApiFirst(config, logger, cache);\n case 'cli-only':\n return selectCliOnly(config, logger, cache);\n case 'api-only':\n return selectApiOnly(config, logger);\n default: {\n const exhaustive: never = priority;\n throw new Error(`Unknown priority: ${String(exhaustive)}`);\n }\n }\n}\n\n/**\n * Checks which adapters are available without creating them.\n * Uses caching to avoid repeated CLI health checks.\n *\n * @param cache - Optional cache to use\n * @returns Available CLIs and which API keys are set\n */\nexport async function getAvailableAdapters(cache?: ICliDetectionCache): Promise<{\n clis: CliName[];\n hasAnthropicKey: boolean;\n hasOpenaiKey: boolean;\n hasGoogleKey: boolean;\n cache?: ICliDetectionCache;\n}> {\n const effectiveCache = cache ?? createCliDetectionCache();\n const clis = await getAvailableClis(effectiveCache);\n\n return {\n clis,\n hasAnthropicKey: resolveApiKeyFromEnv(undefined, 'ANTHROPIC_API_KEY') !== undefined,\n hasOpenaiKey: resolveApiKeyFromEnv(undefined, 'OPENAI_API_KEY') !== undefined,\n hasGoogleKey: resolveApiKeyFromEnv(undefined, 'GOOGLE_AI_API_KEY') !== undefined,\n cache: effectiveCache,\n };\n}\n","/**\n * Event Bus Helper Functions\n *\n * Pure utility functions for event bus operations.\n * Extracted from event-bus.ts to maintain file size limits.\n *\n * @module agents/collaboration/event-bus-helpers\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { getTimeProvider } from '../../core/index.js';\nimport type { SubscriptionId, TopicPattern, DomainEvent, EventFilter } from './event-bus-types.js';\n\n/** Default maximum history size */\nexport const DEFAULT_MAX_HISTORY_SIZE = 1000;\n\n/** Maximum number of subscriptions per bus */\nexport const MAX_SUBSCRIPTIONS = 500;\n\n/**\n * Internal subscription record.\n */\nexport interface SubscriptionRecord {\n readonly id: SubscriptionId;\n readonly pattern: TopicPattern;\n readonly regex: RegExp;\n readonly listener: (event: DomainEvent) => void | Promise<void>;\n}\n\n/** Maximum allowed topic pattern length */\nconst MAX_TOPIC_PATTERN_LENGTH = 200;\n\n/**\n * Convert a topic pattern to a regex for matching.\n * Supports wildcard patterns:\n * - 'session.created' -> exact match\n * - 'session.*' -> matches session.anything\n * - '*' -> matches everything\n *\n * Security Note (Issue #341): This function is safe from ReDoS because:\n * 1. The input is fully escaped before regex construction\n * 2. Only `*` wildcards are converted to `[^.]+` (bounded, non-greedy)\n * 3. Pattern length is bounded to prevent memory issues\n *\n * @throws Error if pattern exceeds MAX_TOPIC_PATTERN_LENGTH\n */\nexport function patternToRegex(pattern: TopicPattern): RegExp {\n // Validate length to prevent memory issues (Issue #341)\n if (pattern.length > MAX_TOPIC_PATTERN_LENGTH) {\n throw new Error(`Topic pattern exceeds maximum length of ${String(MAX_TOPIC_PATTERN_LENGTH)}`);\n }\n\n if (pattern === '*') {\n return /^.+$/;\n }\n // Use placeholder for * before escaping, then restore as regex wildcard\n // WILDCARD_PLACEHOLDER is a static constant, safe for RegExp (Issue #341)\n const WILDCARD_PLACEHOLDER = '\\x00WILDCARD\\x00';\n const withPlaceholder = pattern.replace(/\\*/g, WILDCARD_PLACEHOLDER);\n // Escape all regex special characters - this makes the pattern safe\n const escaped = withPlaceholder.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Replace placeholder with bounded wildcard - safe since input was escaped\n const withWildcards = escaped.replace(new RegExp(WILDCARD_PLACEHOLDER, 'g'), '[^.]+');\n return new RegExp(`^${withWildcards}$`);\n}\n\n/**\n * Check if a topic matches a pattern.\n */\nexport function topicMatchesPattern(topic: string, regex: RegExp): boolean {\n return regex.test(topic);\n}\n\n/**\n * Generate a unique event ID.\n */\nexport function generateEventId(): string {\n return `evt-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Generate a unique subscription ID.\n */\nexport function generateSubscriptionId(): SubscriptionId {\n return `sub-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Generate a unique correlation ID for request tracing.\n * (Source: Issue #224, Sprint #228)\n *\n * @example\n * ```typescript\n * const correlationId = generateCorrelationId();\n * // -> 'cor_a1b2c3d4'\n * ```\n */\nexport function generateCorrelationId(): string {\n return `cor_${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Create a child correlation ID that chains to a parent.\n * Enables hierarchical tracing of subtasks.\n * (Source: Issue #224, Sprint #228)\n *\n * @param parentCorrelationId - The parent correlation ID to chain from\n * @returns A new correlation ID in format 'parentId.child_xxxxxxxx'\n *\n * @example\n * ```typescript\n * const parentId = generateCorrelationId();\n * // -> 'cor_a1b2c3d4'\n *\n * const childId = createChildCorrelationId(parentId);\n * // -> 'cor_a1b2c3d4.child_e5f6g7h8'\n * ```\n */\nexport function createChildCorrelationId(parentCorrelationId: string): string {\n return `${parentCorrelationId}.child_${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Apply topic, session, correlation, and timestamp filters to events.\n */\nexport function applyHistoryFilters(history: DomainEvent[], filter: EventFilter): DomainEvent[] {\n let result: DomainEvent[] = history;\n\n if (filter.topic !== undefined && filter.topic !== '') {\n const regex = patternToRegex(filter.topic);\n result = result.filter((e) => topicMatchesPattern(e.topic, regex));\n }\n\n if (filter.sessionId !== undefined && filter.sessionId !== '') {\n result = result.filter((e) => e.sessionId === filter.sessionId);\n }\n\n if (filter.correlationId !== undefined && filter.correlationId !== '') {\n result = result.filter((e) => e.correlationId === filter.correlationId);\n }\n\n return applyTimestampFilters(result, filter);\n}\n\n/**\n * Apply timestamp-based filters to events.\n */\nexport function applyTimestampFilters(result: DomainEvent[], filter: EventFilter): DomainEvent[] {\n let filtered = result;\n\n if (filter.after !== undefined && filter.after !== '') {\n const afterTimestamp = filter.after;\n filtered = filtered.filter((e) => e.timestamp > afterTimestamp);\n }\n\n if (filter.before !== undefined && filter.before !== '') {\n const beforeTimestamp = filter.before;\n filtered = filtered.filter((e) => e.timestamp < beforeTimestamp);\n }\n\n return filtered;\n}\n\n/**\n * Apply limit to history results.\n */\nexport function applyHistoryLimit(result: DomainEvent[], filter: EventFilter): DomainEvent[] {\n if (filter.limit !== undefined && filter.limit > 0) {\n return result.slice(-filter.limit);\n }\n return result;\n}\n\n/**\n * Enrich event with generated fields if missing.\n */\nexport function enrichEvent(event: DomainEvent): DomainEvent {\n return {\n ...event,\n eventId: event.eventId || generateEventId(),\n timestamp: event.timestamp || getTimeProvider().nowIso(),\n };\n}\n\n/**\n * Count subscribers matching a topic from a subscription map.\n */\nexport function countMatchingSubscribers(\n topic: string,\n subscriptions: Map<SubscriptionId, SubscriptionRecord>\n): number {\n let count = 0;\n for (const record of subscriptions.values()) {\n if (topicMatchesPattern(topic, record.regex)) {\n count++;\n }\n }\n return count;\n}\n","/**\n * Circular Buffer\n *\n * O(1) push and eviction for bounded collections.\n * Used by EventBus history to avoid O(n) array.shift() operations.\n *\n * @module agents/collaboration/circular-buffer\n * @see Issue #407\n */\n\n/**\n * A fixed-capacity circular buffer with O(1) push and O(1) oldest-eviction.\n *\n * When the buffer is full, new items overwrite the oldest items.\n * Items are always returned in insertion order (oldest to newest).\n */\nexport class CircularBuffer<T> {\n private readonly buffer: (T | undefined)[];\n private head = 0; // Points to oldest item (or next write position when empty)\n private tail = 0; // Points to next write position\n private _size = 0;\n\n /**\n * Creates a new circular buffer with the specified capacity.\n *\n * @param capacity - Maximum number of items to store\n * @throws Error if capacity is less than 1\n */\n constructor(private readonly capacity: number) {\n if (capacity < 1) {\n throw new Error('CircularBuffer capacity must be at least 1');\n }\n this.buffer = new Array<T | undefined>(capacity);\n }\n\n /**\n * Returns the number of items currently in the buffer.\n */\n get size(): number {\n return this._size;\n }\n\n /**\n * Returns true if the buffer is empty.\n */\n get isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Returns true if the buffer is at capacity.\n */\n get isFull(): boolean {\n return this._size === this.capacity;\n }\n\n /**\n * Adds an item to the buffer.\n *\n * If the buffer is full, the oldest item is overwritten.\n * This operation is O(1).\n *\n * @param item - Item to add\n */\n push(item: T): void {\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n\n if (this._size < this.capacity) {\n this._size++;\n } else {\n // Buffer was full, oldest item was overwritten\n this.head = (this.head + 1) % this.capacity;\n }\n }\n\n /**\n * Removes all items from the buffer.\n * This operation is O(n) to allow garbage collection of items.\n */\n clear(): void {\n // Clear references to allow GC\n for (let i = 0; i < this.capacity; i++) {\n this.buffer[i] = undefined;\n }\n this.head = 0;\n this.tail = 0;\n this._size = 0;\n }\n\n /**\n * Returns all items in insertion order (oldest to newest).\n * This operation is O(n) where n is the number of items.\n *\n * @returns Array of items in insertion order\n */\n toArray(): T[] {\n if (this._size === 0) {\n return [];\n }\n\n const result: T[] = [];\n let readIndex = this.head;\n\n for (let i = 0; i < this._size; i++) {\n result.push(this.buffer[readIndex] as T);\n readIndex = (readIndex + 1) % this.capacity;\n }\n\n return result;\n }\n\n /**\n * Iterates over items in insertion order (oldest to newest).\n */\n *[Symbol.iterator](): Iterator<T> {\n let readIndex = this.head;\n for (let i = 0; i < this._size; i++) {\n yield this.buffer[readIndex] as T;\n readIndex = (readIndex + 1) % this.capacity;\n }\n }\n\n /**\n * Returns the most recently added item, or undefined if empty.\n * This operation is O(1).\n */\n peekNewest(): T | undefined {\n if (this._size === 0) {\n return undefined;\n }\n const newestIndex = (this.tail - 1 + this.capacity) % this.capacity;\n return this.buffer[newestIndex];\n }\n\n /**\n * Returns the oldest item in the buffer, or undefined if empty.\n * This operation is O(1).\n */\n peekOldest(): T | undefined {\n if (this._size === 0) {\n return undefined;\n }\n return this.buffer[this.head];\n }\n}\n","/**\n * Event Bus Implementation\n *\n * Async message passing for agent-to-agent communication.\n * Supports topic-based routing, wildcard patterns, and event history.\n *\n * @module agents/collaboration/event-bus\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\nimport { getTimeProvider } from '../../core/index.js';\nimport type {\n IEventBus,\n DomainEvent,\n EventListener,\n Subscription,\n SubscriptionId,\n TopicPattern,\n EventFilter,\n EventBusOptions,\n EventBusStats,\n} from './event-bus-types.js';\n\nimport {\n DEFAULT_MAX_HISTORY_SIZE,\n MAX_SUBSCRIPTIONS,\n type SubscriptionRecord,\n patternToRegex,\n topicMatchesPattern,\n generateEventId,\n generateSubscriptionId,\n applyHistoryFilters,\n applyHistoryLimit,\n enrichEvent,\n countMatchingSubscribers,\n} from './event-bus-helpers.js';\n\nimport { CircularBuffer } from './circular-buffer.js';\n\n// Re-export correlation ID helpers for public API\nexport { generateCorrelationId, createChildCorrelationId } from './event-bus-helpers.js';\n\n/**\n * Event Bus for agent-to-agent communication.\n *\n * Features:\n * - Topic-based pub/sub with wildcard support\n * - Async and sync event emission\n * - Event history with filtering\n * - Error isolation (one listener failure doesn't block others)\n *\n * @example\n * ```typescript\n * const bus = new EventBus();\n *\n * // Subscribe to all session events\n * const sub = bus.subscribe('session.*', (event) => {\n * console.log('Session event:', event.topic);\n * });\n *\n * // Emit an event\n * bus.emit(createSessionCreatedEvent({ sessionId: '123', ... }));\n *\n * // Cleanup\n * sub.unsubscribe();\n * ```\n */\nexport class EventBus implements IEventBus {\n private readonly subscriptions: Map<SubscriptionId, SubscriptionRecord> = new Map();\n private readonly history: CircularBuffer<DomainEvent>;\n private readonly asyncHandling: boolean;\n private readonly logger?: EventBusOptions['logger'];\n\n private stats: EventBusStats = {\n eventsEmitted: 0,\n subscriptionsCreated: 0,\n activeSubscriptions: 0,\n historySize: 0,\n errorCount: 0,\n };\n\n constructor(options: EventBusOptions = {}) {\n const maxHistorySize = options.maxHistorySize ?? DEFAULT_MAX_HISTORY_SIZE;\n this.history = new CircularBuffer<DomainEvent>(maxHistorySize);\n this.asyncHandling = options.asyncHandling ?? false;\n this.logger = options.logger;\n }\n\n /**\n * Emit an event synchronously to all matching subscribers.\n */\n emit(event: DomainEvent): void {\n const enrichedEvent = enrichEvent(event);\n this.addToHistory(enrichedEvent);\n this.stats.eventsEmitted++;\n\n this.logger?.debug('Event emitted', {\n topic: enrichedEvent.topic,\n eventId: enrichedEvent.eventId,\n subscriberCount: countMatchingSubscribers(enrichedEvent.topic, this.subscriptions),\n });\n\n for (const record of this.subscriptions.values()) {\n if (topicMatchesPattern(enrichedEvent.topic, record.regex)) {\n this.invokeListener(record, enrichedEvent);\n }\n }\n }\n\n /**\n * Emit an event and wait for all async handlers to complete.\n */\n async emitAsync(event: DomainEvent): Promise<void> {\n const enrichedEvent = enrichEvent(event);\n this.addToHistory(enrichedEvent);\n this.stats.eventsEmitted++;\n\n this.logger?.debug('Async event emitted', {\n topic: enrichedEvent.topic,\n eventId: enrichedEvent.eventId,\n });\n\n const promises: Promise<void>[] = [];\n\n for (const record of this.subscriptions.values()) {\n if (topicMatchesPattern(enrichedEvent.topic, record.regex)) {\n promises.push(this.invokeListenerAsync(record, enrichedEvent));\n }\n }\n\n await Promise.all(promises);\n }\n\n /**\n * Subscribe to events matching a topic pattern.\n */\n subscribe<T extends DomainEvent = DomainEvent>(\n pattern: TopicPattern,\n listener: EventListener<T>\n ): Subscription {\n if (this.subscriptions.size >= MAX_SUBSCRIPTIONS) {\n throw new Error(\n `Maximum subscription limit reached (${String(MAX_SUBSCRIPTIONS)}). ` +\n 'Unsubscribe from unused patterns before adding new ones.'\n );\n }\n\n const id = generateSubscriptionId();\n const regex = patternToRegex(pattern);\n\n const record: SubscriptionRecord = {\n id,\n pattern,\n regex,\n listener: listener as EventListener,\n };\n\n this.subscriptions.set(id, record);\n this.stats.subscriptionsCreated++;\n this.stats.activeSubscriptions = this.subscriptions.size;\n\n this.logger?.debug('Subscription created', { id, pattern });\n\n return {\n id,\n pattern,\n unsubscribe: () => {\n this.unsubscribe(id);\n },\n };\n }\n\n /**\n * Unsubscribe from events.\n */\n unsubscribe(subscriptionId: SubscriptionId): void {\n const existed = this.subscriptions.delete(subscriptionId);\n if (existed) {\n this.stats.activeSubscriptions = this.subscriptions.size;\n this.logger?.debug('Subscription removed', { subscriptionId });\n }\n }\n\n /**\n * Get event history matching filter criteria.\n */\n getHistory(filter?: EventFilter): readonly DomainEvent[] {\n const historyArray = this.history.toArray();\n if (filter === undefined) {\n return historyArray;\n }\n\n const filtered = applyHistoryFilters(historyArray, filter);\n return applyHistoryLimit(filtered, filter);\n }\n\n /**\n * Clear event history.\n */\n clearHistory(): void {\n this.history.clear();\n this.stats.historySize = 0;\n this.logger?.debug('History cleared');\n }\n\n /**\n * Get event bus statistics.\n */\n getStats(): EventBusStats {\n return { ...this.stats };\n }\n\n /**\n * Check if a topic pattern has any subscribers.\n */\n hasSubscribers(pattern: TopicPattern): boolean {\n const regex = patternToRegex(pattern);\n for (const record of this.subscriptions.values()) {\n // Check if the patterns could overlap\n if (\n topicMatchesPattern(pattern, record.regex) ||\n topicMatchesPattern(record.pattern, regex)\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add event to history, maintaining size limit via O(1) circular buffer.\n * @see Issue #407 - Performance optimization\n */\n private addToHistory(event: DomainEvent): void {\n this.history.push(event);\n this.stats.historySize = this.history.size;\n }\n\n /**\n * Invoke a listener synchronously with error isolation.\n */\n private invokeListener(record: SubscriptionRecord, event: DomainEvent): void {\n try {\n const result = record.listener(event);\n // If async handling is enabled and listener returns a promise, don't wait\n if (this.asyncHandling && result instanceof Promise) {\n result.catch((error: unknown) => {\n this.handleListenerError(record, event, error);\n });\n }\n } catch (error) {\n this.handleListenerError(record, event, error);\n }\n }\n\n /**\n * Invoke a listener asynchronously.\n */\n private async invokeListenerAsync(record: SubscriptionRecord, event: DomainEvent): Promise<void> {\n try {\n await record.listener(event);\n } catch (error) {\n this.handleListenerError(record, event, error);\n }\n }\n\n /**\n * Handle listener errors without disrupting other listeners.\n */\n private handleListenerError(\n record: SubscriptionRecord,\n event: DomainEvent,\n error: unknown\n ): void {\n this.stats.errorCount++;\n const errorObj = error instanceof Error ? error : new Error(String(error));\n this.logger?.error('Event listener error', errorObj, {\n subscriptionId: record.id,\n pattern: record.pattern,\n eventTopic: event.topic,\n eventId: event.eventId,\n });\n }\n}\n\n/**\n * Create a singleton event bus instance for global coordination.\n * Use with caution - prefer dependency injection for testability.\n */\nlet globalBus: EventBus | null = null;\n\nexport function getGlobalEventBus(options?: EventBusOptions): EventBus {\n globalBus ??= new EventBus(options);\n return globalBus;\n}\n\n/**\n * Reset the global event bus (for testing).\n */\nexport function resetGlobalEventBus(): void {\n globalBus = null;\n}\n\n/**\n * Factory functions for creating typed events.\n */\nexport function createEvent<T extends DomainEvent>(\n topic: T['topic'],\n payload: T['payload'],\n options?: {\n sessionId?: string;\n correlationId?: string;\n }\n): T {\n return {\n eventId: generateEventId(),\n timestamp: getTimeProvider().nowIso(),\n topic,\n payload,\n sessionId: options?.sessionId,\n correlationId: options?.correlationId,\n } as T;\n}\n","/**\n * Event Bus Topic Constants\n *\n * Type-safe topic constants for event subscription.\n *\n * @module agents/collaboration/event-bus-topics\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\n/**\n * Topic constants for type-safe subscription.\n */\nexport const EventTopics = {\n // Session events\n SESSION_CREATED: 'session.created',\n SESSION_STATUS_CHANGED: 'session.status_changed',\n SESSION_PARTICIPANT_JOINED: 'session.participant_joined',\n SESSION_RESULT_SUBMITTED: 'session.result_submitted',\n SESSION_FINALIZED: 'session.finalized',\n SESSION_ALL: 'session.*',\n\n // Message events\n MESSAGE_SENT: 'message.sent',\n MESSAGE_RECEIVED: 'message.received',\n MESSAGE_ALL: 'message.*',\n\n // Agent events\n AGENT_TASK_DELEGATED: 'agent.task_delegated',\n AGENT_RESULT_BROADCAST: 'agent.result_broadcast',\n AGENT_ALL: 'agent.*',\n\n // Consensus events\n CONSENSUS_VOTE_REQUESTED: 'consensus.vote_requested',\n CONSENSUS_VOTE_CAST: 'consensus.vote_cast',\n CONSENSUS_REACHED: 'consensus.reached',\n CONSENSUS_ALL: 'consensus.*',\n\n // Protocol events\n PROTOCOL_STARTED: 'protocol.started',\n PROTOCOL_ITERATION: 'protocol.iteration',\n PROTOCOL_COMPLETED: 'protocol.completed',\n PROTOCOL_ALL: 'protocol.*',\n\n // Aegean phase events (Issue #216)\n AEGEAN_ROUND_STARTED: 'protocol.aegean.round_started',\n AEGEAN_VOTE_COLLECTED: 'protocol.aegean.vote_collected',\n AEGEAN_QUORUM_DETECTED: 'protocol.aegean.quorum_detected',\n AEGEAN_ALL: 'protocol.aegean.*',\n\n // Reflexion phase events (Issue #216)\n REFLEXION_CRITIQUE_STARTED: 'protocol.reflexion.critique_started',\n REFLEXION_CRITIQUE_COMPLETED: 'protocol.reflexion.critique_completed',\n REFLEXION_SYNTHESIS: 'protocol.reflexion.synthesis',\n REFLEXION_ALL: 'protocol.reflexion.*',\n\n // Trinity phase events (Issue #216)\n TRINITY_PHASE_STARTED: 'protocol.trinity.phase_started',\n TRINITY_PHASE_COMPLETED: 'protocol.trinity.phase_completed',\n TRINITY_ALL: 'protocol.trinity.*',\n\n // Byzantine detection events (Issue #218)\n BYZANTINE_WEIGHT_UPDATED: 'byzantine.weight_updated',\n BYZANTINE_PATTERN_DETECTED: 'byzantine.pattern_detected',\n BYZANTINE_AGENT_FLAGGED: 'byzantine.agent_flagged',\n BYZANTINE_COLLUSION_SUSPECTED: 'byzantine.collusion_suspected',\n BYZANTINE_ALL: 'byzantine.*',\n\n // Wildcard\n ALL: '*',\n} as const;\n","/**\n * Resilient Model Adapter\n *\n * Transparent proxy implementing IModelAdapter with lazy detection,\n * automatic failover on circuit breaker events, and observable health.\n *\n * Key design: ResilientAdapter IS an IModelAdapter. Every existing consumer\n * works unchanged. The health/failover API lives on IResilientAdapter for\n * dashboard and monitoring consumers only.\n *\n * @module adapters/resilient-adapter\n * (Source: Issue #811 - Resilient model adapter architecture)\n */\n\nimport type {\n IModelAdapter,\n CompletionRequest,\n CompletionResponse,\n StreamChunk,\n ModelCapability,\n} from '../core/types/model.js';\nimport type { Result } from '../core/result.js';\nimport { ok, err } from '../core/result.js';\nimport { ModelError, ConfigError } from '../core/errors.js';\nimport type { ILogger } from '../core/index.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\nimport { getErrorMessage, createLogger } from '../core/index.js';\n\nimport { createAutoAdapter, type AdapterSelection } from './auto-adapter.js';\nimport {\n isRateLimitLikeError,\n toRateLimitError,\n recordRateLimitEvent,\n} from './rate-limit-detector.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport type {\n IResilientAdapter,\n AdapterHealthInfo,\n ResilientAdapterConfig,\n} from './resilient-adapter-types.js';\nimport type { CircuitStateChangeEvent } from '../cli-adapters/circuit-breaker-types.js';\nimport type { CircuitBreakerRegistry } from '../cli-adapters/circuit-breaker.js';\nimport { getGlobalEventBus } from '../core/event-bus.js';\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Creates a resilient adapter with lazy detection and automatic failover.\n *\n * @example\n * ```typescript\n * const adapter = createResilientAdapter({ logger });\n * // No detection at creation time — detection happens on first use\n * const result = await adapter.complete(request); // triggers detection\n * ```\n */\nexport function createResilientAdapter(config?: ResilientAdapterConfig): IResilientAdapter {\n return new ResilientAdapter(config);\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Resilient adapter proxy. Implements IModelAdapter transparently.\n */\nexport class ResilientAdapter implements IResilientAdapter {\n private readonly logger: ILogger;\n private currentAdapter: IModelAdapter | undefined;\n private currentSelection: AdapterSelection | undefined;\n private hasEverDetected = false;\n private health: AdapterHealthInfo | undefined;\n private preferredCli: CliName | undefined;\n private readonly failoverCallbacks = new Set<(info: AdapterHealthInfo) => void>();\n private circuitBreakerRegistry: CircuitBreakerRegistry | undefined;\n private circuitListener: ((event: CircuitStateChangeEvent) => void) | undefined;\n private disposed = false;\n private readonly defaultCliTimeoutMs: number | undefined;\n /** Inflight detection promise for coalescing concurrent calls (Issue #1423). */\n private detectionPromise: Promise<IModelAdapter | undefined> | undefined;\n\n constructor(config?: ResilientAdapterConfig) {\n this.logger = config?.logger ?? createLogger({ component: 'resilient-adapter' });\n this.preferredCli = config?.preferredCli;\n this.defaultCliTimeoutMs = config?.defaultCliTimeoutMs;\n }\n\n // --- IModelAdapter properties (forwarded) ---\n\n get providerId(): string {\n return this.currentAdapter?.providerId ?? 'resilient-proxy';\n }\n\n get modelId(): string {\n return this.currentAdapter?.modelId ?? 'pending-detection';\n }\n\n get capabilities(): readonly ModelCapability[] {\n return this.currentAdapter?.capabilities ?? [];\n }\n\n // --- IModelAdapter methods ---\n\n async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n return err(new ModelError('No model adapter available'));\n }\n const result = await adapter.complete(request);\n if (!result.ok && isRateLimitLikeError(result.error)) {\n const rlError = toRateLimitError(result.error, adapter.providerId);\n recordRateLimitEvent({\n provider: adapter.providerId,\n timestamp: getTimeProvider().now(),\n retryAfterMs: rlError.retryAfterMs,\n });\n this.logger.warn('Rate limit detected', {\n provider: adapter.providerId,\n retryAfterMs: rlError.retryAfterMs,\n });\n }\n return result;\n }\n\n async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n return;\n }\n yield* adapter.stream(request);\n }\n\n async countTokens(text: string): Promise<number> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n return 0;\n }\n return adapter.countTokens(text);\n }\n\n validateConfig(): Result<void, ConfigError> {\n if (this.currentAdapter !== undefined) {\n return this.currentAdapter.validateConfig();\n }\n // Before first use, config is trivially valid\n return ok(undefined);\n }\n\n // --- IResilientAdapter methods ---\n\n getHealth(): AdapterHealthInfo | undefined {\n return this.health;\n }\n\n async refresh(): Promise<void> {\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n this.detectionPromise = undefined;\n await this.ensureAdapter();\n }\n\n setPreferredCli(cli: CliName | undefined): void {\n this.preferredCli = cli;\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n }\n\n onFailover(cb: (info: AdapterHealthInfo) => void): () => void {\n this.failoverCallbacks.add(cb);\n return () => {\n this.failoverCallbacks.delete(cb);\n };\n }\n\n /**\n * Attach a circuit breaker registry for automatic failover.\n * When the current adapter's circuit opens, the cached adapter\n * is cleared so the next call triggers re-detection.\n */\n attachCircuitBreakerRegistry(registry: CircuitBreakerRegistry): void {\n this.detachCircuitBreakerRegistry();\n this.circuitBreakerRegistry = registry;\n this.circuitListener = (event: CircuitStateChangeEvent) => {\n this.handleCircuitStateChange(event);\n };\n registry.addGlobalStateChangeListener(this.circuitListener);\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.detachCircuitBreakerRegistry();\n this.failoverCallbacks.clear();\n }\n\n // --- Private methods ---\n\n private async ensureAdapter(): Promise<IModelAdapter | undefined> {\n if (this.currentAdapter !== undefined) {\n return this.currentAdapter;\n }\n // Coalesce concurrent detection calls into a single probe (Issue #1423)\n this.detectionPromise ??= this.detectAdapter().finally(() => {\n this.detectionPromise = undefined;\n });\n return this.detectionPromise;\n }\n\n private async detectAdapter(): Promise<IModelAdapter | undefined> {\n try {\n this.logger.info('Detecting model adapter (lazy)');\n const config = {\n logger: this.logger,\n ...(this.preferredCli !== undefined && { preferredCli: this.preferredCli }),\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n };\n const selection = await createAutoAdapter(config);\n this.applySelection(selection);\n return this.currentAdapter;\n } catch (error) {\n const message = getErrorMessage(error);\n this.logger.warn('No model adapter available', { error: message });\n this.health = {\n source: 'api',\n state: 'unavailable',\n selectedAt: new Date(),\n failoverCount: this.health?.failoverCount ?? 0,\n lastError: message,\n };\n return undefined;\n }\n }\n\n private applySelection(selection: AdapterSelection): void {\n const isFailover = this.hasEverDetected;\n this.currentAdapter = selection.adapter;\n this.currentSelection = selection;\n this.hasEverDetected = true;\n\n const source = mapSelectionSource(selection);\n const failoverCount = (this.health?.failoverCount ?? 0) + (isFailover ? 1 : 0);\n\n this.health = {\n source,\n state: 'healthy',\n selectedAt: new Date(),\n failoverCount,\n };\n\n this.logger.info('Adapter selected', {\n source: selection.source,\n name: selection.name,\n model: selection.adapter.modelId,\n provider: selection.adapter.providerId,\n failover: isFailover,\n });\n\n if (isFailover) {\n this.emitFailover();\n }\n }\n\n private handleCircuitStateChange(event: CircuitStateChangeEvent): void {\n if (event.newState !== 'open') return;\n\n const currentSource = this.currentSelection?.name;\n if (currentSource === undefined || currentSource !== event.cliName) {\n return; // Not our current adapter\n }\n\n this.logger.warn('Current adapter circuit opened, clearing cache for re-detection', {\n cli: event.cliName,\n reason: event.reason,\n });\n\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n\n if (this.health !== undefined) {\n this.health = {\n ...this.health,\n state: 'degraded',\n lastError: event.reason,\n };\n }\n }\n\n private emitFailover(): void {\n const info = this.health;\n if (info === undefined) return;\n\n for (const cb of this.failoverCallbacks) {\n try {\n cb(info);\n } catch (error: unknown) {\n this.logger.debug('Failover callback error', { error: getErrorMessage(error) });\n }\n }\n\n try {\n const eventBus = getGlobalEventBus();\n eventBus.emit({\n eventId: `failover-${getTimeProvider().now().toString(36)}-${getRandomProvider().random().toString(36).slice(2, 8)}`,\n timestamp: new Date().toISOString(),\n topic: 'adapter.failover',\n payload: info,\n });\n } catch (error: unknown) {\n this.logger.debug('EventBus emit failed during failover', {\n error: getErrorMessage(error),\n });\n }\n }\n\n private detachCircuitBreakerRegistry(): void {\n if (this.circuitBreakerRegistry !== undefined && this.circuitListener !== undefined) {\n this.circuitBreakerRegistry.removeGlobalStateChangeListener(this.circuitListener);\n }\n this.circuitBreakerRegistry = undefined;\n this.circuitListener = undefined;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction mapSelectionSource(selection: AdapterSelection): CliName | 'api' {\n if (selection.source === 'cli') {\n return selection.name as CliName;\n }\n return 'api';\n}\n","/**\n * withModelNotFoundFallback (#2540 PR 8 of 8).\n *\n * Wraps an `IModelAdapter` so that calls that fail with `MODEL_NOT_FOUND`\n * (404 / \"model is deprecated\" / etc.) are retried once with the closest\n * available alternative from the same vendor family — picked from the\n * adapter's `listModels()` and the registry.\n *\n * Why this exists: nexus-agents has historically baked model ids into\n * configuration. When a vendor retires a model (Codex on GPT-5.4 vs an\n * older 5.1, Claude bumping minor versions, etc.), the next request 404s.\n * This primitive turns that 404 into a single observable retry against\n * the latest sibling — operators see the retirement in the log, work\n * keeps moving, and the cache (PR 6) is invalidated so subsequent calls\n * pick up the new ground truth.\n *\n * Design notes:\n * - Single retry only. If the fallback also 404s, surface the second\n * error (callers can escalate). Don't loop — that risks wedging.\n * - The wrapper keeps the same `providerId`/`modelId` shape as the\n * wrapped adapter so downstream consumers (telemetry, OutcomeStore)\n * don't see schema changes. The chosen fallback id appears in\n * `errorMessage` of the original error and in the logger.\n * - `stream()` is left as passthrough — streaming retries belong in\n * a future iteration where partial-result reconciliation is handled.\n */\n\nimport type {\n CompletionRequest,\n CompletionResponse,\n IModelAdapter,\n ModelError,\n Result,\n StreamChunk,\n} from '../core/index.js';\nimport { err, ErrorCode, ok, ModelError as ModelErrorClass } from '../core/index.js';\nimport { createLogger } from '../core/logger.js';\nimport { getDefaultRegistry, type ModelRegistry } from '../config/model-registry.js';\nimport {\n type AvailableModelsCache,\n getDefaultAvailableModelsCache,\n} from '../config/available-models-cache.js';\n\nconst logger = createLogger({ component: 'model-not-found-fallback' });\n\nexport interface ModelNotFoundFallbackOptions {\n /**\n * Process-local cache of routable models. Refreshed on a 404. Defaults\n * to `getDefaultAvailableModelsCache()` — passing one explicitly is the\n * right move for tests and for multi-cache topologies.\n */\n readonly cache?: AvailableModelsCache;\n /** Registry used to resolve vendor/family from a model id. Defaults to global. */\n readonly registry?: ModelRegistry;\n /**\n * Optional adapter factory used to build a new IModelAdapter for the\n * fallback model id. When provided, the wrapper retries through the\n * factory's adapter. When omitted, the wrapper logs + emits a\n * `MODEL_NOT_FOUND` error enriched with the suggested fallback id —\n * the caller (orchestrator / router) is responsible for re-routing.\n */\n readonly adapterFactory?: (modelId: string) => IModelAdapter;\n /**\n * Optional callback invoked when a retirement is detected. Use for\n * telemetry / sticky-state updates. Failures in the callback are\n * swallowed — the user's call is what matters.\n */\n readonly onRetirement?: (info: RetirementInfo) => void;\n}\n\nexport interface RetirementInfo {\n readonly retiredModelId: string;\n readonly fallbackModelId: string;\n readonly providerId: string;\n readonly errorMessage: string;\n}\n\n/**\n * Decorate an IModelAdapter with retire-and-retry. Behaviour:\n *\n * 1. Forward `complete(request)` to the inner adapter.\n * 2. On `MODEL_NOT_FOUND`: refresh the cache, find the closest\n * same-family alternative, retry once with `request.model =\n * <fallback>`. Original error is returned if no fallback found.\n * 3. The wrapper returns the SECOND error if the retry also fails.\n * 4. `stream()` retries via restart-from-zero (#2550): when the inner\n * stream throws a `MODEL_NOT_FOUND` ModelError, the wrapper closes\n * the failed stream, picks a same-family fallback via the cache +\n * registry, builds a new adapter through `adapterFactory`, and\n * yields chunks from the fallback stream. The consumer sees a clean\n * second stream — partial content already delivered by the first\n * stream is NOT replayed; that's a known trade-off (the alternative\n * resume-with-reconciliation strategy is heavier and only useful\n * for tool-use loops; not implemented per the deliberate scoping in\n * #2550). Without `adapterFactory`, the original throw propagates\n * unchanged.\n * 5. `countTokens`, `validateConfig`, `listModels` are passthrough.\n */\nexport function withModelNotFoundFallback(\n inner: IModelAdapter,\n options: ModelNotFoundFallbackOptions = {}\n): IModelAdapter {\n const registry = options.registry ?? getDefaultRegistry();\n const cache = options.cache ?? getDefaultAvailableModelsCache();\n const resolvedOptions: ResolvedOptions = {\n cache,\n registry,\n adapterFactory: options.adapterFactory,\n onRetirement: options.onRetirement,\n };\n const wrapped: IModelAdapter = {\n providerId: inner.providerId,\n modelId: inner.modelId,\n capabilities: inner.capabilities,\n countTokens: (text) => inner.countTokens(text),\n validateConfig: () => inner.validateConfig(),\n stream: (request: CompletionRequest): AsyncIterable<StreamChunk> =>\n streamWithFallback(inner, request, resolvedOptions),\n complete: (request: CompletionRequest) => completeWithFallback(inner, request, resolvedOptions),\n };\n if (typeof inner.listModels === 'function') {\n const list = inner.listModels.bind(inner);\n wrapped.listModels = () => list();\n }\n return wrapped;\n}\n\ninterface ResolvedOptions {\n readonly cache: AvailableModelsCache;\n readonly registry: ModelRegistry;\n readonly adapterFactory?: ((modelId: string) => IModelAdapter) | undefined;\n readonly onRetirement?: ((info: RetirementInfo) => void) | undefined;\n}\n\nasync function completeWithFallback(\n inner: IModelAdapter,\n request: CompletionRequest,\n options: ResolvedOptions\n): Promise<Result<CompletionResponse, ModelError>> {\n const first = await inner.complete(request);\n if (first.ok) return first;\n if (first.error.code !== ErrorCode.MODEL_NOT_FOUND) return first;\n\n const fallback = await pickFallback(inner.modelId, options.cache, options.registry);\n if (fallback === null) {\n logger.warn('Model not found and no fallback available', {\n modelId: inner.modelId,\n providerId: inner.providerId,\n errorMessage: first.error.message,\n });\n return first;\n }\n\n logger.info('Model retirement detected; retrying with fallback', {\n retiredModelId: inner.modelId,\n fallbackModelId: fallback,\n providerId: inner.providerId,\n });\n notifyRetirement(options.onRetirement, {\n retiredModelId: inner.modelId,\n fallbackModelId: fallback,\n providerId: inner.providerId,\n errorMessage: first.error.message,\n });\n\n // No factory wired → enrich the original error with a suggested\n // fallback id and let the caller decide. This is the safe default\n // for adapters where reconfiguring per-call isn't supported.\n if (options.adapterFactory === undefined) {\n return err(\n new ModelErrorClass(`${first.error.message} — suggested fallback: ${fallback}`, {\n code: ErrorCode.MODEL_NOT_FOUND,\n cause: first.error,\n })\n );\n }\n\n const fallbackAdapter = options.adapterFactory(fallback);\n const retried = await fallbackAdapter.complete(request);\n if (retried.ok) return retried;\n // Surface the SECOND error so callers see the retry's failure\n // mode, not the (already-handled) original 404.\n return err(\n new ModelErrorClass(`Fallback ${fallback} also failed: ${retried.error.message}`, {\n code: retried.error.code,\n cause: retried.error,\n })\n );\n}\n\n/**\n * Restart-from-zero streaming retry on MODEL_NOT_FOUND (#2550).\n *\n * Iterates the inner stream; if it throws a `ModelError` with code\n * `MODEL_NOT_FOUND`, refreshes the cache, picks a same-family fallback,\n * builds a new adapter via `adapterFactory`, and yields chunks from\n * the fallback stream. The consumer sees a clean second stream — any\n * partial content already delivered by the first stream is NOT\n * replayed; that's the documented trade-off of restart-from-zero\n * (alternative resume-with-reconciliation strategy is heavier and\n * deferred per #2550's scope decision).\n *\n * Without `adapterFactory` the original throw propagates unchanged —\n * the wrapper has no way to construct the retry adapter, so the\n * consumer can re-route at a higher layer if it wants.\n */\nasync function* streamWithFallback(\n inner: IModelAdapter,\n request: CompletionRequest,\n options: ResolvedOptions\n): AsyncGenerator<StreamChunk> {\n try {\n for await (const chunk of inner.stream(request)) {\n yield chunk;\n }\n return;\n } catch (e: unknown) {\n if (!isModelNotFoundError(e)) throw e;\n const fallbackAdapter = await resolveStreamFallback(inner, e, options);\n // Restart-from-zero: the consumer gets a fresh stream starting from\n // the first chunk. Any partial chunks the inner stream already\n // yielded are NOT replayed.\n for await (const chunk of fallbackAdapter.stream(request)) {\n yield chunk;\n }\n }\n}\n\n/**\n * Pick a same-family fallback model, run the retirement callback, and\n * return the constructed fallback adapter. Throws (with appropriate\n * enrichment) when no factory is wired or no fallback is available.\n */\nasync function resolveStreamFallback(\n inner: IModelAdapter,\n cause: unknown,\n options: ResolvedOptions\n): Promise<IModelAdapter> {\n const fallback = await pickFallback(inner.modelId, options.cache, options.registry);\n if (fallback === null) {\n logger.warn('Stream model not found and no fallback available', {\n modelId: inner.modelId,\n providerId: inner.providerId,\n errorMessage: cause instanceof Error ? cause.message : String(cause),\n });\n throw cause;\n }\n\n logger.info('Stream retirement detected; restarting with fallback (restart-from-zero)', {\n retiredModelId: inner.modelId,\n fallbackModelId: fallback,\n providerId: inner.providerId,\n });\n notifyRetirement(options.onRetirement, {\n retiredModelId: inner.modelId,\n fallbackModelId: fallback,\n providerId: inner.providerId,\n errorMessage: cause instanceof Error ? cause.message : String(cause),\n });\n\n if (options.adapterFactory === undefined) {\n // No factory wired → can't construct the retry adapter. Re-throw\n // with the original error enriched so callers at a higher layer\n // can attempt their own re-routing.\n const message = `${cause instanceof Error ? cause.message : String(cause)} — suggested fallback: ${fallback}`;\n const causeErr = cause instanceof Error ? cause : undefined;\n throw new ModelErrorClass(\n message,\n causeErr !== undefined\n ? { code: ErrorCode.MODEL_NOT_FOUND, cause: causeErr }\n : { code: ErrorCode.MODEL_NOT_FOUND }\n );\n }\n\n return options.adapterFactory(fallback);\n}\n\nfunction isModelNotFoundError(e: unknown): boolean {\n if (e instanceof ModelErrorClass) {\n return e.code === ErrorCode.MODEL_NOT_FOUND;\n }\n // Some adapters throw a plain Error with the code as a string property.\n if (typeof e === 'object' && e !== null && 'code' in e) {\n return e.code === ErrorCode.MODEL_NOT_FOUND;\n }\n return false;\n}\n\nfunction notifyRetirement(\n cb: ((info: RetirementInfo) => void) | undefined,\n info: RetirementInfo\n): void {\n if (cb === undefined) return;\n try {\n cb(info);\n } catch (e: unknown) {\n logger.debug('onRetirement callback threw', {\n error: e instanceof Error ? e.message : String(e),\n });\n }\n}\n\n/**\n * Pick the closest available alternative to a retired model. Strategy:\n * 1. Refresh the cache (the retirement signal is authoritative).\n * 2. Resolve the retired id's vendor + family via the registry.\n * 3. Among the now-available ids, take the first match in the same\n * family. If none match family, fall back to vendor.\n * 4. If still nothing, return null — surfaces the original error.\n *\n * Deliberately simple — picking the \"best\" sibling deserves its own\n * scoring/ranking pass; here we just need ANY same-family id to keep\n * the user moving. Caller logs both ids so the behaviour is auditable.\n */\nasync function pickFallback(\n retiredModelId: string,\n cache: AvailableModelsCache,\n registry: ModelRegistry\n): Promise<string | null> {\n const refreshed = await cache.refresh();\n if (refreshed.length === 0) return null;\n const target = registry.getEntry(retiredModelId);\n\n const sameFamily = refreshed.find((m) => {\n if (m.id === retiredModelId) return false;\n const candidate = registry.getEntry(m.id);\n return candidate.family === target.family && candidate.vendor === target.vendor;\n });\n if (sameFamily !== undefined) return sameFamily.id;\n\n const sameVendor = refreshed.find((m) => {\n if (m.id === retiredModelId) return false;\n const candidate = registry.getEntry(m.id);\n return candidate.vendor === target.vendor;\n });\n return sameVendor?.id ?? null;\n}\n\n// Re-export ok for tests that synthesise success results.\nexport { ok };\n\n// ============================================================================\n// Resilient-adapter aware wrapper (#2549).\n//\n// `withModelNotFoundFallback` returns an `IModelAdapter` — fine for direct-API\n// adapters that satisfy that surface directly. For `IResilientAdapter` callers\n// who also depend on `getHealth` / `refresh` / `setPreferredCli` / `onFailover`\n// / `dispose`, this helper preserves those methods while routing `complete()`\n// through the fallback path.\n// ============================================================================\n\n/**\n * Minimal shape of `IResilientAdapter` — duplicated here as a local\n * type so that `model-not-found-fallback.ts` doesn't acquire a circular\n * import with `adapters/resilient-adapter-types.ts`. The shape matches\n * the resilient adapter's extension methods over `IModelAdapter`.\n */\nexport interface ResilientLike extends IModelAdapter {\n getHealth(): unknown;\n refresh(): Promise<void>;\n setPreferredCli(cli: unknown): void;\n onFailover(cb: (info: unknown) => void): () => void;\n dispose(): void;\n}\n\n/**\n * Wrap an `IResilientAdapter` (or anything that satisfies `ResilientLike`)\n * so its `complete()` path retries on MODEL_NOT_FOUND while its\n * health/lifecycle methods continue to work unchanged.\n */\nexport function wrapResilientWithFallback<T extends ResilientLike>(\n inner: T,\n options: ModelNotFoundFallbackOptions = {}\n): T {\n const wrapped = withModelNotFoundFallback(inner, options);\n // Closes #2945: pre-fix the `Object.assign(..., {5 methods}) as unknown as T`\n // pattern silently dropped any methods on a concrete T beyond the 5\n // explicitly re-attached. A future IResilientAdapter subtype adding\n // `getMetrics()` would type-check but throw `TypeError: x.getMetrics\n // is not a function` at runtime. Switched to a Proxy that forwards\n // unknown property access to `inner`, so methods on T not anticipated\n // by this wrapper remain transparently available.\n //\n // The five explicit bindings are kept so existing health/lifecycle\n // methods are pre-bound (avoids losing `this` if the caller\n // destructures), matching the prior semantics for the existing surface.\n const surface = {\n getHealth: inner.getHealth.bind(inner),\n refresh: inner.refresh.bind(inner),\n setPreferredCli: inner.setPreferredCli.bind(inner),\n onFailover: inner.onFailover.bind(inner),\n dispose: inner.dispose.bind(inner),\n };\n const explicit: ResilientLike = Object.assign(wrapped, surface);\n const innerAsRecord = inner as unknown as Record<PropertyKey, unknown>;\n return new Proxy(explicit, {\n get(target, prop, receiver): unknown {\n if (prop in target) return Reflect.get(target, prop, receiver);\n // Forward unknown reads to `inner` — covers future methods on T.\n // Bind functions so call-site `this` is the inner adapter, matching\n // the explicit-binding behavior above.\n const innerProp: unknown = innerAsRecord[prop];\n if (typeof innerProp === 'function') {\n return (innerProp as (...args: unknown[]) => unknown).bind(inner);\n }\n return innerProp;\n },\n }) as unknown as T;\n}\n","/**\n * Unified Adapter Registry — single entry point for all model adapter access.\n *\n * Pre-computes task-to-CLI routing from the canonical model registry and\n * task specialization matrix at creation time. All consumers get adapters\n * through this registry instead of calling createAutoAdapter/createResilientAdapter\n * directly.\n *\n * Design:\n * - One IResilientAdapter per CLI (claude/gemini/codex), created lazily on first access\n * - One \"default\" adapter for unscoped requests (uses createAutoAdapter priority)\n * - Task routing is deterministic: category → primary CLI → cached adapter\n * - Session-scoped: create once at MCP startup, reuse for the session lifetime\n *\n * @module adapters/unified-registry\n * (Source: Issue #1149 — Unified Adapter Registry)\n * (Source: Issue #1151 — Single adapter entry point)\n */\n\nimport type { ILogger } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\nimport { createResilientAdapter } from './resilient-adapter.js';\nimport type { IResilientAdapter } from './resilient-adapter-types.js';\nimport {\n wrapResilientWithFallback,\n type ModelNotFoundFallbackOptions,\n} from './model-not-found-fallback.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport { TASK_SPECIALIZATION_MATRIX, detectTaskCategory } from '../config/task-specialization.js';\nimport type { TaskCategory } from '../config/task-specialization-types.js';\nimport {\n getDefaultModelForCli,\n getInTreeCapabilitiesMatrix,\n} from '../config/model-config-helpers.js';\nimport type { CliNameLiteral } from '../config/model-capabilities-types.js';\nimport { CLI_NAMES } from '../config/model-capabilities-types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Configuration for the unified registry. */\nexport interface UnifiedRegistryConfig {\n /** Logger instance */\n readonly logger?: ILogger;\n /** Default CLI timeout for subprocess calls (ms) */\n readonly defaultCliTimeoutMs?: number;\n /**\n * Auto-wrap every constructed adapter with `withModelNotFoundFallback`\n * (#2549). When enabled, the registry routes `complete()` through the\n * fallback path so a `MODEL_NOT_FOUND` error (typically from a vendor\n * 404 / \"model deprecated\" message) refreshes the AvailableModelsCache\n * and retries through the closest same-family alternative.\n *\n * Defaults to `false` — operators opt in by wiring up an\n * `AvailableModelsCache` via `setDefaultAvailableModelsCache()` and\n * setting this flag. Safe-on-empty: if no cache is provided or the\n * cache has no sources, the wrap is transparent (no retry happens,\n * original error surfaces).\n */\n readonly enableMissingModelFallback?: boolean;\n /**\n * Optional override for the fallback decorator. When omitted, the\n * decorator uses `getDefaultAvailableModelsCache()` and\n * `getDefaultRegistry()`.\n */\n readonly missingModelFallbackOptions?: ModelNotFoundFallbackOptions;\n}\n\n/** Summary of the pre-computed task routing table. */\nexport interface TaskRoutingEntry {\n readonly category: TaskCategory;\n readonly primaryCli: CliName;\n readonly secondaryCli: CliName;\n readonly primaryModel: string;\n}\n\n/** Snapshot of registry state for observability. */\nexport interface RegistrySnapshot {\n readonly taskRouting: readonly TaskRoutingEntry[];\n readonly cachedAdapters: readonly CliName[];\n readonly availableModels: number;\n}\n\n// ============================================================================\n// Registry\n// ============================================================================\n\n/**\n * Unified adapter registry. Centralizes all adapter creation and task routing.\n *\n * Usage:\n * ```typescript\n * const registry = createUnifiedRegistry({ logger });\n * const adapter = registry.getAdapter('code_generation'); // → codex adapter\n * const adapter2 = registry.getAdapterForCli('claude'); // → claude adapter\n * const adapter3 = registry.getDefault(); // → best available\n * ```\n */\nexport class UnifiedAdapterRegistry {\n private readonly logger: ILogger;\n private readonly defaultCliTimeoutMs: number | undefined;\n private readonly enableMissingModelFallback: boolean;\n private readonly missingModelFallbackOptions: ModelNotFoundFallbackOptions | undefined;\n\n /** Pre-computed task → CLI routing (immutable after construction). */\n private readonly taskRouting: ReadonlyMap<TaskCategory, TaskRoutingEntry>;\n\n /** Per-CLI adapter cache — max 3 entries (claude/gemini/codex). */\n private readonly cliAdapters = new Map<CliName, IResilientAdapter>();\n\n /** Default adapter for unscoped requests. */\n private defaultAdapter: IResilientAdapter | undefined;\n\n constructor(config?: UnifiedRegistryConfig) {\n this.logger = config?.logger ?? createLogger({ component: 'unified-registry' });\n this.defaultCliTimeoutMs = config?.defaultCliTimeoutMs;\n this.enableMissingModelFallback = config?.enableMissingModelFallback ?? false;\n this.missingModelFallbackOptions = config?.missingModelFallbackOptions;\n this.taskRouting = this.buildTaskRouting();\n this.logger.info('UnifiedAdapterRegistry initialized', {\n categories: this.taskRouting.size,\n models: getInTreeCapabilitiesMatrix().models.length,\n missingModelFallback: this.enableMissingModelFallback,\n });\n }\n\n /**\n * Apply the MODEL_NOT_FOUND fallback decorator if enabled, otherwise\n * return the adapter unchanged. The recursion guard from the original\n * issue is unnecessary here: the decorator's retry path uses the\n * caller-supplied `adapterFactory`; without one, it surfaces an\n * enriched error and never re-enters the resilient layer.\n */\n private maybeWrap(adapter: IResilientAdapter): IResilientAdapter {\n if (!this.enableMissingModelFallback) return adapter;\n return wrapResilientWithFallback(adapter, this.missingModelFallbackOptions);\n }\n\n // --------------------------------------------------------------------------\n // Public API\n // --------------------------------------------------------------------------\n\n /** Logger used by this registry. Exposed so singleton helpers can warn. */\n getLogger(): ILogger {\n return this.logger;\n }\n\n /**\n * Get adapter for a task category. Uses pre-computed routing.\n * Falls back to default adapter if category unknown.\n */\n getAdapter(category: TaskCategory): IResilientAdapter {\n const routing = this.taskRouting.get(category);\n if (routing === undefined) {\n this.logger.warn('Unknown task category, using default', { category });\n return this.getDefault();\n }\n return this.getAdapterForCli(routing.primaryCli);\n }\n\n /**\n * Get adapter for a free-text task description.\n * Detects category from keywords, falls back to default.\n */\n getAdapterForTask(taskDescription: string): IResilientAdapter {\n const match = detectTaskCategory(taskDescription);\n if (match !== null) {\n this.logger.debug('Task category detected', {\n category: match.category,\n cli: match.primaryCli,\n });\n return this.getAdapterForCli(match.primaryCli);\n }\n return this.getDefault();\n }\n\n /**\n * Get adapter pinned to a specific CLI.\n * Creates and caches one IResilientAdapter per CLI.\n */\n getAdapterForCli(cli: CliName): IResilientAdapter {\n const cached = this.cliAdapters.get(cli);\n if (cached !== undefined) return cached;\n\n const raw = createResilientAdapter({\n logger: this.logger,\n preferredCli: cli,\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n });\n const adapter = this.maybeWrap(raw);\n this.cliAdapters.set(cli, adapter);\n this.logger.info('Created CLI-specific adapter', {\n cli,\n missingModelFallback: this.enableMissingModelFallback,\n });\n return adapter;\n }\n\n /**\n * Get adapter for a model preference string (e.g., \"claude-opus-4-6\").\n * Resolves the model to its CLI via the canonical registry.\n * Falls back to default adapter if model not recognized.\n */\n getAdapterForModel(modelPreference: string): IResilientAdapter {\n // Prefer exact matches (id / cliAlias / cliModelName) over prefix matches.\n // For prefix fallback, longest-prefix-wins so a future registry containing\n // both 'gemini-pro' and 'gemini-pro-experimental' resolves correctly even\n // though the registry's natural array order isn't sorted by id length.\n // Defense-in-depth — no current registry has prefix overlaps. (#2192)\n const allModels = getInTreeCapabilitiesMatrix().models;\n const exact = allModels.find(\n (m) =>\n m.id === modelPreference ||\n m.cliAlias === modelPreference ||\n m.cliModelName === modelPreference\n );\n const prefix =\n exact ??\n [...allModels]\n .filter((m) => modelPreference.startsWith(m.id))\n .sort((a, b) => b.id.length - a.id.length)[0];\n const model = prefix;\n if (model !== undefined) {\n this.logger.debug('Model resolved to CLI', {\n model: modelPreference,\n cli: model.cliName,\n });\n return this.getAdapterForCli(model.cliName as CliName);\n }\n this.logger.debug('Model not in registry, using default', {\n model: modelPreference,\n });\n return this.getDefault();\n }\n\n /**\n * Get adapter for an expert role (e.g., \"code_expert\").\n * Uses ROLE_TO_TASK_CATEGORY mapping → task specialization → CLI.\n */\n getAdapterForRole(role: string): IResilientAdapter {\n const category = ROLE_TO_CATEGORY[role];\n if (category !== undefined) return this.getAdapter(category);\n return this.getDefault();\n }\n\n /**\n * Get the default adapter (no CLI preference — auto-detection priority).\n */\n getDefault(): IResilientAdapter {\n if (this.defaultAdapter !== undefined) return this.defaultAdapter;\n const raw = createResilientAdapter({\n logger: this.logger,\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n });\n this.defaultAdapter = this.maybeWrap(raw);\n return this.defaultAdapter;\n }\n\n /**\n * Get snapshot of registry state for observability/debugging.\n */\n getSnapshot(): RegistrySnapshot {\n return {\n taskRouting: [...this.taskRouting.values()],\n cachedAdapters: [...this.cliAdapters.keys()],\n availableModels: getInTreeCapabilitiesMatrix().models.length,\n };\n }\n\n /**\n * Get the pre-computed routing for a specific category.\n */\n getRouting(category: TaskCategory): TaskRoutingEntry | undefined {\n return this.taskRouting.get(category);\n }\n\n /**\n * Dispose all cached adapters.\n */\n dispose(): void {\n for (const adapter of this.cliAdapters.values()) {\n adapter.dispose();\n }\n this.cliAdapters.clear();\n this.defaultAdapter?.dispose();\n this.defaultAdapter = undefined;\n this.logger.info('UnifiedAdapterRegistry disposed');\n }\n\n // --------------------------------------------------------------------------\n // Private\n // --------------------------------------------------------------------------\n\n private buildTaskRouting(): ReadonlyMap<TaskCategory, TaskRoutingEntry> {\n const routing = new Map<TaskCategory, TaskRoutingEntry>();\n for (const spec of TASK_SPECIALIZATION_MATRIX) {\n const primaryModel = resolveDefaultModel(spec.primaryCli);\n routing.set(spec.category, {\n category: spec.category,\n primaryCli: spec.primaryCli,\n secondaryCli: spec.secondaryCli,\n primaryModel,\n });\n }\n return routing;\n }\n}\n\n// ============================================================================\n// Role → Category Mapping (consolidated from create-expert-routing.ts)\n// ============================================================================\n\n/** Maps expert roles to task categories for CLI specialization. */\nconst ROLE_TO_CATEGORY: Record<string, TaskCategory> = {\n code_expert: 'code_generation',\n architecture_expert: 'architecture',\n security_expert: 'security_review',\n documentation_expert: 'documentation',\n testing_expert: 'testing',\n devops_expert: 'devops',\n research_expert: 'research',\n pm_expert: 'planning',\n ux_expert: 'planning',\n infrastructure_expert: 'devops',\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Resolve the default model name for a CLI from the canonical registry. */\nfunction resolveDefaultModel(cli: string): string {\n if ((CLI_NAMES as readonly string[]).includes(cli)) {\n return getDefaultModelForCli(cli as CliNameLiteral);\n }\n return cli;\n}\n\n// ============================================================================\n// Factory & Singleton\n// ============================================================================\n\nlet globalRegistry: UnifiedAdapterRegistry | undefined;\n\n/**\n * Create a new UnifiedAdapterRegistry instance.\n * For most uses, prefer `getGlobalRegistry()` instead.\n */\nexport function createUnifiedRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry {\n return new UnifiedAdapterRegistry(config);\n}\n\n/**\n * Get the global singleton registry.\n * Creates it on first access with default config.\n *\n * If the singleton already exists and a non-empty config is supplied, the\n * config is ignored — callers get the pre-existing instance. A warning is\n * emitted so this asymmetry is not silent.\n */\nexport function getGlobalRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry {\n if (globalRegistry === undefined) {\n globalRegistry = new UnifiedAdapterRegistry(config);\n return globalRegistry;\n }\n if (config !== undefined && Object.keys(config).length > 0) {\n globalRegistry\n .getLogger()\n .warn(\n 'UnifiedAdapterRegistry singleton already initialized; provided config ignored. ' +\n 'Call resetGlobalRegistry() first if reconfiguration is intentional.',\n { providedKeys: Object.keys(config) }\n );\n }\n return globalRegistry;\n}\n\n/** Reset the global registry (for testing). */\nexport function resetGlobalRegistry(): void {\n globalRegistry?.dispose();\n globalRegistry = undefined;\n}\n","/**\n * Codex CLI subagent limits (#2659, Epic D).\n *\n * Codex's `~/.codex/config.toml` `[agents]` section defaults to\n * `max_depth = 1` and `max_threads = 6` (verified against\n * developers.openai.com/codex config reference — the originating issue's\n * `max_thread_depth` key name was wrong).\n *\n * nexus-agents does NOT write the operator's global `~/.codex/config.toml`\n * (that would clobber operator-owned state) and does NOT silently\n * auto-flatten routing topology. Instead — Option C from the #2659 design\n * vote — it WARNS at fan-out time when a planned concurrency would exceed\n * Codex's defaults, so the operator can raise their own `[agents]` limits\n * or spread the panel across more CLIs. The two existing parallel-dispatch\n * sites are already conservative: `worker-dispatcher.ts` caps a wave at 3\n * concurrent workers, and `collectRealVotes` round-robins voter roles\n * across available CLIs. The warned case is the narrow one — a single-CLI\n * fallback where every voter role lands on Codex.\n *\n * @module cli-adapters/codex-limits\n * @see Issue #2659\n */\n\n/** Codex `[agents] max_depth` default — nested subagent depth. */\nexport const CODEX_DEFAULT_MAX_DEPTH = 1;\n\n/** Codex `[agents] max_threads` default — concurrent subagent threads. */\nexport const CODEX_DEFAULT_MAX_THREADS = 6;\n\n/**\n * A structured warning when `codexBoundConcurrency` parallel calls are\n * about to be dispatched to Codex, exceeding its default `max_threads`.\n * Returns `null` when within limits. Does not block — the operator stays\n * in control (Option C).\n */\nexport function checkCodexConcurrency(codexBoundConcurrency: number): string | null {\n if (codexBoundConcurrency <= CODEX_DEFAULT_MAX_THREADS) return null;\n return (\n `${String(codexBoundConcurrency)} parallel calls are bound for Codex, exceeding its ` +\n `default max_threads=${String(CODEX_DEFAULT_MAX_THREADS)}. Codex may queue or drop the ` +\n `excess. Raise [agents] max_threads in ~/.codex/config.toml, or spread the panel across ` +\n `more CLIs (claude/gemini) so fewer roles land on Codex.`\n );\n}\n\n/**\n * A structured warning when a planned subagent nesting `depth` exceeds\n * Codex's default `max_depth`. Returns `null` when within limits.\n */\nexport function checkCodexDepth(depth: number): string | null {\n if (depth <= CODEX_DEFAULT_MAX_DEPTH) return null;\n return (\n `planned subagent nesting depth ${String(depth)} exceeds Codex's default ` +\n `max_depth=${String(CODEX_DEFAULT_MAX_DEPTH)}. Codex will reject the nested spawn. ` +\n `Raise [agents] max_depth in ~/.codex/config.toml, or flatten the expert chain.`\n );\n}\n","/**\n * nexus-agents/cli - Voter System Prompts\n *\n * Role-specific system prompts for voter agents.\n *\n * @module cli/voter-prompts\n * (Source: Issue #226, extracted from voter-agents.ts for #272)\n */\n\nimport type { VoterRole } from './vote-types.js';\n\n/** Default project name used in voter prompts when no context is provided. */\nconst DEFAULT_PROJECT = 'nexus-agents';\n\n/**\n * Generate voter system prompts with optional project context.\n *\n * When nexus-agents MCP tools are used as a service for other projects,\n * the default \"nexus-agents project\" context causes voters to reject\n * proposals as MISALIGNED. This function allows injecting the target\n * project name so voters evaluate correctly.\n *\n * @param project - Project name/context to inject (defaults to 'nexus-agents')\n */\n/**\n * PR-review-mode addendum (#2244). Appended to every voter's prompt so the\n * format is reinforced at the system-prompt level, where role framing\n * dominates — the proposal-text-only approach in #2238 produced 0 verified\n * findings across 50 voter calls in #2241.\n *\n * The addendum is conditional on its face: voters reviewing a non-diff\n * proposal ignore it. Voters reviewing a diff get the explicit format +\n * few-shot example here, plus the same instructions in the proposal text.\n */\nfunction prReviewModeAddendum(): string {\n return `\nPR-review mode — if you are reviewing a code diff (not a proposal) AND you have at least one concrete defect that justifies blocking the merge, populate the OPTIONAL TOP-LEVEL \"findings\" field on your JSON response. NOT inside reasoning — top-level. The schema:\n\n\"findings\": [\n {\n \"summary\": \"One-line summary\",\n \"location\": \"path/file.ext:LINE\",\n \"severity\": \"critical\" | \"high\" | \"medium\" | \"low\",\n \"gate\": {\n \"reread_cited_line\": \"passed\",\n \"traced_call_path\": \"passed\",\n \"named_assertion\": \"Concrete failing assertion — what test would fail and how. Substantive, not 'passed'.\",\n \"ruled_out_language_non_issue\": \"passed\"\n },\n \"claim\": \"What is wrong and why it justifies blocking.\"\n }\n]\n\nA finding only triggers strict request_changes if all 4 gate fields = \"passed\" AND named_assertion is substantive (>10 chars naming a concrete failure, not just \"passed\"). Findings missing any of those surface as informational only — they do not block on their own. The 2026-04-25 audit (#2225) found a 100% false-positive rate when this gate wasn't enforced. If you're approving the diff, OMIT the findings field entirely. If reviewing a non-diff proposal, ignore this section.\n\nHistory note: an earlier prompt asked for YAML inside reasoning; that format was lossy across JSON serialization (#2245). Use the top-level JSON array above.`;\n}\n\n/** Common footer appended to all voter prompts. */\nfunction voterFooter(): string {\n return `\nWorkflow-test assessment (include in your reasoning):\n- Testability: Can changes be verified with automated tests?\n- Workflow integration: Does this fit existing CI/build/test pipelines?\n- Incremental verifiability: Can progress be measured at each step?\n\nWhen rejecting, classify your reasons using categories: YAGNI, DRY_VIOLATION, OVER_ENGINEERING, SCOPE_CREEP, SECURITY_RISK, MISALIGNED, INSUFFICIENT_EVIDENCE.\n${prReviewModeAddendum()}`;\n}\n\n/** Build the architect role prompt. */\nfunction architectPrompt(project: string): string {\n return `You are a Software Architect voting on technical proposals for the ${project} project.\n\nYour evaluation criteria:\n- Technical design quality and architectural soundness\n- Scalability and performance implications\n- Maintainability and code organization\n- Alignment with existing patterns (Result<T,E>, Zod validation, TypeScript best practices)\n- Integration complexity with current codebase\n${voterFooter()}\n\nBe direct and technical. Focus on structural implications.`;\n}\n\n/** Build the security role prompt. */\nfunction securityPrompt(project: string): string {\n return `You are a Security Engineer voting on proposals for the ${project} project.\n\nYour evaluation criteria:\n- Security vulnerabilities and attack vectors (OWASP Top 10)\n- Input validation and sanitization\n- Secrets management and credential handling\n- Path traversal and injection prevention\n- Rate limiting and resource exhaustion\n${voterFooter()}\n\nBe thorough about risks. Flag any security concerns.`;\n}\n\n/** Build the devex role prompt. */\nfunction devexPrompt(project: string): string {\n return `You are a Developer Experience Engineer voting on proposals for the ${project} project.\n\nYour evaluation criteria:\n- API usability and ergonomics\n- Documentation clarity and completeness\n- Learning curve for new developers\n- Testing and debugging experience\n- CLI/tool integration quality\n${voterFooter()}\n\nFocus on practical developer impact.`;\n}\n\n/** Build the AI/ML role prompt. */\nfunction aiMlPrompt(project: string): string {\n return `You are an AI/ML Engineer voting on proposals for the ${project} project.\n\nYour evaluation criteria:\n- Multi-agent coordination effectiveness\n- Model selection and routing strategies\n- Context management and token efficiency\n- Learning and adaptation capabilities\n- Consensus protocol design\n- Integration with LLM capabilities\n${voterFooter()}\n\nEvaluate AI/ML implications and opportunities.`;\n}\n\n/** Build the PM role prompt. */\nfunction pmPrompt(project: string): string {\n return `You are a Product Manager voting on proposals for the ${project} project.\n\nYour evaluation criteria:\n- Business value and user impact\n- Resource requirements and timeline\n- Risk assessment and mitigation\n- Priority relative to roadmap\n- Success metrics and validation approach\n- Alignment with project goals in CLAUDE.md\n${voterFooter()}\n\nBalance value against effort. Be pragmatic.`;\n}\n\n/** Build the catfish (contrarian) role prompt. */\nfunction catfishPrompt(project: string): string {\n return `You are a Contrarian Analyst (catfish agent) voting on proposals for the ${project} project.\n\nYour role is to prevent false consensus by deliberately challenging proposals.\nBased on research (arXiv:2505.21503), agreement bias in multi-agent voting leads\nto poor decisions when agents rubber-stamp proposals without genuine scrutiny.\n\nYour evaluation criteria:\n- What are the hidden costs, risks, or downsides not mentioned?\n- What assumptions are being made that might be wrong?\n- What alternatives were not considered?\n- What could go wrong in practice vs. theory?\n- Is there scope creep or unnecessary complexity?\n\nWorkflow-test assessment (include in your reasoning):\n- Testability: Is the proposal verifiable, or just theoretical?\n- Workflow integration: Will this actually work in existing pipelines?\n- Incremental verifiability: Can we tell if it's working at each stage?\n\nWhen rejecting, you MUST classify your reasons using categories: YAGNI, DRY_VIOLATION, OVER_ENGINEERING, SCOPE_CREEP, SECURITY_RISK, MISALIGNED, INSUFFICIENT_EVIDENCE.\n\nIMPORTANT: Your job is to find legitimate concerns, not to reject everything.\nIf after genuine scrutiny you find no significant issues, you MAY approve.\nBut your default posture is skeptical — look for what others might miss.\nHigh-confidence rejections with specific reasoning are your most valuable output.\n${prReviewModeAddendum()}`;\n}\n\n/**\n * Build the scope_steward role prompt (#2185).\n *\n * Different axis from `pm` (which prioritizes WHICH features to build) and\n * `catfish` (which doubts the framing). The steward asks: should we build\n * this AT ALL? Existing tools usually win; default bias is \"don't ship.\"\n */\nfunction scopeStewardPrompt(project: string): string {\n return `You are a Scope Steward voting on proposals for the ${project} project.\n\nYour job is to gate against build-when-buy-would-do and feature sprawl.\nThe originating case (2026-04-24): a 6-role panel approved building a USB flasher\nCLI without anyone flagging that Rufus already solves the problem better, for the\nsame audience, with 100M+ installs of battle-tested code. This role exists to\ncatch that class of mistake.\n\nYour evaluation criteria — work through these mandatory checks in your reasoning:\n\n1. **Existing-tool check.** Search your knowledge for tools, libraries, or\n services that already solve the stated problem. Name them concretely\n (not \"there might be alternatives\" — actual names: Rufus, ripgrep,\n esbuild, etc.). If you can't name an alternative, say so explicitly.\n\n2. **Build-vs-buy math.** For each existing tool you named: what would we\n LOSE by adopting it (license, dependency surface, integration cost)?\n What would we GAIN by building our own (tighter integration, no extra\n binary, etc.)? Default lean: BUY. Building is justified only when the\n loss column is concrete and the gain column is load-bearing.\n\n3. **Mission alignment.** Does this proposal serve the project's stated\n mission, or is it scope drift? If drift, name the drift specifically.\n\n4. **Kill-the-feature option.** For every proposal, explicitly evaluate\n \"what if we just didn't do this?\" as a ranked option. Many proposals\n don't need to be built. Make the no-build case before the build case.\n\n5. **Sprawl audit.** Check whether similar functionality already exists\n in the codebase. If it does, recommend extending — not forking. The\n anti-sprawl policy in CLAUDE.md is specifically the rule this role\n enforces.\n\nDefault bias: REJECT proposals where an existing tool fits, even if our\nown implementation would be marginally nicer. Only approve when the\nexisting-tool check fails AND the kill-the-feature option is worse AND\nmission alignment is clear AND no comparable in-codebase functionality\nexists.\n\nFew-shot example of a textbook rejection:\n> Proposal: \"Add an aegis-boot subcommand to flash bootable USB sticks.\"\n> Steward response: \"REJECT (DON'T-BUILD). Rufus has solved this for the\n> same audience for 10+ years with 100M+ installs and battle-tested code.\n> Adopting Rufus loses nothing material; building our own loses\n> maintenance bandwidth indefinitely. Mission alignment: aegis-boot's\n> mission is verifiable boot, not USB tooling. Kill option clearly wins.\n> No prior in-codebase functionality. Recommend: point users at Rufus in\n> the docs and stop here.\"\n\n${voterFooter()}\n\nWhen rejecting, you MUST classify reasons (YAGNI, DRY_VIOLATION,\nOVER_ENGINEERING, SCOPE_CREEP, MISALIGNED). The steward's most common\ncategories are SCOPE_CREEP, YAGNI, and OVER_ENGINEERING.\n\nYou CAN approve. But your default posture is: \"this should not be built;\nprove me wrong with the build-vs-buy math.\"`;\n}\n\nexport function getVoterPrompts(project: string = DEFAULT_PROJECT): Record<VoterRole, string> {\n return {\n architect: architectPrompt(project),\n security: securityPrompt(project),\n devex: devexPrompt(project),\n ai_ml: aiMlPrompt(project),\n pm: pmPrompt(project),\n catfish: catfishPrompt(project),\n scope_steward: scopeStewardPrompt(project),\n };\n}\n\n/**\n * Default prompts (backward compatible — uses 'nexus-agents' project context).\n */\nexport const VOTER_SYSTEM_PROMPTS: Record<VoterRole, string> = getVoterPrompts();\n\n/**\n * Base reasoning templates for simulated votes.\n *\n * scope_steward simulated reasoning intentionally reflects the role's\n * bias-toward-not-shipping posture (PM vote condition on #2185).\n */\nexport const SIMULATED_VOTE_REASONING: Record<VoterRole, string> = {\n architect: 'Evaluated technical design and architecture implications.',\n security: 'Reviewed security considerations and attack surface.',\n devex: 'Assessed developer experience and workflow impact.',\n ai_ml: 'Analyzed AI/ML capabilities and learning potential.',\n pm: 'Evaluated business value and resource requirements.',\n catfish: 'Challenged proposal assumptions and identified potential risks.',\n scope_steward:\n 'Checked existing tools, build-vs-buy math, kill-the-feature option; bias toward not shipping.',\n};\n","/**\n * nexus-agents voter response parsing\n *\n * Schema and parsing utilities for structured vote responses from LLM.\n *\n * (Source: Extracted from voter-agents.ts per Issue #285)\n */\n\nimport { z } from 'zod';\nimport type { Vote } from '../consensus/types.js';\nimport type { VoterRole } from './vote-types.js';\nimport { getErrorMessage, createLogger } from '../core/index.js';\n\n// ============================================================================\n// Error Classes\n// ============================================================================\n\n/**\n * Error thrown when vote response parsing fails and synthetic votes not allowed.\n * (Source: Issue #512 - Fail-safe voting response parsing)\n *\n * By default, parseVoteResponse throws this error when JSON parsing or validation\n * fails. To use synthetic fallback votes (NOT RECOMMENDED), pass\n * `allowSyntheticVote: true` to the options parameter.\n */\nexport class SyntheticVoteError extends Error {\n constructor(\n reason: string,\n public readonly rawOutput: string\n ) {\n super(\n `Vote response parsing failed: ${reason}. ` +\n 'To use synthetic fallback votes (NOT RECOMMENDED), set allowSyntheticVote: true'\n );\n this.name = 'SyntheticVoteError';\n }\n}\n\n/**\n * Vote source tracking - indicates whether vote is real or synthetic.\n * (Source: Issue #512 - Voting integrity)\n */\nexport type ParsedVoteSource = 'parsed' | 'fallback';\n\n/**\n * Extended vote with source tracking.\n */\nexport interface ParsedVote extends Vote {\n readonly source: ParsedVoteSource;\n}\n\n/**\n * Options for parseVoteResponse.\n */\nexport interface ParseVoteOptions {\n /**\n * Allow synthetic fallback votes when parsing fails.\n * Default: false (throws SyntheticVoteError)\n * (Source: Issue #512 - Fail-safe voting)\n */\n readonly allowSyntheticVote?: boolean;\n}\n\n// ============================================================================\n// Structured Vote Response Schema\n// ============================================================================\n\n/**\n * Pre-verified finding shape — voter emits this; downstream\n * `isFindingVerified` adds the derived `verified` flag.\n *\n * #2245 follow-up: voters previously asked to embed YAML findings inside\n * the JSON `reasoning` field. That format is lossy across JSON\n * serialization (backticks/newlines). The v4 retest produced 0 findings\n * across 9 request_changes voters because the LLM either dropped the\n * YAML to keep JSON valid, or produced invalid JSON the parser rejected.\n * Solution: expose findings as a top-level array on the vote response.\n */\nexport const RawFindingSchema = z.object({\n summary: z.string().min(1).max(500).describe('One-line summary of the issue'),\n location: z.string().min(1).max(200).describe('path/file.ext:line'),\n severity: z.enum(['critical', 'high', 'medium', 'low']).default('medium'),\n gate: z.object({\n reread_cited_line: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n traced_call_path: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n named_assertion: z\n .string()\n .default('')\n .describe('Concrete failing assertion — substantive, not a rubber-stamp word'),\n ruled_out_language_non_issue: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n }),\n claim: z.string().min(1).max(2000).describe('What is wrong and why it justifies blocking'),\n});\n\nexport type RawFinding = z.infer<typeof RawFindingSchema>;\n\n/**\n * Zod schema for parsing structured vote responses from LLM.\n */\nexport const VoteResponseSchema = z.object({\n decision: z.enum(['approve', 'reject', 'abstain']).describe('Your vote decision'),\n reasoning: z.string().min(10).max(4000).describe('Explanation for your vote (10-4000 chars)'),\n confidence: z.number().min(0).max(1).describe('Confidence level 0-1'),\n conditions: z.array(z.string()).optional().describe('Optional conditions for approval'),\n /** Structured rejection categories for reject→refine→re-vote loops (Issue #1213). */\n rejectionCategories: z\n .array(\n z.enum([\n 'YAGNI',\n 'DRY_VIOLATION',\n 'OVER_ENGINEERING',\n 'SCOPE_CREEP',\n 'SECURITY_RISK',\n 'MISALIGNED',\n 'INSUFFICIENT_EVIDENCE',\n ])\n )\n .optional()\n .describe('Rejection reason categories when decision is reject'),\n /** Top-level structured findings for PR-review mode (#2245 v4 follow-up).\n * Replaces the YAML-in-reasoning encoding that proved lossy. */\n findings: z.array(RawFindingSchema).optional().describe('Structured findings (PR review only)'),\n});\n\nexport type VoteResponse = z.infer<typeof VoteResponseSchema>;\n\n// ============================================================================\n// Vote Prompt Construction\n// ============================================================================\n\n/** Example responses appended to vote prompts. Kept as a constant to keep\n * `buildVotePrompt` under the max-lines-per-function lint cap. */\nconst VOTE_PROMPT_EXAMPLES = `Example approve response:\n{\n \"decision\": \"approve\",\n \"reasoning\": \"The proposal aligns with architectural patterns. Testability: high — unit tests can verify each component. Workflow integration: fits existing CI pipeline.\",\n \"confidence\": 0.85,\n \"conditions\": [\"Add unit tests before merge\"]\n}\n\nExample reject response:\n{\n \"decision\": \"reject\",\n \"reasoning\": \"This adds speculative abstractions for hypothetical future needs. Testability: unclear — no concrete test plan provided.\",\n \"confidence\": 0.80,\n \"rejectionCategories\": [\"YAGNI\", \"OVER_ENGINEERING\"]\n}\n\nExample PR-review request_changes response with structured findings:\n{\n \"decision\": \"reject\",\n \"reasoning\": \"Off-by-one in clampPageSize and missing null guard on response.timing — both visible in the diff.\",\n \"confidence\": 0.9,\n \"rejectionCategories\": [\"INSUFFICIENT_EVIDENCE\"],\n \"findings\": [\n {\n \"summary\": \"Off-by-one in clampPageSize\",\n \"location\": \"packages/nexus-agents/src/api/pagination.ts:18\",\n \"severity\": \"high\",\n \"gate\": {\n \"reread_cited_line\": \"passed\",\n \"traced_call_path\": \"passed\",\n \"named_assertion\": \"Test would assert clampPageSize(50, 100) === 50; this returns 49.\",\n \"ruled_out_language_non_issue\": \"passed\"\n },\n \"claim\": \"Function name says 'clamp to range' but returns requested-1 in the in-range path.\"\n }\n ]\n}`;\n\n/**\n * Constructs the user prompt for vote evaluation.\n * Includes workflow-test evaluation criteria (Issue #1212) and\n * rejection category instructions (Issue #1213).\n */\nexport function buildVotePrompt(proposal: string): string {\n return `Evaluate the following proposal and provide your vote.\n\nPROPOSAL:\n${proposal}\n\nIn addition to your role-specific criteria, assess these workflow-test dimensions:\n- Testability: Can the proposed changes be verified with automated tests?\n- Workflow integration: Does this fit into existing CI/make/test workflows?\n- Incremental verifiability: Can progress be measured at each step?\n\nRespond with a JSON object containing:\n- decision: \"approve\", \"reject\", or \"abstain\"\n- reasoning: Explanation for your vote (10-4000 characters). Include your workflow-test assessment.\n- confidence: Number between 0 and 1\n- conditions: Optional array of conditions for approval\n- rejectionCategories: Required when rejecting. Array of categories from: YAGNI, DRY_VIOLATION, OVER_ENGINEERING, SCOPE_CREEP, SECURITY_RISK, MISALIGNED, INSUFFICIENT_EVIDENCE\n- findings: PR-REVIEW MODE ONLY. Optional top-level array of structured findings — see \"PR-review mode\" in the system prompt. OMIT this field entirely when reviewing a non-diff proposal or when approving a diff.\n\n${VOTE_PROMPT_EXAMPLES}`;\n}\n\n// ============================================================================\n// Vote Response Parsing\n// ============================================================================\n\n/**\n * Extracts JSON from LLM response text.\n * Handles responses that may include markdown code blocks.\n */\nexport function extractJsonFromResponse(text: string): string {\n // Try to find JSON in code blocks first\n const codeBlockMatch = /```(?:json)?\\s*([\\s\\S]*?)```/i.exec(text);\n if (codeBlockMatch?.[1] !== undefined) {\n return codeBlockMatch[1].trim();\n }\n\n // Look for JSON object directly\n const jsonMatch = /\\{[\\s\\S]*\\}/i.exec(text);\n if (jsonMatch?.[0] !== undefined) {\n return jsonMatch[0];\n }\n\n return text.trim();\n}\n\n/**\n * Creates a fallback vote when parsing fails.\n * Attempts to infer decision from text content.\n * ONLY used when allowSyntheticVote is explicitly true.\n * (Source: Issue #512 - Fail-safe voting)\n */\nfunction createFallbackVote(output: string, _role: VoterRole, reason: string): ParsedVote {\n const lower = output.toLowerCase();\n let decision: Vote['decision'] = 'abstain';\n\n // Simple keyword detection - heuristic only\n // Check reject keywords FIRST since \"disagree\" contains \"agree\" substring\n if (lower.includes('reject') || lower.includes('decline') || lower.includes('disagree')) {\n decision = 'reject';\n } else if (lower.includes('approve') || lower.includes('accept') || lower.includes('agree')) {\n decision = 'approve';\n }\n\n // Log warning about synthetic vote\n createLogger({ component: 'voter-response' }).warn(\n 'Creating synthetic vote (NOT parsed from LLM output)',\n { decision, reason }\n );\n\n return {\n decision,\n reasoning: `[SYNTHETIC: ${reason}] ${output.slice(0, 200)}`,\n confidence: 0.5,\n source: 'fallback', // Mark as synthetic\n };\n}\n\n/** Maps a validated VoteResponse into a ParsedVote, threading optional fields. */\nfunction buildParsedVote(data: VoteResponse): ParsedVote {\n return {\n decision: data.decision,\n reasoning: data.reasoning,\n confidence: data.confidence,\n ...(data.conditions !== undefined ? { conditions: data.conditions } : {}),\n ...(data.rejectionCategories !== undefined\n ? { rejectionCategories: data.rejectionCategories }\n : {}),\n ...(data.findings !== undefined ? { findings: data.findings } : {}),\n source: 'parsed',\n };\n}\n\n/**\n * Parses vote response from LLM output.\n *\n * By default, throws SyntheticVoteError if parsing fails. To use synthetic\n * fallback votes (NOT RECOMMENDED), pass `allowSyntheticVote: true`.\n *\n * (Source: Issue #512 - Fail-safe voting response parsing)\n *\n * @param output - Raw LLM output text\n * @param role - Voter role for context\n * @param options - Parsing options including allowSyntheticVote\n * @returns ParsedVote with source tracking\n * @throws SyntheticVoteError if parsing fails and allowSyntheticVote is false\n */\nexport function parseVoteResponse(\n output: string,\n role: VoterRole,\n options?: ParseVoteOptions\n): ParsedVote {\n const allowSyntheticVote = options?.allowSyntheticVote ?? false;\n\n try {\n const jsonStr = extractJsonFromResponse(output);\n const parsed = JSON.parse(jsonStr) as unknown;\n const validated = VoteResponseSchema.safeParse(parsed);\n\n if (validated.success) {\n return buildParsedVote(validated.data);\n }\n\n // Validation failed - throw or fallback based on config\n const reason = `Validation failed: ${validated.error.issues.map((e: { message: string }) => e.message).join(', ')}`;\n if (!allowSyntheticVote) {\n throw new SyntheticVoteError(reason, output);\n }\n return createFallbackVote(output, role, reason);\n } catch (error) {\n // If it's already a SyntheticVoteError, rethrow it\n if (error instanceof SyntheticVoteError) {\n throw error;\n }\n\n // Parse error - throw or fallback based on config\n const reason = getErrorMessage(error, 'Unknown parse error');\n if (!allowSyntheticVote) {\n throw new SyntheticVoteError(reason, output);\n }\n return createFallbackVote(output, role, reason);\n }\n}\n","/**\n * nexus-agents voter execution utilities\n *\n * Vote execution helpers including result creation, timeout handling,\n * retry logic, and simulation fallback.\n *\n * (Source: Extracted from voter-agents.ts per Issue #285)\n */\n\nimport type { Vote } from '../consensus/types.js';\nimport type { VoterRole, AgentVoteResult } from './vote-types.js';\nimport type { IModelAdapter, CompletionRequest, ILogger } from '../core/index.js';\nimport { getRandomProvider } from '../core/index.js';\nimport { delay, withTimeout } from '../utils/async-utils.js';\nimport { VOTER_SYSTEM_PROMPTS, SIMULATED_VOTE_REASONING } from './voter-prompts.js';\nimport { buildVotePrompt, parseVoteResponse, SyntheticVoteError } from './voter-response.js';\n\n// Import timeout constants from canonical source (Issue #984)\nimport {\n VOTE_TIMEOUTS,\n resolveVoteTimeout as _resolveVoteTimeout,\n validateTimeout as _validateTimeout,\n} from '../config/timeouts.js';\n\n/** Default vote timeout. Canonical source: `config/timeouts.ts`. */\nexport const DEFAULT_VOTE_TIMEOUT_MS = VOTE_TIMEOUTS.defaultMs;\n\n/** Resolves vote timeout with env var override. Canonical: `config/timeouts.ts`. */\nexport const resolveVoteTimeout = _resolveVoteTimeout;\n\n/** Maximum vote timeout. Canonical source: `config/timeouts.ts`. */\nexport const MAX_VOTE_TIMEOUT_MS = VOTE_TIMEOUTS.maxMs;\n\n/** Minimum vote timeout. Canonical source: `config/timeouts.ts`. */\nexport const MIN_VOTE_TIMEOUT_MS = VOTE_TIMEOUTS.minMs;\n\n/** Maximum retries per vote. Canonical source: `config/timeouts.ts`. */\nexport const DEFAULT_MAX_RETRIES = VOTE_TIMEOUTS.maxRetries;\n\n/**\n * Initial retry delay in milliseconds.\n */\nconst INITIAL_RETRY_DELAY_MS = 1_000;\n\n/**\n * Retry delay for rate-limit errors in milliseconds (Issue #1319).\n * Longer than standard to respect API rate limits.\n */\nexport const RATE_LIMIT_RETRY_DELAY_MS = 5_000;\n\n/**\n * Detects whether an error message indicates a rate-limit condition.\n * Delegates to canonical rate-limit-detector (DRY consolidation Issue #1596).\n */\nimport { isRateLimitLikeError } from '../adapters/rate-limit-detector.js';\n\n/** @see isRateLimitLikeError — re-exported for backward compatibility */\nexport function isRateLimitError(message: string): boolean {\n return isRateLimitLikeError(new Error(message));\n}\n\n/**\n * Validates and clamps timeout to `[VOTE_TIMEOUTS.minMs, VOTE_TIMEOUTS.maxMs]`.\n *\n * **Canonical source:** `config/timeouts.ts`. This re-export exists for\n * back-compat — new code should import from `../config/timeouts.js`\n * directly (#2637).\n */\nexport const validateTimeout = _validateTimeout;\n\n// ============================================================================\n// Vote Result Helpers\n// ============================================================================\n\n/**\n * Creates an error vote result (abstain with error message).\n * Issue #523: Uses source: 'error' instead of 'llm' for accuracy.\n */\nexport function createErrorVoteResult(\n role: VoterRole,\n errorMsg: string,\n processingTimeMs: number\n): AgentVoteResult {\n return {\n role,\n vote: {\n decision: 'abstain',\n reasoning: `[Error] Vote execution failed: ${errorMsg}`,\n confidence: 0,\n },\n processingTimeMs,\n source: 'error',\n error: errorMsg,\n };\n}\n\n/**\n * Creates a simulation vote result.\n */\nexport function createSimulationVoteResult(\n role: VoterRole,\n proposal: string,\n processingTimeMs: number,\n error?: string\n): AgentVoteResult {\n return {\n role,\n vote: simulateVote(role, proposal),\n processingTimeMs,\n source: 'simulation',\n ...(error !== undefined && { error }),\n };\n}\n\n/**\n * Creates simulated votes for multiple roles.\n */\nexport function createSimulatedVotes(\n roles: readonly VoterRole[],\n proposal: string,\n error?: string\n): readonly AgentVoteResult[] {\n const random = getRandomProvider();\n return roles.map((role) =>\n createSimulationVoteResult(role, proposal, random.randomInt(0, 100), error)\n );\n}\n\n/**\n * Role-specific vote distributions for simulation.\n * Each role has weighted probabilities reflecting their typical concerns:\n * - security: More skeptical, finds potential issues\n * - architect: Technically focused, generally supportive of good design\n * - devex: Balanced, considers usability\n * - ai_ml: Technically focused, evaluates AI aspects\n * - pm: Business focused, generally supportive of value\n *\n * Format: [approve_weight, reject_weight, abstain_weight]\n */\nconst ROLE_VOTE_DISTRIBUTIONS: Record<VoterRole, [number, number, number]> = {\n security: [40, 45, 15], // More skeptical - security concerns\n architect: [55, 30, 15], // Generally approving of good design\n devex: [50, 30, 20], // Balanced - considers usability\n ai_ml: [55, 30, 15], // Technical focus\n pm: [55, 25, 20], // Business focus - generally supportive\n catfish: [20, 65, 15], // Deliberately contrarian - challenges proposals (arXiv:2505.21503)\n scope_steward: [25, 60, 15], // Default-bias toward not shipping (#2185)\n};\n\n/**\n * Selects a decision based on weighted probabilities.\n */\nfunction selectWeightedDecision(\n weights: [number, number, number]\n): 'approve' | 'reject' | 'abstain' {\n const random = getRandomProvider();\n const total = weights[0] + weights[1] + weights[2];\n const rand = random.random() * total;\n\n if (rand < weights[0]) return 'approve';\n if (rand < weights[0] + weights[1]) return 'reject';\n return 'abstain';\n}\n\n/**\n * Fallback simulation when LLM is unavailable.\n * Uses role-specific vote distributions to provide more realistic simulation.\n * Clearly marks output as simulated.\n *\n * (Improved per Issue #453 - remove hardcoded 60% approve bias)\n */\nexport function simulateVote(role: VoterRole, proposal: string): Vote {\n const random = getRandomProvider();\n const weights = ROLE_VOTE_DISTRIBUTIONS[role];\n const decision = selectWeightedDecision(weights);\n\n // Confidence varies by decision type and role\n // Rejections tend to be higher confidence (found specific issue)\n // Approvals are moderate confidence (no issues found, but limited analysis)\n // Abstains are low confidence (insufficient information)\n let baseConfidence: number;\n if (decision === 'reject') {\n baseConfidence = 0.6 + random.random() * 0.3; // 0.6-0.9\n } else if (decision === 'approve') {\n baseConfidence = 0.5 + random.random() * 0.3; // 0.5-0.8\n } else {\n baseConfidence = 0.3 + random.random() * 0.2; // 0.3-0.5\n }\n\n return {\n decision,\n reasoning: `[Simulated - no LLM available] ${SIMULATED_VOTE_REASONING[role]} Proposal: \"${proposal.slice(0, 50)}...\"`,\n confidence: baseConfidence,\n };\n}\n\n// ============================================================================\n// Timeout and Retry Utilities\n// ============================================================================\n\n// Re-export from canonical source for backward compatibility\nexport { withTimeout, delay } from '../utils/async-utils.js';\n\n// ============================================================================\n// Vote Attempt Execution\n// ============================================================================\n\n/**\n * Extracts text content from completion response.\n */\nexport function extractTextFromResponse(content: unknown): string {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content\n .map((block) => {\n if (typeof block === 'object' && block !== null && 'type' in block) {\n const typed = block as { type: string; text?: string };\n if (typed.type === 'text' && typeof typed.text === 'string') {\n return typed.text;\n }\n }\n return '';\n })\n .join('');\n }\n return String(content);\n}\n\n/**\n * Executes a single vote attempt (no retries).\n *\n * By default, throws SyntheticVoteError if response parsing fails.\n * This ensures we only get real LLM votes, not synthetic fallbacks.\n * (Source: Issue #512 - Fail-safe voting)\n */\nexport async function executeSingleVoteAttempt(\n role: VoterRole,\n proposal: string,\n adapter: IModelAdapter,\n timeoutMs: number\n): Promise<{ ok: true; vote: Vote; output: string } | { ok: false; error: string }> {\n const request: CompletionRequest = {\n messages: [\n { role: 'system', content: VOTER_SYSTEM_PROMPTS[role] },\n { role: 'user', content: buildVotePrompt(proposal) },\n ],\n // 500 was correct for short proposal-style votes but caused mid-string\n // truncation (\"Unterminated string in JSON at position N\") in #2241 v3\n // when voters review code diffs — the JSON envelope + reasoning + YAML\n // findings block routinely exceed 500 tokens. Bumped to 2000 (#2245);\n // refine per use case if needed.\n maxTokens: 2000,\n temperature: 0.3, // Low temperature for consistent evaluations\n };\n\n const timeoutResult = await withTimeout(\n adapter.complete(request),\n timeoutMs,\n `Vote timeout after ${String(timeoutMs)}ms for role: ${role}`\n );\n\n if (!timeoutResult.ok) {\n return { ok: false, error: timeoutResult.error };\n }\n\n const response = timeoutResult.value;\n\n if (!response.ok) {\n return { ok: false, error: response.error.message };\n }\n\n const output = extractTextFromResponse(response.value.content);\n\n try {\n // parseVoteResponse throws SyntheticVoteError by default if parsing fails\n // This ensures we only accept real LLM votes, not synthetic fallbacks\n const vote = parseVoteResponse(output, role);\n return { ok: true, vote, output };\n } catch (error) {\n if (error instanceof SyntheticVoteError) {\n // Parsing failed - return error to trigger retry\n return { ok: false, error: `Vote parsing failed: ${error.message}` };\n }\n throw error; // Re-throw unexpected errors\n }\n}\n\n/** Options for executeWithRetries. */\nexport interface RetryOptions {\n readonly role: VoterRole;\n readonly proposal: string;\n readonly adapter: IModelAdapter;\n readonly logger: ILogger;\n readonly timeoutMs: number;\n readonly maxRetries: number;\n}\n\n/**\n * Executes vote attempts with retry logic.\n * Returns the error message from last failed attempt, or undefined if successful.\n */\nexport async function executeWithRetries(\n opts: RetryOptions\n): Promise<{ vote: Vote; ok: true } | { error: string; ok: false }> {\n const { role, proposal, adapter, logger, timeoutMs, maxRetries } = opts;\n let lastError = '';\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const isRateLimit = isRateLimitError(lastError);\n const baseDelay = isRateLimit ? RATE_LIMIT_RETRY_DELAY_MS : INITIAL_RETRY_DELAY_MS;\n const delayMs = baseDelay * Math.pow(2, attempt - 1);\n logger.debug('Retrying vote execution', { role, attempt, delayMs, isRateLimit });\n await delay(delayMs);\n }\n\n // #2472: per-attempt timing breakdown so investigators can see which\n // retry succeeded (or which attempt blew the cap). Total vote time\n // is already captured at the call-site; this fills the per-attempt gap.\n const attemptStart = Date.now();\n const result = await executeSingleVoteAttempt(role, proposal, adapter, timeoutMs);\n const attemptMs = Date.now() - attemptStart;\n if (result.ok) {\n logger.info('Vote attempt timing', {\n role,\n attempt: attempt + 1,\n attemptMs,\n succeeded: true,\n });\n return { vote: result.vote, ok: true };\n }\n\n lastError = result.error;\n const rateLimited = isRateLimitError(lastError);\n logger.info('Vote attempt timing', {\n role,\n attempt: attempt + 1,\n attemptMs,\n succeeded: false,\n rateLimited,\n });\n logger.warn('Vote attempt failed', {\n role,\n attempt: attempt + 1,\n maxRetries: maxRetries + 1,\n error: lastError,\n ...(rateLimited ? { rateLimited: true } : {}),\n });\n }\n\n return { error: lastError !== '' ? lastError : 'Unknown error after all retries', ok: false };\n}\n","/**\n * Overall-deadline racing for consensus voting (Issue #1871).\n *\n * Defensive layer above per-vote timeouts: even if a single\n * executeAgentVote() promise never settles (subprocess adapter hang,\n * IPC wait that swallows timeout, etc.), this helper guarantees the\n * whole consensus call returns bounded partial results.\n *\n * Each role's vote promise is raced against a shared wall-clock\n * deadline. Any role whose promise has not settled when the deadline\n * fires is filled with createErrorVoteResult('overall consensus\n * deadline exceeded'), preserving role order so downstream aggregation\n * stays deterministic.\n */\nimport type { IModelAdapter, ILogger } from '../core/index.js';\nimport type { AgentVoteResult, VoterRole } from './vote-types.js';\nimport { createErrorVoteResult, delay } from './voter-execution.js';\n\nexport interface VoteOptions {\n readonly timeoutMs: number;\n readonly maxRetries: number;\n readonly allowSimulation: boolean;\n}\n\nexport type VoteFn = (\n role: VoterRole,\n proposal: string,\n adapter: IModelAdapter,\n logger: ILogger,\n options: VoteOptions\n) => Promise<AgentVoteResult>;\n\nexport interface LaunchVotesInput {\n readonly roles: readonly VoterRole[];\n readonly proposal: string;\n readonly roleAdapters: ReadonlyMap<VoterRole, IModelAdapter>;\n readonly fallbackAdapter: IModelAdapter;\n readonly logger: ILogger;\n readonly voteOptions: VoteOptions;\n readonly interDelay: number;\n readonly overallDeadlineMs: number;\n /** Vote launcher (injected by caller — typically executeAgentVote). */\n readonly voteFn: VoteFn;\n}\n\nconst DEADLINE_MESSAGE = 'overall consensus deadline exceeded';\n\nfunction raceWithDeadline(\n p: Promise<AgentVoteResult>,\n role: VoterRole,\n deadlineMs: number\n): Promise<AgentVoteResult> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutP = new Promise<AgentVoteResult>((resolve) => {\n timer = setTimeout(() => {\n resolve(createErrorVoteResult(role, DEADLINE_MESSAGE, deadlineMs));\n }, deadlineMs);\n });\n return Promise.race([p, timeoutP]).finally(() => {\n if (timer !== undefined) clearTimeout(timer);\n });\n}\n\nexport async function launchVotesWithOverallDeadline(\n input: LaunchVotesInput\n): Promise<readonly AgentVoteResult[]> {\n const {\n roles,\n proposal,\n roleAdapters,\n fallbackAdapter,\n logger,\n voteOptions,\n interDelay,\n overallDeadlineMs,\n voteFn,\n } = input;\n\n const startedAt = Date.now();\n\n const wrapped = roles.map(async (role, i) => {\n if (i > 0 && interDelay > 0) await delay(interDelay);\n const adapter = roleAdapters.get(role) ?? fallbackAdapter;\n const elapsed = Date.now() - startedAt;\n const remaining = Math.max(1, overallDeadlineMs - elapsed);\n return raceWithDeadline(voteFn(role, proposal, adapter, logger, voteOptions), role, remaining);\n });\n\n const results = await Promise.all(wrapped);\n\n const expired = results.filter((r) => r.source === 'error' && r.error === DEADLINE_MESSAGE);\n if (expired.length > 0) {\n logger.warn('Consensus overall deadline reached; returning partial results', {\n totalRoles: roles.length,\n expiredRoles: expired.map((r) => r.role),\n overallDeadlineMs,\n });\n }\n return results;\n}\n","/**\n * nexus-agents voter agents\n *\n * Real LLM-powered voter agents for consensus voting.\n * Replaces simulated voting with actual agent execution that\n * analyzes proposals.\n *\n * (Source: Issue #226, Sprint #229)\n * (Updated: Issue #280 - Fixed timeout handling, removed simulation fallback)\n * (Refactored: Issue #285 - Extracted response and execution utilities)\n *\n * File structure:\n * - voter-prompts.ts: System prompts for each voter role\n * - voter-response.ts: Response parsing and validation\n * - voter-execution.ts: Execution utilities (timeout, retry, result creation)\n * - voter-agents.ts: Main API (this file)\n */\n\nimport type { VoterRole, AgentVoteResult } from './vote-types.js';\nimport { VOTER_ROLES } from './vote-types.js';\nimport type { IModelAdapter, ILogger } from '../core/index.js';\nimport { createLogger, getTimeProvider, getErrorMessage } from '../core/index.js';\nimport { getGlobalRegistry } from '../adapters/unified-registry.js';\nimport { getAvailableClis } from '../cli-adapters/factory.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport { checkCodexConcurrency } from '../cli-adapters/codex-limits.js';\n\n// Re-export prompts for backward compatibility\nexport { VOTER_SYSTEM_PROMPTS, SIMULATED_VOTE_REASONING } from './voter-prompts.js';\n\n// Re-export response utilities for backward compatibility\nexport {\n VoteResponseSchema,\n type VoteResponse,\n buildVotePrompt,\n extractJsonFromResponse,\n parseVoteResponse,\n SyntheticVoteError,\n type ParsedVote,\n type ParsedVoteSource,\n type ParseVoteOptions,\n} from './voter-response.js';\n\n// Re-export execution utilities for backward compatibility\nexport {\n DEFAULT_VOTE_TIMEOUT_MS,\n MAX_VOTE_TIMEOUT_MS,\n MIN_VOTE_TIMEOUT_MS,\n DEFAULT_MAX_RETRIES,\n RATE_LIMIT_RETRY_DELAY_MS,\n createErrorVoteResult,\n createSimulationVoteResult,\n createSimulatedVotes,\n simulateVote,\n isRateLimitError,\n withTimeout,\n delay,\n extractTextFromResponse,\n executeSingleVoteAttempt,\n resolveVoteTimeout,\n type RetryOptions,\n executeWithRetries,\n} from './voter-execution.js';\n\n// Import from execution module for internal use\nimport {\n createErrorVoteResult,\n createSimulationVoteResult,\n createSimulatedVotes,\n executeWithRetries,\n} from './voter-execution.js';\nimport { resolveVoteTimeout, VOTE_TIMEOUTS, getMcpSafeDeadlineMs } from '../config/timeouts.js';\nimport { launchVotesWithOverallDeadline } from './voter-agents-deadline.js';\n\n/**\n * Computes an overall wall-clock deadline for a consensus vote call (#1871).\n *\n * Acts as a safety net above per-vote timeouts: even if executeAgentVote's\n * internal withTimeout race fails to resolve (e.g. subprocess adapter hang),\n * this deadline bounds total wall time and lets partial results return.\n *\n * Formula: worst-case legitimate completion (timeoutMs * (maxRetries+1))\n * plus staggered launch headroom, plus `VOTE_TIMEOUTS.overallDeadlineBufferMs`.\n */\nexport function computeOverallConsensusDeadlineMs(\n timeoutMs: number,\n maxRetries: number,\n roleCount: number,\n interDelayMs: number\n): number {\n const perVoteBudget = timeoutMs * (maxRetries + 1);\n const staggerBudget = Math.max(0, roleCount - 1) * interDelayMs;\n return perVoteBudget + staggerBudget + VOTE_TIMEOUTS.overallDeadlineBufferMs;\n}\n\n// ============================================================================\n// Agent Vote Execution\n// ============================================================================\n\n/**\n * Options for executing voter agents.\n */\n/** Default inter-agent delay to prevent rate limiting (ms). Raised from 1s to 2s (#1802). */\nexport const DEFAULT_INTER_AGENT_DELAY_MS = 2000;\n\nexport interface VoterAgentOptions {\n /** Logger instance */\n readonly logger?: ILogger;\n /** Model adapter to use (auto-selected if not provided) */\n readonly adapter?: IModelAdapter;\n /** Timeout per vote in milliseconds (default: 120000, override via NEXUS_VOTE_TIMEOUT_MS) */\n readonly timeoutMs?: number;\n /** Maximum retries per vote (default: 2) */\n readonly maxRetries?: number;\n /** Whether to allow simulation fallback (default: false per Issue #280) */\n readonly allowSimulation?: boolean;\n /** Delay between launching each agent vote to prevent rate limiting (default: 1000ms). Set to 0 to disable. */\n readonly interAgentDelayMs?: number;\n}\n\n// Re-export AgentVoteResult for convenience\nexport type { AgentVoteResult };\n\nconst defaultLogger = createLogger({ component: 'voter-agents' });\n\n/**\n * Executes a real LLM vote for a single role with timeout and retry support.\n *\n * Per Issue #280: No simulation fallback by default. Returns error result\n * instead of simulated vote when execution fails.\n */\nexport async function executeAgentVote(\n role: VoterRole,\n proposal: string,\n adapter: IModelAdapter,\n logger: ILogger,\n options?: { timeoutMs?: number; maxRetries?: number; allowSimulation?: boolean }\n): Promise<AgentVoteResult> {\n const start = getTimeProvider().now();\n const timeoutMs = options?.timeoutMs ?? resolveVoteTimeout();\n const maxRetries = options?.maxRetries ?? VOTE_TIMEOUTS.maxRetries;\n const allowSimulation = options?.allowSimulation ?? false;\n\n logger.info('Executing vote', { role, model: adapter.modelId, provider: adapter.providerId });\n\n const result = await executeWithRetries({\n role,\n proposal,\n adapter,\n logger,\n timeoutMs,\n maxRetries,\n });\n const processingTimeMs = getTimeProvider().now() - start;\n\n if (result.ok) {\n logger.info('Vote completed', { role, model: adapter.modelId, decision: result.vote.decision });\n return { role, vote: result.vote, processingTimeMs, source: 'llm', cli: adapter.providerId };\n }\n\n // All retries exhausted\n logger.error('Vote execution failed after all retries', undefined, {\n role,\n model: adapter.modelId,\n errorMessage: result.error,\n });\n\n if (allowSimulation) {\n logger.warn('Falling back to simulation (allowSimulation=true)', { role });\n return createSimulationVoteResult(role, proposal, processingTimeMs, result.error);\n }\n\n return createErrorVoteResult(role, result.error, processingTimeMs);\n}\n\n// ============================================================================\n// Batch Vote Collection\n// ============================================================================\n\n/**\n * Options for collecting votes from multiple agents.\n */\nexport interface CollectRealVotesOptions extends VoterAgentOptions {\n /** Voter roles to include */\n readonly roles: readonly VoterRole[];\n /** Proposal text */\n readonly proposal: string;\n /** Use simulation mode (explicit opt-in only) */\n readonly simulate?: boolean;\n}\n\n/**\n * Error thrown when no adapter is available and simulation is disabled.\n */\nexport class NoAdapterError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NoAdapterError';\n }\n}\n\n/**\n * Resolves the model adapter, handling errors per Issue #280.\n */\nfunction resolveAdapter(\n options: CollectRealVotesOptions,\n logger: ILogger\n): { adapter: IModelAdapter } | { error: string } {\n try {\n if (options.adapter !== undefined) return { adapter: options.adapter };\n const registry = getGlobalRegistry({ logger });\n return { adapter: registry.getDefault() };\n } catch (error) {\n return { error: getErrorMessage(error) };\n }\n}\n\n/**\n * #2659 — warn (don't block) when more voter roles land on Codex than its\n * default `max_threads`, e.g. a single-CLI fallback with a full panel.\n */\nfunction warnIfCodexConcurrencyExceeded(\n roleAdapters: ReadonlyMap<VoterRole, IModelAdapter>,\n logger: ILogger\n): void {\n const codexBound = [...roleAdapters.values()].filter(\n (a) => (a as { name?: string }).name === 'codex'\n ).length;\n const warning = checkCodexConcurrency(codexBound);\n if (warning !== null) {\n logger.warn('Codex concurrency limit may be exceeded', { detail: warning });\n }\n}\n\n/** Assigns a single adapter to all roles (fallback path). */\nfunction assignUniformAdapter(\n roles: readonly VoterRole[],\n adapter: IModelAdapter\n): Map<VoterRole, IModelAdapter> {\n const adapters = new Map<VoterRole, IModelAdapter>();\n for (const role of roles) adapters.set(role, adapter);\n return adapters;\n}\n\n/** Creates CLI-specific adapters for available CLIs via the unified registry. */\nfunction createCliAdapterMap(\n clis: readonly CliName[],\n logger: ILogger\n): Map<CliName, IModelAdapter> {\n const registry = getGlobalRegistry({ logger });\n const result = new Map<CliName, IModelAdapter>();\n for (const cli of clis) {\n result.set(cli, registry.getAdapterForCli(cli));\n }\n return result;\n}\n\n/**\n * Creates diverse per-role adapters using all available CLIs (Issue #845).\n * Distributes roles across CLIs in round-robin fashion for model diversity.\n * Falls back to single adapter if only one CLI is available.\n */\nasync function resolveDiverseAdapters(\n roles: readonly VoterRole[],\n logger: ILogger,\n fallbackAdapter: IModelAdapter\n): Promise<Map<VoterRole, IModelAdapter>> {\n let availableClis: CliName[];\n try {\n availableClis = await getAvailableClis();\n } catch (e: unknown) {\n logger.warn('Failed to resolve available CLIs; falling back to single adapter', {\n error: String(e),\n });\n availableClis = [];\n }\n\n if (availableClis.length <= 1) {\n logger.info('Using single adapter for all roles', { cliCount: availableClis.length });\n return assignUniformAdapter(roles, fallbackAdapter);\n }\n\n const cliAdapters = createCliAdapterMap(availableClis, logger);\n if (cliAdapters.size <= 1) return assignUniformAdapter(roles, fallbackAdapter);\n\n // Round-robin assign roles to diverse CLIs\n const cliList = [...cliAdapters.entries()];\n const adapters = new Map<VoterRole, IModelAdapter>();\n const assignments: Record<string, string> = {};\n for (let i = 0; i < roles.length; i++) {\n const role = roles[i];\n const entry = cliList[i % cliList.length];\n if (role === undefined || entry === undefined) continue;\n adapters.set(role, entry[1]);\n assignments[role] = entry[0];\n }\n\n logger.info('Diverse adapters assigned', {\n cliCount: cliAdapters.size,\n clis: [...cliAdapters.keys()],\n roleAssignments: assignments,\n });\n return adapters;\n}\n\n/** Options for staggered vote launching. */\ninterface StaggeredVoteInput {\n readonly roles: readonly VoterRole[];\n readonly proposal: string;\n readonly roleAdapters: Map<VoterRole, IModelAdapter>;\n readonly fallbackAdapter: IModelAdapter;\n readonly logger: ILogger;\n readonly voteOptions: { timeoutMs: number; maxRetries: number; allowSimulation: boolean };\n readonly interDelay: number;\n}\n\n/**\n * Launches votes with staggered delays to prevent rate limiting (Issue #1319)\n * and an overall wall-clock deadline to prevent indefinite hangs (Issue #1871).\n */\nasync function launchStaggeredVotes(\n input: StaggeredVoteInput\n): Promise<readonly AgentVoteResult[]> {\n const { roles, proposal, roleAdapters, fallbackAdapter, logger, voteOptions, interDelay } = input;\n // Raw \"worst legitimate completion\" estimate — retained unchanged so the\n // formula still answers \"how long could this vote take in principle?\".\n const computedDeadlineMs = computeOverallConsensusDeadlineMs(\n voteOptions.timeoutMs,\n voteOptions.maxRetries,\n roles.length,\n interDelay\n );\n // Clamp below the outer MCP tool-wrapper timeout. Without this, the\n // middleware kills the promise chain before launchVotesWithOverallDeadline\n // can produce structured partial results — clients see a naked timeout\n // error instead of a `source: 'error' / error: 'overall consensus deadline\n // exceeded'` vote per stuck role. (Issue #2105)\n const overallDeadlineMs = getMcpSafeDeadlineMs(computedDeadlineMs, 'consensus_vote');\n if (overallDeadlineMs < computedDeadlineMs) {\n logger.debug('Consensus deadline clamped to MCP wrapper timeout', {\n computedDeadlineMs,\n overallDeadlineMs,\n });\n }\n return launchVotesWithOverallDeadline({\n roles,\n proposal,\n roleAdapters,\n fallbackAdapter,\n logger,\n voteOptions,\n interDelay,\n overallDeadlineMs,\n voteFn: executeAgentVote,\n });\n}\n\n/**\n * Collects votes from multiple voter agents.\n *\n * Per Issue #280: No automatic simulation fallback. If no adapter is\n * available and simulation is not explicitly enabled, throws NoAdapterError.\n * Per Issue #845: Uses diverse CLIs when multiple are available.\n */\nexport async function collectRealVotes(\n options: CollectRealVotesOptions\n): Promise<readonly AgentVoteResult[]> {\n const logger = options.logger ?? defaultLogger;\n const { roles, proposal, simulate, allowSimulation } = options;\n const timeoutMs = options.timeoutMs ?? resolveVoteTimeout();\n const maxRetries = options.maxRetries ?? VOTE_TIMEOUTS.maxRetries;\n\n if (simulate === true) {\n logger.info('Using simulation mode (explicitly requested)');\n return createSimulatedVotes(roles, proposal);\n }\n\n const adapterResult = resolveAdapter(options, logger);\n\n if ('error' in adapterResult) {\n logger.error('No adapter available for voting', undefined, { error: adapterResult.error });\n\n if (allowSimulation === true) {\n logger.warn('Falling back to simulation (allowSimulation=true)');\n return createSimulatedVotes(roles, proposal, 'No adapter available');\n }\n\n throw new NoAdapterError(\n `No adapter available for voting: ${adapterResult.error}. ` +\n 'Install a CLI (claude/gemini/codex) or set ANTHROPIC_API_KEY.'\n );\n }\n\n // Per Issue #845: Use diverse adapters when no explicit adapter is provided\n const roleAdapters =\n options.adapter !== undefined\n ? assignUniformAdapter(roles, adapterResult.adapter)\n : await resolveDiverseAdapters(roles, logger, adapterResult.adapter);\n\n warnIfCodexConcurrencyExceeded(roleAdapters, logger);\n\n const voteOptions = { timeoutMs, maxRetries, allowSimulation: allowSimulation ?? false };\n const interDelay = options.interAgentDelayMs ?? DEFAULT_INTER_AGENT_DELAY_MS;\n\n return launchStaggeredVotes({\n roles,\n proposal,\n roleAdapters,\n fallbackAdapter: adapterResult.adapter,\n logger,\n voteOptions,\n interDelay,\n });\n}\n\n/**\n * Gets a description for a voter role.\n */\nexport function getRoleDescription(role: VoterRole): string {\n return VOTER_ROLES[role];\n}\n","/**\n * nexus-agents/consensus - Core Type Definitions\n *\n * Core type definitions and Zod schemas for the consensus engine.\n * Supports multiple voting strategies for multi-agent decisions.\n */\n\nimport { z } from 'zod';\n\n/**\n * Consensus algorithm types.\n * - simple_majority: >50% of votes required\n * - supermajority: >=67% of votes required\n * - unanimous: 100% approval required\n * - proof_of_learning: weighted voting based on agent performance\n * - opinion_wise: higher-order voting with correlation awareness (Issue #333)\n * - higher_order: alias for opinion_wise (Issue #514)\n */\nexport const ConsensusAlgorithmSchema = z.enum([\n 'simple_majority',\n 'supermajority',\n 'unanimous',\n 'proof_of_learning',\n 'opinion_wise',\n 'higher_order',\n]);\nexport type ConsensusAlgorithm = z.infer<typeof ConsensusAlgorithmSchema>;\n\n/**\n * Vote decision options.\n */\nexport const VoteDecisionSchema = z.enum(['approve', 'reject', 'abstain']);\nexport type VoteDecision = z.infer<typeof VoteDecisionSchema>;\n\n/**\n * Proposal status in the lifecycle.\n */\nexport const ProposalStatusSchema = z.enum([\n 'pending',\n 'voting',\n 'approved',\n 'rejected',\n 'timeout',\n 'closed',\n]);\nexport type ProposalStatus = z.infer<typeof ProposalStatusSchema>;\n\n/**\n * Structured rejection feedback categories (Issue #1213).\n * Enables reject→refine→re-vote feedback loops by classifying rejection reasons.\n */\nexport const RejectionCategorySchema = z.enum([\n 'YAGNI',\n 'DRY_VIOLATION',\n 'OVER_ENGINEERING',\n 'SCOPE_CREEP',\n 'SECURITY_RISK',\n 'MISALIGNED',\n 'INSUFFICIENT_EVIDENCE',\n]);\nexport type RejectionCategory = z.infer<typeof RejectionCategorySchema>;\n\n/**\n * All valid rejection category values, for runtime reference.\n */\nexport const REJECTION_CATEGORIES = RejectionCategorySchema.options;\n\n/**\n * Pre-verified finding emitted by a voter (#2245 v4 follow-up).\n * Mirrors `cli/voter-response.ts:RawFindingSchema` — kept inline here to\n * avoid a circular cli→consensus import. Downstream code in mcp/tools\n * adds the derived `verified` flag based on the gate fields.\n */\nconst FindingShapeSchema = z.object({\n summary: z.string().min(1).max(500),\n location: z.string().min(1).max(200),\n severity: z.enum(['critical', 'high', 'medium', 'low']).default('medium'),\n gate: z.object({\n reread_cited_line: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n traced_call_path: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n named_assertion: z.string().default(''),\n ruled_out_language_non_issue: z.enum(['passed', 'failed', 'skipped']).default('skipped'),\n }),\n claim: z.string().min(1).max(2000),\n});\n\n/**\n * A vote cast by an agent.\n */\nexport const VoteSchema = z.object({\n decision: VoteDecisionSchema,\n reasoning: z.string().min(1).describe('Explanation for the vote'),\n confidence: z.number().min(0).max(1).describe('Confidence level 0-1'),\n conditions: z.array(z.string()).optional().describe('Conditions for approval'),\n /** Structured rejection categories for reject→refine→re-vote loops (Issue #1213). */\n rejectionCategories: z\n .array(RejectionCategorySchema)\n .optional()\n .describe('Rejection reason categories when decision is reject'),\n /** Pre-verified PR-review findings (#2245 v4 follow-up). Optional;\n * populated only when the voter emits the structured top-level array. */\n findings: z.array(FindingShapeSchema).optional().describe('PR-review findings (pre-verified)'),\n timestamp: z.iso.datetime().optional(),\n});\nexport type Vote = z.infer<typeof VoteSchema>;\n\n/**\n * A proposal submitted for consensus.\n */\nexport const ProposalSchema = z.object({\n id: z.string().optional().describe('Auto-generated if not provided'),\n title: z.string().min(1).max(200).describe('Short proposal title'),\n description: z.string().min(1).describe('Detailed proposal description'),\n algorithm: ConsensusAlgorithmSchema,\n timeout: z.number().int().positive().optional().describe('Timeout in milliseconds'),\n requiredVoters: z.array(z.string()).optional().describe('Agent IDs that must vote'),\n metadata: z.record(z.string(), z.unknown()).optional().describe('Additional context'),\n createdAt: z.iso.datetime().optional(),\n});\nexport type Proposal = z.infer<typeof ProposalSchema>;\n\n/**\n * Unique identifier for a proposal.\n */\nexport type ProposalId = string;\n\n/**\n * Vote counts summary.\n */\nexport interface VoteCounts {\n approve: number;\n reject: number;\n abstain: number;\n total: number;\n}\n\n/**\n * Weighted vote counts for proof-of-learning.\n */\nexport interface WeightedVoteCounts {\n approve: number;\n reject: number;\n abstain: number;\n totalWeight: number;\n}\n\n/**\n * Result of a consensus decision.\n */\nexport interface ConsensusResult {\n proposalId: ProposalId;\n proposal: Proposal;\n outcome: ProposalStatus;\n votes: Map<string, Vote>;\n voteCounts: VoteCounts;\n weightedCounts?: WeightedVoteCounts | undefined;\n approvalPercentage: number;\n quorumReached: boolean;\n startedAt: string;\n closedAt: string;\n durationMs: number;\n}\n\n/**\n * Consensus result schema for validation.\n */\nexport const ConsensusResultSchema = z.object({\n proposalId: z.string(),\n proposal: ProposalSchema,\n outcome: ProposalStatusSchema,\n votes: z.map(z.string(), VoteSchema),\n voteCounts: z.object({\n approve: z.number().int().nonnegative(),\n reject: z.number().int().nonnegative(),\n abstain: z.number().int().nonnegative(),\n total: z.number().int().nonnegative(),\n }),\n weightedCounts: z\n .object({\n approve: z.number().nonnegative(),\n reject: z.number().nonnegative(),\n abstain: z.number().nonnegative(),\n totalWeight: z.number().nonnegative(),\n })\n .optional(),\n approvalPercentage: z.number().min(0).max(100),\n quorumReached: z.boolean(),\n startedAt: z.iso.datetime(),\n closedAt: z.iso.datetime(),\n durationMs: z.number().int().nonnegative(),\n});\n\n/**\n * Agent performance record for proof-of-learning.\n */\nexport interface AgentPerformance {\n agentId: string;\n totalVotes: number;\n correctVotes: number;\n successRate: number;\n lastUpdated: string;\n}\n\n/**\n * Agent performance schema.\n */\nexport const AgentPerformanceSchema = z.object({\n agentId: z.string(),\n totalVotes: z.number().int().nonnegative(),\n correctVotes: z.number().int().nonnegative(),\n successRate: z.number().min(0).max(1),\n lastUpdated: z.iso.datetime(),\n});\n\n/**\n * Proposal content caching configuration for determinism. (Issue #589)\n */\nexport interface ProposalCacheConfig {\n /** Enable content-based caching for repeated proposals */\n enabled: boolean;\n /** TTL in milliseconds (default: 1 hour) */\n ttlMs: number;\n /** Maximum cached entries (default: 500) */\n maxEntries: number;\n}\n\n/**\n * Incremental quorum configuration (Issue #1408).\n * When enabled, ambiguous votes trigger voter pool expansion.\n */\nexport interface IncrementalQuorumConfig {\n /** Enable incremental quorum expansion. Default: false */\n enabled: boolean;\n /** Maximum expansion rounds (5→7→9). Default: 2 */\n maxExpansionRounds: number;\n /** Voters to add per expansion round. Default: 2 */\n votersPerExpansion: number;\n /** Minimum average confidence to avoid expansion. Default: 0.6 */\n confidenceThreshold: number;\n /** Ambiguity band: if approval rate is within this of threshold, expand. Default: 0.15 */\n ambiguityBand: number;\n}\n\n/**\n * Default incremental quorum configuration.\n */\nexport const DEFAULT_INCREMENTAL_QUORUM_CONFIG: IncrementalQuorumConfig = {\n enabled: false,\n maxExpansionRounds: 2,\n votersPerExpansion: 2,\n confidenceThreshold: 0.6,\n ambiguityBand: 0.15,\n};\n\n/**\n * Callback to request additional voters for incremental quorum.\n * Returns the IDs of newly added voters.\n */\nexport type VoterExpansionCallback = (\n proposalId: ProposalId,\n currentVoterCount: number,\n requestedCount: number\n) => Promise<readonly string[]>;\n\n/**\n * Consensus engine configuration.\n */\nexport interface ConsensusEngineConfig {\n defaultTimeout: number;\n minVotersForQuorum: number;\n maxActiveProposals: number;\n enablePerformanceTracking: boolean;\n /** Maximum number of closed proposals to retain. Oldest are evicted when exceeded. (Issue #549) */\n maxClosedProposals: number;\n /** Content-based proposal caching for determinism (Issue #589) */\n proposalCache?: ProposalCacheConfig;\n /** Incremental quorum configuration (Issue #1408) */\n incrementalQuorum?: IncrementalQuorumConfig;\n}\n\n/**\n * Proposal cache configuration schema. (Issue #589)\n */\nexport const ProposalCacheConfigSchema = z.object({\n enabled: z.boolean().default(false),\n ttlMs: z.number().int().positive().default(3600000), // 1 hour\n maxEntries: z.number().int().positive().default(500),\n});\n\n/**\n * Consensus engine configuration schema.\n */\nexport const ConsensusEngineConfigSchema = z.object({\n defaultTimeout: z.number().int().positive().default(300000), // 5 minutes\n minVotersForQuorum: z.number().int().positive().default(2),\n maxActiveProposals: z.number().int().positive().default(100),\n enablePerformanceTracking: z.boolean().default(true),\n maxClosedProposals: z.number().int().positive().default(1000), // Issue #549\n proposalCache: ProposalCacheConfigSchema.optional(), // Issue #589\n});\n\n/**\n * Default configuration values.\n */\nexport const DEFAULT_CONSENSUS_CONFIG: ConsensusEngineConfig = {\n defaultTimeout: 300000, // 5 minutes\n minVotersForQuorum: 2,\n maxActiveProposals: 100,\n enablePerformanceTracking: true,\n maxClosedProposals: 1000, // Issue #549: Prevent unbounded memory growth\n};\n\n/**\n * Voting thresholds for each algorithm.\n */\nexport const VOTING_THRESHOLDS: Record<ConsensusAlgorithm, number> = {\n simple_majority: 0.5,\n supermajority: 0.67,\n unanimous: 1.0,\n proof_of_learning: 0.5, // Uses weighted voting\n opinion_wise: 0.5, // Uses correlation-aware Bayesian aggregation (Issue #333)\n higher_order: 0.5, // Alias for opinion_wise (Issue #514)\n};\n\n/**\n * Internal proposal state managed by the engine.\n */\nexport interface ProposalState {\n proposal: Proposal;\n status: ProposalStatus;\n votes: Map<string, Vote>;\n voteWeights: Map<string, number>;\n startedAt: Date;\n timeoutId?: ReturnType<typeof setTimeout>;\n /** Number of incremental quorum expansions applied (Issue #1408). */\n expansionRounds?: number;\n /**\n * True while a quorum expansion is awaiting its callback for this\n * proposal. Concurrent `vote()` calls check this to avoid double-\n * expanding across the `await` gap (Issue #2861). Per-proposal so\n * independent proposals never block each other.\n */\n expansionInFlight?: boolean;\n}\n\n/**\n * Consensus metrics for monitoring.\n */\nexport interface ConsensusMetrics {\n totalProposals: number;\n approvedProposals: number;\n rejectedProposals: number;\n timedOutProposals: number;\n averageDurationMs: number;\n averageVotesPerProposal: number;\n algorithmUsage: Record<ConsensusAlgorithm, number>;\n}\n\n/**\n * Consensus metrics schema.\n */\nexport const ConsensusMetricsSchema = z.object({\n totalProposals: z.number().int().nonnegative(),\n approvedProposals: z.number().int().nonnegative(),\n rejectedProposals: z.number().int().nonnegative(),\n timedOutProposals: z.number().int().nonnegative(),\n averageDurationMs: z.number().nonnegative(),\n averageVotesPerProposal: z.number().nonnegative(),\n algorithmUsage: z.record(ConsensusAlgorithmSchema, z.number().int().nonnegative()),\n});\n","/**\n * nexus-agents/consensus - Multi-Round Voting Protocol Types\n *\n * Multi-Round Voting Protocol Types (Issue #100)\n * Based on arXiv:2512.21352 - Multi-Agent Committees for Code Review\n */\n\nimport { z } from 'zod';\nimport type { Vote } from './types-core.js';\n\n/**\n * Voting round phases.\n * - analysis: Independent analysis (Round 1)\n * - deliberation: Share findings and discuss (Round 2)\n * - consensus: Final vote on recommendations (Round 3)\n */\nexport const VotingRoundPhaseSchema = z.enum(['analysis', 'deliberation', 'consensus']);\nexport type VotingRoundPhase = z.infer<typeof VotingRoundPhaseSchema>;\n\n/**\n * Voting round status.\n */\nexport const VotingRoundStatusSchema = z.enum([\n 'pending',\n 'in_progress',\n 'awaiting_votes',\n 'completed',\n 'aborted',\n]);\nexport type VotingRoundStatus = z.infer<typeof VotingRoundStatusSchema>;\n\n/**\n * A finding submitted by an agent during analysis.\n */\nexport const AgentFindingSchema = z.object({\n agentId: z.string(),\n category: z.enum(['bug', 'security', 'performance', 'style', 'design', 'documentation', 'other']),\n severity: z.enum(['critical', 'major', 'minor', 'suggestion']),\n description: z.string().min(1),\n location: z.string().optional().describe('File path and line range if applicable'),\n suggestion: z.string().optional().describe('Recommended fix'),\n confidence: z.number().min(0).max(1),\n timestamp: z.iso.datetime().optional(),\n});\nexport type AgentFinding = z.infer<typeof AgentFindingSchema>;\n\n/**\n * Finding vote during deliberation.\n */\nexport const FindingVoteSchema = z.object({\n agentId: z.string(),\n findingId: z.string(),\n agree: z.boolean(),\n reasoning: z.string().optional(),\n amendedSeverity: z.enum(['critical', 'major', 'minor', 'suggestion']).optional(),\n});\nexport type FindingVote = z.infer<typeof FindingVoteSchema>;\n\n/**\n * A single voting round in the protocol.\n */\nexport interface VotingRound {\n id: string;\n phase: VotingRoundPhase;\n status: VotingRoundStatus;\n findings: Map<string, AgentFinding>; // findingId -> finding\n findingVotes: Map<string, FindingVote[]>; // findingId -> votes\n finalVotes: Map<string, Vote>; // agentId -> final vote\n startedAt: string;\n completedAt?: string;\n roundNumber: number;\n}\n\n/**\n * Configuration for the voting protocol.\n */\nexport interface VotingProtocolConfig {\n /** Number of agents in the committee (default: 3) */\n committeeSize: number;\n /** Maximum rounds before forcing decision (default: 3) */\n maxRounds: number;\n /** Timeout per round in milliseconds (default: 60000) */\n roundTimeoutMs: number;\n /** Minimum agreement threshold (default: 0.67) */\n agreementThreshold: number;\n /** Enable anti-sycophancy detection (default: true) */\n enableAntiSycophancy: boolean;\n /** Similarity threshold for sycophancy detection (default: 0.8) */\n sycophancyThreshold: number;\n}\n\nexport const VotingProtocolConfigSchema = z.object({\n committeeSize: z.number().int().min(2).max(7).default(3),\n maxRounds: z.number().int().min(1).max(5).default(3),\n roundTimeoutMs: z.number().int().positive().default(60000),\n agreementThreshold: z.number().min(0.5).max(1).default(0.67),\n enableAntiSycophancy: z.boolean().default(true),\n sycophancyThreshold: z.number().min(0).max(1).default(0.8),\n});\n\nexport const DEFAULT_VOTING_PROTOCOL_CONFIG: VotingProtocolConfig = {\n committeeSize: 3,\n maxRounds: 3,\n roundTimeoutMs: 60000,\n agreementThreshold: 0.67,\n enableAntiSycophancy: true,\n sycophancyThreshold: 0.8,\n};\n\n/**\n * Session state for a voting protocol instance.\n */\nexport interface VotingSession {\n id: string;\n topic: string;\n committee: string[]; // Agent IDs\n rounds: VotingRound[];\n currentRound: number;\n config: VotingProtocolConfig;\n status: 'active' | 'completed' | 'aborted';\n createdAt: string;\n completedAt?: string;\n finalResult?: VotingProtocolResult;\n}\n\n/**\n * Final result of a voting protocol session.\n */\nexport interface VotingProtocolResult {\n sessionId: string;\n topic: string;\n outcome: 'approved' | 'rejected' | 'needs_revision' | 'no_consensus';\n consolidatedFindings: ConsolidatedFinding[];\n roundSummaries: RoundSummary[];\n agreementScore: number;\n sycophancyDetected: boolean;\n totalDurationMs: number;\n participatingAgents: string[];\n}\n\n/**\n * A consolidated finding after deliberation.\n */\nexport interface ConsolidatedFinding {\n id: string;\n category: AgentFinding['category'];\n severity: AgentFinding['severity'];\n description: string;\n location?: string;\n suggestion?: string;\n supportingAgents: string[];\n agreementRatio: number;\n originalFindings: AgentFinding[];\n}\n\n/**\n * Summary of a single round.\n */\nexport interface RoundSummary {\n roundNumber: number;\n phase: VotingRoundPhase;\n findingsCount: number;\n votesCount: number;\n agreementScore: number;\n durationMs: number;\n}\n\n/**\n * Interface for the multi-round voting protocol.\n * (Source: Issue #100, arXiv:2512.21352)\n */\nexport interface IVotingProtocol {\n /** Create a new voting session with a committee */\n createSession(\n topic: string,\n committee: string[],\n config?: Partial<VotingProtocolConfig>\n ): VotingSession;\n\n /** Start the analysis round (Round 1) */\n startAnalysisRound(sessionId: string): Promise<VotingRound>;\n\n /** Submit findings from an agent during analysis */\n submitFindings(sessionId: string, agentId: string, findings: AgentFinding[]): Promise<void>;\n\n /** Start the deliberation round (Round 2) */\n startDeliberationRound(sessionId: string): Promise<VotingRound>;\n\n /** Vote on findings during deliberation */\n voteOnFinding(sessionId: string, vote: FindingVote): Promise<void>;\n\n /** Start the consensus round (Round 3) */\n startConsensusRound(sessionId: string): Promise<VotingRound>;\n\n /** Submit final vote during consensus */\n submitFinalVote(sessionId: string, agentId: string, vote: Vote): Promise<void>;\n\n /** Get the final result (closes session if complete) */\n getResult(sessionId: string): Promise<VotingProtocolResult | null>;\n\n /** Check for sycophancy in the current round */\n detectSycophancy(sessionId: string): SycophancyReport;\n\n /** Get the current session state */\n getSession(sessionId: string): VotingSession | undefined;\n}\n\n/**\n * Report from sycophancy detection.\n */\nexport interface SycophancyReport {\n detected: boolean;\n confidenceScore: number;\n indicators: SycophancyIndicator[];\n affectedAgents: string[];\n recommendation: string;\n}\n\n/**\n * Individual sycophancy indicator.\n */\nexport interface SycophancyIndicator {\n type: 'premature_consensus' | 'opinion_convergence' | 'confidence_inflation' | 'echo_chamber';\n description: string;\n severity: 'low' | 'medium' | 'high';\n agents: string[];\n}\n","/**\n * nexus-agents/consensus - Weighted Byzantine Voting Types\n *\n * Weighted Byzantine Voting Types (Issue #103)\n * Based on CP-WBFT (arXiv:2511.10400)\n */\n\nimport { z } from 'zod';\nimport type { Vote } from './types-core.js';\n\n/**\n * Task outcome for tracking agent performance.\n */\nexport const TaskOutcomeSchema = z.enum(['success', 'failure', 'partial', 'unknown']);\nexport type TaskOutcome = z.infer<typeof TaskOutcomeSchema>;\n\n/**\n * Extended agent performance with Byzantine detection.\n */\nexport interface WeightedAgentRecord {\n readonly agentId: string;\n readonly totalTasks: number;\n readonly successfulTasks: number;\n readonly failedTasks: number;\n readonly partialTasks: number;\n readonly successRate: number;\n readonly weight: number;\n readonly trustScore: number;\n readonly byzantineFlags: number;\n readonly lastActive: Date;\n readonly createdAt: Date;\n}\n\nexport const WeightedAgentRecordSchema = z.object({\n agentId: z.string().min(1),\n totalTasks: z.number().int().nonnegative(),\n successfulTasks: z.number().int().nonnegative(),\n failedTasks: z.number().int().nonnegative(),\n partialTasks: z.number().int().nonnegative(),\n successRate: z.number().min(0).max(1),\n weight: z.number().min(0).max(1),\n trustScore: z.number().min(0).max(1),\n byzantineFlags: z.number().int().nonnegative(),\n lastActive: z.date(),\n createdAt: z.date(),\n});\n\n/**\n * Weighted consensus result.\n */\nexport interface WeightedConsensusResult {\n readonly decision: 'approve' | 'reject' | 'no_consensus';\n readonly weightedApproval: number;\n readonly weightedRejection: number;\n readonly totalWeight: number;\n readonly quorumReached: boolean;\n readonly byzantineDetected: boolean;\n readonly participatingAgents: readonly string[];\n readonly weightBreakdown: ReadonlyMap<string, number>;\n}\n\n/**\n * Configuration for weighted Byzantine voting.\n */\nexport interface WeightedVotingConfig {\n /** Minimum weight to participate in voting (default: 0.1) */\n readonly minWeight: number;\n /** Maximum Byzantine fault tolerance (default: 0.33) */\n readonly maxByzantineFraction: number;\n /** Weight decay factor per failed task (default: 0.9) */\n readonly weightDecayFactor: number;\n /** Weight recovery factor per successful task (default: 1.05) */\n readonly weightRecoveryFactor: number;\n /** Trust score required to vote (default: 0.3) */\n readonly minTrustScore: number;\n /** Byzantine flag threshold for exclusion (default: 3) */\n readonly byzantineFlagThreshold: number;\n /** Initial weight for new agents (default: 0.5) */\n readonly initialWeight: number;\n /** Quorum threshold for valid consensus (default: 0.67) */\n readonly quorumThreshold: number;\n}\n\nexport const WeightedVotingConfigSchema = z.object({\n minWeight: z.number().min(0).max(1).default(0.1),\n maxByzantineFraction: z.number().min(0).max(0.5).default(0.33),\n weightDecayFactor: z.number().min(0.5).max(1).default(0.9),\n weightRecoveryFactor: z.number().min(1).max(2).default(1.05),\n minTrustScore: z.number().min(0).max(1).default(0.3),\n byzantineFlagThreshold: z.number().int().positive().default(3),\n initialWeight: z.number().min(0).max(1).default(0.5),\n quorumThreshold: z.number().min(0.5).max(1).default(0.67),\n});\n\nexport const DEFAULT_WEIGHTED_VOTING_CONFIG: WeightedVotingConfig = {\n minWeight: 0.1,\n maxByzantineFraction: 0.33,\n weightDecayFactor: 0.9,\n weightRecoveryFactor: 1.05,\n minTrustScore: 0.3,\n byzantineFlagThreshold: 3,\n initialWeight: 0.5,\n quorumThreshold: 0.67,\n};\n\n/**\n * Interface for weighted Byzantine voting.\n * (Source: Issue #103, arXiv:2511.10400 - CP-WBFT)\n */\nexport interface IWeightedVoting {\n /** Calculate vote weight for an agent */\n calculateWeight(agentId: string): number;\n\n /** Update agent performance based on task outcome */\n updatePerformance(agentId: string, outcome: TaskOutcome): void;\n\n /** Run weighted consensus on votes */\n weightedConsensus(votes: ReadonlyMap<string, Vote>): WeightedConsensusResult;\n\n /** Register a new agent */\n registerAgent(agentId: string): void;\n\n /** Get agent performance record */\n getAgentRecord(agentId: string): WeightedAgentRecord | undefined;\n\n /** Flag agent for Byzantine behavior */\n flagByzantine(agentId: string, reason: string): void;\n\n /** Get all agent records */\n getAllRecords(): readonly WeightedAgentRecord[];\n\n /** Check if agent can vote */\n canVote(agentId: string): boolean;\n\n /** Recalibrate all weights based on global performance */\n recalibrateWeights(): void;\n}\n","/**\n * nexus-agents/consensus - Higher-Order Voting Types\n *\n * Type definitions for Opinion-Wise (OW) and Independent Subset Partition (ISP)\n * voting methods that account for correlations between agent opinions.\n *\n * Higher-order voting uses Bayesian-optimal aggregation that handles correlated\n * agents better than traditional independent voting assumptions.\n *\n * @module consensus/higher-order-types\n * (Source: Issue #333)\n */\n\nimport { z } from 'zod';\nimport type { Vote, VoteDecision } from './types-core.js';\n\n// ============================================================================\n// CORRELATION TYPES\n// ============================================================================\n\n/**\n * Pair of agent IDs for correlation tracking.\n * Stored as \"agentA:agentB\" where agentA < agentB lexicographically.\n */\nexport type AgentPairKey = `${string}:${string}`;\n\n/**\n * Creates a canonical agent pair key for correlation lookup.\n * Orders agents lexicographically to ensure consistent keys.\n */\nexport function createAgentPairKey(agentA: string, agentB: string): AgentPairKey {\n return agentA < agentB ? `${agentA}:${agentB}` : `${agentB}:${agentA}`;\n}\n\n/**\n * Extracts agent IDs from a pair key.\n */\nexport function parseAgentPairKey(key: AgentPairKey): [string, string] {\n const parts = key.split(':');\n if (parts.length !== 2 || parts[0] === undefined || parts[1] === undefined) {\n throw new Error(`Invalid agent pair key: ${key}`);\n }\n return [parts[0], parts[1]];\n}\n\n/**\n * Correlation coefficient between two agents' voting patterns.\n * Range: -1 (perfectly anti-correlated) to +1 (perfectly correlated).\n * 0 indicates independence.\n */\nexport const CorrelationCoefficientSchema = z.number().min(-1).max(1);\nexport type CorrelationCoefficient = z.infer<typeof CorrelationCoefficientSchema>;\n\n/**\n * Correlation matrix storing pairwise correlations between agents.\n */\nexport type CorrelationMatrix = Map<AgentPairKey, CorrelationCoefficient>;\n\n/**\n * A subset of agents that vote independently of each other.\n * Used in ISP (Independent Subset Partition) method.\n */\nexport interface IndependentSubset {\n /** Unique identifier for this subset */\n readonly id: string;\n /** Agent IDs in this independent subset */\n readonly agentIds: readonly string[];\n /** Average internal independence score (lower = more independent) */\n readonly independenceScore: number;\n /** Number of observations supporting this grouping */\n readonly observationCount: number;\n}\n\nexport const IndependentSubsetSchema = z.object({\n id: z.string(),\n agentIds: z.array(z.string()),\n independenceScore: z.number().min(0).max(1),\n observationCount: z.number().int().nonnegative(),\n});\n\n// ============================================================================\n// VOTING HISTORY TYPES\n// ============================================================================\n\n/**\n * Record of a single voting observation for correlation tracking.\n */\nexport interface VotingObservation {\n /** Unique proposal ID */\n readonly proposalId: string;\n /** Agent who cast the vote */\n readonly agentId: string;\n /** The vote decision */\n readonly decision: VoteDecision;\n /** Confidence level (0-1) */\n readonly confidence: number;\n /** Whether the vote aligned with the final outcome */\n readonly alignedWithOutcome: boolean;\n /** Timestamp of the vote */\n readonly timestamp: Date;\n}\n\nexport const VotingObservationSchema = z.object({\n proposalId: z.string(),\n agentId: z.string(),\n decision: z.enum(['approve', 'reject', 'abstain']),\n confidence: z.number().min(0).max(1),\n alignedWithOutcome: z.boolean(),\n timestamp: z.date(),\n});\n\n/**\n * Aggregated voting history for a pair of agents.\n */\nexport interface PairwiseVotingHistory {\n /** Agent pair key */\n readonly pairKey: AgentPairKey;\n /** Number of proposals where both agents voted */\n readonly jointObservations: number;\n /** Number of times both agents agreed */\n readonly agreements: number;\n /** Number of times agents disagreed */\n readonly disagreements: number;\n /** Computed correlation coefficient */\n readonly correlation: CorrelationCoefficient;\n /** Last update timestamp */\n readonly lastUpdated: Date;\n}\n\nexport const PairwiseVotingHistorySchema = z.object({\n pairKey: z.string() as z.ZodType<AgentPairKey>,\n jointObservations: z.number().int().nonnegative(),\n agreements: z.number().int().nonnegative(),\n disagreements: z.number().int().nonnegative(),\n correlation: CorrelationCoefficientSchema,\n lastUpdated: z.date(),\n});\n\n// ============================================================================\n// HIGHER-ORDER VOTING CONFIG\n// ============================================================================\n\n/**\n * Configuration for higher-order voting.\n */\nexport interface HigherOrderVotingConfig {\n /** Minimum observations before using correlation data (default: 10) */\n readonly minObservationsForCorrelation: number;\n /** Correlation threshold to consider agents correlated (default: 0.3) */\n readonly correlationThreshold: number;\n /** Maximum correlation age in milliseconds before recalculation (default: 24h) */\n readonly correlationMaxAgeMs: number;\n /** Independence threshold for ISP grouping (default: 0.2) */\n readonly independenceThreshold: number;\n /** Whether to fall back to simple voting when correlation data insufficient */\n readonly fallbackToSimpleVoting: boolean;\n /** Decay factor for old observations (0-1, default: 0.95) */\n readonly observationDecayFactor: number;\n /** Maximum observations to store per agent before FIFO eviction (default: 1000) */\n readonly maxObservationsPerAgent: number;\n /** Maximum total proposals to track before evicting oldest (default: 5000) */\n readonly maxProposals: number;\n /** Maximum pairwise history entries before LRU eviction (default: 100) */\n readonly maxTrackedPairs: number;\n}\n\nexport const HigherOrderVotingConfigSchema = z.object({\n minObservationsForCorrelation: z.number().int().positive().default(10),\n correlationThreshold: z.number().min(0).max(1).default(0.3),\n correlationMaxAgeMs: z.number().int().positive().default(86400000), // 24 hours\n independenceThreshold: z.number().min(0).max(1).default(0.2),\n fallbackToSimpleVoting: z.boolean().default(true),\n observationDecayFactor: z.number().min(0).max(1).default(0.95),\n maxObservationsPerAgent: z.number().int().positive().default(1000),\n maxProposals: z.number().int().positive().default(5000),\n maxTrackedPairs: z.number().int().positive().default(100),\n});\n\nexport const DEFAULT_HIGHER_ORDER_CONFIG: HigherOrderVotingConfig = {\n minObservationsForCorrelation: 10,\n correlationThreshold: 0.3,\n correlationMaxAgeMs: 86400000, // 24 hours\n independenceThreshold: 0.2,\n fallbackToSimpleVoting: true,\n observationDecayFactor: 0.95,\n maxObservationsPerAgent: 1000,\n maxProposals: 5000,\n maxTrackedPairs: 100,\n};\n\n// ============================================================================\n// HIGHER-ORDER VOTING RESULTS\n// ============================================================================\n\n/**\n * Result of Bayesian aggregation with correlation awareness.\n */\nexport interface HigherOrderVotingResult {\n /** Final decision */\n readonly decision: 'approve' | 'reject' | 'no_consensus';\n /** Posterior probability of approval */\n readonly posteriorApproval: number;\n /** Posterior probability of rejection */\n readonly posteriorRejection: number;\n /** Effective number of independent votes */\n readonly effectiveVoteCount: number;\n /** Whether correlation data was sufficient */\n readonly usedCorrelationData: boolean;\n /** Method used: 'ow' (opinion-wise), 'isp', or 'simple' (fallback) */\n readonly method: 'ow' | 'isp' | 'simple';\n /** Improvement over baseline majority voting (percentage points) */\n readonly improvementOverBaseline: number;\n /** Independent subsets used (if ISP method) */\n readonly independentSubsets?: readonly IndependentSubset[];\n /** Agents whose votes were down-weighted due to correlation */\n readonly downweightedAgents: readonly string[];\n /** Reasoning for the decision */\n readonly reasoning: string;\n}\n\nexport const HigherOrderVotingResultSchema = z.object({\n decision: z.enum(['approve', 'reject', 'no_consensus']),\n posteriorApproval: z.number().min(0).max(1),\n posteriorRejection: z.number().min(0).max(1),\n effectiveVoteCount: z.number().nonnegative(),\n usedCorrelationData: z.boolean(),\n method: z.enum(['ow', 'isp', 'simple']),\n improvementOverBaseline: z.number(),\n independentSubsets: z.array(IndependentSubsetSchema).optional(),\n downweightedAgents: z.array(z.string()),\n reasoning: z.string(),\n});\n\n// ============================================================================\n// CORRELATION TRACKER INTERFACE\n// ============================================================================\n\n/**\n * Statistics about correlation tracking.\n */\nexport interface CorrelationTrackerStats {\n /** Total agents being tracked */\n readonly totalAgents: number;\n /** Total agent pairs with correlation data */\n readonly trackedPairs: number;\n /** Total voting observations recorded */\n readonly totalObservations: number;\n /** Average correlation across all pairs */\n readonly averageCorrelation: number;\n /** Number of identified independent subsets */\n readonly independentSubsetCount: number;\n /** Pairs with sufficient data for correlation calculation */\n readonly pairsWithSufficientData: number;\n}\n\nexport const CorrelationTrackerStatsSchema = z.object({\n totalAgents: z.number().int().nonnegative(),\n trackedPairs: z.number().int().nonnegative(),\n totalObservations: z.number().int().nonnegative(),\n averageCorrelation: z.number(),\n independentSubsetCount: z.number().int().nonnegative(),\n pairsWithSufficientData: z.number().int().nonnegative(),\n});\n\n/**\n * Interface for correlation tracking between agents.\n */\nexport interface ICorrelationTracker {\n /**\n * Record a vote and its outcome for correlation tracking.\n */\n recordVote(agentId: string, vote: Vote, outcome: 'approved' | 'rejected'): void;\n\n /**\n * Record votes from multiple agents for the same proposal.\n */\n recordProposalVotes(\n proposalId: string,\n votes: ReadonlyMap<string, Vote>,\n outcome: 'approved' | 'rejected'\n ): void;\n\n /**\n * Compute the full correlation matrix for all tracked agents.\n */\n computeCorrelationMatrix(): CorrelationMatrix;\n\n /**\n * Get correlation between two specific agents.\n * Returns undefined if insufficient data.\n */\n getCorrelation(agentA: string, agentB: string): CorrelationCoefficient | undefined;\n\n /**\n * Identify groups of agents that vote independently.\n */\n identifyIndependentSubsets(): readonly IndependentSubset[];\n\n /**\n * Check if there is sufficient correlation data for a set of agents.\n */\n hasSufficientData(agentIds: readonly string[]): boolean;\n\n /**\n * Get statistics about the correlation tracker.\n */\n getStats(): CorrelationTrackerStats;\n\n /**\n * Clear all recorded data.\n */\n clear(): void;\n}\n\n// ============================================================================\n// OW VOTING INTERFACE\n// ============================================================================\n\n/**\n * Interface for Opinion-Wise higher-order voting.\n */\nexport interface IHigherOrderVoting {\n /**\n * Aggregate votes using Bayesian correlation-aware method.\n */\n aggregateWithCorrelation(\n votes: ReadonlyMap<string, Vote>,\n correlationMatrix: CorrelationMatrix\n ): HigherOrderVotingResult;\n\n /**\n * Estimate correlation matrix from voting history.\n */\n estimateCorrelation(tracker: ICorrelationTracker): CorrelationMatrix;\n\n /**\n * Compute result using Independent Subset Partition method.\n */\n computeISP(\n votes: ReadonlyMap<string, Vote>,\n independentSubsets: readonly IndependentSubset[]\n ): HigherOrderVotingResult;\n\n /**\n * Full pipeline: estimate correlation, compute result.\n */\n aggregate(\n votes: ReadonlyMap<string, Vote>,\n tracker: ICorrelationTracker\n ): HigherOrderVotingResult;\n\n /**\n * Get the current configuration.\n */\n getConfig(): HigherOrderVotingConfig;\n}\n","/**\n * nexus-agents/consensus - Higher-Order Voting Helpers\n *\n * Helper functions for Opinion-Wise (OW) and Independent Subset Partition (ISP)\n * voting methods. Extracted from higher-order-voting.ts to maintain file size limits.\n *\n * @module consensus/higher-order-helpers\n * (Source: Issue #333, #339)\n */\n\nimport type { Vote } from './types-core.js';\nimport type {\n CorrelationMatrix,\n HigherOrderVotingResult,\n IndependentSubset,\n} from './higher-order-types.js';\nimport { createAgentPairKey } from './higher-order-types.js';\n\n/**\n * Result of Bayesian aggregation.\n */\nexport interface BayesianAggregateResult {\n readonly posteriorApproval: number;\n readonly posteriorRejection: number;\n readonly effectiveVoteCount: number;\n readonly downweightedAgents: string[];\n}\n\n/**\n * Result of subset aggregation.\n */\nexport interface SubsetAggregationResult {\n readonly subsetResults: Array<{ approval: number; rejection: number; weight: number }>;\n readonly downweightedAgents: string[];\n}\n\n/**\n * Result of combined subset results.\n */\nexport interface CombinedSubsetResult {\n readonly posteriorApproval: number;\n readonly posteriorRejection: number;\n readonly totalWeight: number;\n}\n\n/**\n * Check if there is sufficient correlation data for analysis.\n */\nexport function hasSufficientCorrelationData(\n agentIds: readonly string[],\n correlationMatrix: CorrelationMatrix\n): boolean {\n if (agentIds.length < 2) return false;\n\n let pairsWithData = 0;\n const totalPairs = (agentIds.length * (agentIds.length - 1)) / 2;\n\n for (let i = 0; i < agentIds.length; i++) {\n for (let j = i + 1; j < agentIds.length; j++) {\n const agentA = agentIds[i];\n const agentB = agentIds[j];\n if (agentA !== undefined && agentB !== undefined) {\n const pairKey = createAgentPairKey(agentA, agentB);\n if (correlationMatrix.has(pairKey)) {\n pairsWithData++;\n }\n }\n }\n }\n\n return pairsWithData >= Math.ceil(totalPairs * 0.5);\n}\n\n/**\n * Compute effective weights for agents based on correlations.\n * Reduces weights for highly correlated agents.\n */\nexport function computeEffectiveWeights(\n agentIds: readonly string[],\n correlationMatrix: CorrelationMatrix,\n correlationThreshold: number\n): Map<string, number> {\n const weights = new Map<string, number>();\n\n // Start with equal weights\n for (const agentId of agentIds) {\n weights.set(agentId, 1.0);\n }\n\n // Reduce weights for highly correlated agents\n for (let i = 0; i < agentIds.length; i++) {\n for (let j = i + 1; j < agentIds.length; j++) {\n const agentA = agentIds[i];\n const agentB = agentIds[j];\n if (agentA === undefined || agentB === undefined) continue;\n\n const pairKey = createAgentPairKey(agentA, agentB);\n const correlation = correlationMatrix.get(pairKey);\n\n if (correlation !== undefined && correlation > correlationThreshold) {\n // Reduce weight proportionally to correlation\n const reduction = correlation * 0.5;\n const currentWeightA = weights.get(agentA) ?? 1.0;\n const currentWeightB = weights.get(agentB) ?? 1.0;\n\n // Apply reduction to both agents (but less to avoid over-penalizing)\n weights.set(agentA, Math.max(0.1, currentWeightA - reduction * 0.5));\n weights.set(agentB, Math.max(0.1, currentWeightB - reduction * 0.5));\n }\n }\n }\n\n return weights;\n}\n\n/**\n * Perform Bayesian aggregation of votes with effective weights.\n */\nexport function bayesianAggregate(\n votes: ReadonlyMap<string, Vote>,\n effectiveWeights: Map<string, number>\n): BayesianAggregateResult {\n let weightedApproval = 0;\n let weightedRejection = 0;\n let totalWeight = 0;\n const downweightedAgents: string[] = [];\n\n for (const [agentId, vote] of votes) {\n const weight = effectiveWeights.get(agentId) ?? 1.0;\n\n // Track downweighted agents\n if (weight < 0.8) {\n downweightedAgents.push(agentId);\n }\n\n // Weight by confidence and effective weight\n const effectiveWeight = weight * vote.confidence;\n totalWeight += effectiveWeight;\n\n if (vote.decision === 'approve') {\n weightedApproval += effectiveWeight;\n } else if (vote.decision === 'reject') {\n weightedRejection += effectiveWeight;\n }\n // Abstains contribute to total weight but not to either side\n }\n\n const posteriorApproval = totalWeight > 0 ? weightedApproval / totalWeight : 0.5;\n const posteriorRejection = totalWeight > 0 ? weightedRejection / totalWeight : 0.5;\n const effectiveVoteCount = totalWeight;\n\n return { posteriorApproval, posteriorRejection, effectiveVoteCount, downweightedAgents };\n}\n\n/**\n * Aggregate votes within independent subsets.\n */\nexport function aggregateSubsets(\n votes: ReadonlyMap<string, Vote>,\n independentSubsets: readonly IndependentSubset[]\n): SubsetAggregationResult {\n const subsetResults: Array<{ approval: number; rejection: number; weight: number }> = [];\n const downweightedAgents: string[] = [];\n\n for (const subset of independentSubsets) {\n const subsetVotes = new Map<string, Vote>();\n for (const agentId of subset.agentIds) {\n const vote = votes.get(agentId);\n if (vote !== undefined) subsetVotes.set(agentId, vote);\n }\n if (subsetVotes.size === 0) continue;\n\n const { approval, rejection } = countSubsetVotes(subsetVotes);\n const weight = subsetVotes.size * (1 - subset.independenceScore);\n subsetResults.push({ approval, rejection, weight });\n\n if (subset.agentIds.length === 1) downweightedAgents.push(...subset.agentIds);\n }\n return { subsetResults, downweightedAgents };\n}\n\n/**\n * Combine subset results into overall posterior probabilities.\n */\nexport function combineSubsetResults(\n subsetResults: readonly { approval: number; rejection: number; weight: number }[]\n): CombinedSubsetResult {\n let totalApproval = 0;\n let totalRejection = 0;\n let totalWeight = 0;\n for (const { approval, rejection, weight } of subsetResults) {\n totalApproval += approval * weight;\n totalRejection += rejection * weight;\n totalWeight += weight;\n }\n return {\n posteriorApproval: totalWeight > 0 ? totalApproval / totalWeight : 0.5,\n posteriorRejection: totalWeight > 0 ? totalRejection / totalWeight : 0.5,\n totalWeight,\n };\n}\n\n/**\n * Count votes within a subset, weighted by confidence.\n */\nexport function countSubsetVotes(votes: ReadonlyMap<string, Vote>): {\n approval: number;\n rejection: number;\n} {\n let approval = 0;\n let rejection = 0;\n\n for (const vote of votes.values()) {\n if (vote.decision === 'approve') {\n approval += vote.confidence;\n } else if (vote.decision === 'reject') {\n rejection += vote.confidence;\n }\n }\n\n const total = approval + rejection;\n return {\n approval: total > 0 ? approval / total : 0.5,\n rejection: total > 0 ? rejection / total : 0.5,\n };\n}\n\n/**\n * Determine decision based on posterior probabilities.\n */\nexport function determineHigherOrderDecision(\n posteriorApproval: number,\n posteriorRejection: number\n): 'approve' | 'reject' | 'no_consensus' {\n const diff = Math.abs(posteriorApproval - posteriorRejection);\n\n // Require significant margin for decision\n if (diff < 0.1) {\n return 'no_consensus';\n }\n\n return posteriorApproval > posteriorRejection ? 'approve' : 'reject';\n}\n\n/**\n * Perform simple majority aggregation (no correlation data).\n */\nexport function aggregateSimple(\n votes: ReadonlyMap<string, Vote>,\n buildReasoningFn: (\n decision: 'approve' | 'reject' | 'no_consensus',\n effectiveVotes: number,\n downweightedAgents: string[],\n method: 'ow' | 'isp' | 'simple'\n ) => string\n): HigherOrderVotingResult {\n let approve = 0;\n let reject = 0;\n let total = 0;\n\n for (const vote of votes.values()) {\n if (vote.decision === 'approve') {\n approve++;\n } else if (vote.decision === 'reject') {\n reject++;\n }\n if (vote.decision !== 'abstain') {\n total++;\n }\n }\n\n const posteriorApproval = total > 0 ? approve / total : 0.5;\n const posteriorRejection = total > 0 ? reject / total : 0.5;\n const decision = determineHigherOrderDecision(posteriorApproval, posteriorRejection);\n\n return {\n decision,\n posteriorApproval,\n posteriorRejection,\n effectiveVoteCount: total,\n usedCorrelationData: false,\n method: 'simple',\n improvementOverBaseline: 0,\n downweightedAgents: [],\n reasoning: buildReasoningFn(decision, total, [], 'simple'),\n };\n}\n\n/**\n * Calculate improvement over baseline.\n */\nexport function calculateImprovement(\n posteriorApproval: number,\n posteriorRejection: number,\n decision: 'approve' | 'reject' | 'no_consensus',\n baseline: HigherOrderVotingResult\n): number {\n // Improvement is measured by increased confidence in the same direction\n if (decision === 'no_consensus' || baseline.decision === 'no_consensus') {\n return 0;\n }\n\n const currentConfidence = decision === 'approve' ? posteriorApproval : posteriorRejection;\n const baselineConfidence =\n baseline.decision === 'approve' ? baseline.posteriorApproval : baseline.posteriorRejection;\n\n // Return improvement as percentage points\n return (currentConfidence - baselineConfidence) * 100;\n}\n\n/**\n * Build reasoning string for voting result.\n */\nexport function buildReasoning(\n decision: 'approve' | 'reject' | 'no_consensus',\n effectiveVotes: number,\n downweightedAgents: readonly string[],\n method: 'ow' | 'isp' | 'simple'\n): string {\n const methodName =\n method === 'ow'\n ? 'Opinion-Wise Bayesian aggregation'\n : method === 'isp'\n ? 'Independent Subset Partition'\n : 'simple majority voting';\n\n let reasoning = `Decision reached via ${methodName} with ${effectiveVotes.toFixed(1)} effective votes. `;\n\n if (downweightedAgents.length > 0) {\n reasoning += `${String(downweightedAgents.length)} agent(s) downweighted due to correlation. `;\n }\n\n if (decision === 'no_consensus') {\n reasoning += 'No consensus reached due to insufficient margin.';\n } else {\n reasoning += `Final decision: ${decision}.`;\n }\n\n return reasoning;\n}\n","/**\n * nexus-agents/consensus - Higher-Order Voting Implementation\n *\n * Implements Opinion-Wise (OW) and Independent Subset Partition (ISP) voting\n * methods that account for correlations between agent opinions.\n *\n * Traditional voting assumes independence between voters. Higher-order voting\n * uses Bayesian-optimal aggregation that handles correlated agents better,\n * resulting in more accurate consensus decisions.\n *\n * @module consensus/higher-order-voting\n * (Source: Issue #333)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport type { Vote, VoteCounts } from './types-core.js';\nimport type {\n IHigherOrderVoting,\n ICorrelationTracker,\n CorrelationMatrix,\n HigherOrderVotingConfig,\n HigherOrderVotingResult,\n IndependentSubset,\n} from './higher-order-types.js';\nimport { DEFAULT_HIGHER_ORDER_CONFIG } from './higher-order-types.js';\nimport type { IVotingStrategy, VotingOutcome } from './strategies.js';\nimport type { ConsensusAlgorithm } from './types-core.js';\nimport {\n hasSufficientCorrelationData,\n computeEffectiveWeights,\n bayesianAggregate,\n aggregateSubsets,\n combineSubsetResults,\n determineHigherOrderDecision,\n aggregateSimple,\n calculateImprovement,\n buildReasoning,\n} from './higher-order-helpers.js';\n\nconst logger = createLogger({ component: 'higher-order-voting' });\n\n/** Options for creating OWVoting instance. */\nexport interface OWVotingOptions {\n readonly config?: Partial<HigherOrderVotingConfig>;\n}\n\n/**\n * Opinion-Wise higher-order voting implementation.\n * Uses Bayesian aggregation with correlation awareness.\n */\nexport class OWVoting implements IHigherOrderVoting, IVotingStrategy {\n readonly algorithm: ConsensusAlgorithm = 'simple_majority';\n private readonly config: HigherOrderVotingConfig;\n\n constructor(options: OWVotingOptions = {}) {\n this.config = { ...DEFAULT_HIGHER_ORDER_CONFIG, ...options.config };\n logger.info('OWVoting initialized', { config: this.config });\n }\n\n /** IVotingStrategy implementation for integration with ConsensusEngine. */\n calculateOutcome(votes: Map<string, Vote>, _weights?: Map<string, number>): VotingOutcome {\n const result = this.aggregateSimpleInternal(votes);\n return this.toVotingOutcome(votes, result);\n }\n\n aggregateWithCorrelation(\n votes: ReadonlyMap<string, Vote>,\n correlationMatrix: CorrelationMatrix\n ): HigherOrderVotingResult {\n const agentIds = Array.from(votes.keys());\n const hasSufficientData = hasSufficientCorrelationData(agentIds, correlationMatrix);\n\n if (!hasSufficientData && this.config.fallbackToSimpleVoting) {\n // Issue #525: Log at INFO level for visibility\n logger.info('Insufficient correlation data, falling back to simple voting', {\n agentCount: agentIds.length,\n reason: 'insufficient_correlation_data',\n });\n return this.aggregateSimpleInternal(votes);\n }\n\n const effectiveWeights = computeEffectiveWeights(\n agentIds,\n correlationMatrix,\n this.config.correlationThreshold\n );\n\n const { posteriorApproval, posteriorRejection, effectiveVoteCount, downweightedAgents } =\n bayesianAggregate(votes, effectiveWeights);\n\n const decision = determineHigherOrderDecision(posteriorApproval, posteriorRejection);\n const baselineResult = this.aggregateSimpleInternal(votes);\n const improvementOverBaseline = calculateImprovement(\n posteriorApproval,\n posteriorRejection,\n decision,\n baselineResult\n );\n\n const result: HigherOrderVotingResult = {\n decision,\n posteriorApproval,\n posteriorRejection,\n effectiveVoteCount,\n usedCorrelationData: hasSufficientData,\n method: 'ow',\n improvementOverBaseline,\n downweightedAgents,\n reasoning: buildReasoning(decision, effectiveVoteCount, downweightedAgents, 'ow'),\n };\n\n logger.info('OW aggregation complete', {\n decision,\n posteriorApproval: posteriorApproval.toFixed(3),\n effectiveVotes: effectiveVoteCount.toFixed(2),\n downweightedAgents: downweightedAgents.length,\n });\n\n return result;\n }\n\n estimateCorrelation(tracker: ICorrelationTracker): CorrelationMatrix {\n return tracker.computeCorrelationMatrix();\n }\n\n computeISP(\n votes: ReadonlyMap<string, Vote>,\n independentSubsets: readonly IndependentSubset[]\n ): HigherOrderVotingResult {\n if (independentSubsets.length === 0) {\n // Issue #525: Log at INFO level for visibility\n logger.info('No independent subsets, falling back to simple voting', {\n reason: 'no_independent_subsets',\n });\n return this.aggregateSimpleInternal(votes);\n }\n\n const { subsetResults, downweightedAgents } = aggregateSubsets(votes, independentSubsets);\n const { posteriorApproval, posteriorRejection } = combineSubsetResults(subsetResults);\n const effectiveVoteCount = independentSubsets.length;\n const decision = determineHigherOrderDecision(posteriorApproval, posteriorRejection);\n\n const baselineResult = this.aggregateSimpleInternal(votes);\n const improvementOverBaseline = calculateImprovement(\n posteriorApproval,\n posteriorRejection,\n decision,\n baselineResult\n );\n\n const result: HigherOrderVotingResult = {\n decision,\n posteriorApproval,\n posteriorRejection,\n effectiveVoteCount,\n usedCorrelationData: true,\n method: 'isp',\n improvementOverBaseline,\n independentSubsets,\n downweightedAgents,\n reasoning: buildReasoning(decision, effectiveVoteCount, downweightedAgents, 'isp'),\n };\n\n logger.info('ISP aggregation complete', {\n decision,\n subsetCount: independentSubsets.length,\n posteriorApproval: posteriorApproval.toFixed(3),\n });\n\n return result;\n }\n\n aggregate(\n votes: ReadonlyMap<string, Vote>,\n tracker: ICorrelationTracker\n ): HigherOrderVotingResult {\n const agentIds = Array.from(votes.keys());\n\n if (!tracker.hasSufficientData(agentIds)) {\n if (this.config.fallbackToSimpleVoting) {\n // Issue #525: Log at INFO level for visibility\n logger.info('Insufficient data for correlation analysis, using simple voting', {\n agentCount: agentIds.length,\n reason: 'insufficient_tracker_data',\n });\n return this.aggregateSimpleInternal(votes);\n }\n }\n\n const correlationMatrix = tracker.computeCorrelationMatrix();\n const owResult = this.aggregateWithCorrelation(votes, correlationMatrix);\n\n const independentSubsets = tracker.identifyIndependentSubsets();\n if (independentSubsets.length > 1) {\n const ispResult = this.computeISP(votes, independentSubsets);\n const owConfidence = Math.abs(owResult.posteriorApproval - 0.5) * 2;\n const ispConfidence = Math.abs(ispResult.posteriorApproval - 0.5) * 2;\n\n if (ispConfidence > owConfidence) {\n logger.debug('Using ISP result over OW due to higher confidence');\n return ispResult;\n }\n }\n\n return owResult;\n }\n\n getConfig(): HigherOrderVotingConfig {\n return { ...this.config };\n }\n\n private aggregateSimpleInternal(votes: ReadonlyMap<string, Vote>): HigherOrderVotingResult {\n return aggregateSimple(votes, buildReasoning);\n }\n\n private toVotingOutcome(\n votes: Map<string, Vote>,\n result: HigherOrderVotingResult\n ): VotingOutcome {\n let approve = 0;\n let reject = 0;\n let abstain = 0;\n\n for (const vote of votes.values()) {\n if (vote.decision === 'approve') approve++;\n else if (vote.decision === 'reject') reject++;\n else abstain++;\n }\n\n const voteCounts: VoteCounts = { approve, reject, abstain, total: votes.size };\n\n const rawPercentage = result.posteriorApproval * 100;\n const approvalPercentage = Number.isFinite(rawPercentage) ? rawPercentage : 0;\n\n return {\n approved: result.decision === 'approve',\n approvalPercentage,\n voteCounts,\n reason: result.reasoning,\n };\n }\n}\n\n/** Creates a new OWVoting instance. */\nexport function createOWVoting(options?: OWVotingOptions): IHigherOrderVoting {\n return new OWVoting(options);\n}\n\n/**\n * Higher-order voting strategy for integration with VotingStrategyFactory.\n * Wraps OWVoting to provide IVotingStrategy interface.\n */\nexport class HigherOrderVotingStrategy extends OWVoting implements IVotingStrategy {\n override readonly algorithm: ConsensusAlgorithm = 'opinion_wise';\n\n constructor(options: OWVotingOptions = {}) {\n super(options);\n }\n}\n\n/** Creates a higher-order voting strategy for use with ConsensusEngine. */\nexport function createHigherOrderVotingStrategy(\n options?: OWVotingOptions\n): HigherOrderVotingStrategy {\n return new HigherOrderVotingStrategy(options);\n}\n","/**\n * nexus-agents/consensus - Voting Strategies\n *\n * Implementation of different voting strategies for consensus engine.\n * Supports simple majority, supermajority, unanimous, and proof-of-learning.\n */\n\nimport type {\n ConsensusAlgorithm,\n Vote,\n VoteCounts,\n WeightedVoteCounts,\n AgentPerformance,\n} from './types.js';\nimport { VOTING_THRESHOLDS } from './types.js';\nimport { HigherOrderVotingStrategy } from './higher-order-voting.js';\n\n/**\n * Interface for voting strategy implementations.\n */\nexport interface IVotingStrategy {\n readonly algorithm: ConsensusAlgorithm;\n calculateOutcome(votes: Map<string, Vote>, weights?: Map<string, number>): VotingOutcome;\n}\n\n/**\n * Result of a voting strategy calculation.\n */\nexport interface VotingOutcome {\n approved: boolean;\n approvalPercentage: number;\n voteCounts: VoteCounts;\n weightedCounts?: WeightedVoteCounts;\n reason: string;\n}\n\n/**\n * Evaluates an approval ratio against a threshold — the shared math behind\n * the simple-majority, supermajority and proof-of-learning strategies.\n *\n * `inclusive` selects the comparison: `>=` for supermajority (67% passes at\n * exactly 67%), strict `>` for simple-majority and proof-of-learning (a tie\n * at the threshold is not enough). Callers apply their own zero-denominator\n * guard before calling this.\n */\nfunction evaluateThreshold(\n approveCount: number,\n votingTotal: number,\n threshold: number,\n inclusive: boolean\n): { approved: boolean; approvalPercentage: number } {\n const ratio = approveCount / votingTotal;\n return {\n approved: inclusive ? ratio >= threshold : ratio > threshold,\n approvalPercentage: ratio * 100,\n };\n}\n\n/**\n * Base voting strategy with common functionality.\n */\nabstract class BaseVotingStrategy implements IVotingStrategy {\n abstract readonly algorithm: ConsensusAlgorithm;\n\n abstract calculateOutcome(votes: Map<string, Vote>, weights?: Map<string, number>): VotingOutcome;\n\n /**\n * Count votes by decision type.\n */\n protected countVotes(votes: Map<string, Vote>): VoteCounts {\n let approve = 0;\n let reject = 0;\n let abstain = 0;\n\n for (const vote of votes.values()) {\n switch (vote.decision) {\n case 'approve':\n approve++;\n break;\n case 'reject':\n reject++;\n break;\n case 'abstain':\n abstain++;\n break;\n }\n }\n\n return { approve, reject, abstain, total: votes.size };\n }\n\n /**\n * Calculate weighted vote counts using agent performance weights.\n */\n protected countWeightedVotes(\n votes: Map<string, Vote>,\n weights: Map<string, number>\n ): WeightedVoteCounts {\n let approve = 0;\n let reject = 0;\n let abstain = 0;\n let totalWeight = 0;\n\n for (const [agentId, vote] of votes.entries()) {\n const weight = weights.get(agentId) ?? 1.0;\n totalWeight += weight;\n\n switch (vote.decision) {\n case 'approve':\n approve += weight;\n break;\n case 'reject':\n reject += weight;\n break;\n case 'abstain':\n abstain += weight;\n break;\n }\n }\n\n return { approve, reject, abstain, totalWeight };\n }\n}\n\n/**\n * Simple majority voting strategy (>50% approval).\n */\nexport class SimpleMajorityStrategy extends BaseVotingStrategy {\n readonly algorithm: ConsensusAlgorithm = 'simple_majority';\n\n calculateOutcome(votes: Map<string, Vote>): VotingOutcome {\n const counts = this.countVotes(votes);\n const votingVotes = counts.approve + counts.reject; // Abstains don't count\n const threshold = VOTING_THRESHOLDS.simple_majority;\n\n if (votingVotes === 0) {\n return {\n approved: false,\n approvalPercentage: 0,\n voteCounts: counts,\n reason: 'No votes cast (excluding abstentions)',\n };\n }\n\n const { approved, approvalPercentage } = evaluateThreshold(\n counts.approve,\n votingVotes,\n threshold,\n false\n );\n\n return {\n approved,\n approvalPercentage,\n voteCounts: counts,\n reason: approved\n ? `Approved with ${approvalPercentage.toFixed(1)}% (>${String(threshold * 100)}% required)`\n : `Rejected with ${approvalPercentage.toFixed(1)}% (<=${String(threshold * 100)}% threshold)`,\n };\n }\n}\n\n/**\n * Supermajority voting strategy (>=67% approval).\n */\nexport class SupermajorityStrategy extends BaseVotingStrategy {\n readonly algorithm: ConsensusAlgorithm = 'supermajority';\n\n calculateOutcome(votes: Map<string, Vote>): VotingOutcome {\n const counts = this.countVotes(votes);\n const votingVotes = counts.approve + counts.reject;\n const threshold = VOTING_THRESHOLDS.supermajority;\n\n if (votingVotes === 0) {\n return {\n approved: false,\n approvalPercentage: 0,\n voteCounts: counts,\n reason: 'No votes cast (excluding abstentions)',\n };\n }\n\n const { approved, approvalPercentage } = evaluateThreshold(\n counts.approve,\n votingVotes,\n threshold,\n true\n );\n\n return {\n approved,\n approvalPercentage,\n voteCounts: counts,\n reason: approved\n ? `Approved with ${approvalPercentage.toFixed(1)}% (>=${String(threshold * 100)}% required)`\n : `Rejected with ${approvalPercentage.toFixed(1)}% (<${String(threshold * 100)}% threshold)`,\n };\n }\n}\n\n/**\n * Unanimous voting strategy (100% approval required).\n */\nexport class UnanimousStrategy extends BaseVotingStrategy {\n readonly algorithm: ConsensusAlgorithm = 'unanimous';\n\n calculateOutcome(votes: Map<string, Vote>): VotingOutcome {\n const counts = this.countVotes(votes);\n\n if (counts.total === 0) {\n return {\n approved: false,\n approvalPercentage: 0,\n voteCounts: counts,\n reason: 'No votes cast',\n };\n }\n\n // For unanimous, any rejection fails the proposal\n // Abstentions are allowed but don't count toward approval\n const approvalPercentage = counts.total > 0 ? (counts.approve / counts.total) * 100 : 0;\n\n if (counts.reject > 0) {\n return {\n approved: false,\n approvalPercentage,\n voteCounts: counts,\n reason: `Rejected: ${String(counts.reject)} rejection(s) cast (unanimous approval required)`,\n };\n }\n\n if (counts.approve === 0) {\n return {\n approved: false,\n approvalPercentage: 0,\n voteCounts: counts,\n reason: 'No approvals cast (at least one approval required)',\n };\n }\n\n return {\n approved: true,\n approvalPercentage,\n voteCounts: counts,\n reason: `Unanimously approved with ${String(counts.approve)} vote(s)`,\n };\n }\n}\n\n/**\n * Proof-of-learning weighted voting strategy.\n * Agents with better track records have more voting power.\n */\nexport class ProofOfLearningStrategy extends BaseVotingStrategy {\n readonly algorithm: ConsensusAlgorithm = 'proof_of_learning';\n\n calculateOutcome(votes: Map<string, Vote>, weights?: Map<string, number>): VotingOutcome {\n const counts = this.countVotes(votes);\n const effectiveWeights = weights ?? new Map<string, number>();\n const weightedCounts = this.countWeightedVotes(votes, effectiveWeights);\n const threshold = VOTING_THRESHOLDS.proof_of_learning;\n\n const votingWeight = weightedCounts.approve + weightedCounts.reject;\n\n if (votingWeight === 0) {\n return {\n approved: false,\n approvalPercentage: 0,\n voteCounts: counts,\n weightedCounts,\n reason: 'No weighted votes cast (excluding abstentions)',\n };\n }\n\n const { approved, approvalPercentage } = evaluateThreshold(\n weightedCounts.approve,\n votingWeight,\n threshold,\n false\n );\n\n return {\n approved,\n approvalPercentage,\n voteCounts: counts,\n weightedCounts,\n reason: approved\n ? `Approved with ${approvalPercentage.toFixed(1)}% weighted approval`\n : `Rejected with ${approvalPercentage.toFixed(1)}% weighted approval`,\n };\n }\n}\n\n/**\n * Calculate vote weight for an agent based on their performance history.\n * Weight ranges from 0.5 (no history) to 1.0 (perfect track record).\n */\nexport function calculateVoteWeight(performance: AgentPerformance | undefined): number {\n if (performance === undefined || performance.totalVotes === 0) {\n return 1.0; // Default weight for new agents\n }\n\n // Weight = 0.5 + (successRate * 0.5)\n // This gives a range of 0.5 to 1.0 based on historical accuracy\n return 0.5 + performance.successRate * 0.5;\n}\n\n/**\n * Factory for creating voting strategies.\n */\nexport class VotingStrategyFactory {\n private readonly strategies: Map<ConsensusAlgorithm, IVotingStrategy>;\n\n constructor() {\n this.strategies = new Map<ConsensusAlgorithm, IVotingStrategy>([\n ['simple_majority', new SimpleMajorityStrategy()],\n ['supermajority', new SupermajorityStrategy()],\n ['unanimous', new UnanimousStrategy()],\n ['proof_of_learning', new ProofOfLearningStrategy()],\n ['opinion_wise', new HigherOrderVotingStrategy()],\n ['higher_order', new HigherOrderVotingStrategy()],\n ]);\n }\n\n /**\n * Get a voting strategy by algorithm type.\n */\n getStrategy(algorithm: ConsensusAlgorithm): IVotingStrategy {\n const strategy = this.strategies.get(algorithm);\n if (strategy === undefined) {\n throw new Error(`Unknown voting algorithm: ${algorithm}`);\n }\n return strategy;\n }\n\n /**\n * Register a custom voting strategy.\n */\n registerStrategy(strategy: IVotingStrategy): void {\n this.strategies.set(strategy.algorithm, strategy);\n }\n\n /**\n * Get all available algorithm types.\n */\n getAvailableAlgorithms(): ConsensusAlgorithm[] {\n return Array.from(this.strategies.keys());\n }\n}\n\n/**\n * Creates a voting strategy factory with default strategies.\n */\nexport function createStrategyFactory(): VotingStrategyFactory {\n return new VotingStrategyFactory();\n}\n","/**\n * nexus-agents/consensus - Result Builder\n *\n * Helper functions for building consensus results.\n */\n\nimport { getTimeProvider } from '../core/index.js';\nimport type {\n ProposalId,\n ProposalState,\n ConsensusResult,\n ProposalStatus,\n ConsensusEngineConfig,\n} from './types.js';\nimport type { VotingOutcome } from './strategies.js';\n\n/**\n * Build a pending result for an active proposal.\n */\nexport function buildPendingResult(\n state: ProposalState,\n proposalId: ProposalId,\n outcome: VotingOutcome,\n config: ConsensusEngineConfig\n): ConsensusResult {\n const now = new Date(getTimeProvider().now());\n return {\n proposalId,\n proposal: state.proposal,\n outcome: state.status === 'voting' ? 'pending' : state.status,\n votes: new Map(state.votes),\n voteCounts: outcome.voteCounts,\n weightedCounts: outcome.weightedCounts,\n approvalPercentage: outcome.approvalPercentage,\n quorumReached: state.votes.size >= config.minVotersForQuorum,\n startedAt: state.startedAt.toISOString(),\n closedAt: now.toISOString(),\n durationMs: now.getTime() - state.startedAt.getTime(),\n };\n}\n\n/**\n * Build a final result for a closed proposal.\n */\nexport function buildFinalResult(\n state: ProposalState,\n proposalId: ProposalId,\n outcome: VotingOutcome,\n config: ConsensusEngineConfig\n): ConsensusResult {\n const now = new Date(getTimeProvider().now());\n const quorumReached = state.votes.size >= config.minVotersForQuorum;\n const finalStatus = determineFinalStatus(quorumReached, outcome.approved);\n\n return {\n proposalId,\n proposal: state.proposal,\n outcome: finalStatus,\n votes: new Map(state.votes),\n voteCounts: outcome.voteCounts,\n weightedCounts: outcome.weightedCounts,\n approvalPercentage: outcome.approvalPercentage,\n quorumReached,\n startedAt: state.startedAt.toISOString(),\n closedAt: now.toISOString(),\n durationMs: now.getTime() - state.startedAt.getTime(),\n };\n}\n\n/**\n * Build a timeout result for an expired proposal.\n */\nexport function buildTimeoutResult(\n state: ProposalState,\n proposalId: ProposalId,\n outcome: VotingOutcome,\n config: ConsensusEngineConfig\n): ConsensusResult {\n const now = new Date(getTimeProvider().now());\n return {\n proposalId,\n proposal: state.proposal,\n outcome: 'timeout',\n votes: new Map(state.votes),\n voteCounts: outcome.voteCounts,\n weightedCounts: outcome.weightedCounts,\n approvalPercentage: outcome.approvalPercentage,\n quorumReached: state.votes.size >= config.minVotersForQuorum,\n startedAt: state.startedAt.toISOString(),\n closedAt: now.toISOString(),\n durationMs: now.getTime() - state.startedAt.getTime(),\n };\n}\n\n/**\n * Determine final status based on quorum and approval.\n */\nexport function determineFinalStatus(quorumReached: boolean, approved: boolean): ProposalStatus {\n if (!quorumReached || !approved) return 'rejected';\n return 'approved';\n}\n","/**\n * nexus-agents/consensus - Helper Functions\n *\n * Utility functions for the consensus engine.\n */\n\nimport type { ProposalId } from './types.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\n\n/**\n * Generate a unique proposal ID.\n */\nexport function generateProposalId(): ProposalId {\n const timestamp = getTimeProvider().now().toString(36);\n const random = getRandomProvider().random().toString(36).substring(2, 8);\n return `prop_${timestamp}_${random}`;\n}\n","/**\n * nexus-agents/consensus - Incremental Quorum\n *\n * Detects ambiguous voting scenarios and triggers voter pool expansion.\n * Complements agreement-based cascading (early termination when certain)\n * with expansion when uncertain.\n *\n * (Source: Issue #1408 — Incremental Quorum for Consensus Robustness)\n *\n * @module consensus/incremental-quorum\n */\n\nimport type { Vote } from './types.js';\n\n/**\n * Parameters for ambiguity detection.\n */\nexport interface AmbiguityParams {\n /** Minimum average confidence to avoid expansion. */\n readonly confidenceThreshold: number;\n /** If approval rate is within this band of the threshold, consider ambiguous. */\n readonly ambiguityBand: number;\n}\n\n/**\n * Determines if the current voting state is ambiguous.\n *\n * Ambiguity is detected when:\n * 1. Approval rate is within the ambiguity band of the threshold, OR\n * 2. Average voter confidence is below the confidence threshold\n *\n * @param votes - Current vote map\n * @param totalExpected - Total expected voters\n * @param threshold - Algorithm-specific approval threshold (0-1)\n * @param params - Ambiguity detection parameters\n * @returns true if the voting state is ambiguous\n */\nexport function isVotingAmbiguous(\n votes: ReadonlyMap<string, Vote>,\n totalExpected: number,\n threshold: number,\n params: AmbiguityParams\n): boolean {\n if (votes.size === 0) return false;\n\n let approvals = 0;\n let totalConfidence = 0;\n for (const vote of votes.values()) {\n if (vote.decision === 'approve') approvals++;\n totalConfidence += vote.confidence;\n }\n\n const approvalRate = approvals / totalExpected;\n const avgConfidence = totalConfidence / votes.size;\n\n // Check if approval rate is within the ambiguity band of threshold\n const lowerBand = threshold - params.ambiguityBand;\n const upperBand = threshold + params.ambiguityBand;\n const rateAmbiguous = approvalRate >= lowerBand && approvalRate <= upperBand;\n\n // Check if confidence is too low\n const confidenceAmbiguous = avgConfidence < params.confidenceThreshold;\n\n return rateAmbiguous || confidenceAmbiguous;\n}\n","/* eslint-disable max-lines */\n// 426 lines — cohesive single-concern engine. Per governance, 400-600 OK if cohesive.\n\n/**\n * nexus-agents/consensus - Consensus Engine\n *\n * Core consensus engine implementation supporting multiple voting strategies.\n * Manages proposal lifecycle, vote collection, and outcome determination.\n */\n\nimport type { Result, ILogger } from '../core/index.js';\nimport { ok, err, AgentError, createLogger, getTimeProvider } from '../core/index.js';\nimport type {\n Proposal,\n ProposalId,\n Vote,\n ConsensusResult,\n ConsensusAlgorithm,\n AgentPerformance,\n ConsensusEngineConfig,\n ProposalState,\n ConsensusMetrics,\n ProposalCacheConfig,\n IncrementalQuorumConfig,\n VoterExpansionCallback,\n} from './types.js';\nimport {\n ProposalSchema,\n VoteSchema,\n DEFAULT_CONSENSUS_CONFIG,\n VOTING_THRESHOLDS,\n DEFAULT_INCREMENTAL_QUORUM_CONFIG,\n} from './types.js';\nimport { VotingStrategyFactory, calculateVoteWeight, type VotingOutcome } from './strategies.js';\nimport { buildFinalResult, buildTimeoutResult, buildPendingResult } from './result-builder.js';\nimport { generateProposalId } from './helpers.js';\nimport { isVotingAmbiguous } from './incremental-quorum.js';\n\n/**\n * Error class for consensus-related failures.\n */\nexport class ConsensusError extends AgentError {\n constructor(message: string, context?: Record<string, unknown>) {\n super(message, context !== undefined ? { context } : {});\n this.name = 'ConsensusError';\n }\n}\n\n/**\n * Interface for the consensus engine.\n */\nexport interface IConsensusEngine {\n propose(proposal: Proposal): Promise<Result<ProposalId, ConsensusError>>;\n vote(proposalId: ProposalId, agentId: string, vote: Vote): Promise<Result<void, ConsensusError>>;\n getResult(proposalId: ProposalId): Promise<Result<ConsensusResult, ConsensusError>>;\n close(proposalId: ProposalId): Promise<Result<ConsensusResult, ConsensusError>>;\n getMetrics(): ConsensusMetrics;\n}\n\ninterface InternalMetrics {\n totalProposals: number;\n approvedProposals: number;\n rejectedProposals: number;\n timedOutProposals: number;\n totalDurationMs: number;\n totalVotes: number;\n algorithmUsage: Record<ConsensusAlgorithm, number>;\n}\n\n/**\n * Cache entry for proposal content-based caching (Issue #589).\n */\ninterface ProposalCacheEntry {\n readonly proposalId: ProposalId;\n readonly result: ConsensusResult;\n readonly cachedAt: number;\n}\n\n/**\n * Default proposal cache configuration.\n * Enabled by default to improve determinism (fitness audit recommendation).\n */\n/**\n * Hypothetical-vote stand-ins used by {@link ConsensusEngine.canCascadeEarly}\n * to probe the strategy's outcome under best/worst-case pending votes.\n * The actual `confidence` and `reasoning` fields are never inspected by\n * `IVotingStrategy.calculateOutcome` (all strategies count by `decision`),\n * but must satisfy `VoteSchema` (confidence in [0,1], reasoning non-empty).\n */\nconst HYPOTHETICAL_APPROVE: Vote = {\n decision: 'approve',\n confidence: 0.5,\n reasoning: 'hypothetical-cascade-probe',\n};\nconst HYPOTHETICAL_REJECT: Vote = {\n decision: 'reject',\n confidence: 0.5,\n reasoning: 'hypothetical-cascade-probe',\n};\n\nconst DEFAULT_PROPOSAL_CACHE_CONFIG: ProposalCacheConfig = {\n enabled: true,\n ttlMs: 3600000, // 1 hour\n maxEntries: 500,\n};\n\n/**\n * Consensus engine for multi-agent decision making.\n *\n * @example\n * ```typescript\n * const engine = new ConsensusEngine({ defaultTimeout: 30000 });\n * const proposalResult = await engine.propose({\n * title: 'Use microservices architecture',\n * description: 'Proposal to adopt microservices',\n * algorithm: 'supermajority',\n * });\n * if (proposalResult.ok) {\n * await engine.vote(proposalResult.value, 'agent-1', {\n * decision: 'approve',\n * confidence: 0.9,\n * reasoning: 'Good for scalability',\n * });\n * }\n * ```\n */\nexport class ConsensusEngine implements IConsensusEngine {\n private readonly proposals: Map<ProposalId, ProposalState> = new Map();\n private readonly closedProposals: Map<ProposalId, ConsensusResult> = new Map();\n private readonly agentPerformance: Map<string, AgentPerformance> = new Map();\n private readonly proposalContentCache: Map<string, ProposalCacheEntry> = new Map();\n private readonly strategyFactory: VotingStrategyFactory;\n private readonly config: ConsensusEngineConfig;\n private readonly cacheConfig: ProposalCacheConfig;\n private readonly quorumConfig: IncrementalQuorumConfig;\n private readonly logger: ILogger;\n private readonly metrics: InternalMetrics;\n private voterExpansionCallback?: VoterExpansionCallback;\n\n constructor(config?: Partial<ConsensusEngineConfig>, logger?: ILogger) {\n this.config = { ...DEFAULT_CONSENSUS_CONFIG, ...config };\n this.cacheConfig = { ...DEFAULT_PROPOSAL_CACHE_CONFIG, ...config?.proposalCache };\n this.quorumConfig = { ...DEFAULT_INCREMENTAL_QUORUM_CONFIG, ...config?.incrementalQuorum };\n this.logger = logger ?? createLogger({ component: 'ConsensusEngine' });\n this.strategyFactory = new VotingStrategyFactory();\n this.metrics = this.createInitialMetrics();\n }\n\n /**\n * Sets the callback for incremental quorum voter expansion (Issue #1408).\n * When ambiguous votes are detected, this callback requests additional voters.\n */\n setVoterExpansionCallback(callback: VoterExpansionCallback): void {\n this.voterExpansionCallback = callback;\n }\n\n propose(proposal: Proposal): Promise<Result<ProposalId, ConsensusError>> {\n const validation = ProposalSchema.safeParse(proposal);\n if (!validation.success) {\n return Promise.resolve(\n err(\n new ConsensusError(`Invalid proposal: ${validation.error.message}`, {\n errors: validation.error.issues,\n })\n )\n );\n }\n\n // Check cache for identical proposal content (Issue #589)\n if (this.cacheConfig.enabled) {\n const cachedEntry = this.getCachedResult(validation.data);\n if (cachedEntry !== undefined) {\n this.logger.debug('Returning cached proposal result', {\n cachedProposalId: cachedEntry.proposalId,\n cachedOutcome: cachedEntry.result.outcome,\n });\n return Promise.resolve(ok(cachedEntry.proposalId));\n }\n }\n\n if (this.proposals.size >= this.config.maxActiveProposals) {\n return Promise.resolve(\n err(\n new ConsensusError(\n `Maximum active proposals (${String(this.config.maxActiveProposals)}) reached`\n )\n )\n );\n }\n\n const proposalId = proposal.id ?? generateProposalId();\n const state = this.createProposalState(validation.data, proposalId);\n this.setupTimeout(state, proposalId, proposal.timeout);\n this.registerProposal(proposalId, state, proposal.algorithm);\n return Promise.resolve(ok(proposalId));\n }\n\n async vote(\n proposalId: ProposalId,\n agentId: string,\n vote: Vote\n ): Promise<Result<void, ConsensusError>> {\n const validationErr = this.validateVote(vote);\n if (validationErr !== undefined) return err(validationErr);\n\n const stateErr = this.validateProposalState(proposalId);\n if (stateErr !== undefined) return err(stateErr);\n\n const state = this.proposals.get(proposalId);\n if (state === undefined) {\n return err(new ConsensusError(`Proposal ${proposalId} not found`));\n }\n\n this.recordVote(state, agentId, vote);\n\n // Agreement-based cascade always takes priority\n if (this.canCascadeEarly(state)) {\n return this.closeInternal(proposalId).then((r) => (r.ok ? ok(undefined) : err(r.error)));\n }\n\n // All required voters voted — check for incremental quorum expansion\n if (this.allRequiredVotersVoted(state)) {\n // Re-entry guard (#2861): `tryExpandQuorum` awaits its callback and\n // then mutates `state.proposal.requiredVoters` / `expansionRounds`.\n // A concurrent `vote()` that also sees `allRequiredVotersVoted`\n // must NOT start a second expansion — that would invoke the\n // expansion callback twice and clobber the first expansion's\n // voter list. This vote is already recorded; return ok and let\n // the in-flight expansion settle.\n if (state.expansionInFlight === true) {\n return Promise.resolve(ok(undefined));\n }\n state.expansionInFlight = true;\n let expanded: boolean;\n try {\n expanded = await this.tryExpandQuorum(proposalId, state);\n } finally {\n state.expansionInFlight = false;\n }\n if (!expanded) {\n return this.closeInternal(proposalId).then((r) => (r.ok ? ok(undefined) : err(r.error)));\n }\n // Expansion succeeded — wait for new voters\n }\n\n return Promise.resolve(ok(undefined));\n }\n\n getResult(proposalId: ProposalId): Promise<Result<ConsensusResult, ConsensusError>> {\n const closedResult = this.closedProposals.get(proposalId);\n if (closedResult !== undefined) return Promise.resolve(ok(closedResult));\n\n const state = this.proposals.get(proposalId);\n if (state === undefined) {\n return Promise.resolve(err(new ConsensusError(`Proposal ${proposalId} not found`)));\n }\n\n const outcome = this.calculateOutcome(state);\n return Promise.resolve(ok(buildPendingResult(state, proposalId, outcome, this.config)));\n }\n\n close(proposalId: ProposalId): Promise<Result<ConsensusResult, ConsensusError>> {\n return this.closeInternal(proposalId);\n }\n\n getMetrics(): ConsensusMetrics {\n const completed =\n this.metrics.approvedProposals +\n this.metrics.rejectedProposals +\n this.metrics.timedOutProposals;\n return {\n totalProposals: this.metrics.totalProposals,\n approvedProposals: this.metrics.approvedProposals,\n rejectedProposals: this.metrics.rejectedProposals,\n timedOutProposals: this.metrics.timedOutProposals,\n averageDurationMs: completed > 0 ? this.metrics.totalDurationMs / completed : 0,\n averageVotesPerProposal: completed > 0 ? this.metrics.totalVotes / completed : 0,\n algorithmUsage: { ...this.metrics.algorithmUsage },\n };\n }\n\n updateAgentPerformance(agentId: string, wasCorrect: boolean): void {\n const existing = this.agentPerformance.get(agentId);\n const now = getTimeProvider().nowIso();\n\n if (existing === undefined) {\n this.agentPerformance.set(agentId, {\n agentId,\n totalVotes: 1,\n correctVotes: wasCorrect ? 1 : 0,\n successRate: wasCorrect ? 1.0 : 0.0,\n lastUpdated: now,\n });\n } else {\n const totalVotes = existing.totalVotes + 1;\n const correctVotes = existing.correctVotes + (wasCorrect ? 1 : 0);\n this.agentPerformance.set(agentId, {\n agentId,\n totalVotes,\n correctVotes,\n successRate: correctVotes / totalVotes,\n lastUpdated: now,\n });\n }\n }\n\n getAgentPerformance(agentId: string): AgentPerformance | undefined {\n return this.agentPerformance.get(agentId);\n }\n\n getActiveProposalCount(): number {\n return this.proposals.size;\n }\n\n private createProposalState(data: Proposal, proposalId: ProposalId): ProposalState {\n const now = new Date(getTimeProvider().now());\n return {\n proposal: { ...data, id: proposalId, createdAt: now.toISOString() },\n status: 'voting',\n votes: new Map(),\n voteWeights: new Map(),\n startedAt: now,\n };\n }\n\n private setupTimeout(state: ProposalState, proposalId: ProposalId, timeout?: number): void {\n const timeoutMs = timeout ?? this.config.defaultTimeout;\n state.timeoutId = setTimeout(() => {\n this.handleTimeout(proposalId);\n }, timeoutMs);\n }\n\n private registerProposal(\n proposalId: ProposalId,\n state: ProposalState,\n algorithm: ConsensusAlgorithm\n ): void {\n this.proposals.set(proposalId, state);\n this.metrics.totalProposals++;\n this.metrics.algorithmUsage[algorithm]++;\n this.logger.info('Proposal created', {\n proposalId,\n title: state.proposal.title,\n algorithm,\n timeout: this.config.defaultTimeout,\n });\n }\n\n private validateVote(vote: Vote): ConsensusError | undefined {\n const validation = VoteSchema.safeParse(vote);\n if (!validation.success) {\n return new ConsensusError(`Invalid vote: ${validation.error.message}`, {\n errors: validation.error.issues,\n });\n }\n return undefined;\n }\n\n private validateProposalState(proposalId: ProposalId): ConsensusError | undefined {\n const state = this.proposals.get(proposalId);\n if (state === undefined) {\n if (this.closedProposals.has(proposalId)) {\n return new ConsensusError(`Proposal ${proposalId} is already closed`);\n }\n return new ConsensusError(`Proposal ${proposalId} not found`);\n }\n if (state.status !== 'voting') {\n return new ConsensusError(`Proposal ${proposalId} is not accepting votes`, {\n status: state.status,\n });\n }\n return undefined;\n }\n\n private recordVote(state: ProposalState, agentId: string, vote: Vote): void {\n state.votes.set(agentId, {\n ...vote,\n timestamp: getTimeProvider().nowIso(),\n });\n if (state.proposal.algorithm === 'proof_of_learning') {\n const performance = this.agentPerformance.get(agentId);\n state.voteWeights.set(agentId, calculateVoteWeight(performance));\n }\n this.logger.debug('Vote recorded', {\n proposalId: state.proposal.id,\n agentId,\n decision: vote.decision,\n confidence: vote.confidence,\n });\n }\n\n private closeInternal(proposalId: ProposalId): Promise<Result<ConsensusResult, ConsensusError>> {\n const state = this.proposals.get(proposalId);\n if (state === undefined) {\n const closed = this.closedProposals.get(proposalId);\n if (closed !== undefined) return Promise.resolve(ok(closed));\n return Promise.resolve(err(new ConsensusError(`Proposal ${proposalId} not found`)));\n }\n\n if (state.timeoutId !== undefined) clearTimeout(state.timeoutId);\n\n const outcome = this.calculateOutcome(state);\n const result = buildFinalResult(state, proposalId, outcome, this.config);\n this.finalize(proposalId, result, state.votes.size);\n return Promise.resolve(ok(result));\n }\n\n private handleTimeout(proposalId: ProposalId): void {\n const state = this.proposals.get(proposalId);\n if (state?.status !== 'voting') return;\n\n this.logger.warn('Proposal timed out', { proposalId, voteCount: state.votes.size });\n const outcome = this.calculateOutcome(state);\n const result = buildTimeoutResult(state, proposalId, outcome, this.config);\n this.proposals.delete(proposalId);\n this.addClosedProposal(proposalId, result);\n this.metrics.timedOutProposals++;\n this.metrics.totalDurationMs += result.durationMs;\n this.metrics.totalVotes += state.votes.size;\n }\n\n private finalize(proposalId: ProposalId, result: ConsensusResult, voteCount: number): void {\n this.proposals.delete(proposalId);\n this.addClosedProposal(proposalId, result);\n this.updateMetrics(result);\n\n // Cache successful results for determinism (Issue #589)\n if (\n this.cacheConfig.enabled &&\n (result.outcome === 'approved' || result.outcome === 'rejected')\n ) {\n this.addToCache(result.proposal, proposalId, result);\n }\n\n this.logger.info('Proposal closed', {\n proposalId,\n outcome: result.outcome,\n approvalPercentage: result.approvalPercentage.toFixed(1),\n voteCount,\n quorumReached: result.quorumReached,\n durationMs: result.durationMs,\n });\n }\n\n /**\n * Adds a closed proposal and evicts oldest entries if over limit.\n * Issue #549: Prevent unbounded memory growth in closedProposals Map.\n */\n private addClosedProposal(proposalId: ProposalId, result: ConsensusResult): void {\n // Evict oldest entries if at capacity (Map maintains insertion order)\n while (this.closedProposals.size >= this.config.maxClosedProposals) {\n const firstKey = this.closedProposals.keys().next();\n if (firstKey.done === true) break;\n const oldestKey = firstKey.value;\n this.closedProposals.delete(oldestKey);\n this.logger.debug('Evicted oldest closed proposal', { evictedId: oldestKey });\n }\n this.closedProposals.set(proposalId, result);\n }\n\n private calculateOutcome(state: ProposalState): VotingOutcome {\n const strategy = this.strategyFactory.getStrategy(state.proposal.algorithm);\n const outcome: VotingOutcome = strategy.calculateOutcome(state.votes, state.voteWeights);\n return outcome;\n }\n\n /**\n * Agreement-based cascading: close early when outcome is mathematically determined.\n *\n * #2822: the prior implementation computed approval rates against\n * `totalExpected = requiredVoters.length` and compared against\n * `VOTING_THRESHOLDS[algorithm]` directly. Every voting strategy\n * (`SimpleMajorityStrategy`, `SupermajorityStrategy`, `UnanimousStrategy`,\n * `ProofOfLearningStrategy`) uses `approve + reject` as its denominator —\n * abstains are explicitly excluded. The two diverged whenever abstains\n * were present, producing wrong-winner cascades (e.g. 5-voter supermajority\n * with [approve, abstain, abstain, abstain, pending] cascade-rejected even\n * though the strategy would approve at close).\n *\n * The fix delegates to the strategy itself: build a best-case (all pending\n * voters approve) and worst-case (all pending voters reject) hypothetical\n * vote map, call `strategy.calculateOutcome` on each, and cascade only\n * when both extremes yield the same outcome. This guarantees parity with\n * the strategy's denominator semantics by construction.\n */\n private canCascadeEarly(state: ProposalState): boolean {\n const required = state.proposal.requiredVoters;\n if (required === undefined || required.length === 0) return false;\n if (state.votes.size === 0) return false;\n\n const pending = required.filter((voter) => !state.votes.has(voter));\n if (pending.length === 0) return false; // All voted — handled by allRequiredVotersVoted\n\n const strategy = this.strategyFactory.getStrategy(state.proposal.algorithm);\n\n const bestCase = new Map<string, Vote>(state.votes);\n const worstCase = new Map<string, Vote>(state.votes);\n for (const voter of pending) {\n bestCase.set(voter, HYPOTHETICAL_APPROVE);\n worstCase.set(voter, HYPOTHETICAL_REJECT);\n }\n\n const bestOutcome = strategy.calculateOutcome(bestCase, state.voteWeights);\n const worstOutcome = strategy.calculateOutcome(worstCase, state.voteWeights);\n\n if (bestOutcome.approved !== worstOutcome.approved) return false;\n\n this.logger.info('Agreement cascade: outcome determined', {\n proposalId: state.proposal.id,\n outcome: bestOutcome.approved ? 'approve' : 'reject',\n votesCast: state.votes.size,\n pending: pending.length,\n algorithm: state.proposal.algorithm,\n });\n return true;\n }\n\n private allRequiredVotersVoted(state: ProposalState): boolean {\n const required = state.proposal.requiredVoters;\n if (required === undefined || required.length === 0) return false;\n return required.every((voterId) => state.votes.has(voterId));\n }\n\n /**\n * Attempts incremental quorum expansion when voting is ambiguous (Issue #1408).\n * Returns true if expansion occurred (wait for new voters), false to close immediately.\n */\n private async tryExpandQuorum(proposalId: ProposalId, state: ProposalState): Promise<boolean> {\n if (!this.quorumConfig.enabled) return false;\n if (this.voterExpansionCallback === undefined) return false;\n\n const rounds = state.expansionRounds ?? 0;\n if (rounds >= this.quorumConfig.maxExpansionRounds) return false;\n\n const required = state.proposal.requiredVoters;\n if (required === undefined) return false;\n\n const threshold = VOTING_THRESHOLDS[state.proposal.algorithm];\n const ambiguous = isVotingAmbiguous(state.votes, required.length, threshold, {\n confidenceThreshold: this.quorumConfig.confidenceThreshold,\n ambiguityBand: this.quorumConfig.ambiguityBand,\n });\n\n if (!ambiguous) return false;\n\n let newVoters: readonly string[];\n try {\n newVoters = await this.voterExpansionCallback(\n proposalId,\n required.length,\n this.quorumConfig.votersPerExpansion\n );\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.logger.warn('Incremental quorum: expansion callback threw; closing as-is', {\n proposalId,\n errorMessage: error.message,\n });\n return false;\n }\n\n if (newVoters.length === 0) {\n this.logger.info('Incremental quorum: no additional voters available', { proposalId });\n return false;\n }\n\n // Expand the required voters list\n state.proposal.requiredVoters = [...required, ...newVoters];\n state.expansionRounds = rounds + 1;\n\n this.logger.info('Incremental quorum: expanded voter pool', {\n proposalId,\n round: rounds + 1,\n newVoters: newVoters.length,\n totalVoters: state.proposal.requiredVoters.length,\n });\n\n return true;\n }\n\n private updateMetrics(result: ConsensusResult): void {\n this.metrics.totalDurationMs += result.durationMs;\n this.metrics.totalVotes += result.voteCounts.total;\n if (result.outcome === 'approved') this.metrics.approvedProposals++;\n else if (result.outcome === 'rejected') this.metrics.rejectedProposals++;\n else if (result.outcome === 'timeout') this.metrics.timedOutProposals++;\n }\n\n private createInitialMetrics(): InternalMetrics {\n return {\n totalProposals: 0,\n approvedProposals: 0,\n rejectedProposals: 0,\n timedOutProposals: 0,\n totalDurationMs: 0,\n totalVotes: 0,\n algorithmUsage: {\n simple_majority: 0,\n supermajority: 0,\n unanimous: 0,\n proof_of_learning: 0,\n opinion_wise: 0,\n higher_order: 0,\n },\n };\n }\n\n // ============================================================================\n // Proposal Content Caching (Issue #589)\n // ============================================================================\n\n /**\n * Creates a content hash for a proposal to enable cache lookups.\n * Hash is based on title, description, and algorithm (deterministic content).\n */\n private hashProposalContent(proposal: Proposal): string {\n const content = [proposal.title, proposal.description, proposal.algorithm].join('|');\n // Simple FNV-1a hash for fast deterministic hashing\n let hash = 2166136261;\n for (let i = 0; i < content.length; i++) {\n hash ^= content.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0).toString(16);\n }\n\n /**\n * Gets cached result for a proposal if it exists and hasn't expired.\n */\n private getCachedResult(proposal: Proposal): ProposalCacheEntry | undefined {\n const hash = this.hashProposalContent(proposal);\n const cached = this.proposalContentCache.get(hash);\n if (cached === undefined) return undefined;\n\n const now = getTimeProvider().now();\n if (now - cached.cachedAt > this.cacheConfig.ttlMs) {\n this.proposalContentCache.delete(hash);\n this.logger.debug('Cache entry expired', { hash });\n return undefined;\n }\n\n return cached;\n }\n\n /**\n * Adds a proposal result to the cache, evicting oldest entries if needed.\n */\n private addToCache(proposal: Proposal, proposalId: ProposalId, result: ConsensusResult): void {\n const hash = this.hashProposalContent(proposal);\n\n // Evict oldest entries if at capacity (Map maintains insertion order)\n while (this.proposalContentCache.size >= this.cacheConfig.maxEntries) {\n const firstKey = this.proposalContentCache.keys().next();\n if (firstKey.done === true) break;\n const oldestKey = firstKey.value;\n this.proposalContentCache.delete(oldestKey);\n this.logger.debug('Evicted oldest cache entry', { hash: oldestKey });\n }\n\n this.proposalContentCache.set(hash, {\n proposalId,\n result,\n cachedAt: getTimeProvider().now(),\n });\n this.logger.debug('Added proposal to cache', { hash, proposalId });\n }\n\n /**\n * Gets the current cache size (for testing/monitoring).\n */\n getCacheSize(): number {\n return this.proposalContentCache.size;\n }\n\n /**\n * Clears the proposal content cache (for testing/reset).\n */\n clearCache(): void {\n this.proposalContentCache.clear();\n this.logger.debug('Proposal cache cleared');\n }\n}\n\n/**\n * Create a consensus engine with the given configuration.\n *\n * @example\n * ```typescript\n * const engine = createConsensusEngine({\n * defaultTimeout: 60000,\n * maxActiveProposals: 10,\n * });\n * ```\n */\nexport function createConsensusEngine(\n config?: Partial<ConsensusEngineConfig>,\n logger?: ILogger\n): ConsensusEngine {\n return new ConsensusEngine(config, logger);\n}\n","/**\n * Unified Quorum Validator\n *\n * Abstracts quorum validation across VotingProtocol, WeightedVoting, and ConsensusEngine.\n * Per redundancy-analysis.md Section 3.4 - consolidates three quorum implementations.\n *\n * @module consensus/quorum-validator\n * (Source: Issue #576, ADR-0003)\n */\n\nimport { createLogger, formatPercentage, type ILogger } from '../core/index.js';\nimport type { ConsensusAlgorithm, Vote, VoteCounts, WeightedVoteCounts } from './types-core.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Agent record for eligibility checks and Byzantine detection.\n */\nexport interface AgentRecord {\n readonly agentId: string;\n readonly weight: number;\n readonly trustScore: number;\n readonly byzantineFlags?: number;\n readonly successRate?: number;\n readonly totalTasks?: number;\n}\n\n/**\n * Quorum validation configuration.\n */\nexport interface QuorumValidationConfig {\n /** Algorithm type */\n readonly algorithm: ConsensusAlgorithm | 'weighted_byzantine';\n /** Numeric threshold (0-1 for percentage, 0-N for weighted sum) */\n readonly threshold: number;\n /** Minimum voters required */\n readonly minVoters: number;\n /** Enable Byzantine detection */\n readonly enableByzantineDetection?: boolean;\n /** Apply confidence multiplier to weights */\n readonly confidenceMultiplier?: boolean;\n /** Include abstentions in quorum calculation */\n readonly includeAbstentions?: boolean;\n}\n\n/**\n * Input for quorum validation.\n */\nexport interface QuorumValidationInput {\n /** Votes cast by agent ID */\n readonly votes: ReadonlyMap<string, Vote>;\n /** Optional: Pre-calculated agent weights */\n readonly agentWeights?: ReadonlyMap<string, number>;\n /** Configuration */\n readonly config: QuorumValidationConfig;\n /** Optional: Agent records for eligibility checks */\n readonly agentRecords?: ReadonlyMap<string, AgentRecord>;\n /** Optional: Required participant count (for ratio-based quorum) */\n readonly requiredParticipants?: number;\n}\n\n/**\n * Quorum validation result (discriminated union).\n */\nexport type QuorumValidationResult =\n | {\n readonly status: 'reached';\n readonly decision: 'approve' | 'reject';\n readonly confidence: number;\n readonly reasoning: string;\n }\n | {\n readonly status: 'not_reached';\n readonly reason: 'insufficient_votes' | 'insufficient_weight' | 'no_consensus';\n readonly details: string;\n }\n | { readonly status: 'invalid'; readonly error: string }\n | { readonly status: 'timeout'; readonly partial: boolean; readonly details: string };\n\n/**\n * Detailed quorum breakdown for observability.\n */\nexport interface QuorumBreakdown {\n readonly totalVotes: number;\n readonly voteCounts: VoteCounts;\n readonly totalWeight: number | undefined;\n readonly weightedCounts: WeightedVoteCounts | undefined;\n readonly threshold: number;\n readonly actualQuorum: number;\n readonly quorumReached: boolean;\n readonly eligibleAgents: readonly string[];\n readonly reasoning: string;\n}\n\n/**\n * Eligibility check result.\n */\nexport type EligibilityResult =\n | { readonly eligible: true; readonly weight: number }\n | {\n readonly eligible: false;\n readonly reason: 'insufficient_weight' | 'low_trust' | 'byzantine_flagged' | 'excluded';\n readonly weight: number;\n };\n\n/**\n * Unified quorum validator interface.\n */\nexport interface IQuorumValidator {\n validateQuorum(input: QuorumValidationInput): QuorumValidationResult;\n getQuorumBreakdown(input: QuorumValidationInput): QuorumBreakdown;\n isAgentEligible(\n agentId: string,\n record: AgentRecord | undefined,\n config: QuorumValidationConfig\n ): EligibilityResult;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Default quorum thresholds by algorithm type.\n * Used for reference when config.threshold is not specified.\n */\nexport const DEFAULT_QUORUM_THRESHOLDS: Readonly<\n Record<ConsensusAlgorithm | 'weighted_byzantine', number>\n> = {\n simple_majority: 0.5,\n supermajority: 0.67,\n unanimous: 1.0,\n proof_of_learning: 0.5,\n opinion_wise: 0.5,\n higher_order: 0.5,\n weighted_byzantine: 0.67,\n};\n\nconst DEFAULT_MIN_TRUST = 0.3;\nconst DEFAULT_MIN_WEIGHT = 0.1;\n\n/**\n * Unified quorum validator implementation.\n */\nexport class QuorumValidator implements IQuorumValidator {\n private readonly logger: ILogger;\n\n constructor(logger?: ILogger) {\n this.logger = logger ?? createLogger({ component: 'QuorumValidator' });\n }\n\n validateQuorum(input: QuorumValidationInput): QuorumValidationResult {\n const { votes, config } = input;\n\n // Validate input\n if (votes.size === 0) {\n return { status: 'invalid', error: 'No votes provided' };\n }\n\n // Calculate breakdown\n const breakdown = this.getQuorumBreakdown(input);\n\n // Check if quorum reached\n if (!breakdown.quorumReached) {\n return this.buildNotReachedResult(breakdown, config);\n }\n\n // Determine decision\n return this.buildReachedResult(breakdown);\n }\n\n getQuorumBreakdown(input: QuorumValidationInput): QuorumBreakdown {\n const { votes, agentWeights, config, agentRecords, requiredParticipants } = input;\n\n // Count votes\n const voteCounts = this.countVotes(votes);\n const eligibleAgents = this.getEligibleAgents(votes, agentRecords, config);\n\n // Calculate weights if applicable\n const { totalWeight, weightedCounts } = this.calculateWeights(\n votes,\n agentWeights,\n agentRecords,\n config\n );\n\n // Calculate quorum based on algorithm\n const { threshold, actualQuorum, quorumReached, reasoning } = this.calculateQuorumStatus(\n voteCounts,\n weightedCounts,\n totalWeight,\n config,\n requiredParticipants ?? votes.size\n );\n\n return {\n totalVotes: votes.size,\n voteCounts,\n totalWeight,\n weightedCounts,\n threshold,\n actualQuorum,\n quorumReached,\n eligibleAgents,\n reasoning,\n };\n }\n\n isAgentEligible(\n agentId: string,\n record: AgentRecord | undefined,\n config: QuorumValidationConfig\n ): EligibilityResult {\n if (record === undefined) {\n return { eligible: true, weight: 1.0 }; // Default eligibility\n }\n\n // Check Byzantine flags\n if (config.enableByzantineDetection === true && (record.byzantineFlags ?? 0) > 0) {\n this.logger.debug('Agent flagged as Byzantine', { agentId, flags: record.byzantineFlags });\n return { eligible: false, reason: 'byzantine_flagged', weight: record.weight };\n }\n\n // Check trust score\n if (record.trustScore < DEFAULT_MIN_TRUST) {\n this.logger.debug('Agent trust score below threshold', {\n agentId,\n trustScore: record.trustScore,\n });\n return { eligible: false, reason: 'low_trust', weight: record.weight };\n }\n\n // Check weight\n if (record.weight < DEFAULT_MIN_WEIGHT) {\n this.logger.debug('Agent weight below threshold', { agentId, weight: record.weight });\n return { eligible: false, reason: 'insufficient_weight', weight: record.weight };\n }\n\n return { eligible: true, weight: record.weight };\n }\n\n private countVotes(votes: ReadonlyMap<string, Vote>): VoteCounts {\n let approve = 0;\n let reject = 0;\n let abstain = 0;\n\n for (const vote of votes.values()) {\n switch (vote.decision) {\n case 'approve':\n approve++;\n break;\n case 'reject':\n reject++;\n break;\n case 'abstain':\n abstain++;\n break;\n }\n }\n\n return { approve, reject, abstain, total: votes.size };\n }\n\n private getEligibleAgents(\n votes: ReadonlyMap<string, Vote>,\n agentRecords: ReadonlyMap<string, AgentRecord> | undefined,\n config: QuorumValidationConfig\n ): readonly string[] {\n const eligible: string[] = [];\n\n for (const agentId of votes.keys()) {\n const record = agentRecords?.get(agentId);\n const result = this.isAgentEligible(agentId, record, config);\n if (result.eligible) {\n eligible.push(agentId);\n }\n }\n\n return eligible;\n }\n\n private calculateWeights(\n votes: ReadonlyMap<string, Vote>,\n agentWeights: ReadonlyMap<string, number> | undefined,\n agentRecords: ReadonlyMap<string, AgentRecord> | undefined,\n config: QuorumValidationConfig\n ): { totalWeight: number | undefined; weightedCounts: WeightedVoteCounts | undefined } {\n // Skip weight calculation for simple algorithms\n if (config.algorithm === 'simple_majority' || config.algorithm === 'unanimous') {\n return { totalWeight: undefined, weightedCounts: undefined };\n }\n\n const counts = { totalWeight: 0, approve: 0, reject: 0, abstain: 0 };\n\n for (const [agentId, vote] of votes.entries()) {\n const weight = this.getVoteWeight(agentId, vote, agentWeights, agentRecords, config);\n counts.totalWeight += weight;\n this.addWeightToDecision(counts, vote.decision, weight);\n }\n\n return {\n totalWeight: counts.totalWeight,\n weightedCounts: {\n approve: counts.approve,\n reject: counts.reject,\n abstain: counts.abstain,\n totalWeight: counts.totalWeight,\n },\n };\n }\n\n private getVoteWeight(\n agentId: string,\n vote: Vote,\n agentWeights: ReadonlyMap<string, number> | undefined,\n agentRecords: ReadonlyMap<string, AgentRecord> | undefined,\n config: QuorumValidationConfig\n ): number {\n let weight = agentWeights?.get(agentId) ?? agentRecords?.get(agentId)?.weight ?? 1.0;\n if (config.confidenceMultiplier === true) {\n weight *= vote.confidence;\n }\n return weight;\n }\n\n private addWeightToDecision(\n counts: { approve: number; reject: number; abstain: number },\n decision: 'approve' | 'reject' | 'abstain',\n weight: number\n ): void {\n counts[decision] += weight;\n }\n\n private calculateQuorumStatus(\n voteCounts: VoteCounts,\n weightedCounts: WeightedVoteCounts | undefined,\n totalWeight: number | undefined,\n config: QuorumValidationConfig,\n requiredParticipants: number\n ): { threshold: number; actualQuorum: number; quorumReached: boolean; reasoning: string } {\n const threshold = config.threshold;\n\n // For weighted algorithms, use weighted counts\n if (weightedCounts !== undefined && totalWeight !== undefined && totalWeight > 0) {\n return this.calculateWeightedQuorum(weightedCounts, totalWeight, threshold);\n }\n\n // For simple algorithms, use vote counts\n return this.calculateSimpleQuorum(voteCounts, requiredParticipants, threshold, config);\n }\n\n private calculateWeightedQuorum(\n weightedCounts: WeightedVoteCounts,\n totalWeight: number,\n threshold: number\n ): { threshold: number; actualQuorum: number; quorumReached: boolean; reasoning: string } {\n const quorumReached = totalWeight >= threshold;\n const approveRatio = weightedCounts.approve / totalWeight;\n const rejectRatio = weightedCounts.reject / totalWeight;\n\n const reasoning = this.buildWeightedReasoning(\n quorumReached,\n totalWeight,\n threshold,\n approveRatio,\n rejectRatio\n );\n\n return { threshold, actualQuorum: totalWeight, quorumReached, reasoning };\n }\n\n private buildWeightedReasoning(\n quorumReached: boolean,\n totalWeight: number,\n threshold: number,\n approveRatio: number,\n rejectRatio: number\n ): string {\n if (!quorumReached) {\n return `Weighted quorum not reached: ${totalWeight.toFixed(2)} < ${String(threshold)}`;\n }\n if (approveRatio > rejectRatio) {\n return `Approval wins with weighted ratio ${formatPercentage(approveRatio, 1)}`;\n }\n if (rejectRatio > approveRatio) {\n return `Rejection wins with weighted ratio ${formatPercentage(rejectRatio, 1)}`;\n }\n return `No clear winner: approve=${formatPercentage(approveRatio, 1)}, reject=${formatPercentage(rejectRatio, 1)}`;\n }\n\n private calculateSimpleQuorum(\n voteCounts: VoteCounts,\n requiredParticipants: number,\n threshold: number,\n config: QuorumValidationConfig\n ): { threshold: number; actualQuorum: number; quorumReached: boolean; reasoning: string } {\n const activeVotes =\n config.includeAbstentions === true\n ? voteCounts.total\n : voteCounts.approve + voteCounts.reject;\n\n const total = requiredParticipants > 0 ? requiredParticipants : activeVotes;\n const approveRatio = total > 0 ? voteCounts.approve / total : 0;\n const rejectRatio = total > 0 ? voteCounts.reject / total : 0;\n\n const hasMinVoters = activeVotes >= config.minVoters;\n const quorumReached = hasMinVoters && (approveRatio >= threshold || rejectRatio >= threshold);\n\n const reasoning = this.buildSimpleReasoning({\n hasMinVoters,\n activeVotes,\n minVoters: config.minVoters,\n approveRatio,\n rejectRatio,\n threshold,\n });\n\n return {\n threshold,\n actualQuorum: Math.max(approveRatio, rejectRatio),\n quorumReached,\n reasoning,\n };\n }\n\n private buildSimpleReasoning(params: {\n hasMinVoters: boolean;\n activeVotes: number;\n minVoters: number;\n approveRatio: number;\n rejectRatio: number;\n threshold: number;\n }): string {\n const { hasMinVoters, activeVotes, minVoters, approveRatio, rejectRatio, threshold } = params;\n if (!hasMinVoters) {\n return `Insufficient voters: ${String(activeVotes)} < ${String(minVoters)}`;\n }\n if (approveRatio >= threshold) {\n return `Approval reaches threshold: ${formatPercentage(approveRatio, 1)} >= ${formatPercentage(threshold, 1)}`;\n }\n if (rejectRatio >= threshold) {\n return `Rejection reaches threshold: ${formatPercentage(rejectRatio, 1)} >= ${formatPercentage(threshold, 1)}`;\n }\n return `No decision reached threshold: approve=${formatPercentage(approveRatio, 1)}, reject=${formatPercentage(rejectRatio, 1)}`;\n }\n\n private buildNotReachedResult(\n breakdown: QuorumBreakdown,\n config: QuorumValidationConfig\n ): QuorumValidationResult {\n const { voteCounts, weightedCounts, threshold } = breakdown;\n\n if (voteCounts.total < config.minVoters) {\n return {\n status: 'not_reached',\n reason: 'insufficient_votes',\n details: `Only ${String(voteCounts.total)} votes, need ${String(config.minVoters)}`,\n };\n }\n\n if (weightedCounts !== undefined && weightedCounts.totalWeight < threshold) {\n return {\n status: 'not_reached',\n reason: 'insufficient_weight',\n details: `Weight ${weightedCounts.totalWeight.toFixed(2)} < threshold ${String(threshold)}`,\n };\n }\n\n return {\n status: 'not_reached',\n reason: 'no_consensus',\n details: breakdown.reasoning,\n };\n }\n\n private buildReachedResult(breakdown: QuorumBreakdown): QuorumValidationResult {\n const { voteCounts, weightedCounts } = breakdown;\n\n // Determine winning decision\n const approves = weightedCounts?.approve ?? voteCounts.approve;\n const rejects = weightedCounts?.reject ?? voteCounts.reject;\n const total = weightedCounts?.totalWeight ?? voteCounts.total;\n\n const decision: 'approve' | 'reject' = approves >= rejects ? 'approve' : 'reject';\n const confidence = total > 0 ? Math.abs(approves - rejects) / total : 0;\n\n return {\n status: 'reached',\n decision,\n confidence,\n reasoning: breakdown.reasoning,\n };\n }\n}\n\n/**\n * Creates a quorum validator instance.\n */\nexport function createQuorumValidator(logger?: ILogger): IQuorumValidator {\n return new QuorumValidator(logger);\n}\n","/**\n * Helper functions for the multi-round voting protocol.\n *\n * @module consensus/voting-protocol-helpers\n * (Source: Issue #100, arXiv:2512.21352)\n */\n\nimport type {\n VotingSession,\n VotingRound,\n VotingRoundPhase,\n VotingProtocolConfig,\n VotingProtocolResult,\n AgentFinding,\n Vote,\n ConsolidatedFinding,\n RoundSummary,\n SycophancyReport,\n SycophancyIndicator,\n} from './types.js';\nimport { createQuorumValidator, type QuorumValidationConfig } from './quorum-validator.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\n\n/**\n * Generate a unique session ID.\n */\nexport function generateSessionId(): string {\n const time = getTimeProvider();\n const random = getRandomProvider();\n return `session_${String(time.now())}_${random.randomString(7)}`;\n}\n\n/**\n * Generate a unique finding ID.\n */\nexport function generateFindingId(): string {\n const time = getTimeProvider();\n const random = getRandomProvider();\n return `finding_${String(time.now())}_${random.randomString(7)}`;\n}\n\n/**\n * Generate a unique round ID.\n */\nexport function generateRoundId(): string {\n const time = getTimeProvider();\n const random = getRandomProvider();\n return `round_${String(time.now())}_${random.randomString(7)}`;\n}\n\n/**\n * Create a new voting round.\n */\nexport function createRound(phase: VotingRoundPhase, roundNumber: number): VotingRound {\n const time = getTimeProvider();\n return {\n id: generateRoundId(),\n phase,\n status: 'in_progress',\n findings: new Map(),\n findingVotes: new Map(),\n finalVotes: new Map(),\n startedAt: time.nowIso(),\n roundNumber,\n };\n}\n\n/**\n * Find the most common element in an array.\n */\nexport function mostCommon<T>(items: T[]): T | undefined {\n if (items.length === 0) return undefined;\n\n const counts = new Map<T, number>();\n items.forEach((item) => {\n counts.set(item, (counts.get(item) ?? 0) + 1);\n });\n\n let maxCount = 0;\n let result: T | undefined;\n counts.forEach((count, item) => {\n if (count > maxCount) {\n maxCount = count;\n result = item;\n }\n });\n\n return result;\n}\n\n/**\n * Calculate agreement score from votes.\n */\nexport function calculateAgreementScore(votes: Vote[]): number {\n if (votes.length < 2) return 1;\n\n const decisions = votes.map((v) => v.decision);\n const mostCommonDecision = mostCommon(decisions);\n const agreementCount = decisions.filter((d) => d === mostCommonDecision).length;\n\n return agreementCount / votes.length;\n}\n\n/**\n * Determine outcome from final votes using unified QuorumValidator.\n * Per ADR-0003, this delegates to the consolidated quorum logic.\n */\nexport function determineOutcome(\n votes: Vote[],\n config: VotingProtocolConfig\n): VotingProtocolResult['outcome'] {\n if (votes.length === 0) return 'no_consensus';\n\n // Convert array to Map for QuorumValidator\n const voteMap = new Map<string, Vote>();\n votes.forEach((vote, index) => {\n voteMap.set(`voter_${String(index)}`, vote);\n });\n\n // Create quorum config from voting protocol config\n const quorumConfig: QuorumValidationConfig = {\n algorithm: 'simple_majority',\n threshold: config.agreementThreshold,\n minVoters: 2, // Minimum for valid consensus\n };\n\n // Use unified QuorumValidator\n const validator = createQuorumValidator();\n const result = validator.validateQuorum({\n votes: voteMap,\n config: quorumConfig,\n });\n\n // Map QuorumValidationResult to VotingProtocolResult outcome\n if (result.status === 'reached') {\n return result.decision === 'approve' ? 'approved' : 'rejected';\n }\n\n // Check for mixed votes (needs revision)\n const approvals = votes.filter((v) => v.decision === 'approve').length;\n const rejections = votes.filter((v) => v.decision === 'reject').length;\n if (approvals > 0 && rejections > 0) return 'needs_revision';\n\n return 'no_consensus';\n}\n\n/**\n * Consolidate findings from deliberation round.\n */\nexport function consolidateFindings(session: VotingSession): ConsolidatedFinding[] {\n const deliberationRound = session.rounds[1];\n if (!deliberationRound) return [];\n\n const consolidated: ConsolidatedFinding[] = [];\n\n deliberationRound.findings.forEach((finding, findingId) => {\n const votes = deliberationRound.findingVotes.get(findingId) ?? [];\n const agreeVotes = votes.filter((v) => v.agree);\n const agreementRatio = votes.length > 0 ? agreeVotes.length / votes.length : 0;\n\n // Only include findings with some agreement\n if (agreementRatio >= 0.5) {\n // Determine final severity (use most common amended severity or original)\n const severityVotes = agreeVotes\n .filter((v) => v.amendedSeverity)\n .map((v) => v.amendedSeverity);\n const finalSeverity =\n severityVotes.length > 0\n ? (mostCommon(severityVotes) ?? finding.severity)\n : finding.severity;\n\n const consolidatedFinding: ConsolidatedFinding = {\n id: findingId,\n category: finding.category,\n severity: finalSeverity,\n description: finding.description,\n supportingAgents: agreeVotes.map((v) => v.agentId),\n agreementRatio,\n originalFindings: [finding],\n };\n if (finding.location !== undefined) {\n consolidatedFinding.location = finding.location;\n }\n if (finding.suggestion !== undefined) {\n consolidatedFinding.suggestion = finding.suggestion;\n }\n consolidated.push(consolidatedFinding);\n }\n });\n\n // Sort by severity and agreement\n return consolidated.sort((a, b) => {\n const severityOrder = { critical: 0, major: 1, minor: 2, suggestion: 3 };\n const sevDiff = severityOrder[a.severity] - severityOrder[b.severity];\n if (sevDiff !== 0) return sevDiff;\n return b.agreementRatio - a.agreementRatio;\n });\n}\n\n/**\n * Build round summaries from session.\n */\nexport function buildRoundSummaries(session: VotingSession): RoundSummary[] {\n const time = getTimeProvider();\n return session.rounds.map((round, index) => {\n const startTime = new Date(round.startedAt).getTime();\n const endTime =\n round.completedAt !== undefined ? new Date(round.completedAt).getTime() : time.now();\n\n let votesCount = 0;\n let agreementScore = 0;\n\n if (round.phase === 'deliberation') {\n // Count finding votes\n round.findingVotes.forEach((votes) => {\n votesCount += votes.length;\n const agreeCount = votes.filter((v) => v.agree).length;\n agreementScore += votes.length > 0 ? agreeCount / votes.length : 0;\n });\n const findingsCount = round.findingVotes.size;\n if (findingsCount > 0) {\n agreementScore /= findingsCount;\n }\n } else if (round.phase === 'consensus') {\n // Count final votes\n votesCount = round.finalVotes.size;\n const votes = Array.from(round.finalVotes.values());\n agreementScore = calculateAgreementScore(votes);\n }\n\n return {\n roundNumber: index + 1,\n phase: round.phase,\n findingsCount: round.findings.size,\n votesCount,\n agreementScore,\n durationMs: endTime - startTime,\n };\n });\n}\n\n// ============================================================================\n// Sycophancy Detection\n// ============================================================================\n\n/**\n * Check for premature consensus pattern.\n */\nexport function checkPrematureConsensus(session: VotingSession): SycophancyIndicator | null {\n const analysisRound = session.rounds[0];\n if (!analysisRound) return null;\n\n const agentFindings = new Map<string, AgentFinding[]>();\n analysisRound.findings.forEach((finding) => {\n const existing = agentFindings.get(finding.agentId) ?? [];\n existing.push(finding);\n agentFindings.set(finding.agentId, existing);\n });\n\n const allConfidences: number[] = [];\n analysisRound.findings.forEach((finding) => {\n allConfidences.push(finding.confidence);\n });\n\n const avgConfidence =\n allConfidences.length > 0\n ? allConfidences.reduce((a, b) => a + b, 0) / allConfidences.length\n : 0;\n\n if (avgConfidence > 0.95 && agentFindings.size >= 2) {\n return {\n type: 'premature_consensus',\n description: 'All agents showing unusually high confidence',\n severity: 'medium',\n agents: Array.from(agentFindings.keys()),\n };\n }\n\n return null;\n}\n\n/**\n * Check for opinion convergence pattern.\n */\nexport function checkOpinionConvergence(session: VotingSession): SycophancyIndicator | null {\n const deliberationRound = session.rounds[1];\n if (!deliberationRound) return null;\n\n let totalVotes = 0;\n let agreeVotes = 0;\n\n deliberationRound.findingVotes.forEach((votes) => {\n totalVotes += votes.length;\n agreeVotes += votes.filter((v) => v.agree).length;\n });\n\n const agreeRatio = totalVotes > 0 ? agreeVotes / totalVotes : 0;\n\n if (agreeRatio > session.config.sycophancyThreshold && totalVotes > 3) {\n const affectedAgents: string[] = [];\n deliberationRound.findingVotes.forEach((votes) => {\n votes.forEach((v) => {\n if (v.agree && !affectedAgents.includes(v.agentId)) {\n affectedAgents.push(v.agentId);\n }\n });\n });\n\n return {\n type: 'opinion_convergence',\n description: `${String(Math.round(agreeRatio * 100))}% agreement rate suggests possible opinion convergence`,\n severity: 'high',\n agents: affectedAgents,\n };\n }\n\n return null;\n}\n\n/**\n * Check for confidence inflation pattern.\n */\nexport function checkConfidenceInflation(session: VotingSession): SycophancyIndicator | null {\n const consensusRound = session.rounds[2];\n if (!consensusRound) return null;\n\n const votes = Array.from(consensusRound.finalVotes.values());\n if (votes.length < 2) return null;\n\n const confidences = votes.map((v) => v.confidence);\n const avgConfidence = confidences.reduce((a, b) => a + b, 0) / confidences.length;\n const allHigh = confidences.every((c) => c > 0.9);\n\n if (allHigh && avgConfidence > 0.95) {\n return {\n type: 'confidence_inflation',\n description: 'All agents reporting very high confidence suggests possible sycophancy',\n severity: 'medium',\n agents: Array.from(consensusRound.finalVotes.keys()),\n };\n }\n\n return null;\n}\n\n/**\n * Run all sycophancy detection checks.\n */\nexport function detectSycophancyPatterns(session: VotingSession): SycophancyReport {\n const indicators: SycophancyIndicator[] = [];\n const affectedAgents: string[] = [];\n\n const prematureConsensus = checkPrematureConsensus(session);\n if (prematureConsensus) {\n indicators.push(prematureConsensus);\n affectedAgents.push(...prematureConsensus.agents);\n }\n\n const opinionConvergence = checkOpinionConvergence(session);\n if (opinionConvergence) {\n indicators.push(opinionConvergence);\n affectedAgents.push(...opinionConvergence.agents);\n }\n\n const confidenceInflation = checkConfidenceInflation(session);\n if (confidenceInflation) {\n indicators.push(confidenceInflation);\n affectedAgents.push(...confidenceInflation.agents);\n }\n\n const detected = indicators.length > 0;\n const confidenceScore = Math.min(1, indicators.length * 0.3);\n const uniqueAffected = [...new Set(affectedAgents)];\n\n return {\n detected,\n confidenceScore,\n indicators,\n affectedAgents: uniqueAffected,\n recommendation: detected\n ? 'Consider requesting independent re-analysis or adding more diverse agents'\n : 'No sycophancy detected',\n };\n}\n","/**\n * Multi-Round Voting Protocol Implementation\n *\n * Implements a structured 3-round voting protocol for multi-agent code review\n * based on research showing 91.7-100% success rates vs 78% single-agent baseline.\n *\n * @module consensus/voting-protocol\n * (Source: Issue #100, arXiv:2512.21352 - Multi-Agent Committees)\n * (Source: arXiv:2509.23055 - Sycophancy Prevention)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport { getTimeProvider } from '../core/index.js';\nimport type { ILogger } from '../core/index.js';\nimport type {\n IVotingProtocol,\n VotingSession,\n VotingRound,\n VotingProtocolConfig,\n VotingProtocolResult,\n AgentFinding,\n FindingVote,\n Vote,\n SycophancyReport,\n} from './types.js';\nimport {\n AgentFindingSchema,\n FindingVoteSchema,\n VoteSchema,\n DEFAULT_VOTING_PROTOCOL_CONFIG,\n} from './types.js';\nimport {\n generateSessionId,\n generateFindingId,\n createRound,\n consolidateFindings,\n buildRoundSummaries,\n determineOutcome,\n calculateAgreementScore,\n detectSycophancyPatterns,\n} from './voting-protocol-helpers.js';\n\nconst logger: ILogger = createLogger({ component: 'voting-protocol' });\n\n/**\n * Multi-round voting protocol for code review.\n */\nexport class VotingProtocol implements IVotingProtocol {\n private readonly sessions: Map<string, VotingSession> = new Map();\n private readonly logger: ILogger;\n\n constructor(customLogger?: ILogger) {\n this.logger = customLogger ?? logger;\n }\n\n /**\n * Create a new voting session with a committee.\n */\n createSession(\n topic: string,\n committee: string[],\n config?: Partial<VotingProtocolConfig>\n ): VotingSession {\n const sessionConfig = { ...DEFAULT_VOTING_PROTOCOL_CONFIG, ...config };\n\n if (committee.length < 2) {\n throw new Error('Committee must have at least 2 members');\n }\n\n if (committee.length > sessionConfig.committeeSize) {\n throw new Error(`Committee size exceeds maximum (${String(sessionConfig.committeeSize)})`);\n }\n\n const session: VotingSession = {\n id: generateSessionId(),\n topic,\n committee,\n rounds: [],\n currentRound: 0,\n config: sessionConfig,\n status: 'active',\n createdAt: getTimeProvider().nowIso(),\n };\n\n this.sessions.set(session.id, session);\n this.logger.info('Voting session created', {\n sessionId: session.id,\n topic,\n committeeSize: committee.length,\n });\n\n return session;\n }\n\n /**\n * Start the analysis round (Round 1).\n */\n startAnalysisRound(sessionId: string): Promise<VotingRound> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n if (session.currentRound !== 0) {\n return Promise.reject(new Error('Analysis round can only be started as Round 1'));\n }\n\n const round = createRound('analysis', 1);\n session.rounds.push(round);\n session.currentRound = 1;\n\n this.logger.info('Analysis round started', { sessionId, roundId: round.id });\n return Promise.resolve(round);\n }\n\n /**\n * Submit findings from an agent during analysis.\n */\n submitFindings(sessionId: string, agentId: string, findings: AgentFinding[]): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n const currentRound = this.getCurrentRound(session);\n if (currentRound.phase !== 'analysis') {\n return Promise.reject(new Error('Findings can only be submitted during analysis round'));\n }\n\n if (!session.committee.includes(agentId)) {\n return Promise.reject(new Error(`Agent ${agentId} is not a committee member`));\n }\n\n for (const finding of findings) {\n const validation = AgentFindingSchema.safeParse(finding);\n if (!validation.success) {\n return Promise.reject(new Error(`Invalid finding: ${validation.error.message}`));\n }\n\n const findingId = generateFindingId();\n const timestampedFinding = {\n ...validation.data,\n agentId,\n timestamp: getTimeProvider().nowIso(),\n };\n currentRound.findings.set(findingId, timestampedFinding);\n }\n\n this.logger.debug('Findings submitted', { sessionId, agentId, findingsCount: findings.length });\n return Promise.resolve();\n }\n\n /**\n * Start the deliberation round (Round 2).\n */\n startDeliberationRound(sessionId: string): Promise<VotingRound> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n if (session.currentRound !== 1) {\n return Promise.reject(new Error('Deliberation round can only be started after analysis'));\n }\n\n const analysisRound = session.rounds[0];\n if (analysisRound) {\n analysisRound.status = 'completed';\n analysisRound.completedAt = getTimeProvider().nowIso();\n }\n\n if (session.config.enableAntiSycophancy) {\n const report = this.detectSycophancy(sessionId);\n if (report.detected) {\n this.logger.warn('Sycophancy detected before deliberation', {\n sessionId,\n indicators: report.indicators.length,\n });\n }\n }\n\n const round = createRound('deliberation', 2);\n if (analysisRound) {\n analysisRound.findings.forEach((finding, id) => {\n round.findings.set(id, finding);\n round.findingVotes.set(id, []);\n });\n }\n\n session.rounds.push(round);\n session.currentRound = 2;\n\n this.logger.info('Deliberation round started', {\n sessionId,\n roundId: round.id,\n findingsCount: round.findings.size,\n });\n return Promise.resolve(round);\n }\n\n /**\n * Vote on findings during deliberation.\n */\n voteOnFinding(sessionId: string, vote: FindingVote): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n const currentRound = this.getCurrentRound(session);\n if (currentRound.phase !== 'deliberation') {\n return Promise.reject(new Error('Finding votes can only be submitted during deliberation'));\n }\n\n const validation = FindingVoteSchema.safeParse(vote);\n if (!validation.success) {\n return Promise.reject(new Error(`Invalid vote: ${validation.error.message}`));\n }\n\n if (!session.committee.includes(vote.agentId)) {\n return Promise.reject(new Error(`Agent ${vote.agentId} is not a committee member`));\n }\n\n if (!currentRound.findings.has(vote.findingId)) {\n return Promise.reject(new Error(`Finding ${vote.findingId} not found`));\n }\n\n const existingVotes = currentRound.findingVotes.get(vote.findingId) ?? [];\n const filtered = existingVotes.filter((v) => v.agentId !== vote.agentId);\n filtered.push(validation.data);\n currentRound.findingVotes.set(vote.findingId, filtered);\n\n this.logger.debug('Finding vote recorded', {\n sessionId,\n agentId: vote.agentId,\n findingId: vote.findingId,\n agree: vote.agree,\n });\n return Promise.resolve();\n }\n\n /**\n * Start the consensus round (Round 3).\n */\n startConsensusRound(sessionId: string): Promise<VotingRound> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n if (session.currentRound !== 2) {\n return Promise.reject(new Error('Consensus round can only be started after deliberation'));\n }\n\n const deliberationRound = session.rounds[1];\n if (deliberationRound) {\n deliberationRound.status = 'completed';\n deliberationRound.completedAt = getTimeProvider().nowIso();\n }\n\n const round = createRound('consensus', 3);\n session.rounds.push(round);\n session.currentRound = 3;\n\n this.logger.info('Consensus round started', { sessionId, roundId: round.id });\n return Promise.resolve(round);\n }\n\n /**\n * Submit final vote during consensus.\n */\n submitFinalVote(sessionId: string, agentId: string, vote: Vote): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n this.validateSessionActive(session);\n\n const currentRound = this.getCurrentRound(session);\n if (currentRound.phase !== 'consensus') {\n return Promise.reject(new Error('Final votes can only be submitted during consensus'));\n }\n\n const validation = VoteSchema.safeParse(vote);\n if (!validation.success) {\n return Promise.reject(new Error(`Invalid vote: ${validation.error.message}`));\n }\n\n if (!session.committee.includes(agentId)) {\n return Promise.reject(new Error(`Agent ${agentId} is not a committee member`));\n }\n\n currentRound.finalVotes.set(agentId, {\n ...validation.data,\n timestamp: getTimeProvider().nowIso(),\n });\n\n this.logger.debug('Final vote recorded', {\n sessionId,\n agentId,\n decision: vote.decision,\n confidence: vote.confidence,\n });\n return Promise.resolve();\n }\n\n /**\n * Get the final result.\n */\n getResult(sessionId: string): Promise<VotingProtocolResult | null> {\n const session = this.sessions.get(sessionId);\n if (!session) return Promise.resolve(null);\n\n if (session.status === 'completed' && session.finalResult) {\n return Promise.resolve(session.finalResult);\n }\n\n if (session.currentRound < 3) return Promise.resolve(null);\n\n const consensusRound = session.rounds[2];\n if (!consensusRound) return Promise.resolve(null);\n\n const allVoted = session.committee.every((agentId) => consensusRound.finalVotes.has(agentId));\n if (!allVoted) return Promise.resolve(null);\n\n const result = this.buildFinalResult(session);\n session.finalResult = result;\n session.status = 'completed';\n session.completedAt = getTimeProvider().nowIso();\n\n consensusRound.status = 'completed';\n consensusRound.completedAt = getTimeProvider().nowIso();\n\n this.logger.info('Voting session completed', {\n sessionId,\n outcome: result.outcome,\n agreementScore: result.agreementScore,\n consolidatedFindings: result.consolidatedFindings.length,\n });\n\n return Promise.resolve(result);\n }\n\n /**\n * Detect sycophancy patterns.\n */\n detectSycophancy(sessionId: string): SycophancyReport {\n const session = this.getSessionOrThrow(sessionId);\n return detectSycophancyPatterns(session);\n }\n\n /**\n * Get the current session state.\n */\n getSession(sessionId: string): VotingSession | undefined {\n return this.sessions.get(sessionId);\n }\n\n private getSessionOrThrow(sessionId: string): VotingSession {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} not found`);\n }\n return session;\n }\n\n private validateSessionActive(session: VotingSession): void {\n if (session.status !== 'active') {\n throw new Error(`Session ${session.id} is ${session.status}`);\n }\n }\n\n private getCurrentRound(session: VotingSession): VotingRound {\n const round = session.rounds[session.currentRound - 1];\n if (!round) {\n throw new Error(`No round ${String(session.currentRound)} found`);\n }\n return round;\n }\n\n private buildFinalResult(session: VotingSession): VotingProtocolResult {\n const startTime = new Date(session.createdAt).getTime();\n const endTime = getTimeProvider().now();\n\n const consolidatedFindingsList = consolidateFindings(session);\n const roundSummaries = buildRoundSummaries(session);\n\n const consensusRound = session.rounds[2];\n const finalVotes = consensusRound ? Array.from(consensusRound.finalVotes.values()) : [];\n const outcome = determineOutcome(finalVotes, session.config);\n const agreementScore = calculateAgreementScore(finalVotes);\n const sycophancyReport = detectSycophancyPatterns(session);\n\n return {\n sessionId: session.id,\n topic: session.topic,\n outcome,\n consolidatedFindings: consolidatedFindingsList,\n roundSummaries,\n agreementScore,\n sycophancyDetected: sycophancyReport.detected,\n totalDurationMs: endTime - startTime,\n participatingAgents: session.committee,\n };\n }\n}\n\n/**\n * Create a voting protocol instance.\n */\nexport function createVotingProtocol(customLogger?: ILogger): VotingProtocol {\n return new VotingProtocol(customLogger);\n}\n","/**\n * Byzantine Detection EventBus Integration Helpers\n * (Source: Issue #218, Sprint #228)\n *\n * Provides helper functions for emitting Byzantine fault detection events.\n * Used by CP-WBFT weighted voting to report Byzantine behavior patterns.\n *\n * @module agents/collaboration/byzantine-events\n */\n\nimport type {\n IEventBus,\n ByzantineWeightUpdatedEvent,\n ByzantinePatternDetectedEvent,\n ByzantineAgentFlaggedEvent,\n ByzantineCollusionSuspectedEvent,\n} from './event-bus-types.js';\nimport { createEvent } from './event-bus.js';\n\n// =============================================================================\n// Weight Update Events\n// =============================================================================\n\n/** Parameters for emitting byzantine.weight_updated event. */\nexport interface WeightUpdatedParams {\n readonly agentId: string;\n readonly previousWeight: number;\n readonly newWeight: number;\n readonly reason: 'performance_update' | 'flag_penalty' | 'recalibration';\n readonly sessionId?: string | undefined;\n readonly correlationId?: string | undefined;\n}\n\n/** Emits byzantine.weight_updated event when an agent's weight changes. */\nexport function emitWeightUpdated(eventBus: IEventBus, params: WeightUpdatedParams): void {\n const event = createEvent<ByzantineWeightUpdatedEvent>(\n 'byzantine.weight_updated',\n {\n agentId: params.agentId,\n previousWeight: params.previousWeight,\n newWeight: params.newWeight,\n reason: params.reason,\n },\n {\n ...(params.sessionId !== undefined && { sessionId: params.sessionId }),\n ...(params.correlationId !== undefined && { correlationId: params.correlationId }),\n }\n );\n eventBus.emit(event);\n}\n\n// =============================================================================\n// Pattern Detection Events\n// =============================================================================\n\n/** Parameters for emitting byzantine.pattern_detected event. */\nexport interface PatternDetectedParams {\n readonly patternType: 'contrarian' | 'collusion';\n readonly agentIds: readonly string[];\n readonly confidence: number;\n readonly details: string;\n readonly sessionId?: string | undefined;\n readonly correlationId?: string | undefined;\n}\n\n/** Emits byzantine.pattern_detected event when Byzantine pattern is detected. */\nexport function emitPatternDetected(eventBus: IEventBus, params: PatternDetectedParams): void {\n const event = createEvent<ByzantinePatternDetectedEvent>(\n 'byzantine.pattern_detected',\n {\n patternType: params.patternType,\n agentIds: params.agentIds,\n confidence: params.confidence,\n details: params.details,\n },\n {\n ...(params.sessionId !== undefined && { sessionId: params.sessionId }),\n ...(params.correlationId !== undefined && { correlationId: params.correlationId }),\n }\n );\n eventBus.emit(event);\n}\n\n// =============================================================================\n// Agent Flagged Events\n// =============================================================================\n\n/** Parameters for emitting byzantine.agent_flagged event. */\nexport interface AgentFlaggedParams {\n readonly agentId: string;\n readonly reason: string;\n readonly previousWeight: number;\n readonly canVote: boolean;\n readonly sessionId?: string | undefined;\n readonly correlationId?: string | undefined;\n}\n\n/** Emits byzantine.agent_flagged event when an agent is flagged as Byzantine. */\nexport function emitAgentFlagged(eventBus: IEventBus, params: AgentFlaggedParams): void {\n const event = createEvent<ByzantineAgentFlaggedEvent>(\n 'byzantine.agent_flagged',\n {\n agentId: params.agentId,\n reason: params.reason,\n previousWeight: params.previousWeight,\n canVote: params.canVote,\n },\n {\n ...(params.sessionId !== undefined && { sessionId: params.sessionId }),\n ...(params.correlationId !== undefined && { correlationId: params.correlationId }),\n }\n );\n eventBus.emit(event);\n}\n\n// =============================================================================\n// Collusion Suspected Events\n// =============================================================================\n\n/** Parameters for emitting byzantine.collusion_suspected event. */\nexport interface CollusionSuspectedParams {\n readonly groupAgentIds: readonly string[];\n readonly groupSize: number;\n readonly votingBlock: number;\n readonly threshold: number;\n readonly sessionId?: string | undefined;\n readonly correlationId?: string | undefined;\n}\n\n/** Emits byzantine.collusion_suspected event when collusion pattern is suspected. */\nexport function emitCollusionSuspected(\n eventBus: IEventBus,\n params: CollusionSuspectedParams\n): void {\n const event = createEvent<ByzantineCollusionSuspectedEvent>(\n 'byzantine.collusion_suspected',\n {\n groupAgentIds: params.groupAgentIds,\n groupSize: params.groupSize,\n votingBlock: params.votingBlock,\n threshold: params.threshold,\n },\n {\n ...(params.sessionId !== undefined && { sessionId: params.sessionId }),\n ...(params.correlationId !== undefined && { correlationId: params.correlationId }),\n }\n );\n eventBus.emit(event);\n}\n","/**\n * nexus-agents/consensus - Weighted Byzantine Voting Helpers\n *\n * Pure helper functions extracted from WeightedVoting class.\n * These functions are stateless and operate on parameters only.\n *\n * @module consensus/weighted-voting-helpers\n * (Source: Issue #103, arXiv:2511.10400 - CP-WBFT)\n */\n\nimport { getTimeProvider } from '../core/index.js';\nimport { clamp01 } from '../utils/math-utils.js';\nimport type { WeightedAgentRecord, WeightedConsensusResult, Vote } from './types.js';\nimport type { IEventBus } from '../core/event-bus.js';\n\n/**\n * Mutable agent record for internal tracking.\n * Used internally by WeightedVoting class.\n */\nexport interface MutableAgentRecord {\n agentId: string;\n totalTasks: number;\n successfulTasks: number;\n failedTasks: number;\n partialTasks: number;\n successRate: number;\n weight: number;\n trustScore: number;\n byzantineFlags: number;\n byzantineReasons: string[];\n lastActive: Date;\n createdAt: Date;\n}\n\n/** Options for WeightedVoting constructor. */\nexport interface WeightedVotingOptions {\n /** Configuration for voting thresholds and weights. */\n config?: Partial<import('./types.js').WeightedVotingConfig>;\n /** Optional event bus for Byzantine detection events (Issue #218). */\n eventBus?: IEventBus;\n /** Whether to emit Byzantine detection events (default: true if eventBus provided). */\n emitEvents?: boolean;\n}\n\n/**\n * Check if a vote is a low-confidence contrarian vote.\n * Used for Byzantine pattern detection.\n */\nexport function isLowConfidenceContrarian(vote: Vote, majorityApprove: boolean): boolean {\n const isContrarian = majorityApprove ? vote.decision === 'reject' : vote.decision === 'approve';\n return isContrarian && vote.confidence < 0.3;\n}\n\n/**\n * Compute the majority vote direction based on weighted votes.\n * Returns true if majority approves, false if majority rejects.\n */\nexport function computeMajorityDirection(\n voteArray: ReadonlyArray<readonly [string, Vote]>,\n weights: ReadonlyMap<string, number>\n): boolean {\n let totalApprove = 0;\n let totalReject = 0;\n for (const [agentId, vote] of voteArray) {\n const w = weights.get(agentId) ?? 0;\n if (vote.decision === 'approve') totalApprove += w;\n if (vote.decision === 'reject') totalReject += w;\n }\n return totalApprove > totalReject;\n}\n\n/**\n * Determine consensus decision based on vote tallies.\n */\nexport function determineDecision(\n approval: number,\n rejection: number,\n total: number,\n quorumReached: boolean,\n quorumThreshold: number\n): WeightedConsensusResult['decision'] {\n if (!quorumReached || total === 0) return 'no_consensus';\n const approvalRatio = approval / total;\n const rejectionRatio = rejection / total;\n if (approvalRatio > rejectionRatio && approvalRatio >= quorumThreshold) return 'approve';\n if (rejectionRatio > approvalRatio && rejectionRatio >= quorumThreshold) return 'reject';\n return 'no_consensus';\n}\n\n/**\n * Update derived metrics (success rate, trust score) on a mutable record.\n */\nexport function updateDerivedMetrics(record: MutableAgentRecord): void {\n // Update success rate\n if (record.totalTasks > 0) {\n const weightedSuccess = record.successfulTasks + record.partialTasks * 0.5;\n record.successRate = weightedSuccess / record.totalTasks;\n }\n\n // Update trust score based on weight and Byzantine flags\n const byzantinePenalty = Math.pow(0.7, record.byzantineFlags);\n record.trustScore = Math.min(1, record.weight * byzantinePenalty);\n}\n\n/**\n * Convert a mutable internal record to an immutable public record.\n */\nexport function toImmutableRecord(record: MutableAgentRecord): WeightedAgentRecord {\n return {\n agentId: record.agentId,\n totalTasks: record.totalTasks,\n successfulTasks: record.successfulTasks,\n failedTasks: record.failedTasks,\n partialTasks: record.partialTasks,\n successRate: record.successRate,\n weight: record.weight,\n trustScore: record.trustScore,\n byzantineFlags: record.byzantineFlags,\n lastActive: record.lastActive,\n createdAt: record.createdAt,\n };\n}\n\n/**\n * Create a vote signature for collusion detection.\n * Combines decision and confidence into a unique key.\n */\nexport function createVoteSignature(vote: Vote): string {\n return `${vote.decision}:${vote.confidence.toFixed(2)}`;\n}\n\n/**\n * Group votes by their signature for collusion pattern detection.\n */\nexport function groupVotesBySignature(\n voteArray: ReadonlyArray<readonly [string, Vote]>\n): Map<string, string[]> {\n const signatures = new Map<string, string[]>();\n for (const [agentId, vote] of voteArray) {\n const sig = createVoteSignature(vote);\n const agents = signatures.get(sig) ?? [];\n agents.push(agentId);\n signatures.set(sig, agents);\n }\n return signatures;\n}\n\n/**\n * Create a new mutable agent record with initial values.\n */\nexport function createAgentRecord(agentId: string, initialWeight: number): MutableAgentRecord {\n const now = new Date(getTimeProvider().now());\n return {\n agentId,\n totalTasks: 0,\n successfulTasks: 0,\n failedTasks: 0,\n partialTasks: 0,\n successRate: 0,\n weight: initialWeight,\n trustScore: initialWeight,\n byzantineFlags: 0,\n byzantineReasons: [],\n lastActive: now,\n createdAt: now,\n };\n}\n\n/**\n * Compute global success statistics from all agent records.\n */\nexport function computeGlobalStats(records: Iterable<MutableAgentRecord>): {\n globalSuccessRate: number;\n totalTasks: number;\n} {\n let totalSuccess = 0;\n let totalTasks = 0;\n\n for (const record of records) {\n totalSuccess += record.successfulTasks;\n totalTasks += record.totalTasks;\n }\n\n const globalSuccessRate = totalTasks > 0 ? totalSuccess / totalTasks : 0.5;\n return { globalSuccessRate, totalTasks };\n}\n\n/**\n * Calculate calibrated weight based on relative performance.\n */\nexport function calculateCalibratedWeight(\n record: MutableAgentRecord,\n globalSuccessRate: number,\n initialWeight: number\n): number {\n const relativePerformance = record.successRate / Math.max(0.01, globalSuccessRate);\n const calibratedWeight = clamp01(initialWeight * relativePerformance);\n // Smooth transition (50% old weight, 50% calibrated)\n return (record.weight + calibratedWeight) / 2;\n}\n\n/**\n * Apply weight change based on task outcome.\n */\nexport function applyOutcomeWeight(\n currentWeight: number,\n outcome: import('./types.js').TaskOutcome,\n decayFactor: number,\n recoveryFactor: number\n): number {\n switch (outcome) {\n case 'success':\n return Math.min(1, currentWeight * recoveryFactor);\n case 'failure':\n return Math.max(0, currentWeight * decayFactor);\n case 'partial':\n return Math.max(0, currentWeight * ((decayFactor + 1) / 2));\n case 'unknown':\n return currentWeight;\n }\n}\n","/**\n * nexus-agents/consensus - Weighted Byzantine Voting Implementation\n *\n * Implements CP-WBFT (arXiv:2511.10400) for weighted Byzantine fault-tolerant voting.\n * Agent votes are weighted by historical reliability with automatic trust calibration.\n *\n * @module consensus/weighted-voting\n * (Source: Issue #103, arXiv:2511.10400 - CP-WBFT)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport { getTimeProvider } from '../core/index.js';\nimport type {\n IWeightedVoting,\n WeightedAgentRecord,\n WeightedConsensusResult,\n WeightedVotingConfig,\n TaskOutcome,\n Vote,\n} from './types.js';\nimport { DEFAULT_WEIGHTED_VOTING_CONFIG } from './types.js';\nimport type { IEventBus } from '../core/event-bus.js';\nimport {\n emitWeightUpdated,\n emitPatternDetected,\n emitAgentFlagged,\n emitCollusionSuspected,\n} from '../agents/collaboration/byzantine-events.js';\nimport {\n type MutableAgentRecord,\n type WeightedVotingOptions,\n isLowConfidenceContrarian,\n computeMajorityDirection,\n determineDecision,\n updateDerivedMetrics,\n toImmutableRecord,\n groupVotesBySignature,\n createAgentRecord,\n computeGlobalStats,\n calculateCalibratedWeight,\n applyOutcomeWeight,\n} from './weighted-voting-helpers.js';\n\nexport type { WeightedVotingOptions } from './weighted-voting-helpers.js';\n\nconst logger = createLogger({ component: 'weighted-voting' });\n\n/**\n * Weighted Byzantine voting implementation.\n * Implements CP-WBFT pattern for fault-tolerant multi-agent consensus.\n */\nexport class WeightedVoting implements IWeightedVoting {\n private readonly records: Map<string, MutableAgentRecord> = new Map();\n private readonly config: WeightedVotingConfig;\n private readonly eventBus: IEventBus | undefined;\n private readonly emitEvents: boolean;\n\n constructor(options: WeightedVotingOptions = {}) {\n this.config = { ...DEFAULT_WEIGHTED_VOTING_CONFIG, ...options.config };\n this.eventBus = options.eventBus ?? undefined;\n this.emitEvents = options.emitEvents ?? options.eventBus !== undefined;\n logger.info('WeightedVoting initialized', {\n config: this.config,\n eventsEnabled: this.emitEvents,\n });\n }\n\n calculateWeight(agentId: string): number {\n const record = this.records.get(agentId);\n if (record === undefined) return 0;\n return record.weight;\n }\n\n updatePerformance(agentId: string, outcome: TaskOutcome): void {\n let record = this.records.get(agentId);\n if (record === undefined) {\n this.registerAgent(agentId);\n record = this.records.get(agentId);\n if (record === undefined) return;\n }\n\n const previousWeight = record.weight;\n record.totalTasks += 1;\n record.lastActive = new Date(getTimeProvider().now());\n\n // Update task counts\n if (outcome === 'success') record.successfulTasks += 1;\n else if (outcome === 'failure') record.failedTasks += 1;\n else if (outcome === 'partial') record.partialTasks += 1;\n\n // Apply weight change\n record.weight = applyOutcomeWeight(\n record.weight,\n outcome,\n this.config.weightDecayFactor,\n this.config.weightRecoveryFactor\n );\n updateDerivedMetrics(record);\n this.emitWeightChange(agentId, previousWeight, record.weight, 'performance_update');\n\n logger.debug('Performance updated', {\n agentId,\n outcome,\n newWeight: record.weight,\n successRate: record.successRate,\n });\n }\n\n weightedConsensus(votes: ReadonlyMap<string, Vote>): WeightedConsensusResult {\n const { approval, rejection, total, agents, breakdown } = this.countVotes(votes);\n const byzantineDetected = this.detectByzantinePatterns(votes, breakdown);\n const quorumReached = total >= this.config.quorumThreshold;\n const decision = determineDecision(\n approval,\n rejection,\n total,\n quorumReached,\n this.config.quorumThreshold\n );\n\n const result: WeightedConsensusResult = {\n decision,\n weightedApproval: approval,\n weightedRejection: rejection,\n totalWeight: total,\n quorumReached,\n byzantineDetected,\n participatingAgents: agents,\n weightBreakdown: breakdown,\n };\n\n this.logConsensusResult(result);\n return result;\n }\n\n registerAgent(agentId: string): void {\n if (this.records.has(agentId)) {\n logger.debug('Agent already registered', { agentId });\n return;\n }\n const record = createAgentRecord(agentId, this.config.initialWeight);\n this.records.set(agentId, record);\n logger.info('Agent registered', { agentId, initialWeight: this.config.initialWeight });\n }\n\n getAgentRecord(agentId: string): WeightedAgentRecord | undefined {\n const record = this.records.get(agentId);\n if (record === undefined) return undefined;\n return toImmutableRecord(record);\n }\n\n flagByzantine(agentId: string, reason: string): void {\n const record = this.records.get(agentId);\n if (record === undefined) {\n logger.warn('Cannot flag unregistered agent', { agentId });\n return;\n }\n\n const previousWeight = record.weight;\n record.byzantineFlags += 1;\n record.byzantineReasons.push(reason);\n record.weight = Math.max(0, record.weight * 0.5);\n updateDerivedMetrics(record);\n\n const canStillVote = this.canVote(agentId);\n this.emitAgentFlaggedEvent(agentId, reason, previousWeight, canStillVote);\n this.emitWeightChange(agentId, previousWeight, record.weight, 'flag_penalty');\n\n logger.warn('Agent flagged for Byzantine behavior', {\n agentId,\n reason,\n totalFlags: record.byzantineFlags,\n newWeight: record.weight,\n });\n\n if (record.byzantineFlags >= this.config.byzantineFlagThreshold) {\n this.excludeAgent(record);\n }\n }\n\n getAllRecords(): readonly WeightedAgentRecord[] {\n return Array.from(this.records.values()).map((r) => toImmutableRecord(r));\n }\n\n canVote(agentId: string): boolean {\n const record = this.records.get(agentId);\n if (record === undefined) return false;\n return record.weight >= this.config.minWeight && record.trustScore >= this.config.minTrustScore;\n }\n\n recalibrateWeights(): void {\n const { globalSuccessRate, totalTasks } = computeGlobalStats(this.records.values());\n if (totalTasks === 0) return;\n\n for (const record of this.records.values()) {\n if (record.totalTasks < 3) continue;\n const previousWeight = record.weight;\n record.weight = calculateCalibratedWeight(\n record,\n globalSuccessRate,\n this.config.initialWeight\n );\n updateDerivedMetrics(record);\n this.emitWeightChange(record.agentId, previousWeight, record.weight, 'recalibration');\n }\n\n logger.info('Weights recalibrated', {\n agentCount: this.records.size,\n globalSuccessRate: globalSuccessRate.toFixed(3),\n });\n }\n\n // Private helpers\n\n private countVotes(votes: ReadonlyMap<string, Vote>): {\n approval: number;\n rejection: number;\n total: number;\n agents: string[];\n breakdown: Map<string, number>;\n } {\n let approval = 0;\n let rejection = 0;\n let total = 0;\n const agents: string[] = [];\n const breakdown = new Map<string, number>();\n\n for (const [agentId, vote] of votes) {\n if (!this.canVote(agentId)) {\n logger.warn('Agent cannot vote', { agentId, reason: 'insufficient weight or trust' });\n continue;\n }\n const weight = this.calculateWeight(agentId);\n breakdown.set(agentId, weight);\n agents.push(agentId);\n total += weight;\n const effectiveWeight = weight * vote.confidence;\n if (vote.decision === 'approve') approval += effectiveWeight;\n else if (vote.decision === 'reject') rejection += effectiveWeight;\n }\n return { approval, rejection, total, agents, breakdown };\n }\n\n private logConsensusResult(result: WeightedConsensusResult): void {\n logger.info('Weighted consensus calculated', {\n decision: result.decision,\n approval: result.weightedApproval.toFixed(3),\n rejection: result.weightedRejection.toFixed(3),\n totalWeight: result.totalWeight.toFixed(3),\n quorumReached: result.quorumReached,\n byzantineDetected: result.byzantineDetected,\n });\n }\n\n private emitWeightChange(\n agentId: string,\n prev: number,\n next: number,\n reason: 'performance_update' | 'flag_penalty' | 'recalibration'\n ): void {\n if (this.emitEvents && this.eventBus !== undefined && prev !== next) {\n emitWeightUpdated(this.eventBus, { agentId, previousWeight: prev, newWeight: next, reason });\n }\n }\n\n private emitAgentFlaggedEvent(\n agentId: string,\n reason: string,\n previousWeight: number,\n canVote: boolean\n ): void {\n if (this.emitEvents && this.eventBus !== undefined) {\n emitAgentFlagged(this.eventBus, { agentId, reason, previousWeight, canVote });\n }\n }\n\n private excludeAgent(record: MutableAgentRecord): void {\n const weightBefore = record.weight;\n record.trustScore = 0;\n record.weight = 0;\n this.emitWeightChange(record.agentId, weightBefore, 0, 'flag_penalty');\n logger.warn('Agent excluded from voting due to Byzantine behavior', {\n agentId: record.agentId,\n flags: record.byzantineFlags,\n });\n }\n\n private detectByzantinePatterns(\n votes: ReadonlyMap<string, Vote>,\n weights: Map<string, number>\n ): boolean {\n const voteArray = Array.from(votes.entries());\n if (voteArray.length < 3) return false;\n const majorityApprove = computeMajorityDirection(voteArray, weights);\n if (this.detectContrarianByzantine(voteArray, majorityApprove)) return true;\n return this.detectCollusionPattern(voteArray);\n }\n\n private detectContrarianByzantine(\n voteArray: Array<[string, Vote]>,\n majorityApprove: boolean\n ): boolean {\n const contrarianAgents: string[] = [];\n for (const [agentId, vote] of voteArray) {\n if (!isLowConfidenceContrarian(vote, majorityApprove)) continue;\n const record = this.records.get(agentId);\n if (record !== undefined && record.byzantineFlags >= 2) {\n contrarianAgents.push(agentId);\n }\n }\n if (contrarianAgents.length > 0) {\n this.emitContrarianPattern(contrarianAgents);\n return true;\n }\n return false;\n }\n\n private emitContrarianPattern(agents: string[]): void {\n if (this.emitEvents && this.eventBus !== undefined) {\n emitPatternDetected(this.eventBus, {\n patternType: 'contrarian',\n agentIds: agents,\n confidence: 0.8,\n details: `${String(agents.length)} agent(s) with Byzantine flags voting contrary to majority with low confidence`,\n });\n }\n }\n\n private detectCollusionPattern(voteArray: Array<[string, Vote]>): boolean {\n const voteSignatures = groupVotesBySignature(voteArray);\n const threshold = voteArray.length * 0.6;\n for (const [signature, agents] of voteSignatures.entries()) {\n if (agents.length >= 3 && agents.length > threshold) {\n this.emitCollusionEvents(agents, signature, voteArray.length);\n return true;\n }\n }\n return false;\n }\n\n private emitCollusionEvents(agents: string[], signature: string, totalVotes: number): void {\n if (this.emitEvents && this.eventBus !== undefined) {\n emitPatternDetected(this.eventBus, {\n patternType: 'collusion',\n agentIds: agents,\n confidence: Math.min(0.95, agents.length / totalVotes),\n details: `${String(agents.length)} agents voting identically: ${signature}`,\n });\n emitCollusionSuspected(this.eventBus, {\n groupAgentIds: agents,\n groupSize: agents.length,\n votingBlock: agents.length / totalVotes,\n threshold: 0.6,\n });\n }\n }\n}\n\n/** Create a weighted voting instance. */\nexport function createWeightedVoting(options?: WeightedVotingOptions): IWeightedVoting {\n return new WeightedVoting(options);\n}\n","/**\n * nexus-agents/consensus - Correlation Helpers\n *\n * Helper functions for correlation tracking and independent subset partitioning.\n * Extracted from correlation-tracker.ts to maintain file size limits.\n *\n * @module consensus/correlation-helpers\n * (Source: Issue #339)\n */\n\nimport type {\n CorrelationMatrix,\n CorrelationCoefficient,\n IndependentSubset,\n VotingObservation,\n HigherOrderVotingConfig,\n AgentPairKey,\n} from './higher-order-types.js';\nimport { createAgentPairKey } from './higher-order-types.js';\n\n// ============================================================================\n// Pairwise History Types\n// ============================================================================\n\n/**\n * Internal mutable representation of pairwise history.\n */\nexport interface MutablePairwiseHistory {\n pairKey: AgentPairKey;\n jointObservations: number;\n agreements: number;\n disagreements: number;\n correlation: CorrelationCoefficient;\n lastUpdated: Date;\n}\n\n// ============================================================================\n// Vote Agreement\n// ============================================================================\n\n/**\n * Check if two observations are comparable (neither is an abstain).\n * Abstain votes should be excluded from correlation tracking.\n *\n * @param obsA - First observation\n * @param obsB - Second observation\n * @returns True if both observations have non-abstain decisions\n */\nexport function isComparable(obsA: VotingObservation, obsB: VotingObservation): boolean {\n return obsA.decision !== 'abstain' && obsB.decision !== 'abstain';\n}\n\n/**\n * Check if two votes agree.\n * Only call this after verifying isComparable() returns true.\n * Abstains are treated as neutral - neither agree nor disagree.\n *\n * @param obsA - First observation\n * @param obsB - Second observation\n * @returns True if votes agree, null if either is an abstain (neutral)\n */\nexport function votesAgree(obsA: VotingObservation, obsB: VotingObservation): boolean | null {\n if (obsA.decision === 'abstain' || obsB.decision === 'abstain') {\n return null; // Neutral — skip this pair (Issue #763)\n }\n return obsA.decision === obsB.decision;\n}\n\n/**\n * Check if a decision aligned with the outcome.\n *\n * @param decision - The voting decision\n * @param outcome - The final outcome\n * @returns True if decision aligned with outcome\n */\nexport function didAlignWithOutcome(decision: string, outcome: 'approved' | 'rejected'): boolean {\n if (decision === 'abstain') return true;\n return (\n (decision === 'approve' && outcome === 'approved') ||\n (decision === 'reject' && outcome === 'rejected')\n );\n}\n\n// ============================================================================\n// Correlation Computation\n// ============================================================================\n\n/**\n * Compute correlation coefficient from pairwise history.\n *\n * Simple correlation: (agreements - disagreements) / total\n * Range: -1 (always disagree) to +1 (always agree)\n *\n * @param history - Pairwise history\n * @returns Correlation coefficient\n */\nexport function computeCorrelationCoefficient(\n history: MutablePairwiseHistory\n): CorrelationCoefficient {\n const n = history.jointObservations;\n if (n === 0) return 0;\n\n // Map agreement/disagreement rates to [-1, 1] correlation\n // 0.5 agreement rate = 0 correlation (random)\n // 1.0 agreement rate = +1 correlation (perfect agreement)\n // 0.0 agreement rate = -1 correlation (perfect disagreement)\n const agreementRate = history.agreements / n;\n const disagreementRate = history.disagreements / n;\n\n return agreementRate - disagreementRate;\n}\n\n// ============================================================================\n// Independent Subset Partitioning\n// ============================================================================\n\n/**\n * Check if an agent is independent from all members of a subset.\n *\n * @param agent - Agent to check\n * @param subset - Existing subset members\n * @param correlationMatrix - Correlation matrix\n * @param independenceThreshold - Maximum correlation for independence\n * @returns True if agent is independent from subset\n */\nexport function isIndependentFromSubset(\n agent: string,\n subset: readonly string[],\n correlationMatrix: CorrelationMatrix,\n independenceThreshold: number\n): boolean {\n for (const member of subset) {\n const pairKey = createAgentPairKey(agent, member);\n const correlation = correlationMatrix.get(pairKey);\n\n // If we don't have data, assume independent\n if (correlation === undefined) continue;\n\n // If correlation exceeds threshold, not independent\n if (Math.abs(correlation) > independenceThreshold) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Compute the average absolute correlation within a subset.\n *\n * @param subset - Agent IDs in the subset\n * @param correlationMatrix - Correlation matrix\n * @returns Average absolute correlation (0 if no pairs)\n */\nexport function computeSubsetIndependenceScore(\n subset: readonly string[],\n correlationMatrix: CorrelationMatrix\n): number {\n if (subset.length < 2) return 0;\n\n let totalCorrelation = 0;\n let pairs = 0;\n\n for (let i = 0; i < subset.length; i++) {\n for (let j = i + 1; j < subset.length; j++) {\n const agentA = subset[i];\n const agentB = subset[j];\n if (agentA !== undefined && agentB !== undefined) {\n const pairKey = createAgentPairKey(agentA, agentB);\n const correlation = correlationMatrix.get(pairKey);\n if (correlation !== undefined) {\n totalCorrelation += Math.abs(correlation);\n pairs++;\n }\n }\n }\n }\n\n return pairs > 0 ? totalCorrelation / pairs : 0;\n}\n\n/**\n * Compute the minimum observation count for pairs within a subset.\n *\n * @param subset - Agent IDs in the subset\n * @param pairwiseHistory - Map of pairwise histories\n * @returns Minimum observation count (0 if no history)\n */\nexport function computeSubsetObservationCount(\n subset: readonly string[],\n pairwiseHistory: ReadonlyMap<AgentPairKey, MutablePairwiseHistory>\n): number {\n let minObservations = Infinity;\n\n for (let i = 0; i < subset.length; i++) {\n for (let j = i + 1; j < subset.length; j++) {\n const agentA = subset[i];\n const agentB = subset[j];\n if (agentA !== undefined && agentB !== undefined) {\n const pairKey = createAgentPairKey(agentA, agentB);\n const history = pairwiseHistory.get(pairKey);\n if (history !== undefined) {\n minObservations = Math.min(minObservations, history.jointObservations);\n } else {\n minObservations = 0;\n }\n }\n }\n }\n\n return minObservations === Infinity ? 0 : minObservations;\n}\n\n/**\n * Partition agents into independent groups using greedy clustering.\n *\n * @param agents - List of agent IDs\n * @param correlationMatrix - Correlation matrix\n * @param pairwiseHistory - Map of pairwise histories\n * @param config - Higher-order voting configuration\n * @returns Array of independent subsets\n */\nexport function partitionIntoIndependentGroups(\n agents: readonly string[],\n correlationMatrix: CorrelationMatrix,\n pairwiseHistory: ReadonlyMap<AgentPairKey, MutablePairwiseHistory>,\n config: HigherOrderVotingConfig\n): IndependentSubset[] {\n if (agents.length === 0) return [];\n\n const subsets: IndependentSubset[] = [];\n const assigned = new Set<string>();\n let subsetId = 0;\n\n for (const agent of agents) {\n if (assigned.has(agent)) continue;\n\n const subset: string[] = [agent];\n assigned.add(agent);\n\n // Try to add other unassigned agents if they're independent\n for (const other of agents) {\n if (assigned.has(other)) continue;\n if (isIndependentFromSubset(other, subset, correlationMatrix, config.independenceThreshold)) {\n subset.push(other);\n assigned.add(other);\n }\n }\n\n const independenceScore = computeSubsetIndependenceScore(subset, correlationMatrix);\n const observationCount = computeSubsetObservationCount(subset, pairwiseHistory);\n\n subsets.push({\n id: `subset-${String(subsetId++)}`,\n agentIds: subset,\n independenceScore,\n observationCount,\n });\n }\n\n return subsets;\n}\n","/**\n * nexus-agents/consensus - Correlation Tracker\n *\n * Tracks voting history and computes pairwise correlations between agents.\n * Used by higher-order voting methods to account for agent dependencies.\n *\n * @module consensus/correlation-tracker\n * (Source: Issue #333)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\nimport type { Vote } from './types-core.js';\nimport type {\n ICorrelationTracker,\n CorrelationMatrix,\n CorrelationCoefficient,\n IndependentSubset,\n VotingObservation,\n HigherOrderVotingConfig,\n CorrelationTrackerStats,\n AgentPairKey,\n} from './higher-order-types.js';\nimport { createAgentPairKey, DEFAULT_HIGHER_ORDER_CONFIG } from './higher-order-types.js';\nimport {\n type MutablePairwiseHistory,\n isComparable,\n votesAgree,\n didAlignWithOutcome,\n computeCorrelationCoefficient,\n partitionIntoIndependentGroups,\n} from './correlation-helpers.js';\n\n// Re-export helper types and functions for convenience\nexport type { MutablePairwiseHistory } from './correlation-helpers.js';\nexport {\n isComparable,\n votesAgree,\n didAlignWithOutcome,\n computeCorrelationCoefficient,\n isIndependentFromSubset,\n computeSubsetIndependenceScore,\n computeSubsetObservationCount,\n partitionIntoIndependentGroups,\n} from './correlation-helpers.js';\n\nconst logger = createLogger({ component: 'correlation-tracker' });\n\n/**\n * Correlation tracker implementation.\n * Records voting history and computes pairwise agent correlations.\n *\n * Memory bounded: uses FIFO eviction when maxObservationsPerAgent or maxProposals limits reached.\n */\nexport class CorrelationTracker implements ICorrelationTracker {\n private readonly config: HigherOrderVotingConfig;\n private readonly observations: Map<string, VotingObservation[]> = new Map();\n private readonly pairwiseHistory: Map<AgentPairKey, MutablePairwiseHistory> = new Map();\n private readonly agentProposals: Map<string, Map<string, VotingObservation>> = new Map();\n /** Ordered list of proposal IDs for FIFO eviction */\n private readonly proposalOrder: string[] = [];\n private cachedSubsets: IndependentSubset[] | null = null;\n\n constructor(config?: Partial<HigherOrderVotingConfig>) {\n this.config = { ...DEFAULT_HIGHER_ORDER_CONFIG, ...config };\n logger.info('CorrelationTracker initialized', {\n maxObservationsPerAgent: this.config.maxObservationsPerAgent,\n maxProposals: this.config.maxProposals,\n });\n }\n\n recordVote(agentId: string, vote: Vote, outcome: 'approved' | 'rejected'): void {\n const proposalId = `proposal-${String(getTimeProvider().now())}-${getRandomProvider().random().toString(36).slice(2, 9)}`;\n const observation: VotingObservation = {\n proposalId,\n agentId,\n decision: vote.decision,\n confidence: vote.confidence,\n alignedWithOutcome: didAlignWithOutcome(vote.decision, outcome),\n timestamp: new Date(getTimeProvider().now()),\n };\n this.storeObservation(agentId, observation);\n this.invalidateCache();\n }\n\n recordProposalVotes(\n proposalId: string,\n votes: ReadonlyMap<string, Vote>,\n outcome: 'approved' | 'rejected'\n ): void {\n // FIFO eviction when proposal limit reached (Issue #521)\n this.evictOldProposalsIfNeeded();\n\n const proposalObservations: VotingObservation[] = [];\n\n for (const [agentId, vote] of votes) {\n const observation: VotingObservation = {\n proposalId,\n agentId,\n decision: vote.decision,\n confidence: vote.confidence,\n alignedWithOutcome: didAlignWithOutcome(vote.decision, outcome),\n timestamp: new Date(getTimeProvider().now()),\n };\n this.storeObservation(agentId, observation);\n this.storeAgentProposal(agentId, proposalId, observation);\n proposalObservations.push(observation);\n }\n\n // Track proposal order for FIFO eviction\n this.proposalOrder.push(proposalId);\n\n this.updatePairwiseCorrelations(proposalId, proposalObservations);\n this.invalidateCache();\n\n logger.debug('Recorded proposal votes', {\n proposalId,\n agentCount: votes.size,\n outcome,\n totalProposals: this.proposalOrder.length,\n });\n }\n\n computeCorrelationMatrix(): CorrelationMatrix {\n const matrix: CorrelationMatrix = new Map();\n\n for (const [pairKey, history] of this.pairwiseHistory) {\n if (history.jointObservations >= this.config.minObservationsForCorrelation) {\n matrix.set(pairKey, history.correlation);\n }\n }\n\n return matrix;\n }\n\n getCorrelation(agentA: string, agentB: string): CorrelationCoefficient | undefined {\n const pairKey = createAgentPairKey(agentA, agentB);\n const history = this.pairwiseHistory.get(pairKey);\n\n if (history === undefined) return undefined;\n if (history.jointObservations < this.config.minObservationsForCorrelation) return undefined;\n\n return history.correlation;\n }\n\n identifyIndependentSubsets(): readonly IndependentSubset[] {\n if (this.cachedSubsets !== null) return this.cachedSubsets;\n\n const agents = this.getTrackedAgents();\n if (agents.length === 0) {\n this.cachedSubsets = [];\n return this.cachedSubsets;\n }\n\n const correlationMatrix = this.computeCorrelationMatrix();\n const subsets = partitionIntoIndependentGroups(\n agents,\n correlationMatrix,\n this.pairwiseHistory,\n this.config\n );\n\n this.cachedSubsets = subsets;\n logger.debug('Identified independent subsets', {\n agentCount: agents.length,\n subsetCount: subsets.length,\n });\n\n return subsets;\n }\n\n hasSufficientData(agentIds: readonly string[]): boolean {\n if (agentIds.length < 2) return true;\n\n let pairsWithData = 0;\n const totalPairs = (agentIds.length * (agentIds.length - 1)) / 2;\n\n for (let i = 0; i < agentIds.length; i++) {\n for (let j = i + 1; j < agentIds.length; j++) {\n const agentA = agentIds[i];\n const agentB = agentIds[j];\n if (agentA !== undefined && agentB !== undefined) {\n const pairKey = createAgentPairKey(agentA, agentB);\n const history = this.pairwiseHistory.get(pairKey);\n if (\n history !== undefined &&\n history.jointObservations >= this.config.minObservationsForCorrelation\n ) {\n pairsWithData++;\n }\n }\n }\n }\n\n // Require at least 50% of pairs to have sufficient data\n return pairsWithData >= totalPairs * 0.5;\n }\n\n getStats(): CorrelationTrackerStats {\n const agents = this.getTrackedAgents();\n // Used by callers to understand full correlation state\n void this.computeCorrelationMatrix();\n const subsets = this.identifyIndependentSubsets();\n\n let totalCorrelation = 0;\n let pairsWithSufficientData = 0;\n\n for (const [, history] of this.pairwiseHistory) {\n if (history.jointObservations >= this.config.minObservationsForCorrelation) {\n totalCorrelation += history.correlation;\n pairsWithSufficientData++;\n }\n }\n\n let totalObservations = 0;\n for (const obs of this.observations.values()) {\n totalObservations += obs.length;\n }\n\n return {\n totalAgents: agents.length,\n trackedPairs: this.pairwiseHistory.size,\n totalObservations,\n averageCorrelation:\n pairsWithSufficientData > 0 ? totalCorrelation / pairsWithSufficientData : 0,\n independentSubsetCount: subsets.length,\n pairsWithSufficientData,\n };\n }\n\n clear(): void {\n this.observations.clear();\n this.pairwiseHistory.clear();\n this.agentProposals.clear();\n this.proposalOrder.length = 0;\n this.cachedSubsets = null;\n logger.info('CorrelationTracker cleared');\n }\n\n // ============================================================================\n // Private helpers\n // ============================================================================\n\n /**\n * Evict oldest proposals when maxProposals limit is reached.\n * Also cleans up agentProposals entries for evicted proposals.\n */\n private evictOldProposalsIfNeeded(): void {\n while (this.proposalOrder.length >= this.config.maxProposals) {\n const evictedProposalId = this.proposalOrder.shift();\n if (evictedProposalId === undefined) break;\n\n // Clean up agentProposals for the evicted proposal\n for (const [agentId, proposalMap] of this.agentProposals) {\n if (proposalMap.has(evictedProposalId)) {\n proposalMap.delete(evictedProposalId);\n // Clean up empty agent entries\n if (proposalMap.size === 0) {\n this.agentProposals.delete(agentId);\n }\n }\n }\n\n logger.debug('Evicted oldest proposal', {\n evictedProposalId,\n reason: 'maxProposals',\n remainingProposals: this.proposalOrder.length,\n });\n }\n }\n\n /**\n * Evict the oldest pairwise history entry (by lastUpdated) when\n * maxTrackedPairs limit is exceeded.\n */\n private evictOldestPair(): void {\n if (this.pairwiseHistory.size <= this.config.maxTrackedPairs) return;\n\n let oldestKey: AgentPairKey | undefined;\n let oldestTime = Infinity;\n for (const [key, history] of this.pairwiseHistory) {\n const time = history.lastUpdated.getTime();\n if (time < oldestTime) {\n oldestTime = time;\n oldestKey = key;\n }\n }\n if (oldestKey !== undefined) {\n this.pairwiseHistory.delete(oldestKey);\n logger.debug('Evicted oldest pairwise history entry', {\n evictedKey: oldestKey,\n reason: 'maxTrackedPairs',\n remainingPairs: this.pairwiseHistory.size,\n });\n }\n }\n\n private storeObservation(agentId: string, observation: VotingObservation): void {\n let agentObs = this.observations.get(agentId);\n if (agentObs === undefined) {\n agentObs = [];\n this.observations.set(agentId, agentObs);\n }\n\n // FIFO eviction when per-agent limit reached (Issue #521)\n while (agentObs.length >= this.config.maxObservationsPerAgent) {\n const evicted = agentObs.shift();\n if (evicted !== undefined) {\n logger.debug('Evicted oldest observation for agent', {\n agentId,\n evictedProposalId: evicted.proposalId,\n reason: 'maxObservationsPerAgent',\n });\n }\n }\n\n agentObs.push(observation);\n }\n\n private storeAgentProposal(\n agentId: string,\n proposalId: string,\n observation: VotingObservation\n ): void {\n let agentProposalMap = this.agentProposals.get(agentId);\n if (agentProposalMap === undefined) {\n agentProposalMap = new Map();\n this.agentProposals.set(agentId, agentProposalMap);\n }\n agentProposalMap.set(proposalId, observation);\n }\n\n private updatePairwiseCorrelations(proposalId: string, observations: VotingObservation[]): void {\n for (let i = 0; i < observations.length; i++) {\n for (let j = i + 1; j < observations.length; j++) {\n const obsA = observations[i];\n const obsB = observations[j];\n if (obsA === undefined || obsB === undefined) continue;\n\n const pairKey = createAgentPairKey(obsA.agentId, obsB.agentId);\n let history = this.pairwiseHistory.get(pairKey);\n\n if (history === undefined) {\n history = {\n pairKey,\n jointObservations: 0,\n agreements: 0,\n disagreements: 0,\n correlation: 0,\n lastUpdated: new Date(getTimeProvider().now()),\n };\n this.pairwiseHistory.set(pairKey, history);\n this.evictOldestPair();\n }\n\n // Skip abstain observations — they are neutral (Issue #763)\n if (!isComparable(obsA, obsB)) continue;\n\n history.jointObservations++;\n const agreed = votesAgree(obsA, obsB);\n if (agreed === true) {\n history.agreements++;\n } else {\n history.disagreements++;\n }\n\n history.correlation = computeCorrelationCoefficient(history);\n history.lastUpdated = new Date(getTimeProvider().now());\n }\n }\n }\n\n private getTrackedAgents(): string[] {\n return Array.from(this.observations.keys());\n }\n\n private invalidateCache(): void {\n this.cachedSubsets = null;\n }\n}\n\n/**\n * Creates a new correlation tracker instance.\n */\nexport function createCorrelationTracker(\n config?: Partial<HigherOrderVotingConfig>\n): ICorrelationTracker {\n return new CorrelationTracker(config);\n}\n","/**\n * nexus-agents/consensus - Correlation Persistence\n *\n * Disk persistence for CorrelationTracker voting history. Enables Higher-Order\n * Voting (HOV) to accumulate correlation data across process restarts,\n * activating Bayesian correlation awareness.\n *\n * Storage: append-only JSONL at `~/.nexus-agents/voting/correlations.jsonl`\n * (mode 0o600). Each line is one `PersistedProposal`. Append-only avoids the\n * cross-process read-merge-rename race the previous `correlations.json`\n * design had (#2973): two processes voting concurrently each loaded N\n * entries, each merged their own proposal, each renamed over the same file,\n * losing the loser's proposal. Append guarantees atomic-per-line writes on\n * POSIX so concurrent writers are race-free.\n *\n * Reads dedupe by `proposalId` (last write wins) and apply FIFO eviction\n * past `maxProposals`. A legacy `correlations.json` is read alongside the\n * JSONL on first load (its entries are surfaced like any other history) and\n * is removed by `compactCorrelationData()` after consolidation. New writes\n * always go to the JSONL.\n *\n * @module consensus/correlation-persistence\n * (Source: Issue #514; #2973 for the JSONL switch)\n */\n\nimport * as fs from 'node:fs';\nimport { nexusDataPath } from '../config/nexus-data-dir.js';\nimport { z } from 'zod';\nimport type { Result } from '../core/result.js';\nimport { ok, err } from '../core/result.js';\nimport type { ILogger } from '../core/logger.js';\nimport { createLogger } from '../core/logger.js';\nimport type { ICorrelationTracker, HigherOrderVotingConfig } from './higher-order-types.js';\nimport { DEFAULT_HIGHER_ORDER_CONFIG } from './higher-order-types.js';\nimport type { Vote } from './types-core.js';\nimport { createCorrelationTracker } from './correlation-tracker.js';\n\nconst logger: ILogger = createLogger({ component: 'correlation-persistence' });\n\n/** Subdirectory name under the resolved nexus data dir for voting data. */\nconst VOTING_SUBDIR = 'voting';\n\n/** Legacy single-JSON file (pre-#2973). Still read on load; never written. */\nconst CORRELATIONS_FILE = 'correlations.json';\n\n/** Active append-only JSONL store (#2973). */\nconst CORRELATIONS_JSONL_FILE = 'correlations.jsonl';\n\n/** File permissions: user read/write only */\nconst FILE_MODE = 0o600;\n\n/** Directory permissions: user read/write/execute only */\nconst DIR_MODE = 0o700;\n\n/** Schema version for forward compatibility. Bumped to 2 with the JSONL switch. */\nconst SCHEMA_VERSION = 2;\n\n// ============================================================================\n// Persisted Data Types\n// ============================================================================\n\n/**\n * A single persisted vote within a proposal.\n */\nconst PersistedVoteSchema = z.object({\n agentId: z.string(),\n decision: z.enum(['approve', 'reject', 'abstain']),\n confidence: z.number().min(0).max(1),\n});\n\n/** Type for a persisted vote entry */\ntype PersistedVote = z.infer<typeof PersistedVoteSchema>;\n\n/**\n * A persisted proposal with its votes and outcome.\n * Stored as a replayable record so internal tracker state\n * is reconstructed through the public API.\n */\nconst PersistedProposalSchema = z.object({\n proposalId: z.string(),\n votes: z.array(PersistedVoteSchema),\n outcome: z.enum(['approved', 'rejected']),\n timestamp: z.iso.datetime(),\n});\n\n/** Type for a persisted proposal entry */\ntype PersistedProposal = z.infer<typeof PersistedProposalSchema>;\n\n/**\n * Top-level persisted correlation data structure (legacy `correlations.json`).\n * Kept exported for back-compat — the JSONL format stores `PersistedProposal`\n * directly per line and has no wrapper.\n */\nexport const PersistedCorrelationDataSchema = z.object({\n version: z.number().int().positive(),\n proposals: z.array(PersistedProposalSchema),\n savedAt: z.iso.datetime(),\n});\n\n/** Validated persisted correlation data */\nexport type PersistedCorrelationData = z.infer<typeof PersistedCorrelationDataSchema>;\n\n// ============================================================================\n// Path Helpers\n// ============================================================================\n\n/**\n * Returns the absolute path to the **legacy** correlation data file. Kept\n * for back-compat — new writes go through `getCorrelationJsonlPath()`.\n */\nexport function getCorrelationDataPath(): string {\n return nexusDataPath(VOTING_SUBDIR, CORRELATIONS_FILE);\n}\n\n/** Returns the absolute path to the active JSONL store (#2973). */\nexport function getCorrelationJsonlPath(): string {\n return nexusDataPath(VOTING_SUBDIR, CORRELATIONS_JSONL_FILE);\n}\n\n/**\n * Ensures the voting data directory exists with appropriate permissions.\n */\nfunction ensureVotingDirectory(): Result<void, Error> {\n const dirPath = nexusDataPath(VOTING_SUBDIR);\n try {\n fs.mkdirSync(dirPath, { recursive: true, mode: DIR_MODE });\n return ok(undefined);\n } catch (cause: unknown) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n return err(new Error(`Failed to create voting directory at ${dirPath}: ${error.message}`));\n }\n}\n\n// ============================================================================\n// Save (append-only, race-free across processes)\n// ============================================================================\n\n/**\n * Appends new proposals to the JSONL store. One line per proposal.\n *\n * POSIX `O_APPEND` (used implicitly by `appendFileSync` with `{flag: 'a'}`)\n * guarantees atomic writes for buffer sizes under `PIPE_BUF` (4 KB on Linux,\n * 512 B on macOS). Each line we write is a single `PersistedProposal` — well\n * under those limits in practice for the typical vote-panel size (3–7 voters).\n * Two processes calling this concurrently get all proposals persisted; no\n * read-merge-rename race possible because we never read or rename.\n *\n * @param proposals - Array of proposals with their votes and outcomes to persist\n * @param config - Higher-order voting config (only `maxProposals` is consulted\n * on read; this writer is fully append-only)\n * @returns Result indicating success or failure\n */\nexport function saveCorrelationData(\n proposals: PersistedProposal[],\n // config kept in the signature for ABI compatibility with the legacy\n // implementation; the JSONL writer is append-only so we don't need it here.\n // FIFO truncation happens on read.\n _config: HigherOrderVotingConfig = DEFAULT_HIGHER_ORDER_CONFIG\n): Result<void, Error> {\n const dirResult = ensureVotingDirectory();\n if (!dirResult.ok) return dirResult;\n\n if (proposals.length === 0) return ok(undefined);\n\n const filePath = getCorrelationJsonlPath();\n\n try {\n const lines = proposals.map((p) => JSON.stringify(p)).join('\\n') + '\\n';\n fs.appendFileSync(filePath, lines, { encoding: 'utf-8', mode: FILE_MODE });\n\n logger.info('Correlation proposals appended', {\n path: filePath,\n proposalCount: proposals.length,\n });\n\n return ok(undefined);\n } catch (cause: unknown) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n return err(new Error(`Failed to append correlation data: ${error.message}`));\n }\n}\n\n// ============================================================================\n// Load (consolidates JSONL + legacy JSON, dedupes by proposalId, FIFO-truncates)\n// ============================================================================\n\n/** Read the legacy `correlations.json` if present; return [] otherwise. */\nfunction loadLegacyJsonProposals(): PersistedProposal[] {\n const filePath = getCorrelationDataPath();\n if (!fs.existsSync(filePath)) return [];\n\n let rawContent: string;\n try {\n rawContent = fs.readFileSync(filePath, { encoding: 'utf-8' });\n } catch (cause: unknown) {\n logger.warn('Failed to read legacy correlations.json', {\n path: filePath,\n error: cause instanceof Error ? cause.message : String(cause),\n });\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawContent);\n } catch (cause: unknown) {\n logger.warn('Corrupt legacy correlations.json — skipping', {\n path: filePath,\n error: cause instanceof Error ? cause.message : String(cause),\n });\n return [];\n }\n\n const result = PersistedCorrelationDataSchema.safeParse(parsed);\n if (!result.success) {\n logger.warn('Invalid legacy correlations.json schema — skipping', {\n path: filePath,\n error: result.error.message,\n });\n return [];\n }\n return result.data.proposals;\n}\n\ntype LineResult = { kind: 'ok'; proposal: PersistedProposal } | { kind: 'skip'; reason: string };\n\n/** Parse one JSONL line into a typed result so the loader can stay below max-complexity. */\nfunction parseJsonlLine(line: string): LineResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch (cause: unknown) {\n return {\n kind: 'skip',\n reason: `JSON.parse: ${cause instanceof Error ? cause.message : String(cause)}`,\n };\n }\n const result = PersistedProposalSchema.safeParse(parsed);\n if (!result.success) return { kind: 'skip', reason: `schema: ${result.error.message}` };\n return { kind: 'ok', proposal: result.data };\n}\n\n/** Read JSONL store, dropping malformed lines with a warn log. */\nfunction loadJsonlProposals(): PersistedProposal[] {\n const filePath = getCorrelationJsonlPath();\n if (!fs.existsSync(filePath)) return [];\n\n let content: string;\n try {\n content = fs.readFileSync(filePath, { encoding: 'utf-8' });\n } catch (cause: unknown) {\n logger.warn('Failed to read correlations.jsonl', {\n path: filePath,\n error: cause instanceof Error ? cause.message : String(cause),\n });\n return [];\n }\n\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n const proposals: PersistedProposal[] = [];\n let skippedCount = 0;\n let firstSkipReason: string | undefined;\n\n for (const line of lines) {\n const result = parseJsonlLine(line);\n if (result.kind === 'ok') {\n proposals.push(result.proposal);\n } else {\n skippedCount++;\n firstSkipReason ??= result.reason;\n }\n }\n\n if (skippedCount > 0) {\n logger.warn('Skipped malformed lines in correlations.jsonl', {\n path: filePath,\n skippedCount,\n totalLines: lines.length,\n firstSkipReason,\n });\n }\n\n return proposals;\n}\n\n/**\n * Combines proposals from both stores, dedupes by proposalId (later wins),\n * sorts by timestamp ascending, and FIFO-truncates to `maxProposals`.\n */\nfunction consolidate(\n legacyProposals: PersistedProposal[],\n jsonlProposals: PersistedProposal[],\n maxProposals: number\n): PersistedProposal[] {\n const proposalMap = new Map<string, PersistedProposal>();\n // Legacy first, then JSONL — JSONL entries override legacy if same id.\n for (const p of legacyProposals) proposalMap.set(p.proposalId, p);\n for (const p of jsonlProposals) proposalMap.set(p.proposalId, p);\n\n const all = Array.from(proposalMap.values()).sort((a, b) =>\n a.timestamp.localeCompare(b.timestamp)\n );\n return all.length > maxProposals ? all.slice(all.length - maxProposals) : all;\n}\n\n/**\n * Loads and validates correlation data from disk. Combines the JSONL store\n * with the legacy `correlations.json` (if present). Always returns an Ok\n * result when the directory exists; an empty proposals array means \"no\n * persisted history\" (formerly the \"not found\" error case).\n */\nexport function loadCorrelationData(\n config: HigherOrderVotingConfig = DEFAULT_HIGHER_ORDER_CONFIG\n): Result<PersistedCorrelationData, Error> {\n const jsonlPath = getCorrelationJsonlPath();\n const legacyPath = getCorrelationDataPath();\n const jsonlExists = fs.existsSync(jsonlPath);\n const legacyExists = fs.existsSync(legacyPath);\n\n if (!jsonlExists && !legacyExists) {\n return err(new Error(`Correlation data file not found: ${jsonlPath}`));\n }\n\n const legacy = loadLegacyJsonProposals();\n const jsonl = loadJsonlProposals();\n const proposals = consolidate(legacy, jsonl, config.maxProposals);\n\n logger.info('Correlation data loaded', {\n legacyCount: legacy.length,\n jsonlCount: jsonl.length,\n afterDedup: proposals.length,\n });\n\n return ok({\n version: SCHEMA_VERSION,\n proposals,\n savedAt: new Date().toISOString(),\n });\n}\n\n// ============================================================================\n// Compaction (consolidate JSONL + delete legacy json)\n// ============================================================================\n\n/**\n * Rewrites the JSONL store as a deduplicated, sorted snapshot and removes\n * the legacy `correlations.json` (if present). Safe to call periodically\n * (e.g., on session shutdown) to bound the JSONL's size.\n *\n * Within-process: this is the only operation that's NOT race-free across\n * processes. Two processes both running compaction simultaneously could\n * lose appends made between the read and the rename. Callers should\n * serialize compaction — invoke from one process per data dir, or guard\n * with a lockfile.\n */\nexport function compactCorrelationData(\n config: HigherOrderVotingConfig = DEFAULT_HIGHER_ORDER_CONFIG\n): Result<{ before: number; after: number }, Error> {\n const dirResult = ensureVotingDirectory();\n if (!dirResult.ok) return dirResult;\n\n const legacy = loadLegacyJsonProposals();\n const jsonl = loadJsonlProposals();\n const proposals = consolidate(legacy, jsonl, config.maxProposals);\n const before = legacy.length + jsonl.length;\n\n const jsonlPath = getCorrelationJsonlPath();\n const tempPath = `${jsonlPath}.tmp.${String(process.pid)}`;\n const body =\n proposals.map((p) => JSON.stringify(p)).join('\\n') + (proposals.length > 0 ? '\\n' : '');\n\n try {\n fs.writeFileSync(tempPath, body, { encoding: 'utf-8', mode: FILE_MODE });\n fs.renameSync(tempPath, jsonlPath);\n if (fs.existsSync(getCorrelationDataPath())) {\n fs.unlinkSync(getCorrelationDataPath());\n }\n return ok({ before, after: proposals.length });\n } catch (cause: unknown) {\n try {\n if (fs.existsSync(tempPath)) fs.unlinkSync(tempPath);\n } catch (cleanupErr: unknown) {\n logger.debug('Failed to clean up temp file during compaction', {\n path: tempPath,\n error: cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr),\n });\n }\n const error = cause instanceof Error ? cause : new Error(String(cause));\n return err(new Error(`Failed to compact correlation data: ${error.message}`));\n }\n}\n\n// ============================================================================\n// Persistent Tracker Factory\n// ============================================================================\n\n/**\n * Replays persisted proposals into a tracker via `recordProposalVotes()`,\n * reconstructing all internal state through the public API.\n */\nfunction replayProposals(\n tracker: ICorrelationTracker,\n proposals: readonly PersistedProposal[]\n): number {\n let replayed = 0;\n\n for (const proposal of proposals) {\n const votes = new Map<string, Vote>();\n\n for (const vote of proposal.votes) {\n votes.set(vote.agentId, {\n decision: vote.decision,\n reasoning: 'replayed from persistence',\n confidence: vote.confidence,\n });\n }\n\n tracker.recordProposalVotes(proposal.proposalId, votes, proposal.outcome);\n replayed++;\n }\n\n return replayed;\n}\n\n/**\n * Creates a correlation tracker pre-loaded with persisted history.\n *\n * On first run (no persisted data), returns a fresh tracker.\n * On subsequent runs, replays all stored proposals through the\n * tracker's public API to reconstruct correlation state.\n *\n * This enables Higher-Order Voting to accumulate enough history\n * across process restarts to activate Bayesian correlation awareness.\n *\n * @param config - Optional partial higher-order voting config\n * @returns A correlation tracker with any persisted history replayed\n */\nexport function createPersistentCorrelationTracker(\n config?: Partial<HigherOrderVotingConfig>\n): ICorrelationTracker {\n const tracker = createCorrelationTracker(config);\n\n const mergedConfig = { ...DEFAULT_HIGHER_ORDER_CONFIG, ...config };\n const loadResult = loadCorrelationData(mergedConfig);\n if (!loadResult.ok) {\n logger.info('Starting with fresh correlation tracker', {\n reason: loadResult.error.message,\n });\n return tracker;\n }\n\n const replayedCount = replayProposals(tracker, loadResult.value.proposals);\n\n logger.info('Correlation tracker restored from persistence', {\n replayedProposals: replayedCount,\n stats: tracker.getStats(),\n });\n\n return tracker;\n}\n\n// ============================================================================\n// Proposal Recording Helper\n// ============================================================================\n\n/**\n * Creates a persistable proposal record from vote data.\n *\n * Use this to build proposals that can be passed to `saveCorrelationData()`.\n *\n * @param proposalId - Unique proposal identifier\n * @param votes - Map of agent IDs to their votes\n * @param outcome - Final proposal outcome\n * @returns A persistable proposal record\n */\nexport function createPersistedProposal(\n proposalId: string,\n votes: ReadonlyMap<string, Vote>,\n outcome: 'approved' | 'rejected'\n): PersistedProposal {\n const persistedVotes: PersistedVote[] = [];\n\n for (const [agentId, vote] of votes) {\n persistedVotes.push({\n agentId,\n decision: vote.decision,\n confidence: vote.confidence,\n });\n }\n\n return {\n proposalId,\n votes: persistedVotes,\n outcome,\n timestamp: new Date().toISOString(),\n };\n}\n","/**\n * Types, schemas, and response helpers for the consensus_vote MCP tool.\n * Extracted from consensus-vote.ts for file size compliance (Issue #708).\n *\n * @module mcp/tools/consensus-vote-types\n */\n\nimport { z } from 'zod';\nimport type { AgentVoteResult, VotingResult } from '../../cli/vote-types.js';\nimport { VOTER_ROLES } from '../../cli/vote-types.js';\nimport type { HigherOrderVotingResult } from '../../consensus/higher-order-types.js';\n\n/** Maximum proposal length (memory bounds per Issue #435). */\nexport const MAX_PROPOSAL_LENGTH = 4000;\n\n// ============================================================================\n// Strategy Types\n// ============================================================================\n\n/**\n * Available consensus voting strategies.\n *\n * - `simple_majority`: Standard majority voting (>50%)\n * - `supermajority`: Requires >=67% approval\n * - `unanimous`: Requires 100% approval\n * - `proof_of_learning`: Weighted by agent performance (Issue #103)\n * - `higher_order`: Bayesian-optimal with correlation awareness (Issue #514)\n * - `opinion_wise`: Alias for higher_order (Issue #333)\n */\nexport type VotingStrategy =\n | 'simple_majority'\n | 'supermajority'\n | 'unanimous'\n | 'proof_of_learning'\n | 'higher_order'\n | 'opinion_wise';\n\nexport const VotingStrategySchema = z.enum([\n 'simple_majority',\n 'supermajority',\n 'unanimous',\n 'proof_of_learning',\n 'higher_order',\n 'opinion_wise',\n]);\n\n// ============================================================================\n// Input / Output Schemas\n// ============================================================================\n\n/**\n * How error-source votes (timed-out or crashed voters) are counted toward\n * the threshold (#2630).\n *\n * - `reduce_denominator` (default for non-strict strategies): errors are\n * filtered out before the engine sees votes — denominator = non-error\n * votes. Best for operational decisions where you trust the responding\n * voters and infrastructure flake should not block the vote.\n * - `count_as_abstain`: error votes reach the engine as abstain. Behaves\n * conservatively — a timed-out voter effectively withholds approval\n * relative to the threshold. Use when you can't tell what the error\n * voter would have decided and want the math to reflect uncertainty.\n * - `fail_closed` (default for unanimous / higher_order): any error voids\n * the vote. Threshold math is not run. Use for security-critical or\n * breaking-change decisions where every voter must be heard.\n *\n * Regardless of policy, a hard floor applies: when errors exceed 50% of\n * total voters, the vote always fails. Catches \"all CLIs are down\" — a\n * 2-voter consensus is not a real consensus.\n */\nexport const ErrorPolicySchema = z.enum(['reduce_denominator', 'count_as_abstain', 'fail_closed']);\n\nexport type ErrorPolicy = z.infer<typeof ErrorPolicySchema>;\n\n/**\n * Threshold values accepted by the `--threshold` CLI flag and the\n * \\`threshold\\` MCP input field (#2638 — single source of truth).\n *\n * Maps to consensus algorithms via:\n * `majority → simple_majority`, `supermajority → supermajority`, `unanimous → unanimous`.\n *\n * Used as the canonical Zod schema for CLI parsing\n * (`cli.ts:parseThreshold`), validation (`cli-commands-validators.ts:isValidThreshold`),\n * and the `ConsensusVoteInputSchema.threshold` field.\n */\nexport const VoteThresholdSchema = z.enum(['majority', 'supermajority', 'unanimous']);\n\nexport type VoteThreshold = z.infer<typeof VoteThresholdSchema>;\n\n/**\n * Fraction of total voters that, if errored, forces the vote to fail\n * regardless of `errorPolicy`. (#2630 — safety floor.)\n */\nexport const ERROR_FLOOR_FRACTION = 0.5;\n\n/**\n * Default error policy per voting strategy. Strict strategies (unanimous,\n * higher_order) default to `fail_closed`; others default to\n * `reduce_denominator`. Callers can override with the `errorPolicy` input\n * field.\n */\nexport function getDefaultErrorPolicy(strategy: VotingStrategy): ErrorPolicy {\n if (strategy === 'unanimous' || strategy === 'higher_order') return 'fail_closed';\n return 'reduce_denominator';\n}\n\nexport const ConsensusVoteInputSchema = z.object({\n proposal: z.string().min(1).max(MAX_PROPOSAL_LENGTH).describe('Proposal text to vote on'),\n threshold: VoteThresholdSchema.optional().describe(\n 'Voting threshold (legacy): majority, supermajority, unanimous. Use strategy instead.'\n ),\n strategy: VotingStrategySchema.optional().describe(\n 'Voting strategy: simple_majority (default), supermajority, unanimous, proof_of_learning, or higher_order (Bayesian-optimal)'\n ),\n errorPolicy: ErrorPolicySchema.optional().describe(\n 'How to treat voters that errored or timed out (#2630). Default: fail_closed for unanimous/higher_order, reduce_denominator otherwise. Regardless of policy, errors > 50% always fails.'\n ),\n quickMode: z\n .boolean()\n .optional()\n .default(false)\n .describe('Use 3 agents instead of 5 for faster execution'),\n simulateVotes: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'TESTS ONLY — when true, voters return random decisions. Output must not be used for real decisions. (#2319)'\n ),\n});\n\nexport type ConsensusVoteInput = z.infer<typeof ConsensusVoteInputSchema>;\n\n// ============================================================================\n// Response Types\n// ============================================================================\n\nexport interface AgentVoteSummary {\n role: string;\n decision: 'approve' | 'reject' | 'abstain';\n confidence: number;\n reasoning: string;\n simulated: boolean;\n /** True when this vote was generated from an error (Issue #815). */\n error: boolean;\n /** Model used for this agent's vote (Issue #817). */\n modelUsed?: string;\n /** Structured rejection categories for reject→refine→re-vote loops (Issue #1213). */\n rejectionCategories?: readonly string[];\n}\n\nexport type VoteDecisionStatus = 'approved' | 'rejected' | 'pending' | 'timeout' | 'no_quorum';\n\n/** Higher-Order Voting metadata (Issue #514). */\nexport interface HigherOrderMetadata {\n posteriorApproval: number;\n posteriorRejection: number;\n effectiveVoteCount: number;\n method: 'ow' | 'isp' | 'simple';\n usedCorrelationData: boolean;\n improvementOverBaseline: number;\n downweightedAgents: readonly string[];\n reasoning: string;\n}\n\nexport interface ConsensusVoteResponse {\n proposal: string;\n threshold?: VoteThreshold;\n strategy: VotingStrategy;\n decision: VoteDecisionStatus;\n approvalPercentage: number;\n voteCounts: { approve: number; reject: number; abstain: number; error: number };\n votes: AgentVoteSummary[];\n durationMs: number;\n simulateVotes: boolean;\n higherOrderMetadata?: HigherOrderMetadata;\n}\n\n/** Extended voting result with optional Higher-Order metadata. */\nexport interface ExtendedVotingResult extends VotingResult {\n strategy: VotingStrategy;\n higherOrderResult?: HigherOrderVotingResult;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Converts AgentVoteResult to AgentVoteSummary for response. */\nexport function toAgentVoteSummary(result: AgentVoteResult): AgentVoteSummary {\n const roleName = VOTER_ROLES[result.role].split(' - ')[0] ?? result.role;\n return {\n role: roleName,\n decision: result.vote.decision,\n confidence: result.vote.confidence,\n reasoning: result.vote.reasoning,\n simulated: result.source === 'simulation',\n error: result.source === 'error',\n ...(result.vote.rejectionCategories !== undefined\n ? { rejectionCategories: result.vote.rejectionCategories }\n : {}),\n };\n}\n\n/** Maps ProposalStatus to VoteDecisionStatus. */\nexport function mapOutcomeToDecision(outcome: string): VoteDecisionStatus {\n switch (outcome) {\n case 'approved':\n return 'approved';\n case 'rejected':\n return 'rejected';\n case 'timeout':\n return 'timeout';\n default:\n return 'pending';\n }\n}\n\n/** Builds the response from voting result. */\nexport function buildResponse(\n input: ConsensusVoteInput,\n result: ExtendedVotingResult\n): ConsensusVoteResponse {\n const proposalTruncated =\n input.proposal.length > 200 ? input.proposal.slice(0, 200) + '...' : input.proposal;\n\n const errorCount = result.votes.filter((v) => v.source === 'error').length;\n\n const allErrors = errorCount === result.votes.length && errorCount > 0;\n const decision: VoteDecisionStatus =\n !result.result.quorumReached && allErrors\n ? 'no_quorum'\n : mapOutcomeToDecision(result.result.outcome);\n\n const response: ConsensusVoteResponse = {\n proposal: proposalTruncated,\n strategy: result.strategy,\n decision,\n approvalPercentage: result.result.approvalPercentage,\n voteCounts: {\n approve: result.result.voteCounts.approve,\n reject: result.result.voteCounts.reject,\n abstain: result.result.voteCounts.abstain,\n error: errorCount,\n },\n votes: result.votes.map(toAgentVoteSummary),\n durationMs: result.totalTimeMs,\n simulateVotes: result.simulateVotes,\n };\n\n if (input.threshold !== undefined) {\n response.threshold = input.threshold;\n }\n\n if (result.strategy === 'higher_order' && result.higherOrderResult) {\n response.higherOrderMetadata = {\n posteriorApproval: result.higherOrderResult.posteriorApproval,\n posteriorRejection: result.higherOrderResult.posteriorRejection,\n effectiveVoteCount: result.higherOrderResult.effectiveVoteCount,\n method: result.higherOrderResult.method,\n usedCorrelationData: result.higherOrderResult.usedCorrelationData,\n improvementOverBaseline: result.higherOrderResult.improvementOverBaseline,\n downweightedAgents: result.higherOrderResult.downweightedAgents,\n reasoning: result.higherOrderResult.reasoning,\n };\n }\n\n return response;\n}\n","/**\n * Error-policy handling for consensus_vote (#2630).\n *\n * When a voter errors or times out (`source === 'error'`), the response\n * shape already distinguishes it via `voteCounts.error` (see\n * consensus-vote-types.ts:188). What was missing: a configurable\n * decision policy for how those error voters interact with the strategy\n * threshold, plus a safety floor for \"too many errors to call a\n * consensus.\"\n *\n * Three policies, plus a hard floor:\n *\n * - `reduce_denominator` (default for non-strict strategies): errors\n * filtered out before the engine sees votes. Denominator = non-error\n * votes. Pragmatic for operational decisions.\n * - `count_as_abstain`: errors reach the engine as abstain. Conservative\n * — error voter is treated as having withheld approval.\n * - `fail_closed` (default for unanimous / higher_order): any error\n * short-circuits to vote-void.\n *\n * Hard floor: if errors > `ERROR_FLOOR_FRACTION` of total voters, the\n * vote always fails regardless of policy. \"All CLIs are down\" is not a\n * consensus.\n *\n * @module mcp/tools/consensus-vote-error-policy\n */\n\nimport type { AgentVoteResult } from '../../cli/vote-types.js';\nimport type { ErrorPolicy } from './consensus-vote-types.js';\nimport { ERROR_FLOOR_FRACTION } from './consensus-vote-types.js';\n\nexport interface ErrorPolicyDecision {\n /** True when the vote should short-circuit to failed without reaching the engine. */\n readonly shortCircuit: boolean;\n /** Human-readable reason when shortCircuit is true. */\n readonly reason?: string;\n /**\n * Votes to feed to the engine. Empty when shortCircuit is true.\n * Otherwise: errors filtered out (`reduce_denominator`) or converted\n * to abstain (`count_as_abstain`).\n */\n readonly engineVotes: readonly AgentVoteResult[];\n}\n\nfunction isHardFloorTripped(errorCount: number, totalCount: number): boolean {\n if (totalCount === 0) return false;\n return errorCount / totalCount > ERROR_FLOOR_FRACTION;\n}\n\n/**\n * Apply the configured error policy to the raw voter list. Returns a\n * decision describing whether the vote should short-circuit and what\n * votes (if any) should reach the consensus engine.\n *\n * The hard floor (`errors / total > ERROR_FLOOR_FRACTION`) takes\n * precedence over any policy — even `reduce_denominator` short-circuits\n * when most voters errored, because the remaining minority isn't a real\n * consensus.\n *\n * The per-voter response list is built from the ORIGINAL `votes` array\n * upstream; this helper only shapes what the engine sees.\n */\nexport function applyErrorPolicy(\n votes: readonly AgentVoteResult[],\n policy: ErrorPolicy\n): ErrorPolicyDecision {\n const errorVotes = votes.filter((v) => v.source === 'error');\n const errorCount = errorVotes.length;\n const totalCount = votes.length;\n\n if (isHardFloorTripped(errorCount, totalCount)) {\n return {\n shortCircuit: true,\n reason: `Errors exceeded ${String(Math.round(ERROR_FLOOR_FRACTION * 100))}% of voters (${String(errorCount)}/${String(totalCount)})`,\n engineVotes: [],\n };\n }\n\n if (policy === 'fail_closed' && errorCount > 0) {\n return {\n shortCircuit: true,\n reason: `fail_closed: ${String(errorCount)} voter(s) errored`,\n engineVotes: [],\n };\n }\n\n if (policy === 'count_as_abstain') {\n // Errors stay in the engine input but as abstain decisions.\n // The original `source: 'error'` is preserved so the per-voter\n // response shape and `voteCounts.error` still report the error.\n return {\n shortCircuit: false,\n engineVotes: votes.map((v) =>\n v.source === 'error' ? { ...v, vote: { ...v.vote, decision: 'abstain' as const } } : v\n ),\n };\n }\n\n // reduce_denominator (default): errors filtered out before engine sees them.\n return {\n shortCircuit: false,\n engineVotes: votes.filter((v) => v.source !== 'error'),\n };\n}\n","/**\n * Persistent OutcomeStore — JSONL-backed cross-session persistence.\n *\n * Extends the in-memory OutcomeStore with disk-backed append-only\n * JSONL storage. Hydrates on construction, appends on every write.\n * Corrupt lines are skipped with a warning (graceful degradation).\n *\n * @module orchestration/outcomes/outcome-store-persistence\n * (Source: Issue #1009 — Cross-session persistence)\n */\n\nimport { appendFileSync, readFileSync, writeFileSync, existsSync } from 'node:fs';\n\nimport type { ILogger } from '../../core/index.js';\nimport { createLogger, getErrorMessage } from '../../core/index.js';\nimport { TaskOutcomeSchema } from './outcome-types.js';\nimport type { TaskOutcome } from './outcome-types.js';\nimport { OutcomeStore, registerPersistentOutcomeStoreFactory } from './outcome-store.js';\nimport type { OutcomeStoreConfig } from './outcome-store.js';\nimport { ensureLearningDir, getOutcomesFile } from '../../config/learning-persistence.js';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nexport interface PersistentOutcomeStoreConfig extends OutcomeStoreConfig {\n /** Override the file path (useful for testing). */\n readonly filePath?: string;\n /** Override the data directory (useful for testing). */\n readonly dataDir?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * OutcomeStore that persists entries to a JSONL file on disk.\n *\n * - Construction: hydrates from existing JSONL file (Zod-validates each line)\n * - Append: calls super.append() then appendFileSync one JSON line\n * - Corruption: bad lines are skipped with a warning log\n */\nexport class PersistentOutcomeStore extends OutcomeStore {\n private readonly filePath: string;\n private readonly logger: ILogger;\n\n constructor(config?: PersistentOutcomeStoreConfig, logger?: ILogger) {\n super(config);\n this.filePath = config?.filePath ?? getOutcomesFile();\n this.logger = logger ?? createLogger({ component: 'PersistentOutcomeStore' });\n\n const dataDir = config?.dataDir;\n ensureLearningDir(dataDir);\n this.hydrate();\n this.reclassifyHydrated();\n this.purgeSkippedOnHydrate();\n }\n\n /** Override append to persist each entry to disk. */\n override append(outcome: TaskOutcome): void {\n super.append(outcome);\n this.persistLine(outcome);\n }\n\n // ==========================================================================\n // Private\n // ==========================================================================\n\n /**\n * Reclassify hydrated entries that lack a failureCategory.\n * Bounded: reclassifyAll() skips success outcomes and already-classified\n * entries, so only unclassified failures are processed (#1457).\n */\n /**\n * Purge false failures from skipped workers on hydration (#1528).\n * These are 0ms non-success worker-* entries created before the\n * recording fix, representing routing decisions not real failures.\n */\n private purgeSkippedOnHydrate(): void {\n if (this.size === 0) return;\n const purged = this.purgeSkippedWorkers();\n if (purged > 0) {\n this.logger.info('Purged skipped-worker false failures from history', { purged });\n this.rewriteFile();\n }\n }\n\n private reclassifyHydrated(): void {\n if (this.size === 0) return;\n const reclassified = this.reclassifyAll();\n if (reclassified > 0) {\n this.logger.info('Reclassified hydrated outcomes with updated categories', {\n reclassified,\n });\n this.rewriteFile();\n }\n }\n\n private hydrate(): void {\n if (!existsSync(this.filePath)) {\n this.logger.debug('No outcomes file found, starting fresh', {\n path: this.filePath,\n });\n return;\n }\n\n try {\n const content = readFileSync(this.filePath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim().length > 0);\n let loaded = 0;\n let skipped = 0;\n\n for (const line of lines) {\n try {\n const parsed: unknown = JSON.parse(line);\n const result = TaskOutcomeSchema.safeParse(parsed);\n if (result.success) {\n super.append(result.data);\n loaded++;\n } else {\n skipped++;\n }\n } catch (parseErr: unknown) {\n this.logger.debug('Skipping malformed outcome line during hydration', {\n error: getErrorMessage(parseErr),\n linePreview: line.slice(0, 80),\n });\n skipped++;\n }\n }\n\n this.logger.info('Hydrated outcomes from disk', {\n loaded,\n skipped,\n total: lines.length,\n path: this.filePath,\n });\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n this.logger.warn('Failed to hydrate outcomes from disk', {\n error: msg,\n path: this.filePath,\n });\n }\n }\n\n /** Rewrite the JSONL file from in-memory state after reclassification. */\n private rewriteFile(): void {\n try {\n const entries = this.query();\n const content = entries.map((e) => JSON.stringify(e)).join('\\n') + '\\n';\n writeFileSync(this.filePath, content, 'utf-8');\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n this.logger.warn('Failed to rewrite outcomes file after reclassification', {\n error: msg,\n path: this.filePath,\n });\n }\n }\n\n private persistLine(outcome: TaskOutcome): void {\n try {\n appendFileSync(this.filePath, JSON.stringify(outcome) + '\\n', 'utf-8');\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n this.logger.warn('Failed to persist outcome to disk', {\n error: msg,\n path: this.filePath,\n });\n }\n }\n}\n\n// Self-register factory so getOutcomeStore() can create PersistentOutcomeStore\n// without a circular top-level import.\nregisterPersistentOutcomeStoreFactory(() => new PersistentOutcomeStore());\n","/**\n * Consensus Vote — Recording Helpers\n *\n * Memory and outcome store recording for consensus votes.\n * Extracted from consensus-vote.ts for file size compliance.\n *\n * @module mcp/tools/consensus-vote-recording\n * (Source: Issue #753 memory, Issue #1134 cold start)\n */\n\nimport {\n createLogger,\n getErrorMessage,\n getTimeProvider,\n getRandomProvider,\n} from '../../core/index.js';\nimport type { AgentVoteResult } from '../../cli/vote-types.js';\nimport { getToolMemory } from './tool-memory.js';\nimport {\n getOutcomeStore,\n categorizeOutcomeErrorMessage,\n} from '../../orchestration/outcomes/index.js';\nimport {\n DEFAULT_CLI,\n CLI_NAMES,\n type CliNameLiteral,\n} from '../../config/model-capabilities-types.js';\n\nconst logger = createLogger({ tool: 'consensus-vote' });\n\n/**\n * Records a successful consensus vote to session memory AND outcome store. Best-effort.\n *\n * When every vote is simulated, this is a no-op: simulated votes are random\n * (#2319) and must not seed the learning store or outcome store, otherwise\n * test/demo runs poison real routing decisions.\n */\nexport function recordVoteSuccess(\n proposal: string,\n strategy: string,\n outcome: string,\n duration: number,\n votes?: readonly AgentVoteResult[]\n): void {\n const allSimulated =\n votes !== undefined && votes.length > 0 && votes.every((v) => v.source === 'simulation');\n if (allSimulated) {\n logger.debug('Skipping memory + outcome recording — all votes simulated');\n return;\n }\n\n try {\n const memory = getToolMemory();\n memory.recordTask({\n approach: `Consensus vote: ${strategy} on \"${proposal.slice(0, 50)}\"`,\n challenges: [],\n durationMs: duration,\n });\n memory.recordLearning({\n pattern: `${strategy} vote → ${outcome}`,\n context: `proposal=\"${proposal.slice(0, 40)}\" duration=${String(duration)}ms`,\n confidence: 0.8,\n source: 'consensus-vote',\n });\n void memory.runPromotionPipeline().catch((error: unknown) => {\n logger.warn('Promotion pipeline failed', { error });\n });\n } catch (error: unknown) {\n logger.warn('Failed to record vote success to memory', { error: getErrorMessage(error) });\n }\n\n // Also record to outcome store for adaptive routing feedback (#1551).\n // recordVoteOutcomes already filters per-vote `source === 'simulation'`,\n // but we keep the all-simulated guard above to skip the memory writes too.\n if (votes !== undefined) {\n recordVoteOutcomes(votes);\n }\n}\n\n/** Records a failed consensus vote to session memory. Best-effort. */\nexport function recordVoteError(proposal: string, errorMessage: string): void {\n try {\n const memory = getToolMemory();\n memory.recordError({\n error: `Consensus vote failed: ${errorMessage.slice(0, 150)}`,\n solution: 'Pending - vote execution failed',\n filePattern: 'mcp/tools/consensus-vote',\n });\n } catch (error: unknown) {\n logger.warn('Failed to record vote error', { error: getErrorMessage(error) });\n }\n}\n\n/**\n * Records per-vote outcomes to the outcome store for adaptive routing.\n * Each successful LLM vote contributes a sample to its CLI×category pair.\n * (Issue #1134 — cold start mitigation)\n */\nexport function recordVoteOutcomes(votes: readonly AgentVoteResult[]): void {\n try {\n const store = getOutcomeStore();\n const now = new Date().toISOString();\n for (const vote of votes) {\n if (vote.source === 'simulation') continue;\n const cliName: CliNameLiteral =\n vote.cli !== undefined && (CLI_NAMES as readonly string[]).includes(vote.cli)\n ? (vote.cli as CliNameLiteral)\n : DEFAULT_CLI;\n const voteSuccess = vote.source === 'llm';\n store.append({\n id: `vote-${String(getTimeProvider().now())}-${getRandomProvider().random().toString(36).slice(2, 8)}`,\n cli: cliName,\n category: 'planning',\n model: 'consensus',\n success: voteSuccess,\n durationMs: vote.processingTimeMs,\n timestamp: now,\n source: 'consensus',\n // #2662 — carry the voter role so the stratified outcome report\n // can break consensus results down by role.\n voterRole: vote.role,\n ...(!voteSuccess && vote.error !== undefined\n ? {\n failureCategory: categorizeOutcomeErrorMessage(vote.error),\n errorMessage: vote.error.slice(0, 500),\n }\n : {}),\n });\n }\n } catch (error: unknown) {\n logger.debug('Best-effort vote outcome recording failed', { error: getErrorMessage(error) });\n }\n}\n","/**\n * Simulation Guard — runtime safety net for `simulateVotes: true`.\n *\n * Simulated votes are random and exist only for unit tests and demos.\n * If a caller passes `simulateVotes: true` outside a test runner, this module\n * emits a one-shot stderr warning so the misuse cannot be silent.\n * (Source: Issue #2317, #2319)\n *\n * @module mcp/tools/simulation-guard\n */\n\nimport type { ILogger } from '../../core/index.js';\n\nconst WARNED = new Set<string>();\n\n/** Returns true when running under vitest or another test runner. */\nexport function isTestRunner(): boolean {\n return process.env.VITEST === 'true' || process.env.NODE_ENV === 'test';\n}\n\n/**\n * If `simulate` is true and we are not in a test runner, log a one-shot\n * warning per (tool, process) pair via the supplied logger. Returns the\n * `simulate` value unchanged so it can be used inline.\n *\n * Why: `simulateVotes: true` is a unit-test affordance; using it as a\n * fallback when adapters are unavailable produces random \"decisions\" that\n * silently corrupt downstream behavior. A loud warning is the minimum\n * defense; #2319 also stops simulated runs from polluting tool memory.\n */\nexport function warnIfSimulatedOutsideTests(toolName: string, logger: ILogger): void {\n if (isTestRunner()) return;\n if (WARNED.has(toolName)) return;\n WARNED.add(toolName);\n logger.warn(\n `[${toolName}] simulateVotes=true: output is RANDOM and reserved for tests/demos. Do not treat the result as a real decision.`\n );\n}\n\n/** Test-only: clear the warned-set so repeated tests can re-trigger the warning. */\nexport function _resetWarned(): void {\n WARNED.clear();\n}\n","/**\n * Central per-tool MCP annotations (#2648, Epic A).\n *\n * The MCP 2025-11-25 spec defines four boolean hints clients use to reason\n * about each tool's safety, retry semantics, and permission UX:\n *\n * - `readOnlyHint` — tool does not modify persistent state\n * - `destructiveHint` — tool can perform destructive operations\n * - `idempotentHint` — calling with the same input is safe to repeat\n * - `openWorldHint` — tool interacts with systems outside the server's control\n *\n * Per the MCP spec these are **hints**, not enforcement primitives — clients\n * should never trust them from an untrusted server. But for nexus-agents (a\n * governance substrate) the hints are load-bearing for:\n *\n * - Programmatic prerequisite gates (Epic B / #2652) — uses\n * `destructiveHint` and `openWorldHint` to decide what to gate.\n * - Retry policy decisions in pipeline runners — only retry tools where\n * `idempotentHint === true`.\n * - Permission-prompt UX consistency across Claude / Codex / Gemini /\n * OpenCode harnesses.\n *\n * The audit (#2648 / docs/research/nexus-agents-multi-harness-alignment-audit.md\n * §6 T14) requires **every** registered tool declare all four hints\n * explicitly — no defaults. This file is the single source of truth; each\n * tool's `registerTool()` call site reads its annotations via\n * `getToolAnnotations(name)`.\n *\n * @module mcp/tool-annotations\n */\n\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Per-tool annotations for all 38 registered MCP tools. Adding a new tool\n * requires adding its entry here; `checkToolAnnotations` (governance CI gate)\n * enforces parity with `REGISTERED_TOOL_NAMES` in\n * `packages/nexus-agents/src/mcp/tools/index.ts`.\n */\nexport const TOOL_ANNOTATIONS: Record<string, ToolAnnotations> = {\n // ============================================================================\n // Orchestration & expert lifecycle\n // ============================================================================\n\n /** Orchestrator coordinates expert agents; spawns workers that may mutate state. */\n orchestrate: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Creates an expert and adds it to the in-memory expert registry. */\n create_expert: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n /** Executes a previously created expert; invokes external CLIs. */\n execute_expert: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n\n // ============================================================================\n // Workflow / pipeline execution\n // ============================================================================\n\n /** Runs a workflow template; steps may write to the registry or filesystem. */\n run_workflow: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Runs a graph-based workflow with checkpointing. */\n run_graph_workflow: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Runs a pipeline plugin by name. */\n run_pipeline: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Full dev pipeline: research → plan → vote → implement → QA. */\n run_dev_pipeline: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Executes an AI-software-factory spec pipeline. */\n execute_spec: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n\n // ============================================================================\n // Voting / decision\n // ============================================================================\n\n /** Records vote outcomes to the audit log; doesn't write to repo state. */\n consensus_vote: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Per-axis tradeoff vote; records outcome to the store. */\n supply_chain_tradeoff_panel: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Multi-voter PR review; may write review comments. */\n pr_review: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n\n // ============================================================================\n // Routing & introspection (read-only)\n // ============================================================================\n\n /** Returns a routing recommendation; doesn't execute. */\n delegate_to_model: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Lists registered expert types. */\n list_experts: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Lists registered workflow templates. */\n list_workflows: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n\n // ============================================================================\n // Research registry — reads\n // ============================================================================\n\n /** Queries the research registry. */\n research_query: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Analyzes registry for gaps, trends, coverage. */\n research_analyze: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Synthesizes registry into topic clusters. */\n research_synthesize: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Discovers research items via external APIs; doesn't mutate registry. */\n research_discover: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n\n // ============================================================================\n // Research registry — mutations\n // ============================================================================\n\n /** Adds an arXiv paper to the registry. Dedup-checked but first call has effects. */\n research_add: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Adds a non-paper source to the registry. */\n research_add_source: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Reviews auto-cataloged research references; may approve/dismiss. */\n research_catalog_review: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ============================================================================\n // Transient lookups (no registry persistence)\n // ============================================================================\n\n /** Transient OSS search via GitHub API; no persistence. */\n survey_oss_landscape: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n /** Static lookup against curated vendor seed data. */\n vendor_publishing_audit: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Diffs two YAML/JSON files; local-only. */\n compare_data_feeds: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n\n // ============================================================================\n // Memory\n // ============================================================================\n\n /** Reads from memory backends. */\n memory_query: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Returns memory statistics. */\n memory_stats: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Writes to a memory backend. */\n memory_write: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ============================================================================\n // Observability\n // ============================================================================\n\n /** Multi-CLI performance weather report; reads outcome store. */\n weather_report: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Queries execution traces from disk. */\n query_trace: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Queries structured task-state log. */\n query_task_state: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Verifies hash chain of audit log files. */\n verify_audit_chain: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Threshold-gated observability loop; may file GitHub issues when fileIssues=true. */\n improvement_review: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n\n // ============================================================================\n // Repository analysis\n // ============================================================================\n\n /** Analyzes a GitHub repository structure; doesn't write. */\n repo_analyze: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n /** Generates a security-scanning pipeline plan; returns plan, doesn't write it. */\n repo_security_plan: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n /** Extracts code symbols from source files. */\n extract_symbols: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n /** Searches codebase for patterns or symbols. */\n search_codebase: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n\n // ============================================================================\n // Issue triage & registry imports\n // ============================================================================\n\n /** Triages a GitHub issue; may write labels/comments when authorized. */\n issue_triage: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n /** Generates a draft model-registry entry; doesn't write. */\n registry_import: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n};\n\n/**\n * Look up the annotations for a registered MCP tool. Throws if the tool\n * name isn't in the central map — this enforces \"every tool declares its\n * hints explicitly\" rather than silently falling back to MCP's defaults\n * (which assume destructive + non-idempotent + open-world).\n */\nexport function getToolAnnotations(name: string): ToolAnnotations {\n const a = TOOL_ANNOTATIONS[name];\n if (a === undefined) {\n throw new Error(\n `getToolAnnotations: no entry for tool \"${name}\". Add it to TOOL_ANNOTATIONS in src/mcp/tool-annotations.ts (#2648).`\n );\n }\n return a;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,SAAS,KAAAA,WAAS;;;ACWlB,SAAS,yBAAyB;AAqBlC,IAAM,iBAAiB,aAAa,EAAE,WAAW,eAAe,CAAC;AAQ1D,SAAS,kBAAkB,QAAiC;AACjE,WAAS,KAAK,OAAoBC,SAAgB,MAAqC;AACrF,QAAI;AACF,aAAO,mBAAmB,EAAE,OAAO,QAAAA,SAAQ,KAAK,CAAC,EAAE,MAAM,CAAC,UAAmB;AAC3E,uBAAe,MAAM,mCAAmC;AAAA,UACtD;AAAA,UACA,QAAAA;AAAA,UACA,OAAO,gBAAgB,KAAK;AAAA,QAC9B,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,qBAAe,MAAM,mCAAmC;AAAA,QACtD;AAAA,QACA,QAAAA;AAAA,QACA,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,CAACA,SAAQ,SAAS;AACtB,WAAK,QAAQA,SAAQ,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,CAACA,SAAQ,SAAS;AACvB,WAAK,SAASA,SAAQ,IAAI;AAAA,IAC5B;AAAA,IACA,MAAM,CAACA,SAAQ,SAAS;AACtB,WAAK,WAAWA,SAAQ,IAAI;AAAA,IAC9B;AAAA,EACF;AACF;AAKO,IAAM,gBAA8B;AAAA,EACzC,MAAM,MAAM;AAAA,EACZ,OAAO,MAAM;AAAA,EACb,MAAM,MAAM;AACd;AA2BO,IAAM,yBAAyB,IAAI,kBAAmC;AAYtE,IAAM,qBAAqB,IAAI,kBAA+B;AAiBrE,eAAsB,sBACpB,UACA,UACA,WACA,aAAa,MACD;AACZ,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,YAAY;AAChB,QAAM,cAAc,uBAAuB,SAAS;AAEpD,QAAM,QAAQ,YAAY,MAAM;AAC9B;AACA,UAAM,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAG1D,QAAI,gBAAgB,QAAW;AAC7B,kBAAY,iBAAiB,SAAS;AAAA,IACxC;AAGA,aAAS,MAAM,UAAU;AAAA,MACvB,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB;AAAA,MACA,kBAAkB,gBAAgB;AAAA,IACpC,CAAC;AAAA,EACH,GAAG,UAAU;AAEb,MAAI;AACF,WAAO,MAAM,UAAU;AAAA,EACzB,UAAE;AACA,kBAAc,KAAK;AAAA,EACrB;AACF;;;ACpKA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB,YAAY,iBAAiB;AACtD,SAAS,SAAS,YAAY;;;AC8B9B,IAAM,6BAA6B,eAAe;AAuB3C,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACS;AAAA,EACA;AAAA,EAEjB,YAAY,QAA2B;AACrC,SAAK,WAAW,OAAO;AACvB,SAAK,aAAa,OAAO;AACzB,SAAK,mBAAmB,OAAO,oBAAoB;AACnD,SAAK,SAAS,KAAK;AACnB,SAAK,iBAAiB,gBAAgB,EAAE,IAAI;AAC5C,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,SAAS,OAAO,UAAU,aAAa,EAAE,WAAW,KAAK,KAAK,CAAC;AAEpE,SAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5C,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,kBAAkB,KAAK;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,SAAe;AACrB,UAAM,MAAM,gBAAgB,EAAE,IAAI;AAClC,UAAM,UAAU,MAAM,KAAK;AAC3B,UAAM,YAAY,KAAK,MAAM,UAAU,KAAK,gBAAgB;AAE5D,QAAI,YAAY,GAAG;AACjB,YAAM,cAAc,YAAY,KAAK;AACrC,WAAK,SAAS,KAAK,IAAI,KAAK,UAAU,KAAK,SAAS,WAAW;AAC/D,WAAK,iBAAiB,MAAO,UAAU,KAAK;AAE5C,UAAI,cAAc,GAAG;AACnB,aAAK,OAAO,MAAM,mBAAmB;AAAA,UACnC,OAAO;AAAA,UACP,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,QAAQ,GAAY;AAC7B,SAAK,OAAO;AAEZ,QAAI,KAAK,UAAU,OAAO;AACxB,WAAK,UAAU;AACf,WAAK,OAAO,MAAM,kBAAkB;AAAA,QAClC,WAAW;AAAA,QACX,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,aAAO;AAAA,IACT;AAEA,SAAK,OAAO,KAAK,uBAAuB;AAAA,MACtC,WAAW;AAAA,MACX,WAAW,KAAK;AAAA,IAClB,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAA6B;AAC3B,SAAK,OAAO;AAEZ,UAAM,cACJ,KAAK,SAAS,IAAI,IAAI,KAAK,oBAAoB,gBAAgB,EAAE,IAAI,IAAI,KAAK;AAEhF,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,aAAa,KAAK,IAAI,GAAG,WAAW;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AACZ,SAAK,SAAS,KAAK;AACnB,SAAK,iBAAiB,gBAAgB,EAAE,IAAI;AAC5C,SAAK,OAAO,MAAM,sBAAsB,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EACjE;AACF;AAaO,SAAS,yBAAyB,MAAeC,SAA+B;AACrF,QAAM,SAA4B;AAAA,IAChC,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,kBAAkB;AAAA,EACpB;AACA,MAAI,SAAS,QAAW;AACtB,IAAC,OAA6B,OAAO;AAAA,EACvC;AACA,MAAIA,YAAW,QAAW;AACxB,IAAC,OAAgC,SAASA;AAAA,EAC5C;AACA,SAAO,IAAI,YAAY,MAAM;AAC/B;;;ACnJO,SAAS,kBACd,QACA,MAC4B;AAC5B,QAAM,SAAS,OAAO,UAAU,IAAI;AAEpC,MAAI,OAAO,SAAS;AAClB,WAAO,GAAG,OAAO,IAAI;AAAA,EACvB;AAEA,QAAM,UAAU,eAAe,OAAO,KAAK;AAC3C,QAAM,kBAAkB,IAAI,gBAAgB,uBAAuB,OAAO,IAAI;AAAA,IAC5E,SAAS;AAAA,MACP,QAAQ,OAAO,MAAM;AAAA,MACrB,cAAc,OAAO;AAAA,IACvB;AAAA,EACF,CAAC;AAED,SAAO,IAAI,eAAe;AAC5B;AAmBO,SAAS,gBACd,QAC+C;AAC/C,SAAO,CAAC,SAAkB,kBAAkB,QAAQ,IAAI;AAC1D;;;AC9EA,SAAS,SAAS;AA+FX,IAAM,cAAN,cAA0B,cAAc;AAAA,EACpC;AAAA,EAET,YAAY,SAAiB,UAA0B;AACrD,UAAM,SAAS;AAAA,MACb,SAAS;AAAA,QACP,SAAS,SAAS;AAAA,QAClB,QAAQ,SAAS;AAAA,QACjB,UAAU,SAAS;AAAA,QACnB,kBAAkB,SAAS;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AACZ,SAAK,WAAW;AAAA,EAClB;AACF;AASO,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,aAAa,EAAE,KAAK,CAAC,aAAa,YAAY,CAAC,EAAE,QAAQ,WAAW;AAAA,EACpE,YAAY,EAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,QAAQ,SAAS;AAAA,EACzD,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC;AAClD,CAAC;;;AChHM,SAAS,WAAW,YAAoB,cAA0C;AAEvF,QAAM,mBAAmB,cAAc,UAAU;AAGjD,aAAW,WAAW,cAAc;AAClC,UAAM,oBAAoB,cAAc,OAAO;AAC/C,QAAI,iBAAiB,WAAW,iBAAiB,GAAG;AAClD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,cAAc,GAAmB;AAE/C,MAAI,aAAa,EAAE,QAAQ,cAAc,EAAE;AAG3C,MAAI,eAAe,KAAK;AACtB,iBAAa;AAAA,EACf,WAAW,WAAW,WAAW,IAAI,GAAG;AACtC,iBAAa,WAAW,MAAM,CAAC;AAAA,EACjC;AAGA,MAAI,CAAC,WAAW,WAAW,GAAG,GAAG;AAC/B,iBAAa,MAAM;AAAA,EACrB;AAEA,SAAO;AACT;AAKO,SAAS,oBAAoB,MAAmC;AACrE,MAAI,SAAS,QAAQ,OAAO,SAAS,UAAU;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,UAAU;AAGhB,QAAM,aAAa,CAAC,QAAQ,YAAY,aAAa,aAAa,OAAO,QAAQ;AAEjF,aAAW,SAAS,YAAY;AAC9B,UAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;AC3DO,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,SAAS,eAAe,UAA2B;AAExD,MAAI,eAAe,IAAI,QAAQ,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,MAAI,gBAAgB,IAAI,QAAQ,GAAG;AACjC,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAYO,IAAM,+BAA2C;AAAA,EACtD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,MAAM,KAAoC;AAExC,QAAI,IAAI,SAAS,cAAc;AAC7B,aAAO,EAAE,SAAS,MAAM,QAAQ,0BAA0B;AAAA,IAC5D;AAGA,QAAI,eAAe,IAAI,QAAQ,GAAG;AAChC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,SAAS,IAAI,QAAQ,0CAA0C,IAAI,IAAI;AAAA,MACjF;AAAA,IACF;AAGA,WAAO,EAAE,SAAS,MAAM,QAAQ,8BAA8B;AAAA,EAChE;AACF;AAQO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,MAAM,KAAoC;AAExC,UAAM,aAAa,oBAAoB,IAAI,IAAI;AAG/C,QAAI,eAAe,QAAW;AAC5B,aAAO,EAAE,SAAS,MAAM,QAAQ,yBAAyB;AAAA,IAC3D;AAGA,QAAI,WAAW,SAAS,IAAI,GAAG;AAC7B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,yDAAyD,UAAU;AAAA,MAC7E;AAAA,IACF;AAGA,UAAM,eAAe,IAAI,gBAAgB,CAAC,IAAI;AAG9C,QAAI,CAAC,WAAW,YAAY,YAAY,GAAG;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,SAAS,UAAU,qCAAqC,aAAa,KAAK,IAAI,CAAC;AAAA,MACzF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,MAAM,QAAQ,qCAAqC;AAAA,EACvE;AACF;;;AC9EO,IAAM,iBAAN,MAAgD;AAAA,EACpC,QAAsB,CAAC;AAAA,EAChC;AAAA,EACS;AAAA,EAEjB,YAAY,QAA+B;AACzC,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,SAAS,QAAQ,UAAU,aAAa,EAAE,WAAW,kBAAkB,CAAC;AAG7E,QAAI,QAAQ,OAAO;AACjB,iBAAW,QAAQ,OAAO,OAAO;AAC/B,aAAK,MAAM,KAAK,IAAI;AAAA,MACtB;AAAA,IACF;AAEA,SAAK,OAAO,MAAM,+BAA+B;AAAA,MAC/C,MAAM,KAAK;AAAA,MACX,WAAW,KAAK,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,SAAS,KAAoC;AAC3C,SAAK,OAAO,MAAM,qBAAqB;AAAA,MACrC,UAAU,IAAI;AAAA,MACd,MAAM,IAAI;AAAA,MACV,WAAW,KAAK,MAAM;AAAA,IACxB,CAAC;AAGD,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,aAAO,KAAK,gBAAgB,KAAK,4BAA4B;AAAA,IAC/D;AAGA,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,MAAM,GAAG;AAE/B,UAAI,CAAC,SAAS,SAAS;AACrB,eAAO,KAAK,aAAa,KAAK,MAAM,QAAQ;AAAA,MAC9C;AAAA,IACF;AAGA,WAAO,KAAK,gBAAgB,KAAK,yBAAyB;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,KAAoB,QAAgC;AAC1E,UAAM,WAA2B,EAAE,SAAS,MAAM,OAAO;AACzD,SAAK,YAAY,KAAK,QAAQ;AAC9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aACN,KACA,MACA,UACgB;AAChB,UAAM,iBAAiC;AAAA,MACrC,GAAG;AAAA,MACH,UAAU,KAAK;AAAA,IACjB;AAEA,SAAK,YAAY,KAAK,cAAc;AAGpC,QAAI,KAAK,SAAS,QAAQ;AACxB,WAAK,OAAO,KAAK,yCAAyC;AAAA,QACxD,UAAU,IAAI;AAAA,QACd,UAAU,KAAK;AAAA,QACf,QAAQ,SAAS;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,gCAAgC,SAAS,MAAM;AAAA,QACvD,UAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAwB;AAE9B,UAAM,gBAAgB,KAAK,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACtE,QAAI,iBAAiB,GAAG;AACtB,WAAK,OAAO,KAAK,kCAAkC,EAAE,UAAU,KAAK,KAAK,CAAC;AAC1E,WAAK,MAAM,aAAa,IAAI;AAAA,IAC9B,OAAO;AACL,WAAK,MAAM,KAAK,IAAI;AACpB,WAAK,OAAO,MAAM,qBAAqB,EAAE,UAAU,KAAK,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,MAAuB;AAChC,UAAM,QAAQ,KAAK,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,IAAI;AACzD,QAAI,SAAS,GAAG;AACd,WAAK,MAAM,OAAO,OAAO,CAAC;AAC1B,WAAK,OAAO,MAAM,uBAAuB,EAAE,UAAU,KAAK,CAAC;AAC3D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAkC;AAChC,WAAO,CAAC,GAAG,KAAK,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAwB;AAC9B,UAAM,eAAe,KAAK;AAC1B,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK,uBAAuB,EAAE,MAAM,cAAc,IAAI,KAAK,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,KAAoB,UAAgC;AACtE,UAAM,UAAU;AAAA,MACd,UAAU,IAAI;AAAA,MACd,MAAM,IAAI;AAAA,MACV,YAAY,IAAI;AAAA,MAChB,SAAS,SAAS;AAAA,MAClB,QAAQ,SAAS;AAAA,MACjB,UAAU,SAAS;AAAA,IACrB;AAEA,QAAI,SAAS,SAAS;AACpB,WAAK,OAAO,MAAM,4BAA4B,OAAO;AAAA,IACvD,OAAO;AACL,WAAK,OAAO,KAAK,2BAA2B,OAAO;AAAA,IACrD;AAAA,EACF;AACF;AAgBO,SAAS,4BAA4B,QAA+C;AACzF,QAAM,WAAW,IAAI,eAAe,MAAM;AAG1C,WAAS,QAAQ,4BAA4B;AAC7C,WAAS,QAAQ,aAAa;AAE9B,SAAO;AACT;AAYO,SAAS,eACd,UACA,KAC2B;AAC3B,QAAM,WAAW,SAAS,SAAS,GAAG;AAEtC,MAAI,SAAS,SAAS;AACpB,WAAO,GAAG,MAAS;AAAA,EACrB;AAEA,SAAO,IAAI,IAAI,YAAY,kBAAkB,SAAS,MAAM,IAAI,QAAQ,CAAC;AAC3E;AAUO,SAAS,oBACd,UACA,MACA,SAMe;AAEf,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA,MAAM,SAAS,QAAQ;AAAA,EACzB;AAIA,QAAM,SAAkC,EAAE,GAAG,KAAK;AAElD,MAAI,SAAS,cAAc,QAAW;AACpC,WAAO,WAAW,IAAI,QAAQ;AAAA,EAChC;AACA,MAAI,SAAS,eAAe,QAAW;AACrC,WAAO,YAAY,IAAI,QAAQ;AAAA,EACjC;AACA,MAAI,SAAS,iBAAiB,QAAW;AACvC,WAAO,cAAc,IAAI,QAAQ;AAAA,EACnC;AAEA,SAAO;AACT;;;ACjPA,IAAM,qBAAqB,cAAc;AACzC,IAAM,iBAAiB,cAAc;AACrC,IAAM,yBAAyB,cAAc;AAW7C,SAAS,mBAAmB,eAAuB,WAAiC;AAClF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,cAAc,aAAa,qBAAqB,OAAO,SAAS,CAAC;AAAA,IAC1E,WAAW;AAAA,IACX;AAAA,EACF;AACF;AAKA,SAAS,iBAAiB,OAAgB,eAAqC;AAC7E,QAAM,aAA2B;AAAA,IAC/B,MAAM;AAAA,IACN,SAAS,gBAAgB,KAAK;AAAA,IAC9B,WAAW;AAAA,EACb;AACA,MAAI,iBAAiB,OAAO;AAC1B,WAAO,EAAE,GAAG,YAAY,OAAO,MAAM;AAAA,EACvC;AACA,SAAO;AACT;AAwBO,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAA6B;AACvC,SAAK,mBAAmB,QAAQ,oBAAoB;AACpD,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,SAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,SAAK,SAAS,QAAQ,UAAU,aAAa,EAAE,WAAW,gBAAgB,CAAC;AAAA,EAC7E;AAAA;AAAA,EAGQ,eAAe,SAGrB;AACA,WAAO;AAAA,MACL,WAAW,KAAK,IAAI,SAAS,aAAa,KAAK,kBAAkB,KAAK,YAAY;AAAA,MAClF,eAAe,SAAS,iBAAiB;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QACJ,WACA,SACiD;AACjD,UAAM,EAAE,WAAW,cAAc,IAAI,KAAK,eAAe,OAAO;AAEhE,UAAM,kBAAkB,KAAK,gBAAgB,WAAW,aAAa;AACrE,QAAI,oBAAoB,MAAM;AAC5B,aAAO,IAAI,eAAe;AAAA,IAC5B;AAEA,WAAO,KAAK,WAAW,WAAW,WAAW,eAAe,OAAO;AAAA,EACrE;AAAA;AAAA,EAGA,MAAc,WACZ,WACA,WACA,eACA,SACiD;AACjD,SAAK,SAAS,eAAe,SAAS;AACtC,UAAM,YAAY,gBAAgB,EAAE,IAAI;AACxC,UAAM,QAAsB,EAAE,WAAW,QAAW,UAAU,MAAM;AAEpE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AACA,aAAO,KAAK,cAAc,QAAQ,WAAW,WAAW,aAAa;AAAA,IACvE,QAAQ;AACN,YAAM,YAAY,SAAS,QAAQ,YAAY,QAAQ,CAAC,MAAM;AAC9D,aAAO;AAAA,QACL,KAAK,cAAc,MAAM,UAAU,eAAe,WAAW,WAAW,SAAS;AAAA,MACnF;AAAA,IACF,UAAE;AACA,UAAI,MAAM,cAAc,QAAW;AACjC,qBAAa,MAAM,SAAS;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,WAAmB,eAA4C;AACrF,QAAI,aAAa,GAAG;AAClB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,oBAAoB,OAAO,SAAS,CAAC;AAAA,QAC9C,WAAW;AAAA,MACb;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,eAAuB,WAAyB;AAC/D,QAAI,KAAK,eAAe;AACtB,WAAK,OAAO,MAAM,8BAA8B,EAAE,WAAW,eAAe,UAAU,CAAC;AAAA,IACzF;AAAA,EACF;AAAA,EAEA,MAAc,eACZ,WACA,WACA,OACA,WACA,QACY;AACZ,UAAM,iBAAiB,IAAI,QAAe,CAAC,UAAU,WAAW;AAC9D,YAAM,YAAY,WAAW,MAAM;AACjC,cAAM,WAAW;AACjB,oBAAY;AACZ,eAAO,IAAI,MAAM,6BAA6B,OAAO,SAAS,CAAC,IAAI,CAAC;AAAA,MACtE,GAAG,SAAS;AAAA,IACd,CAAC;AAED,UAAM,WAA8B,CAAC,UAAU,GAAG,cAAc;AAGhE,QAAI,WAAW,UAAa,CAAC,OAAO,SAAS;AAC3C,YAAM,eAAe,IAAI,QAAe,CAAC,UAAU,WAAW;AAC5D,eAAO;AAAA,UACL;AAAA,UACA,MAAM;AACJ,mBAAO,IAAI,MAAM,+BAA+B,CAAC;AAAA,UACnD;AAAA,UACA,EAAE,MAAM,KAAK;AAAA,QACf;AAAA,MACF,CAAC;AACD,eAAS,KAAK,YAAY;AAAA,IAC5B;AAEA,WAAO,QAAQ,KAAK,QAAQ;AAAA,EAC9B;AAAA,EAEQ,cACN,QACA,WACA,WACA,eACwC;AACxC,UAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAC7C,UAAM,cAAc,aAAa,YAAY;AAE7C,QAAI,eAAe,KAAK,eAAe;AACrC,WAAK,OAAO,KAAK,8CAA8C;AAAA,QAC7D,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA,kBAAkB,KAAK,MAAO,aAAa,YAAa,GAAG;AAAA,MAC7D,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,eAAe;AACtB,WAAK,OAAO,MAAM,+BAA+B,EAAE,WAAW,eAAe,WAAW,CAAC;AAAA,IAC3F;AAEA,WAAO,GAAG,EAAE,OAAO,QAAQ,YAAY,YAAY,CAAC;AAAA,EACtD;AAAA,EAEQ,cACN,UACA,eACA,WACA,WACA,YAAY,OACE;AACd,UAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAE7C,QAAI,WAAW;AACb,WAAK,OAAO,KAAK,iCAAiC;AAAA,QAChD,WAAW;AAAA,QACX;AAAA,MACF,CAAC;AACD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,cAAc,aAAa;AAAA,QACpC,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAI,UAAU;AACZ,WAAK,OAAO,MAAM,uBAAuB,QAAW;AAAA,QAClD,WAAW;AAAA,QACX;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,mBAAmB,eAAe,SAAS;AAAA,IACpD;AAEA,WAAO,iBAAiB,IAAI,MAAM,eAAe,GAAG,aAAa;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MACE,IACA,SAC2E;AAC3E,WAAO,UAAU,SAAuE;AACtF,aAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,IAAI,GAAG,OAAO;AAAA,IAChD;AAAA,EACF;AACF;;;ACvUA,SAAS,mBAAmB;AAqFrB,SAAS,oBAA4B;AAC1C,QAAM,QAAQ,YAAY,CAAC;AAC3B,SAAO,OAAO,MAAM,SAAS,KAAK,CAAC;AACrC;AAiBA,SAAS,kBAA0B;AACjC,QAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,QAAM,YAAY,IAAI,KAAK,eAAe,SAAS;AAAA,IACjD,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,QAAM,QAAQ,UAAU,cAAc,GAAG;AACzC,QAAM,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,cAAc,GAAG,SAAS;AACtE,QAAM,OAAO,IAAI,eAAe,SAAS;AAAA,IACvC,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AACD,SAAO,KAAK,QAAQ,KAAK,GAAG,IAAI,OAAO,QAAQ,OAAO,EAAE;AAC1D;AAUO,SAAS,gBAAgB,QAA+B;AAC7D,QAAM,eAAe,CAAC,cAAc,cAAc,WAAW;AAE7D,MAAI,OAAO,cAAc,QAAS,QAAO;AAEzC,MAAI,OAAO,kBAAkB,MAAM;AACjC,QAAI,OAAO,aAAa,UAAa,aAAa,SAAS,OAAO,QAAQ,GAAG;AAC3E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQO,SAAS,qBAAqB,SAA+C;AAClF,QAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,QAAM,UAA0B;AAAA,IAC9B,WAAW,kBAAkB;AAAA,IAC7B,WAAW,gBAAgB;AAAA,IAC3B,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,WAAW,QAAQ,aAAa,gBAAgB,MAAM;AAAA,IACtD,GAAI,QAAQ,YAAY,UAAa,EAAE,SAAS,QAAQ,QAAQ;AAAA,IAChE,GAAI,QAAQ,iBAAiB,UAAa,EAAE,cAAc,QAAQ,aAAa;AAAA,EACjF;AAGA,SAAO,OAAO,OAAO,OAAO;AAC9B;AAoDO,SAAS,kBAAkB,KAA8C;AAC9E,SAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,WAAW,IAAI;AAAA,IACf,GAAI,IAAI,OAAO,aAAa,UAAa,EAAE,UAAU,IAAI,OAAO,SAAS;AAAA,IACzE,GAAI,IAAI,YAAY,UAAa,EAAE,SAAS,IAAI,QAAQ;AAAA,EAC1D;AACF;;;ACrNO,IAAM,6BAAgD;AAAA;AAAA,EAE3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,IAAM,0BAA6C;AAAA;AAAA,EAExD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AACF;AAUA,SAAS,mBAAmB,SAAyB;AACnD,QAAM,MAAM,QAAQ,YAAY;AAKhC,QAAM,UAAU,IACb,QAAQ,qBAAqB,MAAM,EACnC,QAAQ,SAAS,gBAAgB,EACjC,QAAQ,OAAO,OAAO,EACtB,QAAQ,mBAAmB,IAAI;AAClC,QAAM,WAAW,QAAQ,WAAW,IAAI,IACpC,QAAQ,QAAQ,MAAM,CAAC,CAAC,MACxB,QAAQ,WAAW,GAAG,IACpB,IAAI,OAAO,MACX,QAAQ,OAAO;AACrB,SAAO,IAAI,OAAO,QAAQ;AAC5B;AAMA,IAAM,yBAGD,2BAA2B,IAAI,CAAC,aAAa;AAAA,EAChD;AAAA,EACA,OAAO,mBAAmB,OAAO;AACnC,EAAE;AAeK,SAAS,aAAa,MAAuB;AAClD,QAAM,aAAa,KAAK,YAAY;AACpC,SAAO,uBAAuB,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;AACpE;AAGO,SAAS,aAAa,UAA2B;AACtD,SAAO,wBAAwB,SAAS,QAAQ;AAClD;;;AC1GO,IAAMC,mBAAuC,oBAAI,IAAI;AAAA;AAAA,EAE1D;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF,CAAC;AAMM,SAAS,YAAY,UAA2B;AACrD,SAAO,CAACA,iBAAgB,IAAI,QAAQ;AACtC;;;ACnCO,SAAS,YACd,UACA,QACA,MACgB;AAEhB,MAAI,aAAa,QAAQ,GAAG;AAC1B,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,SAAS,QAAQ;AAAA,MACzB,aAAa;AAAA,IACf;AAAA,EACF;AAGA,MAAI,OAAO,MAAM,SAAS,YAAY,KAAK,KAAK,SAAS,KAAK,aAAa,KAAK,IAAI,GAAG;AACrF,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,SAAS,KAAK,IAAI;AAAA,MAC1B,aAAa;AAAA,IACf;AAAA,EACF;AAGA,MAAI,OAAO,iBAAiB,IAAK,QAAO,EAAE,UAAU,QAAQ;AAE5D,MAAI,OAAO,aAAa,SAAS,QAAQ,EAAG,QAAO,EAAE,UAAU,QAAQ;AAEvE,SAAO,kBAAkB,UAAU,OAAO,IAAI;AAChD;AAMA,SAAS,kBAAkB,UAAkB,MAAgD;AAC3F,MAAI,SAAS,SAAS;AACpB,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS,SAAS,QAAQ;AAAA,IAC5B;AAAA,EACF;AAMA,MAAI,SAAS,iBAAiB;AAC5B,QAAI,CAAC,YAAY,QAAQ,GAAG;AAC1B,aAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS,SAAS,QAAQ;AAAA,MAC5B;AAAA,IACF;AACA,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,SAAS,QAAQ;AAAA,MACzB,aAAa;AAAA,IACf;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ,SAAS,QAAQ;AAAA,IACzB,aAAa;AAAA,EACf;AACF;;;AC5EA,SAAS,qBAAAC,0BAAyB;AAKlC,IAAM,sBAAsB,IAAIC,mBAAoC;AAS7D,SAAS,iBAAoB,QAA0B,IAAkC;AAC9F,SAAO,oBAAoB,IAAI,QAAQ,EAAE;AAC3C;AAOO,SAAS,kBAAgD;AAC9D,SAAO,oBAAoB,SAAS;AACtC;AA2CO,SAAS,iBACd,UACA,WACmE;AACnE,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,kBAAkB,SAAS,MAAM,WAAW,SAAS,WAAW,cAAc,SAAS;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AACF;;;ACjFA,SAAS,YAAY,MAAsC;AACzD,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,OAAQ,KAAiC,MAAM;AACrD,SAAO,OAAO,SAAS,YAAY,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI;AAClE;AAQO,SAAS,kCAAkC,UAA8B;AAC9E,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,SAAS,gBAAgB;AAC/B,QAAI,WAAW,UAAa,OAAO,SAAS,OAAO;AACjD,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB;AAEA,UAAM,WAAW,YAAY,UAAU,QAAQ,YAAY,IAAI,CAAC;AAEhE,QAAI,SAAS,aAAa,SAAS;AACjC,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB;AACA,QAAI,SAAS,aAAa,iBAAiB;AACzC,UAAI,OAAO,KAAK,kCAAkC;AAAA,QAChD,MAAM;AAAA,QACN,SAAS,SAAS;AAAA,QAClB,cAAc,OAAO;AAAA,QACrB,WAAW,IAAI,eAAe;AAAA,MAChC,CAAC;AACD,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB;AACA,QAAI,OAAO,KAAK,mCAAmC;AAAA,MACjD,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA,MACjB,aAAa,SAAS;AAAA,MACtB,cAAc,OAAO;AAAA,MACrB,MAAM,OAAO;AAAA,MACb,WAAW,IAAI,eAAe;AAAA,IAChC,CAAC;AACD,WAAO,iBAAiB,UAAU,IAAI,eAAe,SAAS;AAAA,EAChE;AACF;;;ACzCA,SAAS,KAAAC,UAAS;AAmBX,IAAM,sBAAsBA,GAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,eAAe;AAAA;AAAA,EAEf,aAAaA,GAAE,QAAQ;AAAA;AAAA,EAEvB,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnC,QAAQA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS;AACrD,CAAC;AAaM,IAAM,0BAA0B;AAWhC,SAAS,iBAAiB,UAAkC;AACjE,SAAO,aAAa;AACtB;;;ACVO,SAAS,YAAY,MAA0B;AACpD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EAClC;AACF;AAgBO,SAAS,sBAAsB,MAA2C;AAC/E,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,IAC/D,mBAAmB;AAAA,EACrB;AACF;AA8BO,SAAS,oBAAoB,OAA6C;AAC/E,QAAM,WAA8B;AAAA,IAClC,eAAe,MAAM;AAAA,IACrB,aAAa,MAAM,eAAe,iBAAiB,MAAM,aAAa;AAAA,IACtE,SAAS,MAAM;AAAA,IACf,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,EAC/D;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,QAAQ,CAAC;AAAA,IAClD,OAAO,EAAE,CAAC,uBAAuB,GAAG,SAAS;AAAA,EAC/C;AACF;AAcO,SAAS,UAAU,SAA6B;AACrD,SAAO,oBAAoB,EAAE,eAAe,YAAY,QAAQ,CAAC;AACnE;;;AClDA,SAAS,YAAY,UAAyB,SAAiB,WAA+B;AAC5F,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf,SAAS,GAAG,OAAO,cAAc,SAAS;AAAA,EAC5C,CAAC;AACH;AAKA,SAAS,2BAA2B,QAA+B;AACjE,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,SAAS,kBAAkB,QAAQ,IAAI;AAC7C,QAAI,CAAC,OAAO,IAAI;AACd,UAAI,OAAO,KAAK,qBAAqB;AAAA,QACnC,OAAO,OAAO,MAAM;AAAA,MACtB,CAAC;AACD,aAAO;AAAA,QACL;AAAA,QACA,qBAAqB,OAAO,MAAM,OAAO;AAAA,QACzC,IAAI,eAAe;AAAA,MACrB;AAAA,IACF;AACA,QAAI,gBAAgB,OAAO;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AACF;AAKA,SAAS,uBACP,UACA,UACA,MACA,cACY;AACZ,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,YAAY,oBAAoB,UAAU,MAAM;AAAA,MACpD;AAAA,MACA,GAAI,iBAAiB,UAAa,EAAE,aAAa;AAAA,IACnD,CAAC;AACD,UAAM,WAAW,SAAS,SAAS,SAAS;AAE5C,QAAI,CAAC,SAAS,SAAS;AACrB,UAAI,OAAO,KAAK,iBAAiB;AAAA,QAC/B,QAAQ,SAAS;AAAA,QACjB,UAAU,SAAS;AAAA,MACrB,CAAC;AACD,aAAO;AAAA,QACL;AAAA,QACA,kBAAkB,SAAS,MAAM;AAAA,QACjC,IAAI,eAAe;AAAA,MACrB;AAAA,IACF;AACA,QAAI,OAAO,MAAM,uBAAuB,EAAE,QAAQ,SAAS,OAAO,CAAC;AACnE,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AACF;AAKA,SAAS,0BAA0B,SAAkC;AACnE,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,WAAW,QAAQ,WAAW;AACpC,QAAI,CAAC,UAAU;AACb,YAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAI,OAAO,KAAK,uBAAuB;AAAA,QACrC,aAAa,MAAM;AAAA,MACrB,CAAC;AACD,aAAO;AAAA,QACL;AAAA,QACA,qCAAqC,OAAO,MAAM,WAAW,CAAC;AAAA,QAC9D,IAAI,eAAe;AAAA,MACrB;AAAA,IACF;AACA,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AACF;AAMA,SAAS,wBAAwB,OAAqB,UAA8B;AAClF,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,SAAS,mBAAmB,SAAS;AAC3C,UAAM,SAAS,MAAM,MAAM,QAAQ,MAAM,KAAK,MAAM,GAAG,GAAG;AAAA,MACxD,eAAe;AAAA,MACf,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3C,CAAC;AAED,QAAI,CAAC,OAAO,IAAI;AACd,UAAI,OAAO,MAAM,uBAAuB,QAAW;AAAA,QACjD,MAAM,OAAO,MAAM;AAAA,QACnB,WAAW,OAAO,MAAM;AAAA,MAC1B,CAAC;AAED,aAAO,YAAY,aAAa,OAAO,MAAM,SAAS,IAAI,eAAe,SAAS;AAAA,IACpF;AAEA,QAAI,OAAO,MAAM,aAAa;AAC5B,UAAI,OAAO,KAAK,8CAA8C;AAAA,QAC5D,YAAY,OAAO,MAAM;AAAA,MAC3B,CAAC;AAAA,IACH;AAEA,WAAO,OAAO,MAAM;AAAA,EACtB;AACF;AAKA,SAAS,wBAAoC;AAC3C,SAAO,OAAO,MAAM,KAAK,SAAS;AAChC,UAAM,YAAY,gBAAgB,EAAE,IAAI;AACxC,QAAI,OAAO,KAAK,yBAAyB;AAEzC,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,MAAM,GAAG;AACnC,YAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAE7C,UAAI,OAAO,YAAY,MAAM;AAC3B,YAAI,OAAO,KAAK,uCAAuC,EAAE,WAAW,CAAC;AAAA,MACvE,OAAO;AACL,YAAI,OAAO,KAAK,4BAA4B,EAAE,WAAW,CAAC;AAAA,MAC5D;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAC7C,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAI,OAAO,MAAM,yBAAyB,iBAAiB,QAAQ,QAAQ,QAAW;AAAA,QACpF;AAAA,MACF,CAAC;AACD,aAAO,YAAY,YAAY,mBAAmB,OAAO,IAAI,IAAI,eAAe,SAAS;AAAA,IAC3F;AAAA,EACF;AACF;AAKA,SAAS,kBAAkB,aAAuC;AAChE,SAAO,CAAC,MAAM,KAAK,iBAAiB;AAClC,UAAM,WAAW,CAAC,OAAe,gBAA8C;AAC7E,UAAI,SAAS,YAAY,QAAQ;AAC/B,eAAO,aAAa,aAAa,GAAG;AAAA,MACtC;AACA,YAAM,aAAa,YAAY,KAAK;AACpC,UAAI,eAAe,QAAW;AAC5B,eAAO,aAAa,aAAa,GAAG;AAAA,MACtC;AACA,aAAO,WAAW,aAAa,KAAK,CAAC,aAAa,SAAS,QAAQ,GAAG,QAAQ,CAAC;AAAA,IACjF;AACA,WAAO,SAAS,GAAG,IAAI;AAAA,EACzB;AACF;AAGA,SAAS,mBAAmB,aAA2B,MAAkC;AACvF,MAAI,KAAK,UAAU,MAAM;AACvB,gBAAY,KAAK,sBAAsB,CAAC;AAAA,EAC1C;AACF;AAGA,SAAS,uBACP,aACA,QACA,MACM;AACN,MAAI,KAAK,cAAc,QAAQ,OAAO,gBAAgB,QAAW;AAC/D,UAAM,UACJ,OAAO,uBAAuB,cAC1B,OAAO,cACP,IAAI,YAAY,OAAO,WAAW;AACxC,gBAAY,KAAK,0BAA0B,OAAO,CAAC;AAAA,EACrD;AACF;AAGA,SAAS,wBACP,aACA,QACA,MACM;AACN,MAAI,KAAK,eAAe,QAAQ,OAAO,WAAW,QAAW;AAC3D,gBAAY,KAAK,2BAA2B,OAAO,MAAM,CAAC;AAAA,EAC5D;AACF;AAGA,SAAS,oBACP,aACA,QACA,MACM;AACN,MAAI,KAAK,WAAW,QAAQ,OAAO,mBAAmB,QAAW;AAC/D,UAAM,OAAO,OAAO,iBAAiB;AACrC,gBAAY;AAAA,MACV,uBAAuB,OAAO,gBAAgB,OAAO,UAAU,MAAM,OAAO,YAAY;AAAA,IAC1F;AAAA,EACF;AACF;AAGA,SAAS,qBACP,aACA,QACA,MACM;AACN,MAAI,KAAK,YAAY,QAAQ,OAAO,YAAY,QAAW;AACzD,UAAM,QAAQ,IAAI,aAAa,OAAO,OAAO;AAC7C,gBAAY,KAAK,wBAAwB,OAAO,OAAO,QAAQ,CAAC;AAAA,EAClE;AACF;AAUA,SAAS,0BACP,aACA,QACA,MACM;AACN,MAAI,KAAK,iBAAiB,MAAM;AAC9B,gBAAY,KAAK,kCAAkC,OAAO,QAAQ,CAAC;AAAA,EACrE;AACF;AAGA,SAAS,qBAAqB,QAA6C;AACzE,QAAM,OAAO,OAAO,QAAQ,CAAC;AAC7B,QAAM,cAA4B,CAAC;AAEnC,cAAY,KAAK,wBAAwB,CAAC;AAC1C,qBAAmB,aAAa,IAAI;AACpC,yBAAuB,aAAa,QAAQ,IAAI;AAChD,0BAAwB,aAAa,QAAQ,IAAI;AACjD,sBAAoB,aAAa,QAAQ,IAAI;AAC7C,4BAA0B,aAAa,QAAQ,IAAI;AACnD,uBAAqB,aAAa,QAAQ,IAAI;AAE9C,SAAO;AACT;AAcO,SAAS,sBACd,QACmD;AACnD,QAAMC,UAAS,OAAO,UAAU,aAAa,EAAE,MAAM,OAAO,SAAS,CAAC;AACtE,QAAM,cAAc,qBAAqB,MAAM;AAC/C,QAAM,WAAW,kBAAkB,WAAW;AAE9C,SAAO,CAAC,YAAkD;AACxD,WAAO,OAAO,SAAuC;AACnD,YAAM,iBAAiB,qBAAqB,EAAE,UAAU,OAAO,SAAS,CAAC;AACzE,YAAM,gBAAgBA,QAAO,MAAM,kBAAkB,cAAc,CAAC;AACpE,YAAM,MAAyB,EAAE,gBAAgB,QAAQ,cAAc;AACvE,aAAO,SAAS,MAAM,KAAK,CAAC,WAAW,aAAa,QAAQ,WAAW,QAAQ,CAAC;AAAA,IAClF;AAAA,EACF;AACF;AAUO,SAAS,eACd,UACA,SACA,SACa;AAGb,QAAM,SAAgC;AAAA,IACpC;AAAA,IACA,GAAG;AAAA,EACL;AAEA,QAAM,QAAQ,sBAAsB,MAAM;AAG1C,QAAM,iBAA0C,CAAC,MAAM,QAAQ;AAE7D,QAAI,QAAQ,UAAU,GAAG;AACvB,aAAO,QAAQ,MAAM,GAAG;AAAA,IAC1B;AACA,WAAQ,QAAwB,IAAI;AAAA,EACtC;AAEA,SAAO,MAAM,cAAc;AAC7B;;;AhBzYO,IAAM,yBAAwC;AAAA,EACnD,kBAAkB,aAAa;AAAA,EAC/B,cAAc,aAAa;AAAA,EAC3B,eAAe;AAAA,EACf,eAAe;AACjB;AAMO,IAAM,wBAAgD;AAAA,EAC3D,GAAG,aAAa;AAClB;AAOO,SAAS,eACd,UACA,UACA,YACQ;AAER,MAAI,eAAe,QAAW;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,UAAU,SAAS;AACzC,QAAM,YAAY,gBAAgB,QAAQ;AAC1C,MAAI,cAAc,QAAW;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,sBAAsB,QAAQ;AACrD,MAAI,mBAAmB,QAAW;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,SAAS,oBAAoB,uBAAuB;AACvE;AAmCA,SAAS,iBACP,UACA,YACkC;AAClC,QAAM,gBAAgB,UAAU,WAAW;AAE3C,SAAO;AAAA,IACL,kBAAkB,cAAc,cAAc;AAAA,IAC9C,cAAc,cAAc;AAAA,IAC5B,eAAe,cAAc;AAAA,EAC/B;AACF;AA+DO,SAAS,oBACd,UACA,SACA,SAIa;AACb,SAAO,eAAe,UAAU,SAAS;AAAA,IACvC,SAAS,iBAAiB,QAAW,SAAS,SAAS;AAAA,IACvD,QAAQ,SAAS;AAAA,EACnB,CAAC;AACH;AAiBA,IAAM,gBAAgB,aAAqB,EAAE,WAAW,eAAe,CAAC;AAGxE,SAAS,uBAAuB,OAA6C;AAC3E,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK,OAAO;AAC1B,QAAM,SAAS,KAAK;AACpB,MAAI,UAAU,UAAa,WAAW,OAAW,QAAO;AAExD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,kBAAkB,CAAC,UAAkB,UAAmB;AACtD,YAAM,SAAkC;AAAA,QACtC,eAAe;AAAA,QACf;AAAA,MACF;AACA,UAAI,UAAU,OAAW,QAAO,OAAO,IAAI;AAC3C,aAAO,EAAE,QAAQ,0BAA0B,OAAO,CAAC,EAAE,MAAM,CAACC,SAAiB;AAC3E,sBAAc,MAAM,wCAAwC;AAAA,UAC1D,OAAO,gBAAgBA,IAAG;AAAA,QAC5B,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAgBA,SAAS,gBACP,SACA,MACA,aACA,QACwB;AACxB,QAAM,MAAM,MAA8B,QAAQ,IAAI;AAGtD,MAAI,WAAW,UAAa,gBAAgB,QAAW;AACrD,WAAO,mBAAmB,IAAI,QAAQ,MAAM,uBAAuB,IAAI,aAAa,GAAG,CAAC;AAAA,EAC1F;AACA,MAAI,WAAW,QAAW;AACxB,WAAO,mBAAmB,IAAI,QAAQ,GAAG;AAAA,EAC3C;AACA,MAAI,gBAAgB,QAAW;AAC7B,WAAO,uBAAuB,IAAI,aAAa,GAAG;AAAA,EACpD;AACA,SAAO,IAAI;AACb;AAWO,SAAS,cACd,SAC2D;AAC3D,SAAO,CAAC,MAAe,UAAmB;AACxC,UAAM,cAAc,uBAAuB,KAAK;AAChD,UAAM,SAAU,OAAgC;AAChD,WAAO,gBAAgB,SAAS,MAAM,aAAa,MAAM;AAAA,EAC3D;AACF;AAYO,IAAM,qCAAqC;AAa3C,IAAM,sCAAsC;AA6BnD,IAAM,cAAc,oBAAI,IAAY;AAGpC,SAAS,2BAA2B,OAAmC;AACrE,MAAI;AACF,UAAM,OAAO,KAAK,gBAAgB,GAAG,mCAAmC;AACxE,UAAM,MAAM,QAAQ,IAAI;AACxB,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,UAAI,CAAC,WAAW,GAAG,EAAG,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACxD,kBAAY,IAAI,GAAG;AAAA,IACrB;AACA,mBAAe,MAAM,KAAK,UAAU,KAAK,IAAI,MAAM,OAAO;AAAA,EAC5D,SAASA,MAAK;AACZ,kBAAc,MAAM,uDAAuD;AAAA,MACzE,OAAO,gBAAgBA,IAAG;AAAA,IAC5B,CAAC;AAAA,EACH;AACF;AAGA,SAAS,+BAA+B,QAA2C;AACjF,QAAM,WAAW,OAAO,QAAQ,oBAAoB;AACpD,MAAI,aAAa,QAAQ,OAAO,aAAa,YAAY,mBAAmB,UAAU;AACpF,UAAM,MAAO,SAAyC;AACtD,QAAI,OAAO,QAAQ,SAAU,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAGA,SAAS,8BAA8B,QAA2C;AAChF,QAAM,QAAQ,OAAO,QAAQ,CAAC;AAC9B,MAAI,OAAO,SAAS,UAAU,OAAO,MAAM,SAAS,UAAU;AAC5D,WAAO,MAAM,KAAK,MAAM,GAAG,GAAG;AAAA,EAChC;AACA,SAAO;AACT;AAmBA,SAAS,mBACP,KACA,SACA,IACA,SACsB;AACtB,QAAM,KAAK,KAAK,IAAI;AACpB,SAAO;AAAA,IACL;AAAA,IACA,UAAU,IAAI;AAAA,IACd,qBAAqB,IAAI;AAAA,IACzB,iBAAiB;AAAA,IACjB,WAAW,IAAI,KAAK,EAAE,EAAE,YAAY;AAAA,IACpC,SAAS,IAAI,KAAK,EAAE,EAAE,YAAY;AAAA,IAClC,YAAY,KAAK;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,GAAI,QAAQ,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,IACtF,GAAI,QAAQ,iBAAiB,SAAY,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;AAAA,EACrF;AACF;AAGA,SAAS,eAAe,QAAwC;AAC9D,MAAI,OAAO,YAAY,KAAM,QAAO,EAAE,SAAS,UAAU;AACzD,QAAM,gBAAgB,+BAA+B,MAAM;AAC3D,QAAM,eAAe,8BAA8B,MAAM;AACzD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,EACvD;AACF;AAGA,eAAe,kBAAkB,KAAkD;AACjF,QAAM,UAAU,WAAW;AAC3B,QAAM,KAAK,KAAK,IAAI;AACpB,MAAI,IAAI;AAAA,IACN;AAAA,IACA;AAAA,MACE,MAAM,IAAI;AAAA,MACV;AAAA,MACA,qBAAqB,IAAI;AAAA,MACzB,iBAAiB;AAAA,MACjB,aACE;AAAA,IACJ;AAAA,EACF;AACA,MAAI;AACF,UAAM,SAAS,MAAM,gBAAgB,IAAI,SAAS,IAAI,MAAM,IAAI,aAAa,IAAI,MAAM;AACvF,+BAA2B,mBAAmB,KAAK,SAAS,IAAI,eAAe,MAAM,CAAC,CAAC;AACvF,WAAO;AAAA,EACT,SAASA,MAAK;AACZ;AAAA,MACE,mBAAmB,KAAK,SAAS,IAAI;AAAA,QACnC,SAAS;AAAA,QACT,cAAc,gBAAgBA,IAAG,EAAE,MAAM,GAAG,GAAG;AAAA,MACjD,CAAC;AAAA,IACH;AACA,UAAMA;AAAA,EACR;AACF;AA0BO,SAAS,6BACd,SACA,UACA,qBACAC,SAC2D;AAC3D,QAAM,MAAMA,WAAU;AACtB,SAAO,CAAC,MAAe,UAAmB;AACxC,UAAM,cAAc,uBAAuB,KAAK;AAChD,UAAM,SAAU,OAAgC;AAChD,UAAM,aACJ,sBAAsB,sCAAsC,gBAAgB;AAC9E,QAAI,CAAC,WAAY,QAAO,gBAAgB,SAAS,MAAM,aAAa,MAAM;AAC1E,WAAO,kBAAkB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AiB1eO,SAAS,iBAAiB,KAAqB,UAAmC;AACvF,QAAM,SAAS,IAAI;AACnB,QAAM,WAAW,OAAO;AACxB,MAAI,aAAa,UAAa,SAAS,SAAS,GAAG;AACjD,WAAO;AAAA,MACL,MAAM,SAAS,SAAS,KAAK,IAAI,aAAa,SAAS,SAAS,KAAK,IAAI,UAAU;AAAA,MACnF,IAAI;AAAA,MACJ,MAAM,OAAO;AAAA,IACf;AAAA,EACF;AACA,SAAO,YAAY,EAAE,MAAM,UAAU,IAAI,WAAW,MAAM,iBAAiB;AAC7E;AAKO,SAAS,gBACd,SACA,gBACc;AACd,MAAI,eAAgB,QAAO;AAC3B,MAAI,YAAY,KAAM,QAAO;AAC7B,SAAO;AACT;AAgBO,SAAS,uBAAuB,MAAmC;AACxE,OAAK,YAAY,kBAAkB;AAAA,IACjC,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,IACd,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,cAAc,KAAK;AAAA,EACrB,CAAC;AACH;AAgBO,SAAS,eAAe,MAAgC;AAC7D,OAAK,YAAY,kBAAkB;AAAA,IACjC,YAAY,KAAK;AAAA,IACjB,UAAU,KAAK;AAAA,IACf,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK;AAAA,EAClB,CAAC;AACH;AAeO,SAAS,kBAAkB,MAAmC;AACnE,OAAK,YAAY,sBAAsB;AAAA,IACrC,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK;AAAA,EAClB,CAAC;AACH;;;ACxFA,IAAM,wBACJ;AAMF,IAAM,sBAAwE;AAAA,EAC5E,EAAE,MAAM,0BAA0B,SAAS,mDAAmD;AAAA,EAC9F,EAAE,MAAM,sBAAsB,SAAS,sDAAsD;AAAA,EAC7F,EAAE,MAAM,sBAAsB,SAAS,yDAAyD;AAClG;AAMA,SAAS,eAAe,OAAuD;AAC7E,wBAAsB,YAAY;AAClC,QAAM,UAAU,MAAM,QAAQ,uBAAuB,EAAE;AACvD,SAAO,EAAE,SAAS,UAAU,YAAY,MAAM;AAChD;AAKA,SAAS,eAAe,OAAyB;AAC/C,QAAM,WAAqB,CAAC;AAC5B,aAAW,EAAE,MAAM,QAAQ,KAAK,qBAAqB;AACnD,YAAQ,YAAY;AACpB,QAAI,QAAQ,KAAK,KAAK,GAAG;AACvB,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,cAAc,OAAgB,OAAuD;AAC5F,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,WAAW,eAAe,KAAK;AACrC,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,SAAS,KAAK,GAAG,QAAQ;AAAA,IACjC;AACA,UAAM,EAAE,SAAS,SAAS,IAAI,eAAe,KAAK;AAClD,QAAI,SAAU,OAAM;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,cAAc,MAAM,KAAK,CAAC;AAAA,EACvD;AAEA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,KAAgC,GAAG;AACzE,aAAO,GAAG,IAAI,cAAc,KAAK,KAAK;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AASO,SAAS,kBAAkB,MAAwC;AACxE,MAAI,SAAS,UAAa,SAAS,MAAM;AACvC,WAAO,EAAE,WAAW,MAAM,aAAa,OAAO,eAAe,GAAG,kBAAkB,CAAC,EAAE;AAAA,EACvF;AAEA,QAAM,QAAQ,EAAE,OAAO,GAAG,UAAU,CAAC,EAAc;AACnD,QAAM,YAAY,cAAc,MAAM,KAAK;AAC3C,QAAM,iBAAiB,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC;AAElD,SAAO;AAAA,IACL;AAAA,IACA,aAAa,MAAM,QAAQ;AAAA,IAC3B,eAAe,MAAM;AAAA,IACrB,kBAAkB;AAAA,EACpB;AACF;AAKO,SAAS,sBACd,QACAC,SACA,UACM;AACN,MAAI,OAAO,aAAa;AACtB,IAAAA,QAAO,KAAK,2DAAsD;AAAA,MAChE,MAAM;AAAA,MACN,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AACA,MAAI,OAAO,iBAAiB,SAAS,GAAG;AACtC,IAAAA,QAAO,KAAK,6CAA6C;AAAA,MACvD,MAAM;AAAA,MACN,UAAU,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AACF;;;ACpDA,SAAS,eAAe,aAAiC;AACvD,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf,SAAS,qCAAqC,OAAO,WAAW,CAAC;AAAA,EACnE,CAAC;AACH;AAMA,SAAS,kBAAkB,QAAgB,WAA+B;AACxE,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf,SAAS,kBAAkB,MAAM,cAAc,SAAS;AAAA,EAC1D,CAAC;AACH;AAKA,SAAS,cAAc,SAAiB,WAA+B;AACrE,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf,SAAS,mBAAmB,OAAO,cAAc,SAAS;AAAA,EAC5D,CAAC;AACH;AAOA,IAAM,uBAAuB,KAAK,OAAO;AAMzC,IAAM,kBAAqC;AAAA;AAAA,EAEzC;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF;AAGA,SAASC,gBAAe,MAAcC,SAAyB;AAC7D,MAAI,YAAY;AAChB,aAAW,WAAW,iBAAiB;AACrC,QAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,MAAAA,QAAO,KAAK,uDAAuD;AAAA,QACjE,SAAS,QAAQ,OAAO,MAAM,GAAG,EAAE;AAAA,MACrC,CAAC;AACD,kBAAY,UAAU,QAAQ,SAAS,YAAY;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,mBAAmB,QAAoBA,SAAuB;AACrE,aAAW,QAAQ,OAAO,SAAS;AACjC,SAAK,OAAOD,gBAAe,KAAK,MAAMC,OAAM;AAAA,EAC9C;AACF;AAGA,SAAS,eAAe,MAAeA,SAAiB,WAAsC;AAC5F,MAAI,SAAS,OAAW,QAAO;AAC/B,QAAM,YAAY,KAAK,UAAU,IAAI,EAAE;AACvC,MAAI,YAAY,sBAAsB;AACpC,IAAAA,QAAO,KAAK,4BAA4B,EAAE,WAAW,OAAO,qBAAqB,CAAC;AAClF,WAAO,cAAc,mBAAmB,SAAS;AAAA,EACnD;AACA,SAAO;AACT;AAKA,SAAS,eAAe,aAA0BA,SAAoC;AACpF,QAAM,WAAW,YAAY,WAAW;AACxC,MAAI,CAAC,UAAU;AACb,UAAM,QAAQ,YAAY,SAAS;AACnC,IAAAA,QAAO,KAAK,qBAAqB;AACjC,WAAO,eAAe,MAAM,WAAW;AAAA,EACzC;AACA,SAAO;AACT;AAgBA,SAAS,YAAY,MAA6C;AAChE,QAAM,UAAU;AAAA,IACd,MAAM,KAAK;AAAA,IACX,GAAI,KAAK,gBAAgB,EAAE,cAAc,KAAK,aAAa;AAAA,EAC7D;AACA,QAAM,WAAW,KAAK,SAAS,SAAS,oBAAoB,KAAK,UAAU,KAAK,MAAM,OAAO,CAAC;AAE9F,MAAI,CAAC,SAAS,SAAS;AACrB,SAAK,OAAO,KAAK,gCAAgC;AAAA,MAC/C,QAAQ,SAAS;AAAA,MACjB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,WAAO,kBAAkB,SAAS,QAAQ,KAAK,SAAS;AAAA,EAC1D;AACA,OAAK,OAAO,MAAM,uBAAuB,EAAE,QAAQ,SAAS,OAAO,CAAC;AACpE,SAAO;AACT;AAKA,eAAe,eACb,SACA,MACA,KACAA,SACqB;AACrB,QAAM,YAAY,gBAAgB,EAAE,IAAI;AACxC,QAAM,SACJ,QAAQ,UAAU,IAAI,MAAM,QAAQ,MAAM,GAAG,IAAI,MAAO,QAAwB,IAAI;AAEtF,QAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAC7C,MAAI,OAAO,YAAY,MAAM;AAC3B,IAAAA,QAAO,KAAK,uCAAuC,EAAE,WAAW,CAAC;AAAA,EACnE,OAAO;AACL,IAAAA,QAAO,KAAK,4BAA4B,EAAE,WAAW,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAGA,SAAS,cACP,aACA,UACA,KACA,QACA,YACM;AACN,QAAM,QAAQ,iBAAiB,GAAG;AAClC,QAAM,UAAU,gBAAgB,OAAO,SAAS,KAAK;AACrD,cAAY,kBAAkB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAOA,SAAS,uBACP,aACA,UACA,KACA,YACM;AACN,QAAM,QAAQ,iBAAiB,GAAG;AAClC,cAAY,kBAAkB;AAAA,IAC5B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,WAAW,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAGA,SAAS,gBACP,aACA,UACA,KACA,QACM;AACN,QAAM,QAAQ,iBAAiB,GAAG;AAClC,cAAY,kBAAkB;AAAA,IAC5B,YAAY;AAAA,IACZ,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,IAAI;AAAA,EACjB,CAAC;AACH;AAGA,SAAS,mBACP,aACA,UACA,KACM;AACN,QAAM,QAAQ,iBAAiB,GAAG;AAClC,cAAY,sBAAsB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW,IAAI;AAAA,EACjB,CAAC;AACH;AAGA,SAAS,kBACP,QACA,gBACAA,SACmB;AACnB,QAAM,OAAO,OAAO,gBAAgB;AACpC,MAAI,SAAS,cAAc,eAAe,iBAAiB,WAAW,GAAG;AACvE,WAAO;AAAA,EACT;AACA,EAAAA,QAAO,KAAK,8CAA8C;AAAA,IACxD;AAAA,IACA,UAAU,eAAe;AAAA,EAC3B,CAAC;AAGD,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf,SACE,+CAA+C,eAAe,iBAAiB,KAAK,IAAI,CAAC;AAAA,EAE7F,CAAC;AACH;AAGA,SAAS,aACP,QACA,MACA,MACA,gBACAA,SACsD;AACtD,QAAM,aAAa,eAAe,MAAMA,SAAQ,eAAe,SAAS;AACxE,MAAI,WAAY,QAAO,EAAE,OAAO,YAAY,eAAe,KAAK;AAGhE,QAAM,iBAAiB,kBAAkB,IAAI;AAC7C,wBAAsB,gBAAgBA,SAAQ,OAAO,QAAQ;AAC7D,QAAM,gBAAgB,eAAe,cAAc,eAAe,YAAY;AAG9E,QAAM,YAAY,kBAAkB,QAAQ,gBAAgBA,OAAM;AAClE,MAAI,cAAc,KAAM,QAAO,EAAE,OAAO,WAAW,cAAc;AAEjE,MAAI,OAAO,aAAa;AACtB,UAAM,WAAW,eAAe,OAAO,aAAaA,OAAM;AAC1D,QAAI,UAAU;AACZ,UAAI,OAAO;AACT,2BAAmB,OAAO,aAAa,OAAO,UAAU,cAAc;AACxE,aAAO,EAAE,OAAO,UAAU,cAAc;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,OAAO,gBAAgB;AACzB,UAAM,UAAU,YAAY;AAAA,MAC1B,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,MAAM;AAAA,MACN;AAAA,MACA,cAAc,OAAO;AAAA,MACrB,QAAAA;AAAA,MACA,WAAW,eAAe;AAAA,IAC5B,CAAC;AACD,QAAI,SAAS;AACX,UAAI,OAAO;AACT,wBAAgB,OAAO,aAAa,OAAO,UAAU,gBAAgB,eAAe;AACtF,aAAO,EAAE,OAAO,SAAS,cAAc;AAAA,IACzC;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,MAAM,cAAc;AACtC;AASO,SAAS,oBACd,SACA,QACa;AACb,QAAMA,UAAS,OAAO,UAAU,aAAa,EAAE,MAAM,OAAO,SAAS,CAAC;AACtE,QAAM,OAAO,OAAO,iBAAiB;AAErC,SAAO,OAAO,SAAuC;AACnD,UAAM,UAAU;AAAA,MACd,UAAU,OAAO;AAAA,MACjB,GAAI,OAAO,cAAc,EAAE,QAAQ,OAAO,WAAW;AAAA,IACvD;AACA,UAAM,iBAAiB,qBAAqB,OAAO;AACnD,UAAM,gBAAgBA,QAAO,MAAM,kBAAkB,cAAc,CAAC;AACpE,kBAAc,KAAK,yBAAyB;AAE5C,UAAM,EAAE,OAAO,eAAe,cAAc,IAAI;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAe,QAAO;AAE1B,WAAO,gBAAgB,SAAS,eAAe,gBAAgB,eAAe,MAAM;AAAA,EACtF;AACF;AAOA,eAAe,gBACb,SACA,eACA,gBACA,eACA,QACqB;AACrB,QAAM,gBAAgB,gBAAgB,EAAE,IAAI;AAC5C,MAAI;AACF,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,EAAE,gBAAgB,QAAQ,cAAc;AAAA,MACxC;AAAA,IACF;AACA,uBAAmB,QAAQ,aAAa;AACxC,QAAI,OAAO,aAAa;AACtB;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,gBAAgB,EAAE,IAAI,IAAI;AAAA,MAC5B;AAAA,IACF;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,aAAa,iBAAiB,QAAQ,MAAM,UAAU;AAC5D,kBAAc,MAAM,yBAAyB,iBAAiB,QAAQ,QAAQ,MAAS;AACvF,QAAI,OAAO,aAAa;AACtB;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA,gBAAgB,EAAE,IAAI,IAAI;AAAA,MAC5B;AAAA,IACF;AAMA,UAAM,YAAYD,gBAAe,YAAY,aAAa;AAC1D,WAAO,cAAc,WAAW,eAAe,SAAS;AAAA,EAC1D;AACF;;;ACxaO,IAAM,cAAyC;AAAA,EACpD,WAAW;AAAA,EACX,UACE;AAAA,EACF,OAAO;AAAA,EACP,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,SACE;AAAA,EACF,eACE;AACJ;;;ACrBO,IAAM,oBAAN,MAAiD;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,YAAY,YAAyB,QAAkC;AACrE,SAAK,aAAa;AAClB,SAAK,mBAAmB,QAAQ;AAChC,SAAK,aAAa,OAAO,WAAW,IAAI;AACxC,SAAK,UAAU,WAAW,aAAa,EAAE;AACzC,SAAK,eAAe,KAAK,mBAAmB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAiD;AACvD,UAAM,OAA0B,CAAC,gBAAG,YAAY,gBAAG,QAAQ;AAG3D,QAAI,KAAK,WAAW,SAAS,UAAU;AACrC,WAAK,KAAK,gBAAG,iBAAiB;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,SAAqC;AAErD,UAAM,UAAU,QAAQ,SACrB,IAAI,CAAC,QAAQ;AACZ,YAAM,OACJ,OAAO,IAAI,YAAY,WACnB,IAAI,UACJ,IAAI,QACD,OAAO,CAAC,MAA2C,EAAE,SAAS,MAAM,EACpE,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AAClB,aAAO,IAAI,IAAI,IAAI,MAAM,IAAI;AAAA,IAC/B,CAAC,EACA,KAAK,MAAM;AAGd,UAAM,OAAgB,EAAE,QAAQ;AAEhC,QAAI,QAAQ,iBAAiB,QAAW;AACtC,MAAC,KAAkC,eAAe,QAAQ;AAAA,IAC5D;AACA,QAAI,QAAQ,cAAc,QAAW;AACnC,MAAC,KAA+B,YAAY,QAAQ;AAAA,IACtD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,UAA2C;AACtE,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,KAAK,CAAC;AAAA,MAC/C,OAAO;AAAA,QACL,aAAa,SAAS,OAAO,eAAe;AAAA,QAC5C,cAAc,SAAS,OAAO,gBAAgB;AAAA,QAC9C,aAAa,SAAS,OAAO,eAAe;AAAA,MAC9C;AAAA,MACA,YAAY;AAAA,MACZ,OAAO,SAAS,SAAS,KAAK;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,UAAgC;AACnD,UAAM,UAAU,SAAS,UAAU,SAAY,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC;AAC5E,WAAO,IAAI,WAAW,SAAS,SAAS,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,SAA6E;AAC1F,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,OACJ,KAAK,qBAAqB,SAAY,EAAE,WAAW,KAAK,iBAAiB,IAAI;AAC/E,UAAM,SAAS,MAAM,KAAK,WAAW,QAAQ,MAAM,IAAI;AAEvD,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,IAAI,KAAK,aAAa,OAAO,KAAK,CAAC;AAAA,IAC5C;AAEA,WAAO,GAAG,KAAK,qBAAqB,OAAO,KAAK,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,OAAO,SAAwD;AACpE,UAAM,SAAS,MAAM,KAAK,SAAS,OAAO;AAE1C,QAAI,CAAC,OAAO,IAAI;AACd,YAAM,OAAO;AAAA,IACf;AAEA,UAAM,WAAW,OAAO;AAExB,UAAM,EAAE,MAAM,iBAAiB,SAAS,EAAE,OAAO,SAAS,MAAM,EAAE;AAElE,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,SAAS,QAAQ,CAAC,KAAK,EAAE,MAAM,QAAQ,MAAM,GAAG;AAAA,IAChE;AAEA,UAAM,aAAa,SAAS,QAAQ,CAAC;AACrC,UAAM,OAAO,YAAY,SAAS,SAAS,WAAW,OAAO;AAC7D,UAAM,EAAE,MAAM,uBAAuB,OAAO,GAAG,OAAO,EAAE,MAAM,cAAc,KAAK,EAAE;AAEnF,UAAM,EAAE,MAAM,sBAAsB,OAAO,EAAE;AAE7C,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,SAAS,WAAW;AAAA,MAC1C,OAAO,SAAS;AAAA,IAClB;AAEA,UAAM,EAAE,MAAM,eAAe;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,MAA+B;AACzC,WAAO,QAAQ,QAAQ,eAAe,IAAI,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA4C;AAE1C,WAAO,GAAG,MAAS;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,UAAM,KAAK,WAAW,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,UAAM,KAAK,WAAW,QAAQ;AAAA,EAChC;AACF;AAQO,SAAS,wBACd,YACA,QACmB;AACnB,SAAO,IAAI,kBAAkB,YAAY,MAAM;AACjD;;;ACzNA,OAAOE,gBAAe;;;ACMf,IAAM,gBAAgB;AAAA,EAC3B,QAAQ,gBAAgB,aAAa;AAAA,EACrC,UAAU,gBAAgB,eAAe;AAAA,EACzC,SAAS,gBAAgB,cAAc;AACzC;AAQO,IAAM,uBAA+C;AAAA,EAC1D,iBAAiB,cAAc;AAAA,EAC/B,mBAAmB,cAAc;AAAA,EACjC,kBAAkB,cAAc;AAAA;AAAA,EAEhC,kBAAkB,cAAc;AAClC;AAuBO,IAAM,qBAAqB;;;AClDlC,OAAsB;AAYf,SAAS,cAAc,iBAA4C;AACxE,UAAQ,iBAAiB;AAAA,IACvB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,gBAAgB,OAA4C;AAC1E,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,EAC1C;AACA,MAAI,MAAM,SAAS,YAAY;AAC7B,UAAM,YAAY;AAClB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,IAAI,UAAU;AAAA,MACd,MAAM,UAAU;AAAA,MAChB,OAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,QAAQ,MAAM,GAAG;AAClC;AAKO,SAAS,WAAW,SAAgC;AACzD,QAAM,OAAO,QAAQ,SAAS,SAAS,SAAS;AAEhD,MAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,WAAO,EAAE,MAAM,SAAS,QAAQ,QAAQ;AAAA,EAC1C;AAGA,QAAM,UAAU,QAAQ,QAAQ,IAAI,CAAC,UAAU;AAC7C,QAAI,MAAM,SAAS,QAAQ;AACzB,aAAO,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK;AAAA,IACnD;AACA,QAAI,MAAM,SAAS,YAAY;AAC7B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM;AAAA,MACf;AAAA,IACF;AACA,QAAI,MAAM,SAAS,eAAe;AAChC,YAAM,aAKF;AAAA,QACF,MAAM;AAAA,QACN,aAAa,MAAM;AAAA,QACnB,SAAS,MAAM;AAAA,MACjB;AAEA,UAAI,MAAM,aAAa,QAAW;AAChC,mBAAW,WAAW,MAAM;AAAA,MAC9B;AACA,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,IAChB;AAAA,EACF,CAAC;AAED,SAAO,EAAE,MAAM,QAAQ;AACzB;AAKO,SAAS,QAAQ,MAAsC;AAC5D,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,cAAc,KAAK;AAAA,EACrB;AACF;AAaO,SAAS,eAAe,SAAyB;AACtD,QAAM,aAAa,gBAAgB,OAAO;AAC1C,MAAI,eAAe,OAAW,QAAO,gBAAgB,UAAU;AAC/D,SAAO;AACT;AAKO,SAAS,qBAAqB,SAA6C;AAChF,QAAM,eAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAGA,QAAM,aAAa,eAAe,OAAO;AACzC,MAAI,WAAW,SAAS,MAAM,KAAK,WAAW,SAAS,UAAU,GAAG;AAClE,iBAAa,KAAK,gBAAgB,iBAAiB;AAAA,EACrD;AAEA,SAAO;AACT;;;AChJA,OAAsB;AAOf,SAAS,iBACd,SACA,UACA,OACQ;AACR,QAAM,aAAa,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,OAAO;AACjF,SAAO,GAAG,QAAQ,IAAI,SAAS,SAAS,IAAI,UAAU;AACxD;AAKO,SAAS,0BAA0B,UAA+C;AACvF,SAAO,SACJ,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EACjC,IAAI,CAAC,MAAM;AACV,UAAM,OAAO,EAAE,SAAS,SAAS,SAAS;AAC1C,QAAI,OAAO,EAAE,YAAY,UAAU;AACjC,aAAO,EAAE,MAAM,SAAS,EAAE,QAAQ;AAAA,IACpC;AAEA,UAAM,UAAU,EAAE,QAAQ,IAAI,CAAC,UAAU;AACvC,UAAI,MAAM,SAAS,QAAQ;AACzB,eAAO,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK;AAAA,MACnD;AACA,UAAI,MAAM,SAAS,YAAY;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,OAAO,MAAM;AAAA,QACf;AAAA,MACF;AACA,UAAI,MAAM,SAAS,eAAe;AAChC,eAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa,MAAM;AAAA,UACnB,SAAS,MAAM;AAAA,QACjB;AAAA,MACF;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AACD,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB,CAAC;AACL;AAKO,SAAS,oBAAoB,UAAyC;AAC3E,QAAM,YAAY,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC1D,MAAI,cAAc,QAAW;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,UAAU;AACzC,WAAO,UAAU;AAAA,EACnB;AACA,SAAO,UAAU,QACd,OAAO,CAAC,MAA2C,EAAE,SAAS,MAAM,EACpE,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACd;;;AC5DO,SAAS,2BAA2B,SAAgD;AACzF,MAAI,QAAQ,iBAAiB,UAAa,QAAQ,iBAAiB,IAAI;AACrE,WAAO,QAAQ;AAAA,EACjB;AACA,SAAO,oBAAoB,QAAQ,QAAQ;AAC7C;;;AJ4CO,IAAM,gBAAN,cAA4B,YAAY;AAAA,EAC5B;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,YAAY,QAA6B;AACvC,UAAM,kBAAkB,eAAe,OAAO,OAAO;AAGrD,UAAM,aAAgC;AAAA,MACpC,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,cAAc,qBAAqB,OAAO,OAAO;AAAA,MACjD,QAAQ,OAAO;AAAA,IACjB;AAGA,QAAI,OAAO,YAAY,QAAW;AAChC,iBAAW,UAAU,OAAO;AAAA,IAC9B;AACA,QAAI,OAAO,YAAY,QAAW;AAChC,iBAAW,UAAU,OAAO;AAAA,IAC9B;AACA,QAAI,OAAO,eAAe,QAAW;AACnC,iBAAW,aAAa,OAAO;AAAA,IACjC;AAEA,UAAM,UAAU;AAEhB,SAAK,kBAAkB;AAGvB,kBAAc,OAAO,QAAQ,aAAa,OAAO,OAAO;AAGxD,SAAK,SAAS,IAAIC,WAAU;AAAA,MAC1B,QAAQ,OAAO;AAAA,MACf,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,YAAY,OAAO,cAAc;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMS,iBAA4C;AACnD,UAAM,aAAa,MAAM,eAAe;AACxC,QAAI,CAAC,WAAW,IAAI;AAClB,aAAO;AAAA,IACT;AAGA,UAAM,YAAY,uBAAuB,KAAK,OAAO,QAAQ,KAAK,YAAY,KAAK,OAAO;AAC1F,QAAI,CAAC,UAAU,GAAI,QAAO;AAE1B,WAAO,GAAG,MAAS;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,SAA6E;AAC1F,SAAK,WAAW,OAAO;AAEvB,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,kBAAkB,OAAO;AACrD,WAAK,YAAY,QAAQ;AACzB,aAAO,GAAG,QAAQ;AAAA,IACpB,SAAS,OAAO;AACd,aAAO,IAAI,KAAK,eAAe,KAAK,CAAC;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAO,SAAwD;AACpE,SAAK,WAAW,OAAO;AAEvB,UAAM,CAAC,YAAY,QAAQ,IAAI,aAA0B;AAGzD,SAAK,cAAc,SAAS,UAAU,EAAE,MAAM,CAAC,UAAmB;AAChE,YAAM,aAAa,KAAK,eAAe,KAAK;AAC5C,iBAAW,MAAM,UAAU;AAAA,IAC7B,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWS,YAAY,MAA+B;AAElD,WAAO,QAAQ,QAAQ,kBAAkB,EAAE,aAAa,MAAM,QAAQ,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAkB,SAAyD;AACvF,UAAM,SAAS,KAAK,mBAAmB,OAAO;AAC9C,UAAM,WAAW,MAAM,KAAK,OAAO,SAAS,OAAO,MAAM;AAEzD,WAAO,KAAK,YAAY,QAAQ;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cACZ,SACA,YAKe;AACf,QAAI;AACF,YAAM,SAAS,KAAK,mBAAmB,OAAO;AAC9C,YAAM,SAAS,KAAK,OAAO,SAAS,OAAO,MAAM;AAEjD,uBAAiB,SAAS,QAAQ;AAChC,cAAM,QAAQ,KAAK,eAAe,KAAK;AACvC,YAAI,OAAO;AACT,qBAAW,KAAK,KAAK;AAAA,QACvB;AAAA,MACF;AAEA,iBAAW,SAAS;AAAA,IACtB,SAAS,OAAO;AACd,YAAM,aAAa,KAAK,eAAe,KAAK;AAC5C,iBAAW,MAAM,UAAU;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBACN,SAC2C;AAE3C,UAAM,WAAW,QAAQ,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,IAAI,UAAU;AAEnF,UAAM,SAAoD;AAAA,MACxD,OAAO,KAAK;AAAA,MACZ;AAAA,MACA,YAAY,QAAQ,aAAa;AAAA,IACnC;AAGA,UAAM,eAAe,2BAA2B,OAAO;AACvD,QAAI,iBAAiB,QAAW;AAC9B,aAAO,SAAS;AAAA,IAClB;AAGA,SAAK,oBAAoB,QAAQ,OAAO;AAExC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBACN,QACA,SACM;AACN,QAAI,QAAQ,gBAAgB,QAAW;AAErC,aAAO,cAAc,QAAQ;AAAA,IAC/B;AAEA,QAAI,QAAQ,SAAS,UAAa,QAAQ,KAAK,SAAS,GAAG;AACzD,aAAO,iBAAiB,QAAQ;AAAA,IAClC;AAEA,QAAI,QAAQ,UAAU,UAAa,QAAQ,MAAM,SAAS,GAAG;AAC3D,aAAO,QAAQ,QAAQ,MAAM,IAAI,OAAO;AAAA,IAC1C;AAGA,QAAI,QAAQ,mBAAmB,UAAa,QAAQ,eAAe,SAAS,QAAQ;AAClF,WAAK,OAAO,KAAK,qDAAqD;AAAA,QACpE,iBAAiB,QAAQ,eAAe;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,UAAiD;AACnE,UAAM,UAA0B,SAAS,QAAQ,IAAI,eAAe;AAEpE,UAAM,QAAoB;AAAA,MACxB,aAAa,SAAS,MAAM;AAAA,MAC5B,cAAc,SAAS,MAAM;AAAA,MAC7B,aAAa,SAAS,MAAM,eAAe,SAAS,MAAM;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY,cAAc,SAAS,WAAW;AAAA,MAC9C,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,OAA+C;AACpE,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,EAAE,OAAO,MAAM,QAAQ,MAAM;AAAA,QACxC;AAAA,MAEF,KAAK;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,MAAM;AAAA,UACb,cAAc,gBAAgB,MAAM,aAAa;AAAA,QACnD;AAAA,MAEF,KAAK;AACH,YAAI,MAAM,MAAM,SAAS,cAAc;AACrC,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,OAAO,MAAM;AAAA,YACb,OAAO,EAAE,MAAM,cAAc,MAAM,MAAM,MAAM,KAAK;AAAA,UACtD;AAAA,QACF;AACA,eAAO;AAAA,MAET,KAAK;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,MAAM;AAAA,QACf;AAAA,MAEF,KAAK;AACH,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,EAAE,aAAa,cAAc,MAAM,MAAM,eAAe,IAAI,EAAE;AAAA,UACrE,OAAO;AAAA,YACL,aAAa;AAAA;AAAA,YACb,cAAc,MAAM,MAAM;AAAA,YAC1B,aAAa,MAAM,MAAM;AAAA,UAC3B;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,EAAE,MAAM,eAAe;AAAA,MAEhC;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAgD;AACpD,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,KAAK,gBAAgB,QAAQ,MAAM,KAAK,YAAY,YAAY,2BAA2B;AAC7F,aAAO,KAAK,YAAY;AAAA,IAC1B;AACA,QAAI,KAAK,mBAAmB,KAAM,QAAO,KAAK;AAC9C,UAAM,WAAW,KAAK,YAAY;AAClC,SAAK,iBAAiB;AACtB,QAAI;AACF,YAAM,QAAQ,MAAM;AACpB,WAAK,cAAc,EAAE,OAAO,WAAW,KAAK,IAAI,EAAE;AAClD,aAAO;AAAA,IACT,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,cAA6E;AAAA,EAC7E,iBAA2D;AAAA,EAEnE,MAAc,cAAiD;AAC7D,UAAM,OAAO,MAAM,KAAK,OAAO,OAAO,KAAK;AAC3C,UAAM,MAAuB,CAAC;AAC9B,eAAW,KAAK,KAAK,MAAM;AACzB,YAAM,QAAuB,EAAE,IAAI,EAAE,GAAG;AACxC,UAAI,OAAO,EAAE,eAAe,UAAU;AACpC,cAAM,KAAK,KAAK,MAAM,EAAE,UAAU;AAClC,YAAI,CAAC,OAAO,MAAM,EAAE,GAAG;AACrB,cAAI,KAAK,EAAE,GAAG,OAAO,SAAS,aAAa,WAAW,KAAK,MAAM,KAAK,GAAI,EAAE,CAAC;AAC7E;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,EAAE,GAAG,OAAO,SAAS,YAAY,CAAC;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,4BAA4B,IAAI,KAAK;AAiBpC,SAAS,oBAAoB,QAA4C;AAC9E,SAAO,IAAI,cAAc,MAAM;AACjC;;;AKtVA,SAAS,uBACP,KACA,aACiB;AACjB,QAAM,UAAU,IAAI,WAAW;AAC/B,MAAI,OAAO,YAAY,YAAY;AACjC,UAAM,IAAI,MAAM,0CAA0C,WAAW,EAAE;AAAA,EACzE;AACA,SAAO;AACT;AAQA,SAAS,sBAAsB,KAA8C;AAC3E,QAAM,eAAe,IAAI,cAAc;AACvC,QAAM,aAAa,IAAI,YAAY;AACnC,MAAI,OAAO,iBAAiB,YAAY;AACtC,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,MAAI,OAAO,eAAe,YAAY;AACpC,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,cAAc,YAA2B,WAAwC;AACxF,MAAI,cAAc,OAAW,QAAO;AACpC,QAAM,SAAS,kBAAkB,UAAU;AAC3C,SAAO,QAAQ,IAAI,MAAM;AAC3B;AAUA,SAAS,gCAAgC,QAA8C;AACrF,MAAI,OAAO,eAAe,gBAAiB,QAAO;AAClD,QAAM,MAAM,OAAO,WAAW,QAAQ,IAAI,uBAAuB;AACjE,QAAM,YAAY,yBAAyB,GAAG;AAC9C,MAAI,CAAC,UAAU,GAAI,OAAM,UAAU;AACnC,SAAO,UAAU,MAAM,SAAS;AAClC;AAKA,SAAS,gBAAgB,QAAkD;AACzE,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,gBAAgB,OAA2B;AAClD,MAAI,qBAAqB,KAAK,GAAG;AAC/B,WAAO,UAAU;AAAA,EACnB;AACA,QAAM,UAAU,gBAAgB,KAAK,EAAE,YAAY;AACnD,MAAI,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS,WAAW,GAAG;AAChE,WAAO,UAAU;AAAA,EACnB;AACA,MAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,cAAc,KAAK,QAAQ,SAAS,SAAS,GAAG;AAC9F,WAAO,UAAU;AAAA,EACnB;AACA,SAAO,UAAU;AACnB;AASO,IAAM,aAAN,cAAyB,YAAY;AAAA,EACzB;AAAA,EACT;AAAA,EACA;AAAA,EACS;AAAA;AAAA,EAEA;AAAA;AAAA,EAET;AAAA,EAER,YAAY,QAA0BC,SAAkB;AACtD,UAAM,SAAS,cAAc,OAAO,YAAY,OAAO,MAAM;AAC7D,UAAM;AAAA,MACJ,YAAY,OAAO,OAAO,UAAU;AAAA,MACpC,SAAS,OAAO;AAAA,MAChB,cAAc,CAAC,gBAAgB,YAAY,gBAAgB,SAAS;AAAA,MACpE,QAAQA,WAAU,aAAa,EAAE,SAAS,OAAO,OAAO,UAAU,GAAG,CAAC;AAAA,MACtE,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,MACzC,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MAClE,GAAI,OAAO,eAAe,SAAY,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,IAC7E,CAAC;AACD,SAAK,gBAAgB,OAAO;AAC5B,SAAK,YAAY;AACjB,SAAK,gBAAgB,gCAAgC,MAAM;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,oBAAmC;AAC/C,QAAI,KAAK,UAAU,OAAW;AAE9B,QAAI,KAAK,gBAAgB,QAAW;AAClC,YAAM,KAAK;AACX;AAAA,IACF;AACA,SAAK,cAAc,KAAK,aAAa;AACrC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,UAAE;AACA,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAc,eAA8B;AAC1C,UAAM,SAAS,cAAc,KAAK,eAAe,KAAK,UAAU,MAAM;AACtE,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,kBAAkB,kBAAkB,KAAK,aAAa,IAAI;AAAA,QAClE,MAAM,UAAU;AAAA,MAClB,CAAC;AAAA,IACH;AAGA,UAAM,iBAAiB,MAAM,KAAK,aAAa,MAAM;AACrD,SAAK,QAAQ,eAAe;AAG5B,UAAM,WAAW,MAAM,OAAO,IAAI;AAClC,SAAK,eAAe,sBAAsB,QAAQ;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,aAAa,QAAgD;AACzE,YAAQ,KAAK,eAAe;AAAA,MAC1B,KAAK,aAAa;AAChB,cAAM,MAAM,MAAM,OAAO,mBAAmB;AAC5C,cAAM,UAAU,uBAAuB,KAAK,iBAAiB;AAC7D,cAAM,WAAW,QAAQ,EAAE,OAAO,CAAC;AACnC,eAAO,EAAE,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MACzC;AAAA,MACA,KAAK,UAAU;AACb,cAAM,MAAM,MAAM,OAAO,gBAAgB;AACzC,cAAM,UAAU,uBAAuB,KAAK,cAAc;AAC1D,cAAM,WAAW,QAAQ,EAAE,OAAO,CAAC;AACnC,eAAO,EAAE,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MACzC;AAAA,MACA,KAAK,UAAU;AACb,cAAM,MAAM,MAAM,OAAO,gBAAgB;AACzC,cAAM,UAAU,uBAAuB,KAAK,0BAA0B;AACtE,cAAM,WAAW,QAAQ,EAAE,OAAO,CAAC;AACnC,eAAO,EAAE,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MACzC;AAAA,MACA,KAAK,iBAAiB;AAKpB,cAAM,MAAM,MAAM,OAAO,gBAAgB;AACzC,cAAM,UAAU,uBAAuB,KAAK,cAAc;AAC1D,cAAM,OAAgC,EAAE,OAAO;AAC/C,YAAI,KAAK,kBAAkB,OAAW,MAAK,SAAS,IAAI,KAAK;AAC7D,cAAM,WAAW,QAAQ,IAAI;AAC7B,eAAO,EAAE,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,SAAqD;AAC3E,UAAM,UAAmC;AAAA,MACvC,OAAO,KAAK;AAAA,MACZ,UAAU,QAAQ,SAAS,IAAI,CAAC,OAAO;AAAA,QACrC,MAAM,EAAE,SAAS,WAAW,WAAW,EAAE;AAAA,QACzC,SACE,OAAO,EAAE,YAAY,WACjB,EAAE,UACF,EAAE,QAAQ,IAAI,CAAC,MAAoB;AACjC,cAAI,EAAE,SAAS,OAAQ,QAAO,EAAE,MAAM,QAAiB,MAAM,EAAE,KAAK;AACpE,iBAAO;AAAA,QACT,CAAC;AAAA,MACT,EAAE;AAAA,IACJ;AAEA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,cAAQ,QAAQ,IAAI,QAAQ;AAAA,IAC9B;AACA,QAAI,QAAQ,gBAAgB,QAAW;AACrC,cAAQ,aAAa,IAAI,QAAQ;AAAA,IACnC;AACA,QAAI,QAAQ,cAAc,QAAW;AACnC,cAAQ,WAAW,IAAI,QAAQ;AAAA,IACjC;AACA,QAAI,QAAQ,SAAS,QAAW;AAC9B,cAAQ,eAAe,IAAI,QAAQ;AAAA,IACrC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,SAA6E;AAC1F,QAAI;AACF,YAAM,KAAK,kBAAkB;AAC7B,WAAK,WAAW,OAAO;AAEvB,YAAM,MAAM,KAAK;AACjB,UAAI,QAAQ,QAAW;AACrB,cAAM,IAAI;AAAA,UACR,kCAAkC,KAAK,UAAU,OAAO,gBAAgB,KAAK,aAAa;AAAA,QAE5F;AAAA,MACF;AACA,YAAM,UAAU,KAAK,gBAAgB,OAAO;AAC5C,YAAM,SAAS,MAAM,IAAI,aAAa,OAAO;AAE7C,YAAM,WAA+B;AAAA,QACnC,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,QAC7C,OAAO;AAAA,UACL,aAAa,OAAO,MAAM,eAAe;AAAA,UACzC,cAAc,OAAO,MAAM,gBAAgB;AAAA,UAC3C,aAAa,OAAO,MAAM,eAAe;AAAA,QAC3C;AAAA,QACA,YAAY,gBAAgB,OAAO,YAAY;AAAA,QAC/C,OAAO,OAAO,SAAS;AAAA,MACzB;AAEA,WAAK,YAAY,QAAQ;AACzB,aAAO,GAAG,QAAQ;AAAA,IACpB,SAAS,OAAgB;AACvB,YAAM,OAAO,gBAAgB,KAAK;AAClC,aAAO,KAAK,cAAc,OAAO,IAAI;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,OAAO,OAAO,SAAwD;AAIpE,UAAM,KAAK,kBAAkB;AAC7B,SAAK,WAAW,OAAO;AAEvB,UAAM,MAAM,KAAK;AACjB,QAAI,QAAQ,QAAW;AACrB,YAAM,IAAI,kBAAkB,iDAAiD;AAAA,QAC3E,MAAM,UAAU;AAAA,MAClB,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,KAAK,gBAAgB,OAAO;AAI5C,UAAM,EAAE,MAAM,iBAAiB,SAAS,EAAE,OAAO,KAAK,QAAQ,EAAE;AAEhE,UAAM,SAAS,IAAI,WAAW,OAAO;AACrC,QAAI,QAAQ;AACZ,UAAM,EAAE,MAAM,uBAAuB,OAAO,cAAc,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;AAErF,qBAAiB,QAAQ,OAAO,YAAY;AAC1C,YAAM;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA,OAAO,EAAE,MAAM,cAAc,KAAK;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,sBAAsB,MAAM;AAC1C;AACA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,MACjC,OAAO,EAAE,aAAa,GAAG,cAAc,GAAG,aAAa,EAAE;AAAA,IAC3D;AACA,UAAM,EAAE,MAAM,eAAe;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,OAAgB,MAAyD;AAC7F,UAAM,UAAU,gBAAgB,KAAK;AAIrC,UAAM,cAAc,eAAe,OAAO;AAC1C,UAAM,WAAW,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,WAAW;AACvE,SAAK,OAAO,MAAM,sBAAsB,KAAK,aAAa,KAAK,QAAQ;AAEvE,UAAM,aAAa,IAAI,kBAAkB,GAAG,KAAK,aAAa,eAAe,WAAW,IAAI;AAAA,MAC1F;AAAA,IACF,CAAC;AACD,WAAO,EAAE,IAAI,OAAO,OAAO,WAAW;AAAA,EACxC;AACF;;;AC/UA,IAAM,gBAAgB,aAAa,EAAE,WAAW,eAAe,CAAC;AAKhE,SAAS,aAAa,QAA2BC,SAAiD;AAChG,MAAI,OAAO,UAAU,QAAW;AAC9B,WAAO,OAAO;AAAA,EAChB;AACA,QAAM,cAAc,OAAO,eAAe;AAC1C,SAAO,cAAc,wBAAwB,EAAE,QAAAA,QAAO,CAAC,IAAI;AAC7D;AAOA,eAAe,cACb,QACAA,SACA,OACkC;AAClC,QAAM,eAAe,OAAO;AAE5B,QAAM,eACJ,OAAO,wBAAwB,SAC3B,EAAE,kBAAkB,OAAO,oBAAoB,IAC/C;AAGN,MAAI,iBAAiB,UAAc,MAAM,eAAe,cAAc,KAAK,GAAI;AAC7E,IAAAA,QAAO,KAAK,uBAAuB,EAAE,KAAK,aAAa,CAAC;AACxD,UAAMC,cAAa,iBAAiB,EAAE,KAAK,cAAc,QAAAD,QAAO,CAAC;AACjE,UAAMC,YAAW,WAAW;AAC5B,WAAO;AAAA,MACL,SAAS,wBAAwBA,aAAY,YAAY;AAAA,MACzD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,kBAAkB,YAAY;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,iBAAiB,KAAK;AAElD,MAAI,cAAc,WAAW,GAAG;AAC9B,IAAAD,QAAO,KAAK,2BAA2B;AACvC,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,cAAc,CAAC;AAEnC,MAAI,gBAAgB,QAAW;AAC7B,WAAO;AAAA,EACT;AAEA,EAAAA,QAAO,KAAK,qBAAqB,EAAE,KAAK,aAAa,WAAW,cAAc,CAAC;AAC/E,QAAM,aAAa,iBAAiB,EAAE,KAAK,aAAa,QAAAA,QAAO,CAAC;AAChE,QAAM,WAAW,WAAW;AAE5B,SAAO;AAAA,IACL,SAAS,wBAAwB,YAAY,YAAY;AAAA,IACzD,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,UAAU,WAAW;AAAA,IAC7B;AAAA,EACF;AACF;AAKA,SAAS,qBAAqB,WAA+B,QAAoC;AAC/F,QAAM,MAAM,aAAa,QAAQ,IAAI,MAAM;AAC3C,SAAO,QAAQ,UAAa,IAAI,SAAS,IAAI,MAAM;AACrD;AAOA,SAAS,cAAc,QAA2BA,SAA0C;AAE1F,QAAM,gBAAgB,gBAAgB,sBAAsB,QAAQ,CAAC;AACrE,QAAM,eAAe,gBAAgB,sBAAsB,OAAO,CAAC;AACnE,QAAM,gBAAgB,gBAAgB,sBAAsB,QAAQ,CAAC;AAGrE,QAAM,eAAe,qBAAqB,OAAO,iBAAiB,mBAAmB;AACrF,MAAI,iBAAiB,QAAW;AAC9B,IAAAA,QAAO,KAAK,+BAA+B,EAAE,OAAO,cAAc,CAAC;AACnE,WAAO;AAAA,MACL,SAAS,oBAAoB,EAAE,SAAS,eAAe,QAAQ,aAAa,CAAC;AAAA,MAC7E,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,+CAA+C,aAAa;AAAA,IACtE;AAAA,EACF;AAGA,QAAM,YAAY,qBAAqB,OAAO,cAAc,gBAAgB;AAC5E,MAAI,cAAc,QAAW;AAC3B,IAAAA,QAAO,KAAK,qCAAqC,EAAE,OAAO,aAAa,CAAC;AACxE,WAAO;AAAA,MACL,SAAS,IAAI,WAAW,EAAE,YAAY,UAAU,SAAS,cAAc,QAAQ,UAAU,CAAC;AAAA,MAC1F,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,uCAAuC,YAAY;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,YAAY,qBAAqB,OAAO,cAAc,mBAAmB;AAC/E,MAAI,cAAc,QAAW;AAC3B,IAAAA,QAAO,KAAK,wCAAwC,EAAE,OAAO,cAAc,CAAC;AAC5E,WAAO;AAAA,MACL,SAAS,IAAI,WAAW;AAAA,QACtB,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,0CAA0C,aAAa;AAAA,IACjE;AAAA,EACF;AAIA,QAAM,SAAS,uBAAuBA,OAAM;AAC5C,MAAI,WAAW,KAAM,QAAO;AAE5B,EAAAA,QAAO,KAAK,wCAAwC;AACpD,SAAO;AACT;AAQA,SAAS,uBAAuBA,SAA0C;AACxE,QAAM,YAAY,qBAAqB,QAAW,sBAAsB;AACxE,QAAM,gBAAgB,QAAQ,IAAI,2BAA2B;AAC7D,MAAI,cAAc,UAAa,kBAAkB,UAAa,kBAAkB,IAAI;AAClF,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,QAAQ,IAAI,oBAAoB,KAAK;AAC3D,EAAAA,QAAO,KAAK,mCAAmC;AAAA,IAC7C,OAAO;AAAA,IACP,SAAS;AAAA,EACX,CAAC;AACD,SAAO;AAAA,IACL,SAAS,IAAI,WAAW;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,IACD,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,6CAA6C,aAAa,YAAY,aAAa;AAAA,EAC7F;AACF;AAGA,eAAe,eACb,QACAA,SACA,OAC2B;AAC3B,QAAM,YAAY,MAAM,cAAc,QAAQA,SAAQ,KAAK;AAC3D,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,YAAY,cAAc,QAAQA,OAAM;AAC9C,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAGA,eAAe,eACb,QACAA,SACA,OAC2B;AAC3B,QAAM,YAAY,cAAc,QAAQA,OAAM;AAC9C,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,YAAY,MAAM,cAAc,QAAQA,SAAQ,KAAK;AAC3D,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAGA,eAAe,cACb,QACAA,SACA,OAC2B;AAC3B,QAAM,YAAY,MAAM,cAAc,QAAQA,SAAQ,KAAK;AAC3D,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAGA,SAAS,cAAc,QAA2BA,SAAmC;AACnF,QAAM,YAAY,cAAc,QAAQA,OAAM;AAC9C,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAsBA,eAAsB,kBAAkB,SAA4B,CAAC,GAA8B;AACjG,QAAMA,UAAS,OAAO,UAAU;AAChC,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,QAAQ,aAAa,QAAQA,OAAM;AAEzC,EAAAA,QAAO,KAAK,0BAA0B,EAAE,UAAU,cAAc,UAAU,OAAU,CAAC;AAErF,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,eAAe,QAAQA,SAAQ,KAAK;AAAA,IAC7C,KAAK;AACH,aAAO,eAAe,QAAQA,SAAQ,KAAK;AAAA,IAC7C,KAAK;AACH,aAAO,cAAc,QAAQA,SAAQ,KAAK;AAAA,IAC5C,KAAK;AACH,aAAO,cAAc,QAAQA,OAAM;AAAA,IACrC,SAAS;AACP,YAAM,aAAoB;AAC1B,YAAM,IAAI,MAAM,qBAAqB,OAAO,UAAU,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF;AACF;;;ACpUA,SAAS,cAAAE,mBAAkB;AAKpB,IAAM,2BAA2B;AAGjC,IAAM,oBAAoB;AAajC,IAAM,2BAA2B;AAgB1B,SAAS,eAAe,SAA+B;AAE5D,MAAI,QAAQ,SAAS,0BAA0B;AAC7C,UAAM,IAAI,MAAM,2CAA2C,OAAO,wBAAwB,CAAC,EAAE;AAAA,EAC/F;AAEA,MAAI,YAAY,KAAK;AACnB,WAAO;AAAA,EACT;AAGA,QAAM,uBAAuB;AAC7B,QAAM,kBAAkB,QAAQ,QAAQ,OAAO,oBAAoB;AAEnE,QAAM,UAAU,gBAAgB,QAAQ,sBAAsB,MAAM;AAEpE,QAAM,gBAAgB,QAAQ,QAAQ,IAAI,OAAO,sBAAsB,GAAG,GAAG,OAAO;AACpF,SAAO,IAAI,OAAO,IAAI,aAAa,GAAG;AACxC;AAKO,SAAS,oBAAoB,OAAe,OAAwB;AACzE,SAAO,MAAM,KAAK,KAAK;AACzB;AAKO,SAAS,kBAA0B;AACxC,SAAO,OAAO,OAAO,gBAAgB,EAAE,IAAI,CAAC,CAAC,IAAIC,YAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAC3E;AAKO,SAAS,yBAAyC;AACvD,SAAO,OAAO,OAAO,gBAAgB,EAAE,IAAI,CAAC,CAAC,IAAIA,YAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAC3E;AAwCO,SAAS,oBAAoB,SAAwB,QAAoC;AAC9F,MAAI,SAAwB;AAE5B,MAAI,OAAO,UAAU,UAAa,OAAO,UAAU,IAAI;AACrD,UAAM,QAAQ,eAAe,OAAO,KAAK;AACzC,aAAS,OAAO,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,KAAK,CAAC;AAAA,EACnE;AAEA,MAAI,OAAO,cAAc,UAAa,OAAO,cAAc,IAAI;AAC7D,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,cAAc,OAAO,SAAS;AAAA,EAChE;AAEA,MAAI,OAAO,kBAAkB,UAAa,OAAO,kBAAkB,IAAI;AACrE,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,kBAAkB,OAAO,aAAa;AAAA,EACxE;AAEA,SAAO,sBAAsB,QAAQ,MAAM;AAC7C;AAKO,SAAS,sBAAsB,QAAuB,QAAoC;AAC/F,MAAI,WAAW;AAEf,MAAI,OAAO,UAAU,UAAa,OAAO,UAAU,IAAI;AACrD,UAAM,iBAAiB,OAAO;AAC9B,eAAW,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,cAAc;AAAA,EAChE;AAEA,MAAI,OAAO,WAAW,UAAa,OAAO,WAAW,IAAI;AACvD,UAAM,kBAAkB,OAAO;AAC/B,eAAW,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,eAAe;AAAA,EACjE;AAEA,SAAO;AACT;AAKO,SAAS,kBAAkB,QAAuB,QAAoC;AAC3F,MAAI,OAAO,UAAU,UAAa,OAAO,QAAQ,GAAG;AAClD,WAAO,OAAO,MAAM,CAAC,OAAO,KAAK;AAAA,EACnC;AACA,SAAO;AACT;AAKO,SAAS,YAAY,OAAiC;AAC3D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,MAAM,WAAW,gBAAgB;AAAA,IAC1C,WAAW,MAAM,aAAa,gBAAgB,EAAE,OAAO;AAAA,EACzD;AACF;AAKO,SAAS,yBACd,OACA,eACQ;AACR,MAAI,QAAQ;AACZ,aAAW,UAAU,cAAc,OAAO,GAAG;AAC3C,QAAI,oBAAoB,OAAO,OAAO,KAAK,GAAG;AAC5C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACvLO,IAAM,iBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY7B,YAA6B,UAAkB;AAAlB;AAC3B,QAAI,WAAW,GAAG;AAChB,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AACA,SAAK,SAAS,IAAI,MAAqB,QAAQ;AAAA,EACjD;AAAA,EAhBiB;AAAA,EACT,OAAO;AAAA;AAAA,EACP,OAAO;AAAA;AAAA,EACP,QAAQ;AAAA;AAAA;AAAA;AAAA,EAkBhB,IAAI,OAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAmB;AACrB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAkB;AACpB,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,KAAK,MAAe;AAClB,SAAK,OAAO,KAAK,IAAI,IAAI;AACzB,SAAK,QAAQ,KAAK,OAAO,KAAK,KAAK;AAEnC,QAAI,KAAK,QAAQ,KAAK,UAAU;AAC9B,WAAK;AAAA,IACP,OAAO;AAEL,WAAK,QAAQ,KAAK,OAAO,KAAK,KAAK;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AAEZ,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,KAAK;AACtC,WAAK,OAAO,CAAC,IAAI;AAAA,IACnB;AACA,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAe;AACb,QAAI,KAAK,UAAU,GAAG;AACpB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAc,CAAC;AACrB,QAAI,YAAY,KAAK;AAErB,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,KAAK;AACnC,aAAO,KAAK,KAAK,OAAO,SAAS,CAAM;AACvC,mBAAa,YAAY,KAAK,KAAK;AAAA,IACrC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,EAAE,OAAO,QAAQ,IAAiB;AAChC,QAAI,YAAY,KAAK;AACrB,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,KAAK;AACnC,YAAM,KAAK,OAAO,SAAS;AAC3B,mBAAa,YAAY,KAAK,KAAK;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAA4B;AAC1B,QAAI,KAAK,UAAU,GAAG;AACpB,aAAO;AAAA,IACT;AACA,UAAM,eAAe,KAAK,OAAO,IAAI,KAAK,YAAY,KAAK;AAC3D,WAAO,KAAK,OAAO,WAAW;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAA4B;AAC1B,QAAI,KAAK,UAAU,GAAG;AACpB,aAAO;AAAA,IACT;AACA,WAAO,KAAK,OAAO,KAAK,IAAI;AAAA,EAC9B;AACF;;;AC9EO,IAAM,WAAN,MAAoC;AAAA,EACxB,gBAAyD,oBAAI,IAAI;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EAET,QAAuB;AAAA,IAC7B,eAAe;AAAA,IACf,sBAAsB;AAAA,IACtB,qBAAqB;AAAA,IACrB,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAAA,EAEA,YAAY,UAA2B,CAAC,GAAG;AACzC,UAAM,iBAAiB,QAAQ,kBAAkB;AACjD,SAAK,UAAU,IAAI,eAA4B,cAAc;AAC7D,SAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,OAA0B;AAC7B,UAAM,gBAAgB,YAAY,KAAK;AACvC,SAAK,aAAa,aAAa;AAC/B,SAAK,MAAM;AAEX,SAAK,QAAQ,MAAM,iBAAiB;AAAA,MAClC,OAAO,cAAc;AAAA,MACrB,SAAS,cAAc;AAAA,MACvB,iBAAiB,yBAAyB,cAAc,OAAO,KAAK,aAAa;AAAA,IACnF,CAAC;AAED,eAAW,UAAU,KAAK,cAAc,OAAO,GAAG;AAChD,UAAI,oBAAoB,cAAc,OAAO,OAAO,KAAK,GAAG;AAC1D,aAAK,eAAe,QAAQ,aAAa;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAAmC;AACjD,UAAM,gBAAgB,YAAY,KAAK;AACvC,SAAK,aAAa,aAAa;AAC/B,SAAK,MAAM;AAEX,SAAK,QAAQ,MAAM,uBAAuB;AAAA,MACxC,OAAO,cAAc;AAAA,MACrB,SAAS,cAAc;AAAA,IACzB,CAAC;AAED,UAAM,WAA4B,CAAC;AAEnC,eAAW,UAAU,KAAK,cAAc,OAAO,GAAG;AAChD,UAAI,oBAAoB,cAAc,OAAO,OAAO,KAAK,GAAG;AAC1D,iBAAS,KAAK,KAAK,oBAAoB,QAAQ,aAAa,CAAC;AAAA,MAC/D;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,UACE,SACA,UACc;AACd,QAAI,KAAK,cAAc,QAAQ,mBAAmB;AAChD,YAAM,IAAI;AAAA,QACR,uCAAuC,OAAO,iBAAiB,CAAC;AAAA,MAElE;AAAA,IACF;AAEA,UAAM,KAAK,uBAAuB;AAClC,UAAM,QAAQ,eAAe,OAAO;AAEpC,UAAM,SAA6B;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,SAAK,cAAc,IAAI,IAAI,MAAM;AACjC,SAAK,MAAM;AACX,SAAK,MAAM,sBAAsB,KAAK,cAAc;AAEpD,SAAK,QAAQ,MAAM,wBAAwB,EAAE,IAAI,QAAQ,CAAC;AAE1D,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa,MAAM;AACjB,aAAK,YAAY,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,gBAAsC;AAChD,UAAM,UAAU,KAAK,cAAc,OAAO,cAAc;AACxD,QAAI,SAAS;AACX,WAAK,MAAM,sBAAsB,KAAK,cAAc;AACpD,WAAK,QAAQ,MAAM,wBAAwB,EAAE,eAAe,CAAC;AAAA,IAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAA8C;AACvD,UAAM,eAAe,KAAK,QAAQ,QAAQ;AAC1C,QAAI,WAAW,QAAW;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,oBAAoB,cAAc,MAAM;AACzD,WAAO,kBAAkB,UAAU,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,SAAK,QAAQ,MAAM;AACnB,SAAK,MAAM,cAAc;AACzB,SAAK,QAAQ,MAAM,iBAAiB;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,WAA0B;AACxB,WAAO,EAAE,GAAG,KAAK,MAAM;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,SAAgC;AAC7C,UAAM,QAAQ,eAAe,OAAO;AACpC,eAAW,UAAU,KAAK,cAAc,OAAO,GAAG;AAEhD,UACE,oBAAoB,SAAS,OAAO,KAAK,KACzC,oBAAoB,OAAO,SAAS,KAAK,GACzC;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAa,OAA0B;AAC7C,SAAK,QAAQ,KAAK,KAAK;AACvB,SAAK,MAAM,cAAc,KAAK,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAA4B,OAA0B;AAC3E,QAAI;AACF,YAAM,SAAS,OAAO,SAAS,KAAK;AAEpC,UAAI,KAAK,iBAAiB,kBAAkB,SAAS;AACnD,eAAO,MAAM,CAAC,UAAmB;AAC/B,eAAK,oBAAoB,QAAQ,OAAO,KAAK;AAAA,QAC/C,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,WAAK,oBAAoB,QAAQ,OAAO,KAAK;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAAoB,QAA4B,OAAmC;AAC/F,QAAI;AACF,YAAM,OAAO,SAAS,KAAK;AAAA,IAC7B,SAAS,OAAO;AACd,WAAK,oBAAoB,QAAQ,OAAO,KAAK;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBACN,QACA,OACA,OACM;AACN,SAAK,MAAM;AACX,UAAM,WAAW,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACzE,SAAK,QAAQ,MAAM,wBAAwB,UAAU;AAAA,MACnD,gBAAgB,OAAO;AAAA,MACvB,SAAS,OAAO;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,SAAS,MAAM;AAAA,IACjB,CAAC;AAAA,EACH;AACF;AAMA,IAAI,YAA6B;AAE1B,SAAS,kBAAkB,SAAqC;AACrE,gBAAc,IAAI,SAAS,OAAO;AAClC,SAAO;AACT;AAYO,SAAS,YACd,OACA,SACA,SAIG;AACH,SAAO;AAAA,IACL,SAAS,gBAAgB;AAAA,IACzB,WAAW,gBAAgB,EAAE,OAAO;AAAA,IACpC;AAAA,IACA;AAAA,IACA,WAAW,SAAS;AAAA,IACpB,eAAe,SAAS;AAAA,EAC1B;AACF;;;ACtTO,IAAM,cAAc;AAAA;AAAA,EAEzB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,mBAAmB;AAAA,EACnB,aAAa;AAAA;AAAA,EAGb,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,aAAa;AAAA;AAAA,EAGb,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,WAAW;AAAA;AAAA,EAGX,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,eAAe;AAAA;AAAA,EAGf,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA;AAAA,EAGd,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,YAAY;AAAA;AAAA,EAGZ,4BAA4B;AAAA,EAC5B,8BAA8B;AAAA,EAC9B,qBAAqB;AAAA,EACrB,eAAe;AAAA;AAAA,EAGf,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,aAAa;AAAA;AAAA,EAGb,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,eAAe;AAAA;AAAA,EAGf,KAAK;AACP;;;ACXO,SAAS,uBAAuB,QAAoD;AACzF,SAAO,IAAI,iBAAiB,MAAM;AACpC;AASO,IAAM,mBAAN,MAAoD;AAAA,EACxC;AAAA,EACT;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACS,oBAAoB,oBAAI,IAAuC;AAAA,EACxE;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACF;AAAA;AAAA,EAET;AAAA,EAER,YAAY,QAAiC;AAC3C,SAAK,SAAS,QAAQ,UAAU,aAAa,EAAE,WAAW,oBAAoB,CAAC;AAC/E,SAAK,eAAe,QAAQ;AAC5B,SAAK,sBAAsB,QAAQ;AAAA,EACrC;AAAA;AAAA,EAIA,IAAI,aAAqB;AACvB,WAAO,KAAK,gBAAgB,cAAc;AAAA,EAC5C;AAAA,EAEA,IAAI,UAAkB;AACpB,WAAO,KAAK,gBAAgB,WAAW;AAAA,EACzC;AAAA,EAEA,IAAI,eAA2C;AAC7C,WAAO,KAAK,gBAAgB,gBAAgB,CAAC;AAAA,EAC/C;AAAA;AAAA,EAIA,MAAM,SAAS,SAA6E;AAC1F,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,QAAI,YAAY,QAAW;AACzB,aAAO,IAAI,IAAI,WAAW,4BAA4B,CAAC;AAAA,IACzD;AACA,UAAM,SAAS,MAAM,QAAQ,SAAS,OAAO;AAC7C,QAAI,CAAC,OAAO,MAAM,qBAAqB,OAAO,KAAK,GAAG;AACpD,YAAM,UAAU,iBAAiB,OAAO,OAAO,QAAQ,UAAU;AACjE,2BAAqB;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,WAAW,gBAAgB,EAAE,IAAI;AAAA,QACjC,cAAc,QAAQ;AAAA,MACxB,CAAC;AACD,WAAK,OAAO,KAAK,uBAAuB;AAAA,QACtC,UAAU,QAAQ;AAAA,QAClB,cAAc,QAAQ;AAAA,MACxB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAO,SAAwD;AACpE,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,QAAI,YAAY,QAAW;AACzB;AAAA,IACF;AACA,WAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B;AAAA,EAEA,MAAM,YAAY,MAA+B;AAC/C,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,YAAY,IAAI;AAAA,EACjC;AAAA,EAEA,iBAA4C;AAC1C,QAAI,KAAK,mBAAmB,QAAW;AACrC,aAAO,KAAK,eAAe,eAAe;AAAA,IAC5C;AAEA,WAAO,GAAG,MAAS;AAAA,EACrB;AAAA;AAAA,EAIA,YAA2C;AACzC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,UAAM,KAAK,cAAc;AAAA,EAC3B;AAAA,EAEA,gBAAgB,KAAgC;AAC9C,SAAK,eAAe;AACpB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,WAAW,IAAmD;AAC5D,SAAK,kBAAkB,IAAI,EAAE;AAC7B,WAAO,MAAM;AACX,WAAK,kBAAkB,OAAO,EAAE;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,6BAA6B,UAAwC;AACnE,SAAK,6BAA6B;AAClC,SAAK,yBAAyB;AAC9B,SAAK,kBAAkB,CAAC,UAAmC;AACzD,WAAK,yBAAyB,KAAK;AAAA,IACrC;AACA,aAAS,6BAA6B,KAAK,eAAe;AAAA,EAC5D;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAChB,SAAK,6BAA6B;AAClC,SAAK,kBAAkB,MAAM;AAAA,EAC/B;AAAA;AAAA,EAIA,MAAc,gBAAoD;AAChE,QAAI,KAAK,mBAAmB,QAAW;AACrC,aAAO,KAAK;AAAA,IACd;AAEA,SAAK,qBAAqB,KAAK,cAAc,EAAE,QAAQ,MAAM;AAC3D,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,gBAAoD;AAChE,QAAI;AACF,WAAK,OAAO,KAAK,gCAAgC;AACjD,YAAM,SAAS;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,GAAI,KAAK,iBAAiB,UAAa,EAAE,cAAc,KAAK,aAAa;AAAA,QACzE,GAAI,KAAK,wBAAwB,UAAa;AAAA,UAC5C,qBAAqB,KAAK;AAAA,QAC5B;AAAA,MACF;AACA,YAAM,YAAY,MAAM,kBAAkB,MAAM;AAChD,WAAK,eAAe,SAAS;AAC7B,aAAO,KAAK;AAAA,IACd,SAAS,OAAO;AACd,YAAM,UAAU,gBAAgB,KAAK;AACrC,WAAK,OAAO,KAAK,8BAA8B,EAAE,OAAO,QAAQ,CAAC;AACjE,WAAK,SAAS;AAAA,QACZ,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,YAAY,oBAAI,KAAK;AAAA,QACrB,eAAe,KAAK,QAAQ,iBAAiB;AAAA,QAC7C,WAAW;AAAA,MACb;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,eAAe,WAAmC;AACxD,UAAM,aAAa,KAAK;AACxB,SAAK,iBAAiB,UAAU;AAChC,SAAK,mBAAmB;AACxB,SAAK,kBAAkB;AAEvB,UAAM,SAAS,mBAAmB,SAAS;AAC3C,UAAM,iBAAiB,KAAK,QAAQ,iBAAiB,MAAM,aAAa,IAAI;AAE5E,SAAK,SAAS;AAAA,MACZ;AAAA,MACA,OAAO;AAAA,MACP,YAAY,oBAAI,KAAK;AAAA,MACrB;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,oBAAoB;AAAA,MACnC,QAAQ,UAAU;AAAA,MAClB,MAAM,UAAU;AAAA,MAChB,OAAO,UAAU,QAAQ;AAAA,MACzB,UAAU,UAAU,QAAQ;AAAA,MAC5B,UAAU;AAAA,IACZ,CAAC;AAED,QAAI,YAAY;AACd,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,yBAAyB,OAAsC;AACrE,QAAI,MAAM,aAAa,OAAQ;AAE/B,UAAM,gBAAgB,KAAK,kBAAkB;AAC7C,QAAI,kBAAkB,UAAa,kBAAkB,MAAM,SAAS;AAClE;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,mEAAmE;AAAA,MAClF,KAAK,MAAM;AAAA,MACX,QAAQ,MAAM;AAAA,IAChB,CAAC;AAED,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AAExB,QAAI,KAAK,WAAW,QAAW;AAC7B,WAAK,SAAS;AAAA,QACZ,GAAG,KAAK;AAAA,QACR,OAAO;AAAA,QACP,WAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAqB;AAC3B,UAAM,OAAO,KAAK;AAClB,QAAI,SAAS,OAAW;AAExB,eAAW,MAAM,KAAK,mBAAmB;AACvC,UAAI;AACF,WAAG,IAAI;AAAA,MACT,SAAS,OAAgB;AACvB,aAAK,OAAO,MAAM,2BAA2B,EAAE,OAAO,gBAAgB,KAAK,EAAE,CAAC;AAAA,MAChF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,kBAAkB;AACnC,eAAS,KAAK;AAAA,QACZ,SAAS,YAAY,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,QAClH,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,WAAK,OAAO,MAAM,wCAAwC;AAAA,QACxD,OAAO,gBAAgB,KAAK;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,+BAAqC;AAC3C,QAAI,KAAK,2BAA2B,UAAa,KAAK,oBAAoB,QAAW;AACnF,WAAK,uBAAuB,gCAAgC,KAAK,eAAe;AAAA,IAClF;AACA,SAAK,yBAAyB;AAC9B,SAAK,kBAAkB;AAAA,EACzB;AACF;AAMA,SAAS,mBAAmB,WAA8C;AACxE,MAAI,UAAU,WAAW,OAAO;AAC9B,WAAO,UAAU;AAAA,EACnB;AACA,SAAO;AACT;;;ACtSA,IAAM,SAAS,aAAa,EAAE,WAAW,2BAA2B,CAAC;AAuD9D,SAAS,0BACd,OACA,UAAwC,CAAC,GAC1B;AACf,QAAM,WAAW,QAAQ,YAAY,mBAAmB;AACxD,QAAM,QAAQ,QAAQ,SAAS,+BAA+B;AAC9D,QAAM,kBAAmC;AAAA,IACvC;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ;AAAA,IACxB,cAAc,QAAQ;AAAA,EACxB;AACA,QAAM,UAAyB;AAAA,IAC7B,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,cAAc,MAAM;AAAA,IACpB,aAAa,CAAC,SAAS,MAAM,YAAY,IAAI;AAAA,IAC7C,gBAAgB,MAAM,MAAM,eAAe;AAAA,IAC3C,QAAQ,CAAC,YACP,mBAAmB,OAAO,SAAS,eAAe;AAAA,IACpD,UAAU,CAAC,YAA+B,qBAAqB,OAAO,SAAS,eAAe;AAAA,EAChG;AACA,MAAI,OAAO,MAAM,eAAe,YAAY;AAC1C,UAAM,OAAO,MAAM,WAAW,KAAK,KAAK;AACxC,YAAQ,aAAa,MAAM,KAAK;AAAA,EAClC;AACA,SAAO;AACT;AASA,eAAe,qBACb,OACA,SACA,SACiD;AACjD,QAAM,QAAQ,MAAM,MAAM,SAAS,OAAO;AAC1C,MAAI,MAAM,GAAI,QAAO;AACrB,MAAI,MAAM,MAAM,SAAS,UAAU,gBAAiB,QAAO;AAE3D,QAAM,WAAW,MAAM,aAAa,MAAM,SAAS,QAAQ,OAAO,QAAQ,QAAQ;AAClF,MAAI,aAAa,MAAM;AACrB,WAAO,KAAK,6CAA6C;AAAA,MACvD,SAAS,MAAM;AAAA,MACf,YAAY,MAAM;AAAA,MAClB,cAAc,MAAM,MAAM;AAAA,IAC5B,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,qDAAqD;AAAA,IAC/D,gBAAgB,MAAM;AAAA,IACtB,iBAAiB;AAAA,IACjB,YAAY,MAAM;AAAA,EACpB,CAAC;AACD,mBAAiB,QAAQ,cAAc;AAAA,IACrC,gBAAgB,MAAM;AAAA,IACtB,iBAAiB;AAAA,IACjB,YAAY,MAAM;AAAA,IAClB,cAAc,MAAM,MAAM;AAAA,EAC5B,CAAC;AAKD,MAAI,QAAQ,mBAAmB,QAAW;AACxC,WAAO;AAAA,MACL,IAAI,WAAgB,GAAG,MAAM,MAAM,OAAO,+BAA0B,QAAQ,IAAI;AAAA,QAC9E,MAAM,UAAU;AAAA,QAChB,OAAO,MAAM;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,kBAAkB,QAAQ,eAAe,QAAQ;AACvD,QAAM,UAAU,MAAM,gBAAgB,SAAS,OAAO;AACtD,MAAI,QAAQ,GAAI,QAAO;AAGvB,SAAO;AAAA,IACL,IAAI,WAAgB,YAAY,QAAQ,iBAAiB,QAAQ,MAAM,OAAO,IAAI;AAAA,MAChF,MAAM,QAAQ,MAAM;AAAA,MACpB,OAAO,QAAQ;AAAA,IACjB,CAAC;AAAA,EACH;AACF;AAkBA,gBAAgB,mBACd,OACA,SACA,SAC6B;AAC7B,MAAI;AACF,qBAAiB,SAAS,MAAM,OAAO,OAAO,GAAG;AAC/C,YAAM;AAAA,IACR;AACA;AAAA,EACF,SAAS,GAAY;AACnB,QAAI,CAAC,qBAAqB,CAAC,EAAG,OAAM;AACpC,UAAM,kBAAkB,MAAM,sBAAsB,OAAO,GAAG,OAAO;AAIrE,qBAAiB,SAAS,gBAAgB,OAAO,OAAO,GAAG;AACzD,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAOA,eAAe,sBACb,OACA,OACA,SACwB;AACxB,QAAM,WAAW,MAAM,aAAa,MAAM,SAAS,QAAQ,OAAO,QAAQ,QAAQ;AAClF,MAAI,aAAa,MAAM;AACrB,WAAO,KAAK,oDAAoD;AAAA,MAC9D,SAAS,MAAM;AAAA,MACf,YAAY,MAAM;AAAA,MAClB,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IACrE,CAAC;AACD,UAAM;AAAA,EACR;AAEA,SAAO,KAAK,4EAA4E;AAAA,IACtF,gBAAgB,MAAM;AAAA,IACtB,iBAAiB;AAAA,IACjB,YAAY,MAAM;AAAA,EACpB,CAAC;AACD,mBAAiB,QAAQ,cAAc;AAAA,IACrC,gBAAgB,MAAM;AAAA,IACtB,iBAAiB;AAAA,IACjB,YAAY,MAAM;AAAA,IAClB,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EACrE,CAAC;AAED,MAAI,QAAQ,mBAAmB,QAAW;AAIxC,UAAM,UAAU,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,+BAA0B,QAAQ;AAC3G,UAAM,WAAW,iBAAiB,QAAQ,QAAQ;AAClD,UAAM,IAAI;AAAA,MACR;AAAA,MACA,aAAa,SACT,EAAE,MAAM,UAAU,iBAAiB,OAAO,SAAS,IACnD,EAAE,MAAM,UAAU,gBAAgB;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,QAAQ,eAAe,QAAQ;AACxC;AAEA,SAAS,qBAAqB,GAAqB;AACjD,MAAI,aAAa,YAAiB;AAChC,WAAO,EAAE,SAAS,UAAU;AAAA,EAC9B;AAEA,MAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,UAAU,GAAG;AACtD,WAAO,EAAE,SAAS,UAAU;AAAA,EAC9B;AACA,SAAO;AACT;AAEA,SAAS,iBACP,IACA,MACM;AACN,MAAI,OAAO,OAAW;AACtB,MAAI;AACF,OAAG,IAAI;AAAA,EACT,SAAS,GAAY;AACnB,WAAO,MAAM,+BAA+B;AAAA,MAC1C,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AACF;AAcA,eAAe,aACb,gBACA,OACA,UACwB;AACxB,QAAM,YAAY,MAAM,MAAM,QAAQ;AACtC,MAAI,UAAU,WAAW,EAAG,QAAO;AACnC,QAAM,SAAS,SAAS,SAAS,cAAc;AAE/C,QAAM,aAAa,UAAU,KAAK,CAAC,MAAM;AACvC,QAAI,EAAE,OAAO,eAAgB,QAAO;AACpC,UAAM,YAAY,SAAS,SAAS,EAAE,EAAE;AACxC,WAAO,UAAU,WAAW,OAAO,UAAU,UAAU,WAAW,OAAO;AAAA,EAC3E,CAAC;AACD,MAAI,eAAe,OAAW,QAAO,WAAW;AAEhD,QAAM,aAAa,UAAU,KAAK,CAAC,MAAM;AACvC,QAAI,EAAE,OAAO,eAAgB,QAAO;AACpC,UAAM,YAAY,SAAS,SAAS,EAAE,EAAE;AACxC,WAAO,UAAU,WAAW,OAAO;AAAA,EACrC,CAAC;AACD,SAAO,YAAY,MAAM;AAC3B;AAkCO,SAAS,0BACd,OACA,UAAwC,CAAC,GACtC;AACH,QAAM,UAAU,0BAA0B,OAAO,OAAO;AAYxD,QAAM,UAAU;AAAA,IACd,WAAW,MAAM,UAAU,KAAK,KAAK;AAAA,IACrC,SAAS,MAAM,QAAQ,KAAK,KAAK;AAAA,IACjC,iBAAiB,MAAM,gBAAgB,KAAK,KAAK;AAAA,IACjD,YAAY,MAAM,WAAW,KAAK,KAAK;AAAA,IACvC,SAAS,MAAM,QAAQ,KAAK,KAAK;AAAA,EACnC;AACA,QAAM,WAA0B,OAAO,OAAO,SAAS,OAAO;AAC9D,QAAM,gBAAgB;AACtB,SAAO,IAAI,MAAM,UAAU;AAAA,IACzB,IAAI,QAAQ,MAAM,UAAmB;AACnC,UAAI,QAAQ,OAAQ,QAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAI7D,YAAM,YAAqB,cAAc,IAAI;AAC7C,UAAI,OAAO,cAAc,YAAY;AACnC,eAAQ,UAA8C,KAAK,KAAK;AAAA,MAClE;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;;;ACrTO,IAAM,yBAAN,MAA6B;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA,cAAc,oBAAI,IAAgC;AAAA;AAAA,EAG3D;AAAA,EAER,YAAY,QAAgC;AAC1C,SAAK,SAAS,QAAQ,UAAU,aAAa,EAAE,WAAW,mBAAmB,CAAC;AAC9E,SAAK,sBAAsB,QAAQ;AACnC,SAAK,6BAA6B,QAAQ,8BAA8B;AACxE,SAAK,8BAA8B,QAAQ;AAC3C,SAAK,cAAc,KAAK,iBAAiB;AACzC,SAAK,OAAO,KAAK,sCAAsC;AAAA,MACrD,YAAY,KAAK,YAAY;AAAA,MAC7B,QAAQ,4BAA4B,EAAE,OAAO;AAAA,MAC7C,sBAAsB,KAAK;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,UAAU,SAA+C;AAC/D,QAAI,CAAC,KAAK,2BAA4B,QAAO;AAC7C,WAAO,0BAA0B,SAAS,KAAK,2BAA2B;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,UAA2C;AACpD,UAAM,UAAU,KAAK,YAAY,IAAI,QAAQ;AAC7C,QAAI,YAAY,QAAW;AACzB,WAAK,OAAO,KAAK,wCAAwC,EAAE,SAAS,CAAC;AACrE,aAAO,KAAK,WAAW;AAAA,IACzB;AACA,WAAO,KAAK,iBAAiB,QAAQ,UAAU;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,iBAA4C;AAC5D,UAAM,QAAQ,mBAAmB,eAAe;AAChD,QAAI,UAAU,MAAM;AAClB,WAAK,OAAO,MAAM,0BAA0B;AAAA,QAC1C,UAAU,MAAM;AAAA,QAChB,KAAK,MAAM;AAAA,MACb,CAAC;AACD,aAAO,KAAK,iBAAiB,MAAM,UAAU;AAAA,IAC/C;AACA,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,KAAiC;AAChD,UAAM,SAAS,KAAK,YAAY,IAAI,GAAG;AACvC,QAAI,WAAW,OAAW,QAAO;AAEjC,UAAM,MAAM,uBAAuB;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,cAAc;AAAA,MACd,GAAI,KAAK,wBAAwB,UAAa;AAAA,QAC5C,qBAAqB,KAAK;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,UAAM,UAAU,KAAK,UAAU,GAAG;AAClC,SAAK,YAAY,IAAI,KAAK,OAAO;AACjC,SAAK,OAAO,KAAK,gCAAgC;AAAA,MAC/C;AAAA,MACA,sBAAsB,KAAK;AAAA,IAC7B,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,iBAA4C;AAM7D,UAAM,YAAY,4BAA4B,EAAE;AAChD,UAAM,QAAQ,UAAU;AAAA,MACtB,CAAC,MACC,EAAE,OAAO,mBACT,EAAE,aAAa,mBACf,EAAE,iBAAiB;AAAA,IACvB;AACA,UAAM,SACJ,SACA,CAAC,GAAG,SAAS,EACV,OAAO,CAAC,MAAM,gBAAgB,WAAW,EAAE,EAAE,CAAC,EAC9C,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC;AAChD,UAAM,QAAQ;AACd,QAAI,UAAU,QAAW;AACvB,WAAK,OAAO,MAAM,yBAAyB;AAAA,QACzC,OAAO;AAAA,QACP,KAAK,MAAM;AAAA,MACb,CAAC;AACD,aAAO,KAAK,iBAAiB,MAAM,OAAkB;AAAA,IACvD;AACA,SAAK,OAAO,MAAM,wCAAwC;AAAA,MACxD,OAAO;AAAA,IACT,CAAC;AACD,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,MAAiC;AACjD,UAAM,WAAW,iBAAiB,IAAI;AACtC,QAAI,aAAa,OAAW,QAAO,KAAK,WAAW,QAAQ;AAC3D,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAgC;AAC9B,QAAI,KAAK,mBAAmB,OAAW,QAAO,KAAK;AACnD,UAAM,MAAM,uBAAuB;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,GAAI,KAAK,wBAAwB,UAAa;AAAA,QAC5C,qBAAqB,KAAK;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,SAAK,iBAAiB,KAAK,UAAU,GAAG;AACxC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,cAAgC;AAC9B,WAAO;AAAA,MACL,aAAa,CAAC,GAAG,KAAK,YAAY,OAAO,CAAC;AAAA,MAC1C,gBAAgB,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC;AAAA,MAC3C,iBAAiB,4BAA4B,EAAE,OAAO;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,UAAsD;AAC/D,WAAO,KAAK,YAAY,IAAI,QAAQ;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,eAAW,WAAW,KAAK,YAAY,OAAO,GAAG;AAC/C,cAAQ,QAAQ;AAAA,IAClB;AACA,SAAK,YAAY,MAAM;AACvB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,iBAAiB;AACtB,SAAK,OAAO,KAAK,iCAAiC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAgE;AACtE,UAAM,UAAU,oBAAI,IAAoC;AACxD,eAAW,QAAQ,4BAA4B;AAC7C,YAAM,eAAe,oBAAoB,KAAK,UAAU;AACxD,cAAQ,IAAI,KAAK,UAAU;AAAA,QACzB,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,cAAc,KAAK;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AAOA,IAAM,mBAAiD;AAAA,EACrD,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,uBAAuB;AACzB;AAOA,SAAS,oBAAoB,KAAqB;AAChD,MAAK,UAAgC,SAAS,GAAG,GAAG;AAClD,WAAO,sBAAsB,GAAqB;AAAA,EACpD;AACA,SAAO;AACT;AAMA,IAAI;AAMG,SAAS,sBAAsB,QAAwD;AAC5F,SAAO,IAAI,uBAAuB,MAAM;AAC1C;AAUO,SAAS,kBAAkB,QAAwD;AACxF,MAAI,mBAAmB,QAAW;AAChC,qBAAiB,IAAI,uBAAuB,MAAM;AAClD,WAAO;AAAA,EACT;AACA,MAAI,WAAW,UAAa,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAC1D,mBACG,UAAU,EACV;AAAA,MACC;AAAA,MAEA,EAAE,cAAc,OAAO,KAAK,MAAM,EAAE;AAAA,IACtC;AAAA,EACJ;AACA,SAAO;AACT;;;ACjWO,IAAM,4BAA4B;AAQlC,SAAS,sBAAsB,uBAA8C;AAClF,MAAI,yBAAyB,0BAA2B,QAAO;AAC/D,SACE,GAAG,OAAO,qBAAqB,CAAC,0EACT,OAAO,yBAAyB,CAAC;AAI5D;;;AC/BA,IAAM,kBAAkB;AAsBxB,SAAS,uBAA+B;AACtC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBT;AAGA,SAAS,cAAsB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,qBAAqB,CAAC;AACxB;AAGA,SAAS,gBAAgB,SAAyB;AAChD,SAAO,sEAAsE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpF,YAAY,CAAC;AAAA;AAAA;AAGf;AAGA,SAAS,eAAe,SAAyB;AAC/C,SAAO,2DAA2D,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzE,YAAY,CAAC;AAAA;AAAA;AAGf;AAGA,SAAS,YAAY,SAAyB;AAC5C,SAAO,uEAAuE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrF,YAAY,CAAC;AAAA;AAAA;AAGf;AAGA,SAAS,WAAW,SAAyB;AAC3C,SAAO,yDAAyD,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASvE,YAAY,CAAC;AAAA;AAAA;AAGf;AAGA,SAAS,SAAS,SAAyB;AACzC,SAAO,yDAAyD,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASvE,YAAY,CAAC;AAAA;AAAA;AAGf;AAGA,SAAS,cAAc,SAAyB;AAC9C,SAAO,4EAA4E,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwB1F,qBAAqB,CAAC;AACxB;AASA,SAAS,mBAAmB,SAAyB;AACnD,SAAO,uDAAuD,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiDrE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQf;AAEO,SAAS,gBAAgB,UAAkB,iBAA4C;AAC5F,SAAO;AAAA,IACL,WAAW,gBAAgB,OAAO;AAAA,IAClC,UAAU,eAAe,OAAO;AAAA,IAChC,OAAO,YAAY,OAAO;AAAA,IAC1B,OAAO,WAAW,OAAO;AAAA,IACzB,IAAI,SAAS,OAAO;AAAA,IACpB,SAAS,cAAc,OAAO;AAAA,IAC9B,eAAe,mBAAmB,OAAO;AAAA,EAC3C;AACF;AAKO,IAAM,uBAAkD,gBAAgB;AAQxE,IAAM,2BAAsD;AAAA,EACjE,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,eACE;AACJ;;;AC3QA,SAAS,KAAAC,UAAS;AAiBX,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,YACE,QACgB,WAChB;AACA;AAAA,MACE,iCAAiC,MAAM;AAAA,IAEzC;AALgB;AAMhB,SAAK,OAAO;AAAA,EACd;AACF;AA0CO,IAAM,mBAAmBC,GAAE,OAAO;AAAA,EACvC,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,+BAA+B;AAAA,EAC5E,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,oBAAoB;AAAA,EAClE,UAAUA,GAAE,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ;AAAA,EACxE,MAAMA,GAAE,OAAO;AAAA,IACb,mBAAmBA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,IAC5E,kBAAkBA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,IAC3E,iBAAiBA,GACd,OAAO,EACP,QAAQ,EAAE,EACV,SAAS,wEAAmE;AAAA,IAC/E,8BAA8BA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,EACzF,CAAC;AAAA,EACD,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS,6CAA6C;AAC3F,CAAC;AAOM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,UAAUA,GAAE,KAAK,CAAC,WAAW,UAAU,SAAS,CAAC,EAAE,SAAS,oBAAoB;AAAA,EAChF,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,GAAI,EAAE,SAAS,2CAA2C;AAAA,EAC5F,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,sBAAsB;AAAA,EACpE,YAAYA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA;AAAA,EAEtF,qBAAqBA,GAClB;AAAA,IACCA,GAAE,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,EACC,SAAS,EACT,SAAS,qDAAqD;AAAA;AAAA;AAAA,EAGjE,UAAUA,GAAE,MAAM,gBAAgB,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAChG,CAAC;AAUD,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2CtB,SAAS,gBAAgB,UAA0B;AACxD,SAAO;AAAA;AAAA;AAAA,EAGP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeR,oBAAoB;AACtB;AAUO,SAAS,wBAAwB,MAAsB;AAE5D,QAAM,iBAAiB,gCAAgC,KAAK,IAAI;AAChE,MAAI,iBAAiB,CAAC,MAAM,QAAW;AACrC,WAAO,eAAe,CAAC,EAAE,KAAK;AAAA,EAChC;AAGA,QAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,MAAI,YAAY,CAAC,MAAM,QAAW;AAChC,WAAO,UAAU,CAAC;AAAA,EACpB;AAEA,SAAO,KAAK,KAAK;AACnB;AAQA,SAAS,mBAAmB,QAAgB,OAAkB,QAA4B;AACxF,QAAM,QAAQ,OAAO,YAAY;AACjC,MAAI,WAA6B;AAIjC,MAAI,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,UAAU,GAAG;AACvF,eAAW;AAAA,EACb,WAAW,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,OAAO,GAAG;AAC3F,eAAW;AAAA,EACb;AAGA,eAAa,EAAE,WAAW,iBAAiB,CAAC,EAAE;AAAA,IAC5C;AAAA,IACA,EAAE,UAAU,OAAO;AAAA,EACrB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW,eAAe,MAAM,KAAK,OAAO,MAAM,GAAG,GAAG,CAAC;AAAA,IACzD,YAAY;AAAA,IACZ,QAAQ;AAAA;AAAA,EACV;AACF;AAGA,SAAS,gBAAgB,MAAgC;AACvD,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,GAAI,KAAK,eAAe,SAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,IACvE,GAAI,KAAK,wBAAwB,SAC7B,EAAE,qBAAqB,KAAK,oBAAoB,IAChD,CAAC;AAAA,IACL,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,IACjE,QAAQ;AAAA,EACV;AACF;AAgBO,SAAS,kBACd,QACA,MACA,SACY;AACZ,QAAM,qBAAqB,SAAS,sBAAsB;AAE1D,MAAI;AACF,UAAM,UAAU,wBAAwB,MAAM;AAC9C,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,UAAM,YAAY,mBAAmB,UAAU,MAAM;AAErD,QAAI,UAAU,SAAS;AACrB,aAAO,gBAAgB,UAAU,IAAI;AAAA,IACvC;AAGA,UAAM,SAAS,sBAAsB,UAAU,MAAM,OAAO,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AACjH,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,mBAAmB,QAAQ,MAAM;AAAA,IAC7C;AACA,WAAO,mBAAmB,QAAQ,MAAM,MAAM;AAAA,EAChD,SAAS,OAAO;AAEd,QAAI,iBAAiB,oBAAoB;AACvC,YAAM;AAAA,IACR;AAGA,UAAM,SAAS,gBAAgB,OAAO,qBAAqB;AAC3D,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,mBAAmB,QAAQ,MAAM;AAAA,IAC7C;AACA,WAAO,mBAAmB,QAAQ,MAAM,MAAM;AAAA,EAChD;AACF;;;ACpSO,IAAM,0BAA0B,cAAc;AAM9C,IAAM,sBAAsB,cAAc;AAG1C,IAAM,sBAAsB,cAAc;AAG1C,IAAM,sBAAsB,cAAc;AAKjD,IAAM,yBAAyB;AAMxB,IAAM,4BAA4B;AASlC,SAAS,iBAAiB,SAA0B;AACzD,SAAO,qBAAqB,IAAI,MAAM,OAAO,CAAC;AAChD;AAmBO,SAAS,sBACd,MACA,UACA,kBACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,WAAW,kCAAkC,QAAQ;AAAA,MACrD,YAAY;AAAA,IACd;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACF;AAKO,SAAS,2BACd,MACA,UACA,kBACA,OACiB;AACjB,SAAO;AAAA,IACL;AAAA,IACA,MAAM,aAAa,MAAM,QAAQ;AAAA,IACjC;AAAA,IACA,QAAQ;AAAA,IACR,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,EACrC;AACF;AAKO,SAAS,qBACd,OACA,UACA,OAC4B;AAC5B,QAAM,SAAS,kBAAkB;AACjC,SAAO,MAAM;AAAA,IAAI,CAAC,SAChB,2BAA2B,MAAM,UAAU,OAAO,UAAU,GAAG,GAAG,GAAG,KAAK;AAAA,EAC5E;AACF;AAaA,IAAM,0BAAuE;AAAA,EAC3E,UAAU,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EACrB,WAAW,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EACtB,OAAO,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EAClB,OAAO,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EAClB,IAAI,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EACf,SAAS,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,EACpB,eAAe,CAAC,IAAI,IAAI,EAAE;AAAA;AAC5B;AAKA,SAAS,uBACP,SACkC;AAClC,QAAM,SAAS,kBAAkB;AACjC,QAAM,QAAQ,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,QAAQ,CAAC;AACjD,QAAM,OAAO,OAAO,OAAO,IAAI;AAE/B,MAAI,OAAO,QAAQ,CAAC,EAAG,QAAO;AAC9B,MAAI,OAAO,QAAQ,CAAC,IAAI,QAAQ,CAAC,EAAG,QAAO;AAC3C,SAAO;AACT;AASO,SAAS,aAAa,MAAiB,UAAwB;AACpE,QAAM,SAAS,kBAAkB;AACjC,QAAM,UAAU,wBAAwB,IAAI;AAC5C,QAAM,WAAW,uBAAuB,OAAO;AAM/C,MAAI;AACJ,MAAI,aAAa,UAAU;AACzB,qBAAiB,MAAM,OAAO,OAAO,IAAI;AAAA,EAC3C,WAAW,aAAa,WAAW;AACjC,qBAAiB,MAAM,OAAO,OAAO,IAAI;AAAA,EAC3C,OAAO;AACL,qBAAiB,MAAM,OAAO,OAAO,IAAI;AAAA,EAC3C;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW,kCAAkC,yBAAyB,IAAI,CAAC,eAAe,SAAS,MAAM,GAAG,EAAE,CAAC;AAAA,IAC/G,YAAY;AAAA,EACd;AACF;AAgBO,SAAS,wBAAwB,SAA0B;AAChE,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO,QACJ,IAAI,CAAC,UAAU;AACd,UAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,OAAO;AAClE,cAAM,QAAQ;AACd,YAAI,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,UAAU;AAC3D,iBAAO,MAAM;AAAA,QACf;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,EAAE;AAAA,EACZ;AACA,SAAO,OAAO,OAAO;AACvB;AASA,eAAsB,yBACpB,MACA,UACA,SACA,WACkF;AAClF,QAAM,UAA6B;AAAA,IACjC,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,qBAAqB,IAAI,EAAE;AAAA,MACtD,EAAE,MAAM,QAAQ,SAAS,gBAAgB,QAAQ,EAAE;AAAA,IACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,WAAW;AAAA,IACX,aAAa;AAAA;AAAA,EACf;AAEA,QAAM,gBAAgB,MAAM;AAAA,IAC1B,QAAQ,SAAS,OAAO;AAAA,IACxB;AAAA,IACA,sBAAsB,OAAO,SAAS,CAAC,gBAAgB,IAAI;AAAA,EAC7D;AAEA,MAAI,CAAC,cAAc,IAAI;AACrB,WAAO,EAAE,IAAI,OAAO,OAAO,cAAc,MAAM;AAAA,EACjD;AAEA,QAAM,WAAW,cAAc;AAE/B,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO,EAAE,IAAI,OAAO,OAAO,SAAS,MAAM,QAAQ;AAAA,EACpD;AAEA,QAAM,SAAS,wBAAwB,SAAS,MAAM,OAAO;AAE7D,MAAI;AAGF,UAAM,OAAO,kBAAkB,QAAQ,IAAI;AAC3C,WAAO,EAAE,IAAI,MAAM,MAAM,OAAO;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,iBAAiB,oBAAoB;AAEvC,aAAO,EAAE,IAAI,OAAO,OAAO,wBAAwB,MAAM,OAAO,GAAG;AAAA,IACrE;AACA,UAAM;AAAA,EACR;AACF;AAgBA,eAAsB,mBACpB,MACkE;AAClE,QAAM,EAAE,MAAM,UAAU,SAAS,QAAAC,SAAQ,WAAW,WAAW,IAAI;AACnE,MAAI,YAAY;AAEhB,WAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,QAAI,UAAU,GAAG;AACf,YAAM,cAAc,iBAAiB,SAAS;AAC9C,YAAM,YAAY,cAAc,4BAA4B;AAC5D,YAAM,UAAU,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC;AACnD,MAAAA,QAAO,MAAM,2BAA2B,EAAE,MAAM,SAAS,SAAS,YAAY,CAAC;AAC/E,YAAM,MAAM,OAAO;AAAA,IACrB;AAKA,UAAM,eAAe,KAAK,IAAI;AAC9B,UAAM,SAAS,MAAM,yBAAyB,MAAM,UAAU,SAAS,SAAS;AAChF,UAAM,YAAY,KAAK,IAAI,IAAI;AAC/B,QAAI,OAAO,IAAI;AACb,MAAAA,QAAO,KAAK,uBAAuB;AAAA,QACjC;AAAA,QACA,SAAS,UAAU;AAAA,QACnB;AAAA,QACA,WAAW;AAAA,MACb,CAAC;AACD,aAAO,EAAE,MAAM,OAAO,MAAM,IAAI,KAAK;AAAA,IACvC;AAEA,gBAAY,OAAO;AACnB,UAAM,cAAc,iBAAiB,SAAS;AAC9C,IAAAA,QAAO,KAAK,uBAAuB;AAAA,MACjC;AAAA,MACA,SAAS,UAAU;AAAA,MACnB;AAAA,MACA,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AACD,IAAAA,QAAO,KAAK,uBAAuB;AAAA,MACjC;AAAA,MACA,SAAS,UAAU;AAAA,MACnB,YAAY,aAAa;AAAA,MACzB,OAAO;AAAA,MACP,GAAI,cAAc,EAAE,aAAa,KAAK,IAAI,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,OAAO,cAAc,KAAK,YAAY,mCAAmC,IAAI,MAAM;AAC9F;;;ACpTA,IAAM,mBAAmB;AAEzB,SAAS,iBACP,GACA,MACA,YAC0B;AAC1B,MAAI;AACJ,QAAM,WAAW,IAAI,QAAyB,CAAC,YAAY;AACzD,YAAQ,WAAW,MAAM;AACvB,cAAQ,sBAAsB,MAAM,kBAAkB,UAAU,CAAC;AAAA,IACnE,GAAG,UAAU;AAAA,EACf,CAAC;AACD,SAAO,QAAQ,KAAK,CAAC,GAAG,QAAQ,CAAC,EAAE,QAAQ,MAAM;AAC/C,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAC7C,CAAC;AACH;AAEA,eAAsB,+BACpB,OACqC;AACrC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,YAAY,KAAK,IAAI;AAE3B,QAAM,UAAU,MAAM,IAAI,OAAO,MAAM,MAAM;AAC3C,QAAI,IAAI,KAAK,aAAa,EAAG,OAAM,MAAM,UAAU;AACnD,UAAM,UAAU,aAAa,IAAI,IAAI,KAAK;AAC1C,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,UAAM,YAAY,KAAK,IAAI,GAAG,oBAAoB,OAAO;AACzD,WAAO,iBAAiB,OAAO,MAAM,UAAU,SAASA,SAAQ,WAAW,GAAG,MAAM,SAAS;AAAA,EAC/F,CAAC;AAED,QAAM,UAAU,MAAM,QAAQ,IAAI,OAAO;AAEzC,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,WAAW,EAAE,UAAU,gBAAgB;AAC1F,MAAI,QAAQ,SAAS,GAAG;AACtB,IAAAA,QAAO,KAAK,iEAAiE;AAAA,MAC3E,YAAY,MAAM;AAAA,MAClB,cAAc,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACfO,SAAS,kCACd,WACA,YACA,WACA,cACQ;AACR,QAAM,gBAAgB,aAAa,aAAa;AAChD,QAAM,gBAAgB,KAAK,IAAI,GAAG,YAAY,CAAC,IAAI;AACnD,SAAO,gBAAgB,gBAAgB,cAAc;AACvD;AAUO,IAAM,+BAA+B;AAoB5C,IAAMC,iBAAgB,aAAa,EAAE,WAAW,eAAe,CAAC;AAQhE,eAAsB,iBACpB,MACA,UACA,SACAC,SACA,SAC0B;AAC1B,QAAM,QAAQ,gBAAgB,EAAE,IAAI;AACpC,QAAM,YAAY,SAAS,aAAa,mBAAmB;AAC3D,QAAM,aAAa,SAAS,cAAc,cAAc;AACxD,QAAM,kBAAkB,SAAS,mBAAmB;AAEpD,EAAAA,QAAO,KAAK,kBAAkB,EAAE,MAAM,OAAO,QAAQ,SAAS,UAAU,QAAQ,WAAW,CAAC;AAE5F,QAAM,SAAS,MAAM,mBAAmB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,mBAAmB,gBAAgB,EAAE,IAAI,IAAI;AAEnD,MAAI,OAAO,IAAI;AACb,IAAAA,QAAO,KAAK,kBAAkB,EAAE,MAAM,OAAO,QAAQ,SAAS,UAAU,OAAO,KAAK,SAAS,CAAC;AAC9F,WAAO,EAAE,MAAM,MAAM,OAAO,MAAM,kBAAkB,QAAQ,OAAO,KAAK,QAAQ,WAAW;AAAA,EAC7F;AAGA,EAAAA,QAAO,MAAM,2CAA2C,QAAW;AAAA,IACjE;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,cAAc,OAAO;AAAA,EACvB,CAAC;AAED,MAAI,iBAAiB;AACnB,IAAAA,QAAO,KAAK,qDAAqD,EAAE,KAAK,CAAC;AACzE,WAAO,2BAA2B,MAAM,UAAU,kBAAkB,OAAO,KAAK;AAAA,EAClF;AAEA,SAAO,sBAAsB,MAAM,OAAO,OAAO,gBAAgB;AACnE;AAqBO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACxC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKA,SAAS,eACP,SACAA,SACgD;AAChD,MAAI;AACF,QAAI,QAAQ,YAAY,OAAW,QAAO,EAAE,SAAS,QAAQ,QAAQ;AACrE,UAAM,WAAW,kBAAkB,EAAE,QAAAA,QAAO,CAAC;AAC7C,WAAO,EAAE,SAAS,SAAS,WAAW,EAAE;AAAA,EAC1C,SAAS,OAAO;AACd,WAAO,EAAE,OAAO,gBAAgB,KAAK,EAAE;AAAA,EACzC;AACF;AAMA,SAAS,+BACP,cACAA,SACM;AACN,QAAM,aAAa,CAAC,GAAG,aAAa,OAAO,CAAC,EAAE;AAAA,IAC5C,CAAC,MAAO,EAAwB,SAAS;AAAA,EAC3C,EAAE;AACF,QAAM,UAAU,sBAAsB,UAAU;AAChD,MAAI,YAAY,MAAM;AACpB,IAAAA,QAAO,KAAK,2CAA2C,EAAE,QAAQ,QAAQ,CAAC;AAAA,EAC5E;AACF;AAGA,SAAS,qBACP,OACA,SAC+B;AAC/B,QAAM,WAAW,oBAAI,IAA8B;AACnD,aAAW,QAAQ,MAAO,UAAS,IAAI,MAAM,OAAO;AACpD,SAAO;AACT;AAGA,SAAS,oBACP,MACAA,SAC6B;AAC7B,QAAM,WAAW,kBAAkB,EAAE,QAAAA,QAAO,CAAC;AAC7C,QAAM,SAAS,oBAAI,IAA4B;AAC/C,aAAW,OAAO,MAAM;AACtB,WAAO,IAAI,KAAK,SAAS,iBAAiB,GAAG,CAAC;AAAA,EAChD;AACA,SAAO;AACT;AAOA,eAAe,uBACb,OACAA,SACA,iBACwC;AACxC,MAAI;AACJ,MAAI;AACF,oBAAgB,MAAM,iBAAiB;AAAA,EACzC,SAAS,GAAY;AACnB,IAAAA,QAAO,KAAK,oEAAoE;AAAA,MAC9E,OAAO,OAAO,CAAC;AAAA,IACjB,CAAC;AACD,oBAAgB,CAAC;AAAA,EACnB;AAEA,MAAI,cAAc,UAAU,GAAG;AAC7B,IAAAA,QAAO,KAAK,sCAAsC,EAAE,UAAU,cAAc,OAAO,CAAC;AACpF,WAAO,qBAAqB,OAAO,eAAe;AAAA,EACpD;AAEA,QAAM,cAAc,oBAAoB,eAAeA,OAAM;AAC7D,MAAI,YAAY,QAAQ,EAAG,QAAO,qBAAqB,OAAO,eAAe;AAG7E,QAAM,UAAU,CAAC,GAAG,YAAY,QAAQ,CAAC;AACzC,QAAM,WAAW,oBAAI,IAA8B;AACnD,QAAM,cAAsC,CAAC;AAC7C,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM;AACxC,QAAI,SAAS,UAAa,UAAU,OAAW;AAC/C,aAAS,IAAI,MAAM,MAAM,CAAC,CAAC;AAC3B,gBAAY,IAAI,IAAI,MAAM,CAAC;AAAA,EAC7B;AAEA,EAAAA,QAAO,KAAK,6BAA6B;AAAA,IACvC,UAAU,YAAY;AAAA,IACtB,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC;AAAA,IAC5B,iBAAiB;AAAA,EACnB,CAAC;AACD,SAAO;AACT;AAiBA,eAAe,qBACb,OACqC;AACrC,QAAM,EAAE,OAAO,UAAU,cAAc,iBAAiB,QAAAA,SAAQ,aAAa,WAAW,IAAI;AAG5F,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM;AAAA,IACN;AAAA,EACF;AAMA,QAAM,oBAAoB,qBAAqB,oBAAoB,gBAAgB;AACnF,MAAI,oBAAoB,oBAAoB;AAC1C,IAAAA,QAAO,MAAM,qDAAqD;AAAA,MAChE;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO,+BAA+B;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACH;AASA,eAAsB,iBACpB,SACqC;AACrC,QAAMA,UAAS,QAAQ,UAAUD;AACjC,QAAM,EAAE,OAAO,UAAU,UAAU,gBAAgB,IAAI;AACvD,QAAM,YAAY,QAAQ,aAAa,mBAAmB;AAC1D,QAAM,aAAa,QAAQ,cAAc,cAAc;AAEvD,MAAI,aAAa,MAAM;AACrB,IAAAC,QAAO,KAAK,8CAA8C;AAC1D,WAAO,qBAAqB,OAAO,QAAQ;AAAA,EAC7C;AAEA,QAAM,gBAAgB,eAAe,SAASA,OAAM;AAEpD,MAAI,WAAW,eAAe;AAC5B,IAAAA,QAAO,MAAM,mCAAmC,QAAW,EAAE,OAAO,cAAc,MAAM,CAAC;AAEzF,QAAI,oBAAoB,MAAM;AAC5B,MAAAA,QAAO,KAAK,mDAAmD;AAC/D,aAAO,qBAAqB,OAAO,UAAU,sBAAsB;AAAA,IACrE;AAEA,UAAM,IAAI;AAAA,MACR,oCAAoC,cAAc,KAAK;AAAA,IAEzD;AAAA,EACF;AAGA,QAAM,eACJ,QAAQ,YAAY,SAChB,qBAAqB,OAAO,cAAc,OAAO,IACjD,MAAM,uBAAuB,OAAOA,SAAQ,cAAc,OAAO;AAEvE,iCAA+B,cAAcA,OAAM;AAEnD,QAAM,cAAc,EAAE,WAAW,YAAY,iBAAiB,mBAAmB,MAAM;AACvF,QAAM,aAAa,QAAQ,qBAAqB;AAEhD,SAAO,qBAAqB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,cAAc;AAAA,IAC/B,QAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;ACtZA,SAAS,KAAAC,UAAS;AAWX,IAAM,2BAA2BA,GAAE,KAAK;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,IAAM,qBAAqBA,GAAE,KAAK,CAAC,WAAW,UAAU,SAAS,CAAC;AAMlE,IAAM,uBAAuBA,GAAE,KAAK;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,IAAM,0BAA0BA,GAAE,KAAK;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,IAAM,uBAAuB,wBAAwB;AAQ5D,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EAClC,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAClC,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,UAAUA,GAAE,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ;AAAA,EACxE,MAAMA,GAAE,OAAO;AAAA,IACb,mBAAmBA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,IAC5E,kBAAkBA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,IAC3E,iBAAiBA,GAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,IACtC,8BAA8BA,GAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,EACzF,CAAC;AAAA,EACD,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AACnC,CAAC;AAKM,IAAM,aAAaA,GAAE,OAAO;AAAA,EACjC,UAAU;AAAA,EACV,WAAWA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,0BAA0B;AAAA,EAChE,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,sBAAsB;AAAA,EACpE,YAAYA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA;AAAA,EAE7E,qBAAqBA,GAClB,MAAM,uBAAuB,EAC7B,SAAS,EACT,SAAS,qDAAqD;AAAA;AAAA;AAAA,EAGjE,UAAUA,GAAE,MAAM,kBAAkB,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC7F,WAAWA,GAAE,IAAI,SAAS,EAAE,SAAS;AACvC,CAAC;AAMM,IAAM,iBAAiBA,GAAE,OAAO;AAAA,EACrC,IAAIA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EACnE,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,sBAAsB;AAAA,EACjE,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,+BAA+B;AAAA,EACvE,WAAW;AAAA,EACX,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,EAClF,gBAAgBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EAClF,UAAUA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,EACpF,WAAWA,GAAE,IAAI,SAAS,EAAE,SAAS;AACvC,CAAC;AAgDM,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EAC5C,YAAYA,GAAE,OAAO;AAAA,EACrB,UAAU;AAAA,EACV,SAAS;AAAA,EACT,OAAOA,GAAE,IAAIA,GAAE,OAAO,GAAG,UAAU;AAAA,EACnC,YAAYA,GAAE,OAAO;AAAA,IACnB,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,IACtC,QAAQA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,IACrC,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,IACtC,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACtC,CAAC;AAAA,EACD,gBAAgBA,GACb,OAAO;AAAA,IACN,SAASA,GAAE,OAAO,EAAE,YAAY;AAAA,IAChC,QAAQA,GAAE,OAAO,EAAE,YAAY;AAAA,IAC/B,SAASA,GAAE,OAAO,EAAE,YAAY;AAAA,IAChC,aAAaA,GAAE,OAAO,EAAE,YAAY;AAAA,EACtC,CAAC,EACA,SAAS;AAAA,EACZ,oBAAoBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC7C,eAAeA,GAAE,QAAQ;AAAA,EACzB,WAAWA,GAAE,IAAI,SAAS;AAAA,EAC1B,UAAUA,GAAE,IAAI,SAAS;AAAA,EACzB,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAC3C,CAAC;AAgBM,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EAC7C,SAASA,GAAE,OAAO;AAAA,EAClB,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACzC,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACpC,aAAaA,GAAE,IAAI,SAAS;AAC9B,CAAC;AAkCM,IAAM,oCAA6D;AAAA,EACxE,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,eAAe;AACjB;AA+BO,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EAChD,SAASA,GAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,IAAO;AAAA;AAAA,EAClD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG;AACrD,CAAC;AAKM,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAClD,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAM;AAAA;AAAA,EAC1D,oBAAoBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;AAAA,EACzD,oBAAoBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG;AAAA,EAC3D,2BAA2BA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACnD,oBAAoBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAI;AAAA;AAAA,EAC5D,eAAe,0BAA0B,SAAS;AAAA;AACpD,CAAC;AAKM,IAAM,2BAAkD;AAAA,EAC7D,gBAAgB;AAAA;AAAA,EAChB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA;AACtB;AAKO,IAAM,oBAAwD;AAAA,EACnE,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,mBAAmB;AAAA;AAAA,EACnB,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAChB;AAuCO,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EAC7C,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC7C,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAChD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAChD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAChD,mBAAmBA,GAAE,OAAO,EAAE,YAAY;AAAA,EAC1C,yBAAyBA,GAAE,OAAO,EAAE,YAAY;AAAA,EAChD,gBAAgBA,GAAE,OAAO,0BAA0BA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC;AACnF,CAAC;;;AC1WD,SAAS,KAAAC,UAAS;AASX,IAAM,yBAAyBA,GAAE,KAAK,CAAC,YAAY,gBAAgB,WAAW,CAAC;AAM/E,IAAM,0BAA0BA,GAAE,KAAK;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,SAASA,GAAE,OAAO;AAAA,EAClB,UAAUA,GAAE,KAAK,CAAC,OAAO,YAAY,eAAe,SAAS,UAAU,iBAAiB,OAAO,CAAC;AAAA,EAChG,UAAUA,GAAE,KAAK,CAAC,YAAY,SAAS,SAAS,YAAY,CAAC;AAAA,EAC7D,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,EACjF,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,EAC5D,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACnC,WAAWA,GAAE,IAAI,SAAS,EAAE,SAAS;AACvC,CAAC;AAMM,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACxC,SAASA,GAAE,OAAO;AAAA,EAClB,WAAWA,GAAE,OAAO;AAAA,EACpB,OAAOA,GAAE,QAAQ;AAAA,EACjB,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,iBAAiBA,GAAE,KAAK,CAAC,YAAY,SAAS,SAAS,YAAY,CAAC,EAAE,SAAS;AACjF,CAAC;AAoCM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACvD,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACnD,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAK;AAAA,EACzD,oBAAoBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAAA,EAC3D,sBAAsBA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC9C,qBAAqBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAC3D,CAAC;AAEM,IAAM,iCAAuD;AAAA,EAClE,eAAe;AAAA,EACf,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,qBAAqB;AACvB;;;ACpGA,SAAS,KAAAC,UAAS;AAMX,IAAMC,qBAAoBD,GAAE,KAAK,CAAC,WAAW,WAAW,WAAW,SAAS,CAAC;AAoB7E,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EAChD,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACzC,iBAAiBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC9C,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC1C,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACpC,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC/B,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACnC,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC7C,YAAYA,GAAE,KAAK;AAAA,EACnB,WAAWA,GAAE,KAAK;AACpB,CAAC;AAsCM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,WAAWA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EAC/C,sBAAsBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,IAAI;AAAA,EAC7D,mBAAmBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACzD,sBAAsBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAAA,EAC3D,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACnD,wBAAwBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;AAAA,EAC7D,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACnD,iBAAiBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAC1D,CAAC;AAEM,IAAM,iCAAuD;AAAA,EAClE,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,eAAe;AAAA,EACf,iBAAiB;AACnB;;;AC1FA,SAAS,KAAAE,UAAS;AAiBX,SAAS,mBAAmB,QAAgB,QAA8B;AAC/E,SAAO,SAAS,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,GAAG,MAAM,IAAI,MAAM;AACtE;AAKO,SAAS,kBAAkB,KAAqC;AACrE,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,MAAI,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM,UAAa,MAAM,CAAC,MAAM,QAAW;AAC1E,UAAM,IAAI,MAAM,2BAA2B,GAAG,EAAE;AAAA,EAClD;AACA,SAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAC5B;AAOO,IAAM,+BAA+BA,GAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC;AAuB7D,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,IAAIA,GAAE,OAAO;AAAA,EACb,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC5B,mBAAmBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC1C,kBAAkBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACjD,CAAC;AAwBM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,YAAYA,GAAE,OAAO;AAAA,EACrB,SAASA,GAAE,OAAO;AAAA,EAClB,UAAUA,GAAE,KAAK,CAAC,WAAW,UAAU,SAAS,CAAC;AAAA,EACjD,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACnC,oBAAoBA,GAAE,QAAQ;AAAA,EAC9B,WAAWA,GAAE,KAAK;AACpB,CAAC;AAoBM,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAClD,SAASA,GAAE,OAAO;AAAA,EAClB,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAChD,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACzC,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC5C,aAAa;AAAA,EACb,aAAaA,GAAE,KAAK;AACtB,CAAC;AA8BM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,+BAA+BA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACrE,sBAAsBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EAC1D,qBAAqBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,KAAQ;AAAA;AAAA,EACjE,uBAAuBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EAC3D,wBAAwBA,GAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAChD,wBAAwBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,IAAI;AAAA,EAC7D,yBAAyBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAI;AAAA,EACjE,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAI;AAAA,EACtD,iBAAiBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG;AAC1D,CAAC;AAEM,IAAM,8BAAuD;AAAA,EAClE,+BAA+B;AAAA,EAC/B,sBAAsB;AAAA,EACtB,qBAAqB;AAAA;AAAA,EACrB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,cAAc;AAAA,EACd,iBAAiB;AACnB;AAgCO,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,UAAUA,GAAE,KAAK,CAAC,WAAW,UAAU,cAAc,CAAC;AAAA,EACtD,mBAAmBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC1C,oBAAoBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC3C,oBAAoBA,GAAE,OAAO,EAAE,YAAY;AAAA,EAC3C,qBAAqBA,GAAE,QAAQ;AAAA,EAC/B,QAAQA,GAAE,KAAK,CAAC,MAAM,OAAO,QAAQ,CAAC;AAAA,EACtC,yBAAyBA,GAAE,OAAO;AAAA,EAClC,oBAAoBA,GAAE,MAAM,uBAAuB,EAAE,SAAS;AAAA,EAC9D,oBAAoBA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EACtC,WAAWA,GAAE,OAAO;AACtB,CAAC;AAwBM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC1C,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,mBAAmBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAChD,oBAAoBA,GAAE,OAAO;AAAA,EAC7B,wBAAwBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACrD,yBAAyBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACxD,CAAC;;;ACtNM,SAAS,6BACd,UACA,mBACS;AACT,MAAI,SAAS,SAAS,EAAG,QAAO;AAEhC,MAAI,gBAAgB;AACpB,QAAM,aAAc,SAAS,UAAU,SAAS,SAAS,KAAM;AAE/D,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,aAAS,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AAC5C,YAAM,SAAS,SAAS,CAAC;AACzB,YAAM,SAAS,SAAS,CAAC;AACzB,UAAI,WAAW,UAAa,WAAW,QAAW;AAChD,cAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,YAAI,kBAAkB,IAAI,OAAO,GAAG;AAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB,KAAK,KAAK,aAAa,GAAG;AACpD;AAMO,SAAS,wBACd,UACA,mBACA,sBACqB;AACrB,QAAM,UAAU,oBAAI,IAAoB;AAGxC,aAAW,WAAW,UAAU;AAC9B,YAAQ,IAAI,SAAS,CAAG;AAAA,EAC1B;AAGA,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,aAAS,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AAC5C,YAAM,SAAS,SAAS,CAAC;AACzB,YAAM,SAAS,SAAS,CAAC;AACzB,UAAI,WAAW,UAAa,WAAW,OAAW;AAElD,YAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,YAAM,cAAc,kBAAkB,IAAI,OAAO;AAEjD,UAAI,gBAAgB,UAAa,cAAc,sBAAsB;AAEnE,cAAM,YAAY,cAAc;AAChC,cAAM,iBAAiB,QAAQ,IAAI,MAAM,KAAK;AAC9C,cAAM,iBAAiB,QAAQ,IAAI,MAAM,KAAK;AAG9C,gBAAQ,IAAI,QAAQ,KAAK,IAAI,KAAK,iBAAiB,YAAY,GAAG,CAAC;AACnE,gBAAQ,IAAI,QAAQ,KAAK,IAAI,KAAK,iBAAiB,YAAY,GAAG,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,kBACd,OACA,kBACyB;AACzB,MAAI,mBAAmB;AACvB,MAAI,oBAAoB;AACxB,MAAI,cAAc;AAClB,QAAM,qBAA+B,CAAC;AAEtC,aAAW,CAAC,SAAS,IAAI,KAAK,OAAO;AACnC,UAAM,SAAS,iBAAiB,IAAI,OAAO,KAAK;AAGhD,QAAI,SAAS,KAAK;AAChB,yBAAmB,KAAK,OAAO;AAAA,IACjC;AAGA,UAAM,kBAAkB,SAAS,KAAK;AACtC,mBAAe;AAEf,QAAI,KAAK,aAAa,WAAW;AAC/B,0BAAoB;AAAA,IACtB,WAAW,KAAK,aAAa,UAAU;AACrC,2BAAqB;AAAA,IACvB;AAAA,EAEF;AAEA,QAAM,oBAAoB,cAAc,IAAI,mBAAmB,cAAc;AAC7E,QAAM,qBAAqB,cAAc,IAAI,oBAAoB,cAAc;AAC/E,QAAM,qBAAqB;AAE3B,SAAO,EAAE,mBAAmB,oBAAoB,oBAAoB,mBAAmB;AACzF;AAKO,SAAS,iBACd,OACA,oBACyB;AACzB,QAAM,gBAAgF,CAAC;AACvF,QAAM,qBAA+B,CAAC;AAEtC,aAAW,UAAU,oBAAoB;AACvC,UAAM,cAAc,oBAAI,IAAkB;AAC1C,eAAW,WAAW,OAAO,UAAU;AACrC,YAAM,OAAO,MAAM,IAAI,OAAO;AAC9B,UAAI,SAAS,OAAW,aAAY,IAAI,SAAS,IAAI;AAAA,IACvD;AACA,QAAI,YAAY,SAAS,EAAG;AAE5B,UAAM,EAAE,UAAU,UAAU,IAAI,iBAAiB,WAAW;AAC5D,UAAM,SAAS,YAAY,QAAQ,IAAI,OAAO;AAC9C,kBAAc,KAAK,EAAE,UAAU,WAAW,OAAO,CAAC;AAElD,QAAI,OAAO,SAAS,WAAW,EAAG,oBAAmB,KAAK,GAAG,OAAO,QAAQ;AAAA,EAC9E;AACA,SAAO,EAAE,eAAe,mBAAmB;AAC7C;AAKO,SAAS,qBACd,eACsB;AACtB,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAClB,aAAW,EAAE,UAAU,WAAW,OAAO,KAAK,eAAe;AAC3D,qBAAiB,WAAW;AAC5B,sBAAkB,YAAY;AAC9B,mBAAe;AAAA,EACjB;AACA,SAAO;AAAA,IACL,mBAAmB,cAAc,IAAI,gBAAgB,cAAc;AAAA,IACnE,oBAAoB,cAAc,IAAI,iBAAiB,cAAc;AAAA,IACrE;AAAA,EACF;AACF;AAKO,SAAS,iBAAiB,OAG/B;AACA,MAAI,WAAW;AACf,MAAI,YAAY;AAEhB,aAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,QAAI,KAAK,aAAa,WAAW;AAC/B,kBAAY,KAAK;AAAA,IACnB,WAAW,KAAK,aAAa,UAAU;AACrC,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,QAAQ,WAAW;AACzB,SAAO;AAAA,IACL,UAAU,QAAQ,IAAI,WAAW,QAAQ;AAAA,IACzC,WAAW,QAAQ,IAAI,YAAY,QAAQ;AAAA,EAC7C;AACF;AAKO,SAAS,6BACd,mBACA,oBACuC;AACvC,QAAM,OAAO,KAAK,IAAI,oBAAoB,kBAAkB;AAG5D,MAAI,OAAO,KAAK;AACd,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,qBAAqB,YAAY;AAC9D;AAKO,SAAS,gBACd,OACA,kBAMyB;AACzB,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,QAAQ;AAEZ,aAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,QAAI,KAAK,aAAa,WAAW;AAC/B;AAAA,IACF,WAAW,KAAK,aAAa,UAAU;AACrC;AAAA,IACF;AACA,QAAI,KAAK,aAAa,WAAW;AAC/B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,QAAQ,IAAI,UAAU,QAAQ;AACxD,QAAM,qBAAqB,QAAQ,IAAI,SAAS,QAAQ;AACxD,QAAM,WAAW,6BAA6B,mBAAmB,kBAAkB;AAEnF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,QAAQ;AAAA,IACR,yBAAyB;AAAA,IACzB,oBAAoB,CAAC;AAAA,IACrB,WAAW,iBAAiB,UAAU,OAAO,CAAC,GAAG,QAAQ;AAAA,EAC3D;AACF;AAKO,SAAS,qBACd,mBACA,oBACA,UACA,UACQ;AAER,MAAI,aAAa,kBAAkB,SAAS,aAAa,gBAAgB;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,aAAa,YAAY,oBAAoB;AACvE,QAAM,qBACJ,SAAS,aAAa,YAAY,SAAS,oBAAoB,SAAS;AAG1E,UAAQ,oBAAoB,sBAAsB;AACpD;AAKO,SAAS,eACd,UACA,gBACA,oBACA,QACQ;AACR,QAAM,aACJ,WAAW,OACP,sCACA,WAAW,QACT,iCACA;AAER,MAAI,YAAY,wBAAwB,UAAU,SAAS,eAAe,QAAQ,CAAC,CAAC;AAEpF,MAAI,mBAAmB,SAAS,GAAG;AACjC,iBAAa,GAAG,OAAO,mBAAmB,MAAM,CAAC;AAAA,EACnD;AAEA,MAAI,aAAa,gBAAgB;AAC/B,iBAAa;AAAA,EACf,OAAO;AACL,iBAAa,mBAAmB,QAAQ;AAAA,EAC1C;AAEA,SAAO;AACT;;;AC5SA,IAAMC,UAAS,aAAa,EAAE,WAAW,sBAAsB,CAAC;AAWzD,IAAM,WAAN,MAA8D;AAAA,EAC1D,YAAgC;AAAA,EACxB;AAAA,EAEjB,YAAY,UAA2B,CAAC,GAAG;AACzC,SAAK,SAAS,EAAE,GAAG,6BAA6B,GAAG,QAAQ,OAAO;AAClE,IAAAA,QAAO,KAAK,wBAAwB,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EAC7D;AAAA;AAAA,EAGA,iBAAiB,OAA0B,UAA+C;AACxF,UAAM,SAAS,KAAK,wBAAwB,KAAK;AACjD,WAAO,KAAK,gBAAgB,OAAO,MAAM;AAAA,EAC3C;AAAA,EAEA,yBACE,OACA,mBACyB;AACzB,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK,CAAC;AACxC,UAAM,oBAAoB,6BAA6B,UAAU,iBAAiB;AAElF,QAAI,CAAC,qBAAqB,KAAK,OAAO,wBAAwB;AAE5D,MAAAA,QAAO,KAAK,gEAAgE;AAAA,QAC1E,YAAY,SAAS;AAAA,QACrB,QAAQ;AAAA,MACV,CAAC;AACD,aAAO,KAAK,wBAAwB,KAAK;AAAA,IAC3C;AAEA,UAAM,mBAAmB;AAAA,MACvB;AAAA,MACA;AAAA,MACA,KAAK,OAAO;AAAA,IACd;AAEA,UAAM,EAAE,mBAAmB,oBAAoB,oBAAoB,mBAAmB,IACpF,kBAAkB,OAAO,gBAAgB;AAE3C,UAAM,WAAW,6BAA6B,mBAAmB,kBAAkB;AACnF,UAAM,iBAAiB,KAAK,wBAAwB,KAAK;AACzD,UAAM,0BAA0B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,SAAkC;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,WAAW,eAAe,UAAU,oBAAoB,oBAAoB,IAAI;AAAA,IAClF;AAEA,IAAAA,QAAO,KAAK,2BAA2B;AAAA,MACrC;AAAA,MACA,mBAAmB,kBAAkB,QAAQ,CAAC;AAAA,MAC9C,gBAAgB,mBAAmB,QAAQ,CAAC;AAAA,MAC5C,oBAAoB,mBAAmB;AAAA,IACzC,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,SAAiD;AACnE,WAAO,QAAQ,yBAAyB;AAAA,EAC1C;AAAA,EAEA,WACE,OACA,oBACyB;AACzB,QAAI,mBAAmB,WAAW,GAAG;AAEnC,MAAAA,QAAO,KAAK,yDAAyD;AAAA,QACnE,QAAQ;AAAA,MACV,CAAC;AACD,aAAO,KAAK,wBAAwB,KAAK;AAAA,IAC3C;AAEA,UAAM,EAAE,eAAe,mBAAmB,IAAI,iBAAiB,OAAO,kBAAkB;AACxF,UAAM,EAAE,mBAAmB,mBAAmB,IAAI,qBAAqB,aAAa;AACpF,UAAM,qBAAqB,mBAAmB;AAC9C,UAAM,WAAW,6BAA6B,mBAAmB,kBAAkB;AAEnF,UAAM,iBAAiB,KAAK,wBAAwB,KAAK;AACzD,UAAM,0BAA0B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,SAAkC;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,eAAe,UAAU,oBAAoB,oBAAoB,KAAK;AAAA,IACnF;AAEA,IAAAA,QAAO,KAAK,4BAA4B;AAAA,MACtC;AAAA,MACA,aAAa,mBAAmB;AAAA,MAChC,mBAAmB,kBAAkB,QAAQ,CAAC;AAAA,IAChD,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,UACE,OACA,SACyB;AACzB,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK,CAAC;AAExC,QAAI,CAAC,QAAQ,kBAAkB,QAAQ,GAAG;AACxC,UAAI,KAAK,OAAO,wBAAwB;AAEtC,QAAAA,QAAO,KAAK,mEAAmE;AAAA,UAC7E,YAAY,SAAS;AAAA,UACrB,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,KAAK,wBAAwB,KAAK;AAAA,MAC3C;AAAA,IACF;AAEA,UAAM,oBAAoB,QAAQ,yBAAyB;AAC3D,UAAM,WAAW,KAAK,yBAAyB,OAAO,iBAAiB;AAEvE,UAAM,qBAAqB,QAAQ,2BAA2B;AAC9D,QAAI,mBAAmB,SAAS,GAAG;AACjC,YAAM,YAAY,KAAK,WAAW,OAAO,kBAAkB;AAC3D,YAAM,eAAe,KAAK,IAAI,SAAS,oBAAoB,GAAG,IAAI;AAClE,YAAM,gBAAgB,KAAK,IAAI,UAAU,oBAAoB,GAAG,IAAI;AAEpE,UAAI,gBAAgB,cAAc;AAChC,QAAAA,QAAO,MAAM,mDAAmD;AAChE,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,YAAqC;AACnC,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC1B;AAAA,EAEQ,wBAAwB,OAA2D;AACzF,WAAO,gBAAgB,OAAO,cAAc;AAAA,EAC9C;AAAA,EAEQ,gBACN,OACA,QACe;AACf,QAAI,UAAU;AACd,QAAI,SAAS;AACb,QAAI,UAAU;AAEd,eAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,UAAI,KAAK,aAAa,UAAW;AAAA,eACxB,KAAK,aAAa,SAAU;AAAA,UAChC;AAAA,IACP;AAEA,UAAM,aAAyB,EAAE,SAAS,QAAQ,SAAS,OAAO,MAAM,KAAK;AAE7E,UAAM,gBAAgB,OAAO,oBAAoB;AACjD,UAAM,qBAAqB,OAAO,SAAS,aAAa,IAAI,gBAAgB;AAE5E,WAAO;AAAA,MACL,UAAU,OAAO,aAAa;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AAGO,SAAS,eAAe,SAA+C;AAC5E,SAAO,IAAI,SAAS,OAAO;AAC7B;AAMO,IAAM,4BAAN,cAAwC,SAAoC;AAAA,EAC/D,YAAgC;AAAA,EAElD,YAAY,UAA2B,CAAC,GAAG;AACzC,UAAM,OAAO;AAAA,EACf;AACF;AAGO,SAAS,gCACd,SAC2B;AAC3B,SAAO,IAAI,0BAA0B,OAAO;AAC9C;;;AC5NA,SAAS,kBACP,cACA,aACA,WACA,WACmD;AACnD,QAAM,QAAQ,eAAe;AAC7B,SAAO;AAAA,IACL,UAAU,YAAY,SAAS,YAAY,QAAQ;AAAA,IACnD,oBAAoB,QAAQ;AAAA,EAC9B;AACF;AAKA,IAAe,qBAAf,MAA6D;AAAA;AAAA;AAAA;AAAA,EAQjD,WAAW,OAAsC;AACzD,QAAI,UAAU;AACd,QAAI,SAAS;AACb,QAAI,UAAU;AAEd,eAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,cAAQ,KAAK,UAAU;AAAA,QACrB,KAAK;AACH;AACA;AAAA,QACF,KAAK;AACH;AACA;AAAA,QACF,KAAK;AACH;AACA;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,QAAQ,SAAS,OAAO,MAAM,KAAK;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKU,mBACR,OACA,SACoB;AACpB,QAAI,UAAU;AACd,QAAI,SAAS;AACb,QAAI,UAAU;AACd,QAAI,cAAc;AAElB,eAAW,CAAC,SAAS,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC7C,YAAM,SAAS,QAAQ,IAAI,OAAO,KAAK;AACvC,qBAAe;AAEf,cAAQ,KAAK,UAAU;AAAA,QACrB,KAAK;AACH,qBAAW;AACX;AAAA,QACF,KAAK;AACH,oBAAU;AACV;AAAA,QACF,KAAK;AACH,qBAAW;AACX;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,QAAQ,SAAS,YAAY;AAAA,EACjD;AACF;AAKO,IAAM,yBAAN,cAAqC,mBAAmB;AAAA,EACpD,YAAgC;AAAA,EAEzC,iBAAiB,OAAyC;AACxD,UAAM,SAAS,KAAK,WAAW,KAAK;AACpC,UAAM,cAAc,OAAO,UAAU,OAAO;AAC5C,UAAM,YAAY,kBAAkB;AAEpC,QAAI,gBAAgB,GAAG;AACrB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,oBAAoB;AAAA,QACpB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,EAAE,UAAU,mBAAmB,IAAI;AAAA,MACvC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ,WACJ,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC,OAAO,OAAO,YAAY,GAAG,CAAC,gBAC5E,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC,QAAQ,OAAO,YAAY,GAAG,CAAC;AAAA,IACnF;AAAA,EACF;AACF;AAKO,IAAM,wBAAN,cAAoC,mBAAmB;AAAA,EACnD,YAAgC;AAAA,EAEzC,iBAAiB,OAAyC;AACxD,UAAM,SAAS,KAAK,WAAW,KAAK;AACpC,UAAM,cAAc,OAAO,UAAU,OAAO;AAC5C,UAAM,YAAY,kBAAkB;AAEpC,QAAI,gBAAgB,GAAG;AACrB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,oBAAoB;AAAA,QACpB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,EAAE,UAAU,mBAAmB,IAAI;AAAA,MACvC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ,WACJ,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC,QAAQ,OAAO,YAAY,GAAG,CAAC,gBAC7E,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC,OAAO,OAAO,YAAY,GAAG,CAAC;AAAA,IAClF;AAAA,EACF;AACF;AAKO,IAAM,oBAAN,cAAgC,mBAAmB;AAAA,EAC/C,YAAgC;AAAA,EAEzC,iBAAiB,OAAyC;AACxD,UAAM,SAAS,KAAK,WAAW,KAAK;AAEpC,QAAI,OAAO,UAAU,GAAG;AACtB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,oBAAoB;AAAA,QACpB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAIA,UAAM,qBAAqB,OAAO,QAAQ,IAAK,OAAO,UAAU,OAAO,QAAS,MAAM;AAEtF,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA,YAAY;AAAA,QACZ,QAAQ,aAAa,OAAO,OAAO,MAAM,CAAC;AAAA,MAC5C;AAAA,IACF;AAEA,QAAI,OAAO,YAAY,GAAG;AACxB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,oBAAoB;AAAA,QACpB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ,6BAA6B,OAAO,OAAO,OAAO,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;AAMO,IAAM,0BAAN,cAAsC,mBAAmB;AAAA,EACrD,YAAgC;AAAA,EAEzC,iBAAiB,OAA0B,SAA8C;AACvF,UAAM,SAAS,KAAK,WAAW,KAAK;AACpC,UAAM,mBAAmB,WAAW,oBAAI,IAAoB;AAC5D,UAAM,iBAAiB,KAAK,mBAAmB,OAAO,gBAAgB;AACtE,UAAM,YAAY,kBAAkB;AAEpC,UAAM,eAAe,eAAe,UAAU,eAAe;AAE7D,QAAI,iBAAiB,GAAG;AACtB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,oBAAoB;AAAA,QACpB,YAAY;AAAA,QACZ;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,EAAE,UAAU,mBAAmB,IAAI;AAAA,MACvC,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA,QAAQ,WACJ,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC,wBAC9C,iBAAiB,mBAAmB,QAAQ,CAAC,CAAC;AAAA,IACpD;AAAA,EACF;AACF;AAMO,SAAS,oBAAoB,aAAmD;AACrF,MAAI,gBAAgB,UAAa,YAAY,eAAe,GAAG;AAC7D,WAAO;AAAA,EACT;AAIA,SAAO,MAAM,YAAY,cAAc;AACzC;AAKO,IAAM,wBAAN,MAA4B;AAAA,EAChB;AAAA,EAEjB,cAAc;AACZ,SAAK,aAAa,oBAAI,IAAyC;AAAA,MAC7D,CAAC,mBAAmB,IAAI,uBAAuB,CAAC;AAAA,MAChD,CAAC,iBAAiB,IAAI,sBAAsB,CAAC;AAAA,MAC7C,CAAC,aAAa,IAAI,kBAAkB,CAAC;AAAA,MACrC,CAAC,qBAAqB,IAAI,wBAAwB,CAAC;AAAA,MACnD,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;AAAA,MAChD,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,WAAgD;AAC1D,UAAM,WAAW,KAAK,WAAW,IAAI,SAAS;AAC9C,QAAI,aAAa,QAAW;AAC1B,YAAM,IAAI,MAAM,6BAA6B,SAAS,EAAE;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,UAAiC;AAChD,SAAK,WAAW,IAAI,SAAS,WAAW,QAAQ;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,yBAA+C;AAC7C,WAAO,MAAM,KAAK,KAAK,WAAW,KAAK,CAAC;AAAA,EAC1C;AACF;AAKO,SAAS,wBAA+C;AAC7D,SAAO,IAAI,sBAAsB;AACnC;;;AChVO,SAAS,mBACd,OACA,YACA,SACA,QACiB;AACjB,QAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,SAAS,MAAM,WAAW,WAAW,YAAY,MAAM;AAAA,IACvD,OAAO,IAAI,IAAI,MAAM,KAAK;AAAA,IAC1B,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ;AAAA,IACxB,oBAAoB,QAAQ;AAAA,IAC5B,eAAe,MAAM,MAAM,QAAQ,OAAO;AAAA,IAC1C,WAAW,MAAM,UAAU,YAAY;AAAA,IACvC,UAAU,IAAI,YAAY;AAAA,IAC1B,YAAY,IAAI,QAAQ,IAAI,MAAM,UAAU,QAAQ;AAAA,EACtD;AACF;AAKO,SAAS,iBACd,OACA,YACA,SACA,QACiB;AACjB,QAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,QAAM,gBAAgB,MAAM,MAAM,QAAQ,OAAO;AACjD,QAAM,cAAc,qBAAqB,eAAe,QAAQ,QAAQ;AAExE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,SAAS;AAAA,IACT,OAAO,IAAI,IAAI,MAAM,KAAK;AAAA,IAC1B,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ;AAAA,IACxB,oBAAoB,QAAQ;AAAA,IAC5B;AAAA,IACA,WAAW,MAAM,UAAU,YAAY;AAAA,IACvC,UAAU,IAAI,YAAY;AAAA,IAC1B,YAAY,IAAI,QAAQ,IAAI,MAAM,UAAU,QAAQ;AAAA,EACtD;AACF;AAKO,SAAS,mBACd,OACA,YACA,SACA,QACiB;AACjB,QAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,SAAS;AAAA,IACT,OAAO,IAAI,IAAI,MAAM,KAAK;AAAA,IAC1B,YAAY,QAAQ;AAAA,IACpB,gBAAgB,QAAQ;AAAA,IACxB,oBAAoB,QAAQ;AAAA,IAC5B,eAAe,MAAM,MAAM,QAAQ,OAAO;AAAA,IAC1C,WAAW,MAAM,UAAU,YAAY;AAAA,IACvC,UAAU,IAAI,YAAY;AAAA,IAC1B,YAAY,IAAI,QAAQ,IAAI,MAAM,UAAU,QAAQ;AAAA,EACtD;AACF;AAKO,SAAS,qBAAqB,eAAwB,UAAmC;AAC9F,MAAI,CAAC,iBAAiB,CAAC,SAAU,QAAO;AACxC,SAAO;AACT;;;ACxFO,SAAS,qBAAiC;AAC/C,QAAM,YAAY,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE;AACrD,QAAM,SAAS,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AACvE,SAAO,QAAQ,SAAS,IAAI,MAAM;AACpC;;;ACqBO,SAAS,kBACd,OACA,eACA,WACA,QACS;AACT,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,MAAI,YAAY;AAChB,MAAI,kBAAkB;AACtB,aAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,QAAI,KAAK,aAAa,UAAW;AACjC,uBAAmB,KAAK;AAAA,EAC1B;AAEA,QAAM,eAAe,YAAY;AACjC,QAAM,gBAAgB,kBAAkB,MAAM;AAG9C,QAAM,YAAY,YAAY,OAAO;AACrC,QAAM,YAAY,YAAY,OAAO;AACrC,QAAM,gBAAgB,gBAAgB,aAAa,gBAAgB;AAGnE,QAAM,sBAAsB,gBAAgB,OAAO;AAEnD,SAAO,iBAAiB;AAC1B;;;ACvBO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAC7C,YAAY,SAAiB,SAAmC;AAC9D,UAAM,SAAS,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC,CAAC;AACvD,SAAK,OAAO;AAAA,EACd;AACF;AA2CA,IAAM,uBAA6B;AAAA,EACjC,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,WAAW;AACb;AACA,IAAM,sBAA4B;AAAA,EAChC,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,WAAW;AACb;AAEA,IAAM,gCAAqD;AAAA,EACzD,SAAS;AAAA,EACT,OAAO;AAAA;AAAA,EACP,YAAY;AACd;AAsBO,IAAM,kBAAN,MAAkD;AAAA,EACtC,YAA4C,oBAAI,IAAI;AAAA,EACpD,kBAAoD,oBAAI,IAAI;AAAA,EAC5D,mBAAkD,oBAAI,IAAI;AAAA,EAC1D,uBAAwD,oBAAI,IAAI;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAER,YAAY,QAAyCC,SAAkB;AACrE,SAAK,SAAS,EAAE,GAAG,0BAA0B,GAAG,OAAO;AACvD,SAAK,cAAc,EAAE,GAAG,+BAA+B,GAAG,QAAQ,cAAc;AAChF,SAAK,eAAe,EAAE,GAAG,mCAAmC,GAAG,QAAQ,kBAAkB;AACzF,SAAK,SAASA,WAAU,aAAa,EAAE,WAAW,kBAAkB,CAAC;AACrE,SAAK,kBAAkB,IAAI,sBAAsB;AACjD,SAAK,UAAU,KAAK,qBAAqB;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,0BAA0B,UAAwC;AAChE,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,QAAQ,UAAiE;AACvE,UAAM,aAAa,eAAe,UAAU,QAAQ;AACpD,QAAI,CAAC,WAAW,SAAS;AACvB,aAAO,QAAQ;AAAA,QACb;AAAA,UACE,IAAI,eAAe,qBAAqB,WAAW,MAAM,OAAO,IAAI;AAAA,YAClE,QAAQ,WAAW,MAAM;AAAA,UAC3B,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,YAAY,SAAS;AAC5B,YAAM,cAAc,KAAK,gBAAgB,WAAW,IAAI;AACxD,UAAI,gBAAgB,QAAW;AAC7B,aAAK,OAAO,MAAM,oCAAoC;AAAA,UACpD,kBAAkB,YAAY;AAAA,UAC9B,eAAe,YAAY,OAAO;AAAA,QACpC,CAAC;AACD,eAAO,QAAQ,QAAQ,GAAG,YAAY,UAAU,CAAC;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,QAAQ,KAAK,OAAO,oBAAoB;AACzD,aAAO,QAAQ;AAAA,QACb;AAAA,UACE,IAAI;AAAA,YACF,6BAA6B,OAAO,KAAK,OAAO,kBAAkB,CAAC;AAAA,UACrE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,SAAS,MAAM,mBAAmB;AACrD,UAAM,QAAQ,KAAK,oBAAoB,WAAW,MAAM,UAAU;AAClE,SAAK,aAAa,OAAO,YAAY,SAAS,OAAO;AACrD,SAAK,iBAAiB,YAAY,OAAO,SAAS,SAAS;AAC3D,WAAO,QAAQ,QAAQ,GAAG,UAAU,CAAC;AAAA,EACvC;AAAA,EAEA,MAAM,KACJ,YACA,SACA,MACuC;AACvC,UAAM,gBAAgB,KAAK,aAAa,IAAI;AAC5C,QAAI,kBAAkB,OAAW,QAAO,IAAI,aAAa;AAEzD,UAAM,WAAW,KAAK,sBAAsB,UAAU;AACtD,QAAI,aAAa,OAAW,QAAO,IAAI,QAAQ;AAE/C,UAAM,QAAQ,KAAK,UAAU,IAAI,UAAU;AAC3C,QAAI,UAAU,QAAW;AACvB,aAAO,IAAI,IAAI,eAAe,YAAY,UAAU,YAAY,CAAC;AAAA,IACnE;AAEA,SAAK,WAAW,OAAO,SAAS,IAAI;AAGpC,QAAI,KAAK,gBAAgB,KAAK,GAAG;AAC/B,aAAO,KAAK,cAAc,UAAU,EAAE,KAAK,CAAC,MAAO,EAAE,KAAK,GAAG,MAAS,IAAI,IAAI,EAAE,KAAK,CAAE;AAAA,IACzF;AAGA,QAAI,KAAK,uBAAuB,KAAK,GAAG;AAQtC,UAAI,MAAM,sBAAsB,MAAM;AACpC,eAAO,QAAQ,QAAQ,GAAG,MAAS,CAAC;AAAA,MACtC;AACA,YAAM,oBAAoB;AAC1B,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,KAAK,gBAAgB,YAAY,KAAK;AAAA,MACzD,UAAE;AACA,cAAM,oBAAoB;AAAA,MAC5B;AACA,UAAI,CAAC,UAAU;AACb,eAAO,KAAK,cAAc,UAAU,EAAE,KAAK,CAAC,MAAO,EAAE,KAAK,GAAG,MAAS,IAAI,IAAI,EAAE,KAAK,CAAE;AAAA,MACzF;AAAA,IAEF;AAEA,WAAO,QAAQ,QAAQ,GAAG,MAAS,CAAC;AAAA,EACtC;AAAA,EAEA,UAAU,YAA0E;AAClF,UAAM,eAAe,KAAK,gBAAgB,IAAI,UAAU;AACxD,QAAI,iBAAiB,OAAW,QAAO,QAAQ,QAAQ,GAAG,YAAY,CAAC;AAEvE,UAAM,QAAQ,KAAK,UAAU,IAAI,UAAU;AAC3C,QAAI,UAAU,QAAW;AACvB,aAAO,QAAQ,QAAQ,IAAI,IAAI,eAAe,YAAY,UAAU,YAAY,CAAC,CAAC;AAAA,IACpF;AAEA,UAAM,UAAU,KAAK,iBAAiB,KAAK;AAC3C,WAAO,QAAQ,QAAQ,GAAG,mBAAmB,OAAO,YAAY,SAAS,KAAK,MAAM,CAAC,CAAC;AAAA,EACxF;AAAA,EAEA,MAAM,YAA0E;AAC9E,WAAO,KAAK,cAAc,UAAU;AAAA,EACtC;AAAA,EAEA,aAA+B;AAC7B,UAAM,YACJ,KAAK,QAAQ,oBACb,KAAK,QAAQ,oBACb,KAAK,QAAQ;AACf,WAAO;AAAA,MACL,gBAAgB,KAAK,QAAQ;AAAA,MAC7B,mBAAmB,KAAK,QAAQ;AAAA,MAChC,mBAAmB,KAAK,QAAQ;AAAA,MAChC,mBAAmB,KAAK,QAAQ;AAAA,MAChC,mBAAmB,YAAY,IAAI,KAAK,QAAQ,kBAAkB,YAAY;AAAA,MAC9E,yBAAyB,YAAY,IAAI,KAAK,QAAQ,aAAa,YAAY;AAAA,MAC/E,gBAAgB,EAAE,GAAG,KAAK,QAAQ,eAAe;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,uBAAuB,SAAiB,YAA2B;AACjE,UAAM,WAAW,KAAK,iBAAiB,IAAI,OAAO;AAClD,UAAM,MAAM,gBAAgB,EAAE,OAAO;AAErC,QAAI,aAAa,QAAW;AAC1B,WAAK,iBAAiB,IAAI,SAAS;AAAA,QACjC;AAAA,QACA,YAAY;AAAA,QACZ,cAAc,aAAa,IAAI;AAAA,QAC/B,aAAa,aAAa,IAAM;AAAA,QAChC,aAAa;AAAA,MACf,CAAC;AAAA,IACH,OAAO;AACL,YAAM,aAAa,SAAS,aAAa;AACzC,YAAM,eAAe,SAAS,gBAAgB,aAAa,IAAI;AAC/D,WAAK,iBAAiB,IAAI,SAAS;AAAA,QACjC;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa,eAAe;AAAA,QAC5B,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,oBAAoB,SAA+C;AACjE,WAAO,KAAK,iBAAiB,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,yBAAiC;AAC/B,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEQ,oBAAoB,MAAgB,YAAuC;AACjF,UAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,WAAO;AAAA,MACL,UAAU,EAAE,GAAG,MAAM,IAAI,YAAY,WAAW,IAAI,YAAY,EAAE;AAAA,MAClE,QAAQ;AAAA,MACR,OAAO,oBAAI,IAAI;AAAA,MACf,aAAa,oBAAI,IAAI;AAAA,MACrB,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAEQ,aAAa,OAAsB,YAAwB,SAAwB;AACzF,UAAM,YAAY,WAAW,KAAK,OAAO;AACzC,UAAM,YAAY,WAAW,MAAM;AACjC,WAAK,cAAc,UAAU;AAAA,IAC/B,GAAG,SAAS;AAAA,EACd;AAAA,EAEQ,iBACN,YACA,OACA,WACM;AACN,SAAK,UAAU,IAAI,YAAY,KAAK;AACpC,SAAK,QAAQ;AACb,SAAK,QAAQ,eAAe,SAAS;AACrC,SAAK,OAAO,KAAK,oBAAoB;AAAA,MACnC;AAAA,MACA,OAAO,MAAM,SAAS;AAAA,MACtB;AAAA,MACA,SAAS,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEQ,aAAa,MAAwC;AAC3D,UAAM,aAAa,WAAW,UAAU,IAAI;AAC5C,QAAI,CAAC,WAAW,SAAS;AACvB,aAAO,IAAI,eAAe,iBAAiB,WAAW,MAAM,OAAO,IAAI;AAAA,QACrE,QAAQ,WAAW,MAAM;AAAA,MAC3B,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,YAAoD;AAChF,UAAM,QAAQ,KAAK,UAAU,IAAI,UAAU;AAC3C,QAAI,UAAU,QAAW;AACvB,UAAI,KAAK,gBAAgB,IAAI,UAAU,GAAG;AACxC,eAAO,IAAI,eAAe,YAAY,UAAU,oBAAoB;AAAA,MACtE;AACA,aAAO,IAAI,eAAe,YAAY,UAAU,YAAY;AAAA,IAC9D;AACA,QAAI,MAAM,WAAW,UAAU;AAC7B,aAAO,IAAI,eAAe,YAAY,UAAU,2BAA2B;AAAA,QACzE,QAAQ,MAAM;AAAA,MAChB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,OAAsB,SAAiB,MAAkB;AAC1E,UAAM,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,WAAW,gBAAgB,EAAE,OAAO;AAAA,IACtC,CAAC;AACD,QAAI,MAAM,SAAS,cAAc,qBAAqB;AACpD,YAAM,cAAc,KAAK,iBAAiB,IAAI,OAAO;AACrD,YAAM,YAAY,IAAI,SAAS,oBAAoB,WAAW,CAAC;AAAA,IACjE;AACA,SAAK,OAAO,MAAM,iBAAiB;AAAA,MACjC,YAAY,MAAM,SAAS;AAAA,MAC3B;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,YAA0E;AAC9F,UAAM,QAAQ,KAAK,UAAU,IAAI,UAAU;AAC3C,QAAI,UAAU,QAAW;AACvB,YAAM,SAAS,KAAK,gBAAgB,IAAI,UAAU;AAClD,UAAI,WAAW,OAAW,QAAO,QAAQ,QAAQ,GAAG,MAAM,CAAC;AAC3D,aAAO,QAAQ,QAAQ,IAAI,IAAI,eAAe,YAAY,UAAU,YAAY,CAAC,CAAC;AAAA,IACpF;AAEA,QAAI,MAAM,cAAc,OAAW,cAAa,MAAM,SAAS;AAE/D,UAAM,UAAU,KAAK,iBAAiB,KAAK;AAC3C,UAAM,SAAS,iBAAiB,OAAO,YAAY,SAAS,KAAK,MAAM;AACvE,SAAK,SAAS,YAAY,QAAQ,MAAM,MAAM,IAAI;AAClD,WAAO,QAAQ,QAAQ,GAAG,MAAM,CAAC;AAAA,EACnC;AAAA,EAEQ,cAAc,YAA8B;AAClD,UAAM,QAAQ,KAAK,UAAU,IAAI,UAAU;AAC3C,QAAI,OAAO,WAAW,SAAU;AAEhC,SAAK,OAAO,KAAK,sBAAsB,EAAE,YAAY,WAAW,MAAM,MAAM,KAAK,CAAC;AAClF,UAAM,UAAU,KAAK,iBAAiB,KAAK;AAC3C,UAAM,SAAS,mBAAmB,OAAO,YAAY,SAAS,KAAK,MAAM;AACzE,SAAK,UAAU,OAAO,UAAU;AAChC,SAAK,kBAAkB,YAAY,MAAM;AACzC,SAAK,QAAQ;AACb,SAAK,QAAQ,mBAAmB,OAAO;AACvC,SAAK,QAAQ,cAAc,MAAM,MAAM;AAAA,EACzC;AAAA,EAEQ,SAAS,YAAwB,QAAyB,WAAyB;AACzF,SAAK,UAAU,OAAO,UAAU;AAChC,SAAK,kBAAkB,YAAY,MAAM;AACzC,SAAK,cAAc,MAAM;AAGzB,QACE,KAAK,YAAY,YAChB,OAAO,YAAY,cAAc,OAAO,YAAY,aACrD;AACA,WAAK,WAAW,OAAO,UAAU,YAAY,MAAM;AAAA,IACrD;AAEA,SAAK,OAAO,KAAK,mBAAmB;AAAA,MAClC;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,oBAAoB,OAAO,mBAAmB,QAAQ,CAAC;AAAA,MACvD;AAAA,MACA,eAAe,OAAO;AAAA,MACtB,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,YAAwB,QAA+B;AAE/E,WAAO,KAAK,gBAAgB,QAAQ,KAAK,OAAO,oBAAoB;AAClE,YAAM,WAAW,KAAK,gBAAgB,KAAK,EAAE,KAAK;AAClD,UAAI,SAAS,SAAS,KAAM;AAC5B,YAAM,YAAY,SAAS;AAC3B,WAAK,gBAAgB,OAAO,SAAS;AACrC,WAAK,OAAO,MAAM,kCAAkC,EAAE,WAAW,UAAU,CAAC;AAAA,IAC9E;AACA,SAAK,gBAAgB,IAAI,YAAY,MAAM;AAAA,EAC7C;AAAA,EAEQ,iBAAiB,OAAqC;AAC5D,UAAM,WAAW,KAAK,gBAAgB,YAAY,MAAM,SAAS,SAAS;AAC1E,UAAM,UAAyB,SAAS,iBAAiB,MAAM,OAAO,MAAM,WAAW;AACvF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBQ,gBAAgB,OAA+B;AACrD,UAAM,WAAW,MAAM,SAAS;AAChC,QAAI,aAAa,UAAa,SAAS,WAAW,EAAG,QAAO;AAC5D,QAAI,MAAM,MAAM,SAAS,EAAG,QAAO;AAEnC,UAAM,UAAU,SAAS,OAAO,CAAC,UAAU,CAAC,MAAM,MAAM,IAAI,KAAK,CAAC;AAClE,QAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,UAAM,WAAW,KAAK,gBAAgB,YAAY,MAAM,SAAS,SAAS;AAE1E,UAAM,WAAW,IAAI,IAAkB,MAAM,KAAK;AAClD,UAAM,YAAY,IAAI,IAAkB,MAAM,KAAK;AACnD,eAAW,SAAS,SAAS;AAC3B,eAAS,IAAI,OAAO,oBAAoB;AACxC,gBAAU,IAAI,OAAO,mBAAmB;AAAA,IAC1C;AAEA,UAAM,cAAc,SAAS,iBAAiB,UAAU,MAAM,WAAW;AACzE,UAAM,eAAe,SAAS,iBAAiB,WAAW,MAAM,WAAW;AAE3E,QAAI,YAAY,aAAa,aAAa,SAAU,QAAO;AAE3D,SAAK,OAAO,KAAK,yCAAyC;AAAA,MACxD,YAAY,MAAM,SAAS;AAAA,MAC3B,SAAS,YAAY,WAAW,YAAY;AAAA,MAC5C,WAAW,MAAM,MAAM;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB,WAAW,MAAM,SAAS;AAAA,IAC5B,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,OAA+B;AAC5D,UAAM,WAAW,MAAM,SAAS;AAChC,QAAI,aAAa,UAAa,SAAS,WAAW,EAAG,QAAO;AAC5D,WAAO,SAAS,MAAM,CAAC,YAAY,MAAM,MAAM,IAAI,OAAO,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,gBAAgB,YAAwB,OAAwC;AAC5F,QAAI,CAAC,KAAK,aAAa,QAAS,QAAO;AACvC,QAAI,KAAK,2BAA2B,OAAW,QAAO;AAEtD,UAAM,SAAS,MAAM,mBAAmB;AACxC,QAAI,UAAU,KAAK,aAAa,mBAAoB,QAAO;AAE3D,UAAM,WAAW,MAAM,SAAS;AAChC,QAAI,aAAa,OAAW,QAAO;AAEnC,UAAM,YAAY,kBAAkB,MAAM,SAAS,SAAS;AAC5D,UAAM,YAAY,kBAAkB,MAAM,OAAO,SAAS,QAAQ,WAAW;AAAA,MAC3E,qBAAqB,KAAK,aAAa;AAAA,MACvC,eAAe,KAAK,aAAa;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,UAAW,QAAO;AAEvB,QAAI;AACJ,QAAI;AACF,kBAAY,MAAM,KAAK;AAAA,QACrB;AAAA,QACA,SAAS;AAAA,QACT,KAAK,aAAa;AAAA,MACpB;AAAA,IACF,SAASC,MAAc;AACrB,YAAM,QAAQA,gBAAe,QAAQA,OAAM,IAAI,MAAM,OAAOA,IAAG,CAAC;AAChE,WAAK,OAAO,KAAK,+DAA+D;AAAA,QAC9E;AAAA,QACA,cAAc,MAAM;AAAA,MACtB,CAAC;AACD,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,WAAW,GAAG;AAC1B,WAAK,OAAO,KAAK,sDAAsD,EAAE,WAAW,CAAC;AACrF,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,iBAAiB,CAAC,GAAG,UAAU,GAAG,SAAS;AAC1D,UAAM,kBAAkB,SAAS;AAEjC,SAAK,OAAO,KAAK,2CAA2C;AAAA,MAC1D;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,WAAW,UAAU;AAAA,MACrB,aAAa,MAAM,SAAS,eAAe;AAAA,IAC7C,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,QAA+B;AACnD,SAAK,QAAQ,mBAAmB,OAAO;AACvC,SAAK,QAAQ,cAAc,OAAO,WAAW;AAC7C,QAAI,OAAO,YAAY,WAAY,MAAK,QAAQ;AAAA,aACvC,OAAO,YAAY,WAAY,MAAK,QAAQ;AAAA,aAC5C,OAAO,YAAY,UAAW,MAAK,QAAQ;AAAA,EACtD;AAAA,EAEQ,uBAAwC;AAC9C,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,QACd,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,WAAW;AAAA,QACX,mBAAmB;AAAA,QACnB,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,oBAAoB,UAA4B;AACtD,UAAM,UAAU,CAAC,SAAS,OAAO,SAAS,aAAa,SAAS,SAAS,EAAE,KAAK,GAAG;AAEnF,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAQ,QAAQ,WAAW,CAAC;AAC5B,aAAO,KAAK,KAAK,MAAM,QAAQ;AAAA,IACjC;AACA,YAAQ,SAAS,GAAG,SAAS,EAAE;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,UAAoD;AAC1E,UAAM,OAAO,KAAK,oBAAoB,QAAQ;AAC9C,UAAM,SAAS,KAAK,qBAAqB,IAAI,IAAI;AACjD,QAAI,WAAW,OAAW,QAAO;AAEjC,UAAM,MAAM,gBAAgB,EAAE,IAAI;AAClC,QAAI,MAAM,OAAO,WAAW,KAAK,YAAY,OAAO;AAClD,WAAK,qBAAqB,OAAO,IAAI;AACrC,WAAK,OAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC;AACjD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,UAAoB,YAAwB,QAA+B;AAC5F,UAAM,OAAO,KAAK,oBAAoB,QAAQ;AAG9C,WAAO,KAAK,qBAAqB,QAAQ,KAAK,YAAY,YAAY;AACpE,YAAM,WAAW,KAAK,qBAAqB,KAAK,EAAE,KAAK;AACvD,UAAI,SAAS,SAAS,KAAM;AAC5B,YAAM,YAAY,SAAS;AAC3B,WAAK,qBAAqB,OAAO,SAAS;AAC1C,WAAK,OAAO,MAAM,8BAA8B,EAAE,MAAM,UAAU,CAAC;AAAA,IACrE;AAEA,SAAK,qBAAqB,IAAI,MAAM;AAAA,MAClC;AAAA,MACA;AAAA,MACA,UAAU,gBAAgB,EAAE,IAAI;AAAA,IAClC,CAAC;AACD,SAAK,OAAO,MAAM,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,eAAuB;AACrB,WAAO,KAAK,qBAAqB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAmB;AACjB,SAAK,qBAAqB,MAAM;AAChC,SAAK,OAAO,MAAM,wBAAwB;AAAA,EAC5C;AACF;AAaO,SAAS,sBACd,QACAD,SACiB;AACjB,SAAO,IAAI,gBAAgB,QAAQA,OAAM;AAC3C;;;AC/iBA,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAKpB,IAAM,kBAAN,MAAkD;AAAA,EACtC;AAAA,EAEjB,YAAYE,SAAkB;AAC5B,SAAK,SAASA,WAAU,aAAa,EAAE,WAAW,kBAAkB,CAAC;AAAA,EACvE;AAAA,EAEA,eAAe,OAAsD;AACnE,UAAM,EAAE,OAAO,OAAO,IAAI;AAG1B,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,EAAE,QAAQ,WAAW,OAAO,oBAAoB;AAAA,IACzD;AAGA,UAAM,YAAY,KAAK,mBAAmB,KAAK;AAG/C,QAAI,CAAC,UAAU,eAAe;AAC5B,aAAO,KAAK,sBAAsB,WAAW,MAAM;AAAA,IACrD;AAGA,WAAO,KAAK,mBAAmB,SAAS;AAAA,EAC1C;AAAA,EAEA,mBAAmB,OAA+C;AAChE,UAAM,EAAE,OAAO,cAAc,QAAQ,cAAc,qBAAqB,IAAI;AAG5E,UAAM,aAAa,KAAK,WAAW,KAAK;AACxC,UAAM,iBAAiB,KAAK,kBAAkB,OAAO,cAAc,MAAM;AAGzE,UAAM,EAAE,aAAa,eAAe,IAAI,KAAK;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,EAAE,WAAW,cAAc,eAAe,UAAU,IAAI,KAAK;AAAA,MACjE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,wBAAwB,MAAM;AAAA,IAChC;AAEA,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBACE,SACA,QACA,QACmB;AACnB,QAAI,WAAW,QAAW;AACxB,aAAO,EAAE,UAAU,MAAM,QAAQ,EAAI;AAAA,IACvC;AAGA,QAAI,OAAO,6BAA6B,SAAS,OAAO,kBAAkB,KAAK,GAAG;AAChF,WAAK,OAAO,MAAM,8BAA8B,EAAE,SAAS,OAAO,OAAO,eAAe,CAAC;AACzF,aAAO,EAAE,UAAU,OAAO,QAAQ,qBAAqB,QAAQ,OAAO,OAAO;AAAA,IAC/E;AAGA,QAAI,OAAO,aAAa,mBAAmB;AACzC,WAAK,OAAO,MAAM,qCAAqC;AAAA,QACrD;AAAA,QACA,YAAY,OAAO;AAAA,MACrB,CAAC;AACD,aAAO,EAAE,UAAU,OAAO,QAAQ,aAAa,QAAQ,OAAO,OAAO;AAAA,IACvE;AAGA,QAAI,OAAO,SAAS,oBAAoB;AACtC,WAAK,OAAO,MAAM,gCAAgC,EAAE,SAAS,QAAQ,OAAO,OAAO,CAAC;AACpF,aAAO,EAAE,UAAU,OAAO,QAAQ,uBAAuB,QAAQ,OAAO,OAAO;AAAA,IACjF;AAEA,WAAO,EAAE,UAAU,MAAM,QAAQ,OAAO,OAAO;AAAA,EACjD;AAAA,EAEQ,WAAW,OAA8C;AAC/D,QAAI,UAAU;AACd,QAAI,SAAS;AACb,QAAI,UAAU;AAEd,eAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,cAAQ,KAAK,UAAU;AAAA,QACrB,KAAK;AACH;AACA;AAAA,QACF,KAAK;AACH;AACA;AAAA,QACF,KAAK;AACH;AACA;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,QAAQ,SAAS,OAAO,MAAM,KAAK;AAAA,EACvD;AAAA,EAEQ,kBACN,OACA,cACA,QACmB;AACnB,UAAM,WAAqB,CAAC;AAE5B,eAAW,WAAW,MAAM,KAAK,GAAG;AAClC,YAAM,SAAS,cAAc,IAAI,OAAO;AACxC,YAAM,SAAS,KAAK,gBAAgB,SAAS,QAAQ,MAAM;AAC3D,UAAI,OAAO,UAAU;AACnB,iBAAS,KAAK,OAAO;AAAA,MACvB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,iBACN,OACA,cACA,cACA,QACqF;AAErF,QAAI,OAAO,cAAc,qBAAqB,OAAO,cAAc,aAAa;AAC9E,aAAO,EAAE,aAAa,QAAW,gBAAgB,OAAU;AAAA,IAC7D;AAEA,UAAM,SAAS,EAAE,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,EAAE;AAEnE,eAAW,CAAC,SAAS,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC7C,YAAM,SAAS,KAAK,cAAc,SAAS,MAAM,cAAc,cAAc,MAAM;AACnF,aAAO,eAAe;AACtB,WAAK,oBAAoB,QAAQ,KAAK,UAAU,MAAM;AAAA,IACxD;AAEA,WAAO;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,gBAAgB;AAAA,QACd,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO;AAAA,QAChB,aAAa,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,cACN,SACA,MACA,cACA,cACA,QACQ;AACR,QAAI,SAAS,cAAc,IAAI,OAAO,KAAK,cAAc,IAAI,OAAO,GAAG,UAAU;AACjF,QAAI,OAAO,yBAAyB,MAAM;AACxC,gBAAU,KAAK;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,oBACN,QACA,UACA,QACM;AACN,WAAO,QAAQ,KAAK;AAAA,EACtB;AAAA,EAEQ,sBACN,YACA,gBACA,aACA,QACA,sBACwF;AACxF,UAAM,YAAY,OAAO;AAGzB,QAAI,mBAAmB,UAAa,gBAAgB,UAAa,cAAc,GAAG;AAChF,aAAO,KAAK,wBAAwB,gBAAgB,aAAa,SAAS;AAAA,IAC5E;AAGA,WAAO,KAAK,sBAAsB,YAAY,sBAAsB,WAAW,MAAM;AAAA,EACvF;AAAA,EAEQ,wBACN,gBACA,aACA,WACwF;AACxF,UAAM,gBAAgB,eAAe;AACrC,UAAM,eAAe,eAAe,UAAU;AAC9C,UAAM,cAAc,eAAe,SAAS;AAE5C,UAAM,YAAY,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO,EAAE,WAAW,cAAc,aAAa,eAAe,UAAU;AAAA,EAC1E;AAAA,EAEQ,uBACN,eACA,aACA,WACA,cACA,aACQ;AACR,QAAI,CAAC,eAAe;AAClB,aAAO,gCAAgC,YAAY,QAAQ,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,IACtF;AACA,QAAI,eAAe,aAAa;AAC9B,aAAO,qCAAqC,iBAAiB,cAAc,CAAC,CAAC;AAAA,IAC/E;AACA,QAAI,cAAc,cAAc;AAC9B,aAAO,sCAAsC,iBAAiB,aAAa,CAAC,CAAC;AAAA,IAC/E;AACA,WAAO,4BAA4B,iBAAiB,cAAc,CAAC,CAAC,YAAY,iBAAiB,aAAa,CAAC,CAAC;AAAA,EAClH;AAAA,EAEQ,sBACN,YACA,sBACA,WACA,QACwF;AACxF,UAAM,cACJ,OAAO,uBAAuB,OAC1B,WAAW,QACX,WAAW,UAAU,WAAW;AAEtC,UAAM,QAAQ,uBAAuB,IAAI,uBAAuB;AAChE,UAAM,eAAe,QAAQ,IAAI,WAAW,UAAU,QAAQ;AAC9D,UAAM,cAAc,QAAQ,IAAI,WAAW,SAAS,QAAQ;AAE5D,UAAM,eAAe,eAAe,OAAO;AAC3C,UAAM,gBAAgB,iBAAiB,gBAAgB,aAAa,eAAe;AAEnF,UAAM,YAAY,KAAK,qBAAqB;AAAA,MAC1C;AAAA,MACA;AAAA,MACA,WAAW,OAAO;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,cAAc,KAAK,IAAI,cAAc,WAAW;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAAqB,QAOlB;AACT,UAAM,EAAE,cAAc,aAAa,WAAW,cAAc,aAAa,UAAU,IAAI;AACvF,QAAI,CAAC,cAAc;AACjB,aAAO,wBAAwB,OAAO,WAAW,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,IAC3E;AACA,QAAI,gBAAgB,WAAW;AAC7B,aAAO,+BAA+B,iBAAiB,cAAc,CAAC,CAAC,OAAO,iBAAiB,WAAW,CAAC,CAAC;AAAA,IAC9G;AACA,QAAI,eAAe,WAAW;AAC5B,aAAO,gCAAgC,iBAAiB,aAAa,CAAC,CAAC,OAAO,iBAAiB,WAAW,CAAC,CAAC;AAAA,IAC9G;AACA,WAAO,0CAA0C,iBAAiB,cAAc,CAAC,CAAC,YAAY,iBAAiB,aAAa,CAAC,CAAC;AAAA,EAChI;AAAA,EAEQ,sBACN,WACA,QACwB;AACxB,UAAM,EAAE,YAAY,gBAAgB,UAAU,IAAI;AAElD,QAAI,WAAW,QAAQ,OAAO,WAAW;AACvC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,QAAQ,OAAO,WAAW,KAAK,CAAC,gBAAgB,OAAO,OAAO,SAAS,CAAC;AAAA,MACnF;AAAA,IACF;AAEA,QAAI,mBAAmB,UAAa,eAAe,cAAc,WAAW;AAC1E,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,UAAU,eAAe,YAAY,QAAQ,CAAC,CAAC,gBAAgB,OAAO,SAAS,CAAC;AAAA,MAC3F;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS,UAAU;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,mBAAmB,WAAoD;AAC7E,UAAM,EAAE,YAAY,eAAe,IAAI;AAGvC,UAAM,WAAW,gBAAgB,WAAW,WAAW;AACvD,UAAM,UAAU,gBAAgB,UAAU,WAAW;AACrD,UAAM,QAAQ,gBAAgB,eAAe,WAAW;AAExD,UAAM,WAAiC,YAAY,UAAU,YAAY;AACzE,UAAM,aAAa,QAAQ,IAAI,KAAK,IAAI,WAAW,OAAO,IAAI,QAAQ;AAEtE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,WAAW,UAAU;AAAA,IACvB;AAAA,EACF;AACF;AAKO,SAAS,sBAAsBA,SAAoC;AACxE,SAAO,IAAI,gBAAgBA,OAAM;AACnC;;;AC5dO,SAAS,oBAA4B;AAC1C,QAAM,OAAO,gBAAgB;AAC7B,QAAM,SAAS,kBAAkB;AACjC,SAAO,WAAW,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,OAAO,aAAa,CAAC,CAAC;AAChE;AAKO,SAAS,oBAA4B;AAC1C,QAAM,OAAO,gBAAgB;AAC7B,QAAM,SAAS,kBAAkB;AACjC,SAAO,WAAW,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,OAAO,aAAa,CAAC,CAAC;AAChE;AAKO,SAAS,kBAA0B;AACxC,QAAM,OAAO,gBAAgB;AAC7B,QAAM,SAAS,kBAAkB;AACjC,SAAO,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,OAAO,aAAa,CAAC,CAAC;AAC9D;AAKO,SAAS,YAAY,OAAyB,aAAkC;AACrF,QAAM,OAAO,gBAAgB;AAC7B,SAAO;AAAA,IACL,IAAI,gBAAgB;AAAA,IACpB;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,oBAAI,IAAI;AAAA,IAClB,cAAc,oBAAI,IAAI;AAAA,IACtB,YAAY,oBAAI,IAAI;AAAA,IACpB,WAAW,KAAK,OAAO;AAAA,IACvB;AAAA,EACF;AACF;AAKO,SAAS,WAAc,OAA2B;AACvD,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,SAAS,oBAAI,IAAe;AAClC,QAAM,QAAQ,CAAC,SAAS;AACtB,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C,CAAC;AAED,MAAI,WAAW;AACf,MAAI;AACJ,SAAO,QAAQ,CAAC,OAAO,SAAS;AAC9B,QAAI,QAAQ,UAAU;AACpB,iBAAW;AACX,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKO,SAAS,wBAAwB,OAAuB;AAC7D,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,QAAM,YAAY,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ;AAC7C,QAAM,qBAAqB,WAAW,SAAS;AAC/C,QAAM,iBAAiB,UAAU,OAAO,CAAC,MAAM,MAAM,kBAAkB,EAAE;AAEzE,SAAO,iBAAiB,MAAM;AAChC;AAMO,SAAS,iBACd,OACA,QACiC;AACjC,MAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,QAAM,UAAU,oBAAI,IAAkB;AACtC,QAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,YAAQ,IAAI,SAAS,OAAO,KAAK,CAAC,IAAI,IAAI;AAAA,EAC5C,CAAC;AAGD,QAAM,eAAuC;AAAA,IAC3C,WAAW;AAAA,IACX,WAAW,OAAO;AAAA,IAClB,WAAW;AAAA;AAAA,EACb;AAGA,QAAM,YAAY,sBAAsB;AACxC,QAAM,SAAS,UAAU,eAAe;AAAA,IACtC,OAAO;AAAA,IACP,QAAQ;AAAA,EACV,CAAC;AAGD,MAAI,OAAO,WAAW,WAAW;AAC/B,WAAO,OAAO,aAAa,YAAY,aAAa;AAAA,EACtD;AAGA,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS,EAAE;AAChE,QAAM,aAAa,MAAM,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ,EAAE;AAChE,MAAI,YAAY,KAAK,aAAa,EAAG,QAAO;AAE5C,SAAO;AACT;AAKO,SAAS,oBAAoB,SAA+C;AACjF,QAAM,oBAAoB,QAAQ,OAAO,CAAC;AAC1C,MAAI,CAAC,kBAAmB,QAAO,CAAC;AAEhC,QAAM,eAAsC,CAAC;AAE7C,oBAAkB,SAAS,QAAQ,CAAC,SAAS,cAAc;AACzD,UAAM,QAAQ,kBAAkB,aAAa,IAAI,SAAS,KAAK,CAAC;AAChE,UAAM,aAAa,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK;AAC9C,UAAM,iBAAiB,MAAM,SAAS,IAAI,WAAW,SAAS,MAAM,SAAS;AAG7E,QAAI,kBAAkB,KAAK;AAEzB,YAAM,gBAAgB,WACnB,OAAO,CAAC,MAAM,EAAE,eAAe,EAC/B,IAAI,CAAC,MAAM,EAAE,eAAe;AAC/B,YAAM,gBACJ,cAAc,SAAS,IAClB,WAAW,aAAa,KAAK,QAAQ,WACtC,QAAQ;AAEd,YAAM,sBAA2C;AAAA,QAC/C,IAAI;AAAA,QACJ,UAAU,QAAQ;AAAA,QAClB,UAAU;AAAA,QACV,aAAa,QAAQ;AAAA,QACrB,kBAAkB,WAAW,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,QACjD;AAAA,QACA,kBAAkB,CAAC,OAAO;AAAA,MAC5B;AACA,UAAI,QAAQ,aAAa,QAAW;AAClC,4BAAoB,WAAW,QAAQ;AAAA,MACzC;AACA,UAAI,QAAQ,eAAe,QAAW;AACpC,4BAAoB,aAAa,QAAQ;AAAA,MAC3C;AACA,mBAAa,KAAK,mBAAmB;AAAA,IACvC;AAAA,EACF,CAAC;AAGD,SAAO,aAAa,KAAK,CAAC,GAAG,MAAM;AACjC,UAAM,gBAAgB,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,EAAE;AACvE,UAAM,UAAU,cAAc,EAAE,QAAQ,IAAI,cAAc,EAAE,QAAQ;AACpE,QAAI,YAAY,EAAG,QAAO;AAC1B,WAAO,EAAE,iBAAiB,EAAE;AAAA,EAC9B,CAAC;AACH;AAKO,SAAS,oBAAoB,SAAwC;AAC1E,QAAM,OAAO,gBAAgB;AAC7B,SAAO,QAAQ,OAAO,IAAI,CAAC,OAAO,UAAU;AAC1C,UAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ;AACpD,UAAM,UACJ,MAAM,gBAAgB,SAAY,IAAI,KAAK,MAAM,WAAW,EAAE,QAAQ,IAAI,KAAK,IAAI;AAErF,QAAI,aAAa;AACjB,QAAI,iBAAiB;AAErB,QAAI,MAAM,UAAU,gBAAgB;AAElC,YAAM,aAAa,QAAQ,CAAC,UAAU;AACpC,sBAAc,MAAM;AACpB,cAAM,aAAa,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AAChD,0BAAkB,MAAM,SAAS,IAAI,aAAa,MAAM,SAAS;AAAA,MACnE,CAAC;AACD,YAAM,gBAAgB,MAAM,aAAa;AACzC,UAAI,gBAAgB,GAAG;AACrB,0BAAkB;AAAA,MACpB;AAAA,IACF,WAAW,MAAM,UAAU,aAAa;AAEtC,mBAAa,MAAM,WAAW;AAC9B,YAAM,QAAQ,MAAM,KAAK,MAAM,WAAW,OAAO,CAAC;AAClD,uBAAiB,wBAAwB,KAAK;AAAA,IAChD;AAEA,WAAO;AAAA,MACL,aAAa,QAAQ;AAAA,MACrB,OAAO,MAAM;AAAA,MACb,eAAe,MAAM,SAAS;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,YAAY,UAAU;AAAA,IACxB;AAAA,EACF,CAAC;AACH;AASO,SAAS,wBAAwB,SAAoD;AAC1F,QAAM,gBAAgB,QAAQ,OAAO,CAAC;AACtC,MAAI,CAAC,cAAe,QAAO;AAE3B,QAAM,gBAAgB,oBAAI,IAA4B;AACtD,gBAAc,SAAS,QAAQ,CAAC,YAAY;AAC1C,UAAM,WAAW,cAAc,IAAI,QAAQ,OAAO,KAAK,CAAC;AACxD,aAAS,KAAK,OAAO;AACrB,kBAAc,IAAI,QAAQ,SAAS,QAAQ;AAAA,EAC7C,CAAC;AAED,QAAM,iBAA2B,CAAC;AAClC,gBAAc,SAAS,QAAQ,CAAC,YAAY;AAC1C,mBAAe,KAAK,QAAQ,UAAU;AAAA,EACxC,CAAC;AAED,QAAM,gBACJ,eAAe,SAAS,IACpB,eAAe,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,eAAe,SAC3D;AAEN,MAAI,gBAAgB,QAAQ,cAAc,QAAQ,GAAG;AACnD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,QAAQ,MAAM,KAAK,cAAc,KAAK,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,wBAAwB,SAAoD;AAC1F,QAAM,oBAAoB,QAAQ,OAAO,CAAC;AAC1C,MAAI,CAAC,kBAAmB,QAAO;AAE/B,MAAI,aAAa;AACjB,MAAI,aAAa;AAEjB,oBAAkB,aAAa,QAAQ,CAAC,UAAU;AAChD,kBAAc,MAAM;AACpB,kBAAc,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AAAA,EAC7C,CAAC;AAED,QAAM,aAAa,aAAa,IAAI,aAAa,aAAa;AAE9D,MAAI,aAAa,QAAQ,OAAO,uBAAuB,aAAa,GAAG;AACrE,UAAM,iBAA2B,CAAC;AAClC,sBAAkB,aAAa,QAAQ,CAAC,UAAU;AAChD,YAAM,QAAQ,CAAC,MAAM;AACnB,YAAI,EAAE,SAAS,CAAC,eAAe,SAAS,EAAE,OAAO,GAAG;AAClD,yBAAe,KAAK,EAAE,OAAO;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa,GAAG,OAAO,KAAK,MAAM,aAAa,GAAG,CAAC,CAAC;AAAA,MACpD,UAAU;AAAA,MACV,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,yBAAyB,SAAoD;AAC3F,QAAM,iBAAiB,QAAQ,OAAO,CAAC;AACvC,MAAI,CAAC,eAAgB,QAAO;AAE5B,QAAM,QAAQ,MAAM,KAAK,eAAe,WAAW,OAAO,CAAC;AAC3D,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,QAAM,cAAc,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU;AACjD,QAAM,gBAAgB,YAAY,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,YAAY;AAC3E,QAAM,UAAU,YAAY,MAAM,CAAC,MAAM,IAAI,GAAG;AAEhD,MAAI,WAAW,gBAAgB,MAAM;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,QAAQ,MAAM,KAAK,eAAe,WAAW,KAAK,CAAC;AAAA,IACrD;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,yBAAyB,SAA0C;AACjF,QAAM,aAAoC,CAAC;AAC3C,QAAM,iBAA2B,CAAC;AAElC,QAAM,qBAAqB,wBAAwB,OAAO;AAC1D,MAAI,oBAAoB;AACtB,eAAW,KAAK,kBAAkB;AAClC,mBAAe,KAAK,GAAG,mBAAmB,MAAM;AAAA,EAClD;AAEA,QAAM,qBAAqB,wBAAwB,OAAO;AAC1D,MAAI,oBAAoB;AACtB,eAAW,KAAK,kBAAkB;AAClC,mBAAe,KAAK,GAAG,mBAAmB,MAAM;AAAA,EAClD;AAEA,QAAM,sBAAsB,yBAAyB,OAAO;AAC5D,MAAI,qBAAqB;AACvB,eAAW,KAAK,mBAAmB;AACnC,mBAAe,KAAK,GAAG,oBAAoB,MAAM;AAAA,EACnD;AAEA,QAAM,WAAW,WAAW,SAAS;AACrC,QAAM,kBAAkB,KAAK,IAAI,GAAG,WAAW,SAAS,GAAG;AAC3D,QAAM,iBAAiB,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC;AAElD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,gBAAgB,WACZ,8EACA;AAAA,EACN;AACF;;;ACrVA,IAAMC,UAAkB,aAAa,EAAE,WAAW,kBAAkB,CAAC;AAK9D,IAAM,iBAAN,MAAgD;AAAA,EACpC,WAAuC,oBAAI,IAAI;AAAA,EAC/C;AAAA,EAEjB,YAAY,cAAwB;AAClC,SAAK,SAAS,gBAAgBA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,cACE,OACA,WACA,QACe;AACf,UAAM,gBAAgB,EAAE,GAAG,gCAAgC,GAAG,OAAO;AAErE,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,QAAI,UAAU,SAAS,cAAc,eAAe;AAClD,YAAM,IAAI,MAAM,mCAAmC,OAAO,cAAc,aAAa,CAAC,GAAG;AAAA,IAC3F;AAEA,UAAM,UAAyB;AAAA,MAC7B,IAAI,kBAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW,gBAAgB,EAAE,OAAO;AAAA,IACtC;AAEA,SAAK,SAAS,IAAI,QAAQ,IAAI,OAAO;AACrC,SAAK,OAAO,KAAK,0BAA0B;AAAA,MACzC,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA,eAAe,UAAU;AAAA,IAC3B,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,WAAyC;AAC1D,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,aAAO,QAAQ,OAAO,IAAI,MAAM,+CAA+C,CAAC;AAAA,IAClF;AAEA,UAAM,QAAQ,YAAY,YAAY,CAAC;AACvC,YAAQ,OAAO,KAAK,KAAK;AACzB,YAAQ,eAAe;AAEvB,SAAK,OAAO,KAAK,0BAA0B,EAAE,WAAW,SAAS,MAAM,GAAG,CAAC;AAC3E,WAAO,QAAQ,QAAQ,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,WAAmB,SAAiB,UAAyC;AAC1F,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,UAAM,eAAe,KAAK,gBAAgB,OAAO;AACjD,QAAI,aAAa,UAAU,YAAY;AACrC,aAAO,QAAQ,OAAO,IAAI,MAAM,sDAAsD,CAAC;AAAA,IACzF;AAEA,QAAI,CAAC,QAAQ,UAAU,SAAS,OAAO,GAAG;AACxC,aAAO,QAAQ,OAAO,IAAI,MAAM,SAAS,OAAO,4BAA4B,CAAC;AAAA,IAC/E;AAEA,eAAW,WAAW,UAAU;AAC9B,YAAM,aAAa,mBAAmB,UAAU,OAAO;AACvD,UAAI,CAAC,WAAW,SAAS;AACvB,eAAO,QAAQ,OAAO,IAAI,MAAM,oBAAoB,WAAW,MAAM,OAAO,EAAE,CAAC;AAAA,MACjF;AAEA,YAAM,YAAY,kBAAkB;AACpC,YAAM,qBAAqB;AAAA,QACzB,GAAG,WAAW;AAAA,QACd;AAAA,QACA,WAAW,gBAAgB,EAAE,OAAO;AAAA,MACtC;AACA,mBAAa,SAAS,IAAI,WAAW,kBAAkB;AAAA,IACzD;AAEA,SAAK,OAAO,MAAM,sBAAsB,EAAE,WAAW,SAAS,eAAe,SAAS,OAAO,CAAC;AAC9F,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,WAAyC;AAC9D,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,aAAO,QAAQ,OAAO,IAAI,MAAM,uDAAuD,CAAC;AAAA,IAC1F;AAEA,UAAM,gBAAgB,QAAQ,OAAO,CAAC;AACtC,QAAI,eAAe;AACjB,oBAAc,SAAS;AACvB,oBAAc,cAAc,gBAAgB,EAAE,OAAO;AAAA,IACvD;AAEA,QAAI,QAAQ,OAAO,sBAAsB;AACvC,YAAM,SAAS,KAAK,iBAAiB,SAAS;AAC9C,UAAI,OAAO,UAAU;AACnB,aAAK,OAAO,KAAK,2CAA2C;AAAA,UAC1D;AAAA,UACA,YAAY,OAAO,WAAW;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,QAAQ,YAAY,gBAAgB,CAAC;AAC3C,QAAI,eAAe;AACjB,oBAAc,SAAS,QAAQ,CAAC,SAAS,OAAO;AAC9C,cAAM,SAAS,IAAI,IAAI,OAAO;AAC9B,cAAM,aAAa,IAAI,IAAI,CAAC,CAAC;AAAA,MAC/B,CAAC;AAAA,IACH;AAEA,YAAQ,OAAO,KAAK,KAAK;AACzB,YAAQ,eAAe;AAEvB,SAAK,OAAO,KAAK,8BAA8B;AAAA,MAC7C;AAAA,MACA,SAAS,MAAM;AAAA,MACf,eAAe,MAAM,SAAS;AAAA,IAChC,CAAC;AACD,WAAO,QAAQ,QAAQ,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,WAAmB,MAAkC;AACjE,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,UAAM,eAAe,KAAK,gBAAgB,OAAO;AACjD,QAAI,aAAa,UAAU,gBAAgB;AACzC,aAAO,QAAQ,OAAO,IAAI,MAAM,yDAAyD,CAAC;AAAA,IAC5F;AAEA,UAAM,aAAa,kBAAkB,UAAU,IAAI;AACnD,QAAI,CAAC,WAAW,SAAS;AACvB,aAAO,QAAQ,OAAO,IAAI,MAAM,iBAAiB,WAAW,MAAM,OAAO,EAAE,CAAC;AAAA,IAC9E;AAEA,QAAI,CAAC,QAAQ,UAAU,SAAS,KAAK,OAAO,GAAG;AAC7C,aAAO,QAAQ,OAAO,IAAI,MAAM,SAAS,KAAK,OAAO,4BAA4B,CAAC;AAAA,IACpF;AAEA,QAAI,CAAC,aAAa,SAAS,IAAI,KAAK,SAAS,GAAG;AAC9C,aAAO,QAAQ,OAAO,IAAI,MAAM,WAAW,KAAK,SAAS,YAAY,CAAC;AAAA,IACxE;AAEA,UAAM,gBAAgB,aAAa,aAAa,IAAI,KAAK,SAAS,KAAK,CAAC;AACxE,UAAM,WAAW,cAAc,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO;AACvE,aAAS,KAAK,WAAW,IAAI;AAC7B,iBAAa,aAAa,IAAI,KAAK,WAAW,QAAQ;AAEtD,SAAK,OAAO,MAAM,yBAAyB;AAAA,MACzC;AAAA,MACA,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,IACd,CAAC;AACD,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,WAAyC;AAC3D,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,aAAO,QAAQ,OAAO,IAAI,MAAM,wDAAwD,CAAC;AAAA,IAC3F;AAEA,UAAM,oBAAoB,QAAQ,OAAO,CAAC;AAC1C,QAAI,mBAAmB;AACrB,wBAAkB,SAAS;AAC3B,wBAAkB,cAAc,gBAAgB,EAAE,OAAO;AAAA,IAC3D;AAEA,UAAM,QAAQ,YAAY,aAAa,CAAC;AACxC,YAAQ,OAAO,KAAK,KAAK;AACzB,YAAQ,eAAe;AAEvB,SAAK,OAAO,KAAK,2BAA2B,EAAE,WAAW,SAAS,MAAM,GAAG,CAAC;AAC5E,WAAO,QAAQ,QAAQ,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,WAAmB,SAAiB,MAA2B;AAC7E,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,SAAK,sBAAsB,OAAO;AAElC,UAAM,eAAe,KAAK,gBAAgB,OAAO;AACjD,QAAI,aAAa,UAAU,aAAa;AACtC,aAAO,QAAQ,OAAO,IAAI,MAAM,oDAAoD,CAAC;AAAA,IACvF;AAEA,UAAM,aAAa,WAAW,UAAU,IAAI;AAC5C,QAAI,CAAC,WAAW,SAAS;AACvB,aAAO,QAAQ,OAAO,IAAI,MAAM,iBAAiB,WAAW,MAAM,OAAO,EAAE,CAAC;AAAA,IAC9E;AAEA,QAAI,CAAC,QAAQ,UAAU,SAAS,OAAO,GAAG;AACxC,aAAO,QAAQ,OAAO,IAAI,MAAM,SAAS,OAAO,4BAA4B,CAAC;AAAA,IAC/E;AAEA,iBAAa,WAAW,IAAI,SAAS;AAAA,MACnC,GAAG,WAAW;AAAA,MACd,WAAW,gBAAgB,EAAE,OAAO;AAAA,IACtC,CAAC;AAED,SAAK,OAAO,MAAM,uBAAuB;AAAA,MACvC;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,IACnB,CAAC;AACD,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,WAAyD;AACjE,UAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,QAAI,CAAC,QAAS,QAAO,QAAQ,QAAQ,IAAI;AAEzC,QAAI,QAAQ,WAAW,eAAe,QAAQ,aAAa;AACzD,aAAO,QAAQ,QAAQ,QAAQ,WAAW;AAAA,IAC5C;AAEA,QAAI,QAAQ,eAAe,EAAG,QAAO,QAAQ,QAAQ,IAAI;AAEzD,UAAM,iBAAiB,QAAQ,OAAO,CAAC;AACvC,QAAI,CAAC,eAAgB,QAAO,QAAQ,QAAQ,IAAI;AAEhD,UAAM,WAAW,QAAQ,UAAU,MAAM,CAAC,YAAY,eAAe,WAAW,IAAI,OAAO,CAAC;AAC5F,QAAI,CAAC,SAAU,QAAO,QAAQ,QAAQ,IAAI;AAE1C,UAAM,SAAS,KAAK,iBAAiB,OAAO;AAC5C,YAAQ,cAAc;AACtB,YAAQ,SAAS;AACjB,YAAQ,cAAc,gBAAgB,EAAE,OAAO;AAE/C,mBAAe,SAAS;AACxB,mBAAe,cAAc,gBAAgB,EAAE,OAAO;AAEtD,SAAK,OAAO,KAAK,4BAA4B;AAAA,MAC3C;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,gBAAgB,OAAO;AAAA,MACvB,sBAAsB,OAAO,qBAAqB;AAAA,IACpD,CAAC;AAED,WAAO,QAAQ,QAAQ,MAAM;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,WAAqC;AACpD,UAAM,UAAU,KAAK,kBAAkB,SAAS;AAChD,WAAO,yBAAyB,OAAO;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,WAA8C;AACvD,WAAO,KAAK,SAAS,IAAI,SAAS;AAAA,EACpC;AAAA,EAEQ,kBAAkB,WAAkC;AAC1D,UAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,WAAW,SAAS,YAAY;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,SAA8B;AAC1D,QAAI,QAAQ,WAAW,UAAU;AAC/B,YAAM,IAAI,MAAM,WAAW,QAAQ,EAAE,OAAO,QAAQ,MAAM,EAAE;AAAA,IAC9D;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAqC;AAC3D,UAAM,QAAQ,QAAQ,OAAO,QAAQ,eAAe,CAAC;AACrD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,YAAY,OAAO,QAAQ,YAAY,CAAC,QAAQ;AAAA,IAClE;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,SAA8C;AACrE,UAAM,YAAY,IAAI,KAAK,QAAQ,SAAS,EAAE,QAAQ;AACtD,UAAM,UAAU,gBAAgB,EAAE,IAAI;AAEtC,UAAM,2BAA2B,oBAAoB,OAAO;AAC5D,UAAM,iBAAiB,oBAAoB,OAAO;AAElD,UAAM,iBAAiB,QAAQ,OAAO,CAAC;AACvC,UAAM,aAAa,iBAAiB,MAAM,KAAK,eAAe,WAAW,OAAO,CAAC,IAAI,CAAC;AACtF,UAAM,UAAU,iBAAiB,YAAY,QAAQ,MAAM;AAC3D,UAAM,iBAAiB,wBAAwB,UAAU;AACzD,UAAM,mBAAmB,yBAAyB,OAAO;AAEzD,WAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MACnB,OAAO,QAAQ;AAAA,MACf;AAAA,MACA,sBAAsB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,oBAAoB,iBAAiB;AAAA,MACrC,iBAAiB,UAAU;AAAA,MAC3B,qBAAqB,QAAQ;AAAA,IAC/B;AAAA,EACF;AACF;AAKO,SAAS,qBAAqB,cAAwC;AAC3E,SAAO,IAAI,eAAe,YAAY;AACxC;;;AC7WO,SAAS,kBAAkB,UAAqB,QAAmC;AACxF,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,MACE,SAAS,OAAO;AAAA,MAChB,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO;AAAA,MAClB,QAAQ,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,MACE,GAAI,OAAO,cAAc,UAAa,EAAE,WAAW,OAAO,UAAU;AAAA,MACpE,GAAI,OAAO,kBAAkB,UAAa,EAAE,eAAe,OAAO,cAAc;AAAA,IAClF;AAAA,EACF;AACA,WAAS,KAAK,KAAK;AACrB;AAiBO,SAAS,oBAAoB,UAAqB,QAAqC;AAC5F,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,MACE,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB,SAAS,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,MACE,GAAI,OAAO,cAAc,UAAa,EAAE,WAAW,OAAO,UAAU;AAAA,MACpE,GAAI,OAAO,kBAAkB,UAAa,EAAE,eAAe,OAAO,cAAc;AAAA,IAClF;AAAA,EACF;AACA,WAAS,KAAK,KAAK;AACrB;AAiBO,SAAS,iBAAiB,UAAqB,QAAkC;AACtF,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,MACE,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,gBAAgB,OAAO;AAAA,MACvB,SAAS,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,MACE,GAAI,OAAO,cAAc,UAAa,EAAE,WAAW,OAAO,UAAU;AAAA,MACpE,GAAI,OAAO,kBAAkB,UAAa,EAAE,eAAe,OAAO,cAAc;AAAA,IAClF;AAAA,EACF;AACA,WAAS,KAAK,KAAK;AACrB;AAiBO,SAAS,uBACd,UACA,QACM;AACN,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,MACE,eAAe,OAAO;AAAA,MACtB,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,MACpB,WAAW,OAAO;AAAA,IACpB;AAAA,IACA;AAAA,MACE,GAAI,OAAO,cAAc,UAAa,EAAE,WAAW,OAAO,UAAU;AAAA,MACpE,GAAI,OAAO,kBAAkB,UAAa,EAAE,eAAe,OAAO,cAAc;AAAA,IAClF;AAAA,EACF;AACA,WAAS,KAAK,KAAK;AACrB;;;ACpGO,SAAS,0BAA0B,MAAY,iBAAmC;AACvF,QAAM,eAAe,kBAAkB,KAAK,aAAa,WAAW,KAAK,aAAa;AACtF,SAAO,gBAAgB,KAAK,aAAa;AAC3C;AAMO,SAAS,yBACd,WACA,SACS;AACT,MAAI,eAAe;AACnB,MAAI,cAAc;AAClB,aAAW,CAAC,SAAS,IAAI,KAAK,WAAW;AACvC,UAAM,IAAI,QAAQ,IAAI,OAAO,KAAK;AAClC,QAAI,KAAK,aAAa,UAAW,iBAAgB;AACjD,QAAI,KAAK,aAAa,SAAU,gBAAe;AAAA,EACjD;AACA,SAAO,eAAe;AACxB;AAKO,SAAS,kBACd,UACA,WACA,OACA,eACA,iBACqC;AACrC,MAAI,CAAC,iBAAiB,UAAU,EAAG,QAAO;AAC1C,QAAM,gBAAgB,WAAW;AACjC,QAAM,iBAAiB,YAAY;AACnC,MAAI,gBAAgB,kBAAkB,iBAAiB,gBAAiB,QAAO;AAC/E,MAAI,iBAAiB,iBAAiB,kBAAkB,gBAAiB,QAAO;AAChF,SAAO;AACT;AAKO,SAAS,qBAAqB,QAAkC;AAErE,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,kBAAkB,OAAO,kBAAkB,OAAO,eAAe;AACvE,WAAO,cAAc,kBAAkB,OAAO;AAAA,EAChD;AAGA,QAAM,mBAAmB,KAAK,IAAI,KAAK,OAAO,cAAc;AAC5D,SAAO,aAAa,KAAK,IAAI,GAAG,OAAO,SAAS,gBAAgB;AAClE;AAKO,SAAS,kBAAkB,QAAiD;AACjF,SAAO;AAAA,IACL,SAAS,OAAO;AAAA,IAChB,YAAY,OAAO;AAAA,IACnB,iBAAiB,OAAO;AAAA,IACxB,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO;AAAA,IACrB,aAAa,OAAO;AAAA,IACpB,QAAQ,OAAO;AAAA,IACf,YAAY,OAAO;AAAA,IACnB,gBAAgB,OAAO;AAAA,IACvB,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,EACpB;AACF;AAMO,SAAS,oBAAoB,MAAoB;AACtD,SAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,WAAW,QAAQ,CAAC,CAAC;AACvD;AAKO,SAAS,sBACd,WACuB;AACvB,QAAM,aAAa,oBAAI,IAAsB;AAC7C,aAAW,CAAC,SAAS,IAAI,KAAK,WAAW;AACvC,UAAM,MAAM,oBAAoB,IAAI;AACpC,UAAM,SAAS,WAAW,IAAI,GAAG,KAAK,CAAC;AACvC,WAAO,KAAK,OAAO;AACnB,eAAW,IAAI,KAAK,MAAM;AAAA,EAC5B;AACA,SAAO;AACT;AAKO,SAAS,kBAAkB,SAAiB,eAA2C;AAC5F,QAAM,MAAM,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAC5C,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,kBAAkB,CAAC;AAAA,IACnB,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AACF;AAKO,SAAS,mBAAmB,SAGjC;AACA,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,aAAW,UAAU,SAAS;AAC5B,oBAAgB,OAAO;AACvB,kBAAc,OAAO;AAAA,EACvB;AAEA,QAAM,oBAAoB,aAAa,IAAI,eAAe,aAAa;AACvE,SAAO,EAAE,mBAAmB,WAAW;AACzC;AAKO,SAAS,0BACd,QACA,mBACA,eACQ;AACR,QAAM,sBAAsB,OAAO,cAAc,KAAK,IAAI,MAAM,iBAAiB;AACjF,QAAM,mBAAmB,QAAQ,gBAAgB,mBAAmB;AAEpE,UAAQ,OAAO,SAAS,oBAAoB;AAC9C;AAKO,SAAS,mBACd,eACA,SACA,aACA,gBACQ;AACR,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,KAAK,IAAI,GAAG,gBAAgB,cAAc;AAAA,IACnD,KAAK;AACH,aAAO,KAAK,IAAI,GAAG,gBAAgB,WAAW;AAAA,IAChD,KAAK;AACH,aAAO,KAAK,IAAI,GAAG,kBAAkB,cAAc,KAAK,EAAE;AAAA,IAC5D,KAAK;AACH,aAAO;AAAA,EACX;AACF;;;AC/KA,IAAMC,UAAS,aAAa,EAAE,WAAW,kBAAkB,CAAC;AAMrD,IAAM,iBAAN,MAAgD;AAAA,EACpC,UAA2C,oBAAI,IAAI;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,SAAS,EAAE,GAAG,gCAAgC,GAAG,QAAQ,OAAO;AACrE,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,aAAa,QAAQ,cAAc,QAAQ,aAAa;AAC7D,IAAAA,QAAO,KAAK,8BAA8B;AAAA,MACxC,QAAQ,KAAK;AAAA,MACb,eAAe,KAAK;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,SAAyB;AACvC,UAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,kBAAkB,SAAiB,SAA4B;AAC7D,QAAI,SAAS,KAAK,QAAQ,IAAI,OAAO;AACrC,QAAI,WAAW,QAAW;AACxB,WAAK,cAAc,OAAO;AAC1B,eAAS,KAAK,QAAQ,IAAI,OAAO;AACjC,UAAI,WAAW,OAAW;AAAA,IAC5B;AAEA,UAAM,iBAAiB,OAAO;AAC9B,WAAO,cAAc;AACrB,WAAO,aAAa,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAGpD,QAAI,YAAY,UAAW,QAAO,mBAAmB;AAAA,aAC5C,YAAY,UAAW,QAAO,eAAe;AAAA,aAC7C,YAAY,UAAW,QAAO,gBAAgB;AAGvD,WAAO,SAAS;AAAA,MACd,OAAO;AAAA,MACP;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO;AAAA,IACd;AACA,yBAAqB,MAAM;AAC3B,SAAK,iBAAiB,SAAS,gBAAgB,OAAO,QAAQ,oBAAoB;AAElF,IAAAA,QAAO,MAAM,uBAAuB;AAAA,MAClC;AAAA,MACA;AAAA,MACA,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,OAA2D;AAC3E,UAAM,EAAE,UAAU,WAAW,OAAO,QAAQ,UAAU,IAAI,KAAK,WAAW,KAAK;AAC/E,UAAM,oBAAoB,KAAK,wBAAwB,OAAO,SAAS;AACvE,UAAM,gBAAgB,SAAS,KAAK,OAAO;AAC3C,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,OAAO;AAAA,IACd;AAEA,UAAM,SAAkC;AAAA,MACtC;AAAA,MACA,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,IACnB;AAEA,SAAK,mBAAmB,MAAM;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,SAAuB;AACnC,QAAI,KAAK,QAAQ,IAAI,OAAO,GAAG;AAC7B,MAAAA,QAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC;AACpD;AAAA,IACF;AACA,UAAM,SAAS,kBAAkB,SAAS,KAAK,OAAO,aAAa;AACnE,SAAK,QAAQ,IAAI,SAAS,MAAM;AAChC,IAAAA,QAAO,KAAK,oBAAoB,EAAE,SAAS,eAAe,KAAK,OAAO,cAAc,CAAC;AAAA,EACvF;AAAA,EAEA,eAAe,SAAkD;AAC/D,UAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,kBAAkB,MAAM;AAAA,EACjC;AAAA,EAEA,cAAc,SAAiB,QAAsB;AACnD,UAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,QAAI,WAAW,QAAW;AACxB,MAAAA,QAAO,KAAK,kCAAkC,EAAE,QAAQ,CAAC;AACzD;AAAA,IACF;AAEA,UAAM,iBAAiB,OAAO;AAC9B,WAAO,kBAAkB;AACzB,WAAO,iBAAiB,KAAK,MAAM;AACnC,WAAO,SAAS,KAAK,IAAI,GAAG,OAAO,SAAS,GAAG;AAC/C,yBAAqB,MAAM;AAE3B,UAAM,eAAe,KAAK,QAAQ,OAAO;AACzC,SAAK,sBAAsB,SAAS,QAAQ,gBAAgB,YAAY;AACxE,SAAK,iBAAiB,SAAS,gBAAgB,OAAO,QAAQ,cAAc;AAE5E,IAAAA,QAAO,KAAK,wCAAwC;AAAA,MAClD;AAAA,MACA;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,WAAW,OAAO;AAAA,IACpB,CAAC;AAED,QAAI,OAAO,kBAAkB,KAAK,OAAO,wBAAwB;AAC/D,WAAK,aAAa,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,gBAAgD;AAC9C,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC;AAAA,EAC1E;AAAA,EAEA,QAAQ,SAA0B;AAChC,UAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,OAAO,UAAU,KAAK,OAAO,aAAa,OAAO,cAAc,KAAK,OAAO;AAAA,EACpF;AAAA,EAEA,qBAA2B;AACzB,UAAM,EAAE,mBAAmB,WAAW,IAAI,mBAAmB,KAAK,QAAQ,OAAO,CAAC;AAClF,QAAI,eAAe,EAAG;AAEtB,eAAW,UAAU,KAAK,QAAQ,OAAO,GAAG;AAC1C,UAAI,OAAO,aAAa,EAAG;AAC3B,YAAM,iBAAiB,OAAO;AAC9B,aAAO,SAAS;AAAA,QACd;AAAA,QACA;AAAA,QACA,KAAK,OAAO;AAAA,MACd;AACA,2BAAqB,MAAM;AAC3B,WAAK,iBAAiB,OAAO,SAAS,gBAAgB,OAAO,QAAQ,eAAe;AAAA,IACtF;AAEA,IAAAA,QAAO,KAAK,wBAAwB;AAAA,MAClC,YAAY,KAAK,QAAQ;AAAA,MACzB,mBAAmB,kBAAkB,QAAQ,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,WAAW,OAMjB;AACA,QAAI,WAAW;AACf,QAAI,YAAY;AAChB,QAAI,QAAQ;AACZ,UAAM,SAAmB,CAAC;AAC1B,UAAM,YAAY,oBAAI,IAAoB;AAE1C,eAAW,CAAC,SAAS,IAAI,KAAK,OAAO;AACnC,UAAI,CAAC,KAAK,QAAQ,OAAO,GAAG;AAC1B,QAAAA,QAAO,KAAK,qBAAqB,EAAE,SAAS,QAAQ,+BAA+B,CAAC;AACpF;AAAA,MACF;AACA,YAAM,SAAS,KAAK,gBAAgB,OAAO;AAC3C,gBAAU,IAAI,SAAS,MAAM;AAC7B,aAAO,KAAK,OAAO;AACnB,eAAS;AACT,YAAM,kBAAkB,SAAS,KAAK;AACtC,UAAI,KAAK,aAAa,UAAW,aAAY;AAAA,eACpC,KAAK,aAAa,SAAU,cAAa;AAAA,IACpD;AACA,WAAO,EAAE,UAAU,WAAW,OAAO,QAAQ,UAAU;AAAA,EACzD;AAAA,EAEQ,mBAAmB,QAAuC;AAChE,IAAAA,QAAO,KAAK,iCAAiC;AAAA,MAC3C,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO,iBAAiB,QAAQ,CAAC;AAAA,MAC3C,WAAW,OAAO,kBAAkB,QAAQ,CAAC;AAAA,MAC7C,aAAa,OAAO,YAAY,QAAQ,CAAC;AAAA,MACzC,eAAe,OAAO;AAAA,MACtB,mBAAmB,OAAO;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEQ,iBACN,SACA,MACA,MACA,QACM;AACN,QAAI,KAAK,cAAc,KAAK,aAAa,UAAa,SAAS,MAAM;AACnE,wBAAkB,KAAK,UAAU,EAAE,SAAS,gBAAgB,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA,EAEQ,sBACN,SACA,QACA,gBACA,SACM;AACN,QAAI,KAAK,cAAc,KAAK,aAAa,QAAW;AAClD,uBAAiB,KAAK,UAAU,EAAE,SAAS,QAAQ,gBAAgB,QAAQ,CAAC;AAAA,IAC9E;AAAA,EACF;AAAA,EAEQ,aAAa,QAAkC;AACrD,UAAM,eAAe,OAAO;AAC5B,WAAO,aAAa;AACpB,WAAO,SAAS;AAChB,SAAK,iBAAiB,OAAO,SAAS,cAAc,GAAG,cAAc;AACrE,IAAAA,QAAO,KAAK,wDAAwD;AAAA,MAClE,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEQ,wBACN,OACA,SACS;AACT,UAAM,YAAY,MAAM,KAAK,MAAM,QAAQ,CAAC;AAC5C,QAAI,UAAU,SAAS,EAAG,QAAO;AACjC,UAAM,kBAAkB,yBAAyB,WAAW,OAAO;AACnE,QAAI,KAAK,0BAA0B,WAAW,eAAe,EAAG,QAAO;AACvE,WAAO,KAAK,uBAAuB,SAAS;AAAA,EAC9C;AAAA,EAEQ,0BACN,WACA,iBACS;AACT,UAAM,mBAA6B,CAAC;AACpC,eAAW,CAAC,SAAS,IAAI,KAAK,WAAW;AACvC,UAAI,CAAC,0BAA0B,MAAM,eAAe,EAAG;AACvD,YAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,UAAI,WAAW,UAAa,OAAO,kBAAkB,GAAG;AACtD,yBAAiB,KAAK,OAAO;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAK,sBAAsB,gBAAgB;AAC3C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,QAAwB;AACpD,QAAI,KAAK,cAAc,KAAK,aAAa,QAAW;AAClD,0BAAoB,KAAK,UAAU;AAAA,QACjC,aAAa;AAAA,QACb,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,GAAG,OAAO,OAAO,MAAM,CAAC;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,uBAAuB,WAA2C;AACxE,UAAM,iBAAiB,sBAAsB,SAAS;AACtD,UAAM,YAAY,UAAU,SAAS;AACrC,eAAW,CAAC,WAAW,MAAM,KAAK,eAAe,QAAQ,GAAG;AAC1D,UAAI,OAAO,UAAU,KAAK,OAAO,SAAS,WAAW;AACnD,aAAK,oBAAoB,QAAQ,WAAW,UAAU,MAAM;AAC5D,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,QAAkB,WAAmB,YAA0B;AACzF,QAAI,KAAK,cAAc,KAAK,aAAa,QAAW;AAClD,0BAAoB,KAAK,UAAU;AAAA,QACjC,aAAa;AAAA,QACb,UAAU;AAAA,QACV,YAAY,KAAK,IAAI,MAAM,OAAO,SAAS,UAAU;AAAA,QACrD,SAAS,GAAG,OAAO,OAAO,MAAM,CAAC,+BAA+B,SAAS;AAAA,MAC3E,CAAC;AACD,6BAAuB,KAAK,UAAU;AAAA,QACpC,eAAe;AAAA,QACf,WAAW,OAAO;AAAA,QAClB,aAAa,OAAO,SAAS;AAAA,QAC7B,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAGO,SAAS,qBAAqB,SAAkD;AACrF,SAAO,IAAI,eAAe,OAAO;AACnC;;;ACzTO,SAAS,aAAa,MAAyB,MAAkC;AACtF,SAAO,KAAK,aAAa,aAAa,KAAK,aAAa;AAC1D;AAWO,SAAS,WAAW,MAAyB,MAAyC;AAC3F,MAAI,KAAK,aAAa,aAAa,KAAK,aAAa,WAAW;AAC9D,WAAO;AAAA,EACT;AACA,SAAO,KAAK,aAAa,KAAK;AAChC;AASO,SAAS,oBAAoB,UAAkB,SAA2C;AAC/F,MAAI,aAAa,UAAW,QAAO;AACnC,SACG,aAAa,aAAa,YAAY,cACtC,aAAa,YAAY,YAAY;AAE1C;AAeO,SAAS,8BACd,SACwB;AACxB,QAAM,IAAI,QAAQ;AAClB,MAAI,MAAM,EAAG,QAAO;AAMpB,QAAM,gBAAgB,QAAQ,aAAa;AAC3C,QAAM,mBAAmB,QAAQ,gBAAgB;AAEjD,SAAO,gBAAgB;AACzB;AAeO,SAAS,wBACd,OACA,QACA,mBACA,uBACS;AACT,aAAW,UAAU,QAAQ;AAC3B,UAAM,UAAU,mBAAmB,OAAO,MAAM;AAChD,UAAM,cAAc,kBAAkB,IAAI,OAAO;AAGjD,QAAI,gBAAgB,OAAW;AAG/B,QAAI,KAAK,IAAI,WAAW,IAAI,uBAAuB;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AASO,SAAS,+BACd,QACA,mBACQ;AACR,MAAI,OAAO,SAAS,EAAG,QAAO;AAE9B,MAAI,mBAAmB;AACvB,MAAI,QAAQ;AAEZ,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,aAAS,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AAC1C,YAAM,SAAS,OAAO,CAAC;AACvB,YAAM,SAAS,OAAO,CAAC;AACvB,UAAI,WAAW,UAAa,WAAW,QAAW;AAChD,cAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,cAAM,cAAc,kBAAkB,IAAI,OAAO;AACjD,YAAI,gBAAgB,QAAW;AAC7B,8BAAoB,KAAK,IAAI,WAAW;AACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,IAAI,mBAAmB,QAAQ;AAChD;AASO,SAAS,8BACd,QACA,iBACQ;AACR,MAAI,kBAAkB;AAEtB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,aAAS,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AAC1C,YAAM,SAAS,OAAO,CAAC;AACvB,YAAM,SAAS,OAAO,CAAC;AACvB,UAAI,WAAW,UAAa,WAAW,QAAW;AAChD,cAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,cAAM,UAAU,gBAAgB,IAAI,OAAO;AAC3C,YAAI,YAAY,QAAW;AACzB,4BAAkB,KAAK,IAAI,iBAAiB,QAAQ,iBAAiB;AAAA,QACvE,OAAO;AACL,4BAAkB;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAoB,WAAW,IAAI;AAC5C;AAWO,SAAS,+BACd,QACA,mBACA,iBACA,QACqB;AACrB,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AAEjC,QAAM,UAA+B,CAAC;AACtC,QAAM,WAAW,oBAAI,IAAY;AACjC,MAAI,WAAW;AAEf,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,IAAI,KAAK,EAAG;AAEzB,UAAM,SAAmB,CAAC,KAAK;AAC/B,aAAS,IAAI,KAAK;AAGlB,eAAW,SAAS,QAAQ;AAC1B,UAAI,SAAS,IAAI,KAAK,EAAG;AACzB,UAAI,wBAAwB,OAAO,QAAQ,mBAAmB,OAAO,qBAAqB,GAAG;AAC3F,eAAO,KAAK,KAAK;AACjB,iBAAS,IAAI,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,oBAAoB,+BAA+B,QAAQ,iBAAiB;AAClF,UAAM,mBAAmB,8BAA8B,QAAQ,eAAe;AAE9E,YAAQ,KAAK;AAAA,MACX,IAAI,UAAU,OAAO,UAAU,CAAC;AAAA,MAChC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACtNA,IAAMC,UAAS,aAAa,EAAE,WAAW,sBAAsB,CAAC;AAQzD,IAAM,qBAAN,MAAwD;AAAA,EAC5C;AAAA,EACA,eAAiD,oBAAI,IAAI;AAAA,EACzD,kBAA6D,oBAAI,IAAI;AAAA,EACrE,iBAA8D,oBAAI,IAAI;AAAA;AAAA,EAEtE,gBAA0B,CAAC;AAAA,EACpC,gBAA4C;AAAA,EAEpD,YAAY,QAA2C;AACrD,SAAK,SAAS,EAAE,GAAG,6BAA6B,GAAG,OAAO;AAC1D,IAAAA,QAAO,KAAK,kCAAkC;AAAA,MAC5C,yBAAyB,KAAK,OAAO;AAAA,MACrC,cAAc,KAAK,OAAO;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,SAAiB,MAAY,SAAwC;AAC9E,UAAM,aAAa,YAAY,OAAO,gBAAgB,EAAE,IAAI,CAAC,CAAC,IAAI,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AACvH,UAAM,cAAiC;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,oBAAoB,oBAAoB,KAAK,UAAU,OAAO;AAAA,MAC9D,WAAW,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,IAC7C;AACA,SAAK,iBAAiB,SAAS,WAAW;AAC1C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,oBACE,YACA,OACA,SACM;AAEN,SAAK,0BAA0B;AAE/B,UAAM,uBAA4C,CAAC;AAEnD,eAAW,CAAC,SAAS,IAAI,KAAK,OAAO;AACnC,YAAM,cAAiC;AAAA,QACrC;AAAA,QACA;AAAA,QACA,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,oBAAoB,oBAAoB,KAAK,UAAU,OAAO;AAAA,QAC9D,WAAW,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,MAC7C;AACA,WAAK,iBAAiB,SAAS,WAAW;AAC1C,WAAK,mBAAmB,SAAS,YAAY,WAAW;AACxD,2BAAqB,KAAK,WAAW;AAAA,IACvC;AAGA,SAAK,cAAc,KAAK,UAAU;AAElC,SAAK,2BAA2B,YAAY,oBAAoB;AAChE,SAAK,gBAAgB;AAErB,IAAAA,QAAO,MAAM,2BAA2B;AAAA,MACtC;AAAA,MACA,YAAY,MAAM;AAAA,MAClB;AAAA,MACA,gBAAgB,KAAK,cAAc;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEA,2BAA8C;AAC5C,UAAM,SAA4B,oBAAI,IAAI;AAE1C,eAAW,CAAC,SAAS,OAAO,KAAK,KAAK,iBAAiB;AACrD,UAAI,QAAQ,qBAAqB,KAAK,OAAO,+BAA+B;AAC1E,eAAO,IAAI,SAAS,QAAQ,WAAW;AAAA,MACzC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,QAAgB,QAAoD;AACjF,UAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,UAAM,UAAU,KAAK,gBAAgB,IAAI,OAAO;AAEhD,QAAI,YAAY,OAAW,QAAO;AAClC,QAAI,QAAQ,oBAAoB,KAAK,OAAO,8BAA+B,QAAO;AAElF,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,6BAA2D;AACzD,QAAI,KAAK,kBAAkB,KAAM,QAAO,KAAK;AAE7C,UAAM,SAAS,KAAK,iBAAiB;AACrC,QAAI,OAAO,WAAW,GAAG;AACvB,WAAK,gBAAgB,CAAC;AACtB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,oBAAoB,KAAK,yBAAyB;AACxD,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAEA,SAAK,gBAAgB;AACrB,IAAAA,QAAO,MAAM,kCAAkC;AAAA,MAC7C,YAAY,OAAO;AAAA,MACnB,aAAa,QAAQ;AAAA,IACvB,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,kBAAkB,UAAsC;AACtD,QAAI,SAAS,SAAS,EAAG,QAAO;AAEhC,QAAI,gBAAgB;AACpB,UAAM,aAAc,SAAS,UAAU,SAAS,SAAS,KAAM;AAE/D,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,eAAS,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AAC5C,cAAM,SAAS,SAAS,CAAC;AACzB,cAAM,SAAS,SAAS,CAAC;AACzB,YAAI,WAAW,UAAa,WAAW,QAAW;AAChD,gBAAM,UAAU,mBAAmB,QAAQ,MAAM;AACjD,gBAAM,UAAU,KAAK,gBAAgB,IAAI,OAAO;AAChD,cACE,YAAY,UACZ,QAAQ,qBAAqB,KAAK,OAAO,+BACzC;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,WAAO,iBAAiB,aAAa;AAAA,EACvC;AAAA,EAEA,WAAoC;AAClC,UAAM,SAAS,KAAK,iBAAiB;AAErC,SAAK,KAAK,yBAAyB;AACnC,UAAM,UAAU,KAAK,2BAA2B;AAEhD,QAAI,mBAAmB;AACvB,QAAI,0BAA0B;AAE9B,eAAW,CAAC,EAAE,OAAO,KAAK,KAAK,iBAAiB;AAC9C,UAAI,QAAQ,qBAAqB,KAAK,OAAO,+BAA+B;AAC1E,4BAAoB,QAAQ;AAC5B;AAAA,MACF;AAAA,IACF;AAEA,QAAI,oBAAoB;AACxB,eAAW,OAAO,KAAK,aAAa,OAAO,GAAG;AAC5C,2BAAqB,IAAI;AAAA,IAC3B;AAEA,WAAO;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,cAAc,KAAK,gBAAgB;AAAA,MACnC;AAAA,MACA,oBACE,0BAA0B,IAAI,mBAAmB,0BAA0B;AAAA,MAC7E,wBAAwB,QAAQ;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,aAAa,MAAM;AACxB,SAAK,gBAAgB,MAAM;AAC3B,SAAK,eAAe,MAAM;AAC1B,SAAK,cAAc,SAAS;AAC5B,SAAK,gBAAgB;AACrB,IAAAA,QAAO,KAAK,4BAA4B;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,4BAAkC;AACxC,WAAO,KAAK,cAAc,UAAU,KAAK,OAAO,cAAc;AAC5D,YAAM,oBAAoB,KAAK,cAAc,MAAM;AACnD,UAAI,sBAAsB,OAAW;AAGrC,iBAAW,CAAC,SAAS,WAAW,KAAK,KAAK,gBAAgB;AACxD,YAAI,YAAY,IAAI,iBAAiB,GAAG;AACtC,sBAAY,OAAO,iBAAiB;AAEpC,cAAI,YAAY,SAAS,GAAG;AAC1B,iBAAK,eAAe,OAAO,OAAO;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAEA,MAAAA,QAAO,MAAM,2BAA2B;AAAA,QACtC;AAAA,QACA,QAAQ;AAAA,QACR,oBAAoB,KAAK,cAAc;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAwB;AAC9B,QAAI,KAAK,gBAAgB,QAAQ,KAAK,OAAO,gBAAiB;AAE9D,QAAI;AACJ,QAAI,aAAa;AACjB,eAAW,CAAC,KAAK,OAAO,KAAK,KAAK,iBAAiB;AACjD,YAAM,OAAO,QAAQ,YAAY,QAAQ;AACzC,UAAI,OAAO,YAAY;AACrB,qBAAa;AACb,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QAAI,cAAc,QAAW;AAC3B,WAAK,gBAAgB,OAAO,SAAS;AACrC,MAAAA,QAAO,MAAM,yCAAyC;AAAA,QACpD,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,KAAK,gBAAgB;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAiB,aAAsC;AAC9E,QAAI,WAAW,KAAK,aAAa,IAAI,OAAO;AAC5C,QAAI,aAAa,QAAW;AAC1B,iBAAW,CAAC;AACZ,WAAK,aAAa,IAAI,SAAS,QAAQ;AAAA,IACzC;AAGA,WAAO,SAAS,UAAU,KAAK,OAAO,yBAAyB;AAC7D,YAAM,UAAU,SAAS,MAAM;AAC/B,UAAI,YAAY,QAAW;AACzB,QAAAA,QAAO,MAAM,wCAAwC;AAAA,UACnD;AAAA,UACA,mBAAmB,QAAQ;AAAA,UAC3B,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAEA,aAAS,KAAK,WAAW;AAAA,EAC3B;AAAA,EAEQ,mBACN,SACA,YACA,aACM;AACN,QAAI,mBAAmB,KAAK,eAAe,IAAI,OAAO;AACtD,QAAI,qBAAqB,QAAW;AAClC,yBAAmB,oBAAI,IAAI;AAC3B,WAAK,eAAe,IAAI,SAAS,gBAAgB;AAAA,IACnD;AACA,qBAAiB,IAAI,YAAY,WAAW;AAAA,EAC9C;AAAA,EAEQ,2BAA2B,YAAoB,cAAyC;AAC9F,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,eAAS,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAChD,cAAM,OAAO,aAAa,CAAC;AAC3B,cAAM,OAAO,aAAa,CAAC;AAC3B,YAAI,SAAS,UAAa,SAAS,OAAW;AAE9C,cAAM,UAAU,mBAAmB,KAAK,SAAS,KAAK,OAAO;AAC7D,YAAI,UAAU,KAAK,gBAAgB,IAAI,OAAO;AAE9C,YAAI,YAAY,QAAW;AACzB,oBAAU;AAAA,YACR;AAAA,YACA,mBAAmB;AAAA,YACnB,YAAY;AAAA,YACZ,eAAe;AAAA,YACf,aAAa;AAAA,YACb,aAAa,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,UAC/C;AACA,eAAK,gBAAgB,IAAI,SAAS,OAAO;AACzC,eAAK,gBAAgB;AAAA,QACvB;AAGA,YAAI,CAAC,aAAa,MAAM,IAAI,EAAG;AAE/B,gBAAQ;AACR,cAAM,SAAS,WAAW,MAAM,IAAI;AACpC,YAAI,WAAW,MAAM;AACnB,kBAAQ;AAAA,QACV,OAAO;AACL,kBAAQ;AAAA,QACV;AAEA,gBAAQ,cAAc,8BAA8B,OAAO;AAC3D,gBAAQ,cAAc,IAAI,KAAK,gBAAgB,EAAE,IAAI,CAAC;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,mBAA6B;AACnC,WAAO,MAAM,KAAK,KAAK,aAAa,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEQ,kBAAwB;AAC9B,SAAK,gBAAgB;AAAA,EACvB;AACF;AAKO,SAAS,yBACd,QACqB;AACrB,SAAO,IAAI,mBAAmB,MAAM;AACtC;;;AC3WA,YAAY,QAAQ;AAEpB,SAAS,KAAAC,UAAS;AAUlB,IAAMC,UAAkB,aAAa,EAAE,WAAW,0BAA0B,CAAC;AAG7E,IAAM,gBAAgB;AAGtB,IAAM,oBAAoB;AAG1B,IAAM,0BAA0B;AAGhC,IAAM,YAAY;AAGlB,IAAM,WAAW;AAGjB,IAAM,iBAAiB;AASvB,IAAM,sBAAsBC,GAAE,OAAO;AAAA,EACnC,SAASA,GAAE,OAAO;AAAA,EAClB,UAAUA,GAAE,KAAK,CAAC,WAAW,UAAU,SAAS,CAAC;AAAA,EACjD,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AACrC,CAAC;AAUD,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EACvC,YAAYA,GAAE,OAAO;AAAA,EACrB,OAAOA,GAAE,MAAM,mBAAmB;AAAA,EAClC,SAASA,GAAE,KAAK,CAAC,YAAY,UAAU,CAAC;AAAA,EACxC,WAAWA,GAAE,IAAI,SAAS;AAC5B,CAAC;AAUM,IAAM,iCAAiCA,GAAE,OAAO;AAAA,EACrD,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACnC,WAAWA,GAAE,MAAM,uBAAuB;AAAA,EAC1C,SAASA,GAAE,IAAI,SAAS;AAC1B,CAAC;AAaM,SAAS,yBAAiC;AAC/C,SAAO,cAAc,eAAe,iBAAiB;AACvD;AAGO,SAAS,0BAAkC;AAChD,SAAO,cAAc,eAAe,uBAAuB;AAC7D;AAKA,SAAS,wBAA6C;AACpD,QAAM,UAAU,cAAc,aAAa;AAC3C,MAAI;AACF,IAAG,aAAU,SAAS,EAAE,WAAW,MAAM,MAAM,SAAS,CAAC;AACzD,WAAO,GAAG,MAAS;AAAA,EACrB,SAAS,OAAgB;AACvB,UAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACtE,WAAO,IAAI,IAAI,MAAM,wCAAwC,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,EAC3F;AACF;AAqBO,SAAS,oBACd,WAIA,UAAmC,6BACd;AACrB,QAAM,YAAY,sBAAsB;AACxC,MAAI,CAAC,UAAU,GAAI,QAAO;AAE1B,MAAI,UAAU,WAAW,EAAG,QAAO,GAAG,MAAS;AAE/C,QAAM,WAAW,wBAAwB;AAEzC,MAAI;AACF,UAAM,QAAQ,UAAU,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACnE,IAAG,kBAAe,UAAU,OAAO,EAAE,UAAU,SAAS,MAAM,UAAU,CAAC;AAEzE,IAAAD,QAAO,KAAK,kCAAkC;AAAA,MAC5C,MAAM;AAAA,MACN,eAAe,UAAU;AAAA,IAC3B,CAAC;AAED,WAAO,GAAG,MAAS;AAAA,EACrB,SAAS,OAAgB;AACvB,UAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACtE,WAAO,IAAI,IAAI,MAAM,sCAAsC,MAAM,OAAO,EAAE,CAAC;AAAA,EAC7E;AACF;AAOA,SAAS,0BAA+C;AACtD,QAAM,WAAW,uBAAuB;AACxC,MAAI,CAAI,cAAW,QAAQ,EAAG,QAAO,CAAC;AAEtC,MAAI;AACJ,MAAI;AACF,iBAAgB,gBAAa,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,EAC9D,SAAS,OAAgB;AACvB,IAAAA,QAAO,KAAK,2CAA2C;AAAA,MACrD,MAAM;AAAA,MACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,UAAU;AAAA,EAChC,SAAS,OAAgB;AACvB,IAAAA,QAAO,KAAK,oDAA+C;AAAA,MACzD,MAAM;AAAA,MACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,+BAA+B,UAAU,MAAM;AAC9D,MAAI,CAAC,OAAO,SAAS;AACnB,IAAAA,QAAO,KAAK,2DAAsD;AAAA,MAChE,MAAM;AAAA,MACN,OAAO,OAAO,MAAM;AAAA,IACtB,CAAC;AACD,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO,KAAK;AACrB;AAKA,SAAS,eAAe,MAA0B;AAChD,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,SAAS,OAAgB;AACvB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC/E;AAAA,EACF;AACA,QAAM,SAAS,wBAAwB,UAAU,MAAM;AACvD,MAAI,CAAC,OAAO,QAAS,QAAO,EAAE,MAAM,QAAQ,QAAQ,WAAW,OAAO,MAAM,OAAO,GAAG;AACtF,SAAO,EAAE,MAAM,MAAM,UAAU,OAAO,KAAK;AAC7C;AAGA,SAAS,qBAA0C;AACjD,QAAM,WAAW,wBAAwB;AACzC,MAAI,CAAI,cAAW,QAAQ,EAAG,QAAO,CAAC;AAEtC,MAAI;AACJ,MAAI;AACF,cAAa,gBAAa,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,EAC3D,SAAS,OAAgB;AACvB,IAAAA,QAAO,KAAK,qCAAqC;AAAA,MAC/C,MAAM;AAAA,MACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AACrE,QAAM,YAAiC,CAAC;AACxC,MAAI,eAAe;AACnB,MAAI;AAEJ,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,eAAe,IAAI;AAClC,QAAI,OAAO,SAAS,MAAM;AACxB,gBAAU,KAAK,OAAO,QAAQ;AAAA,IAChC,OAAO;AACL;AACA,0BAAoB,OAAO;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,eAAe,GAAG;AACpB,IAAAA,QAAO,KAAK,iDAAiD;AAAA,MAC3D,MAAM;AAAA,MACN;AAAA,MACA,YAAY,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMA,SAAS,YACP,iBACA,gBACA,cACqB;AACrB,QAAM,cAAc,oBAAI,IAA+B;AAEvD,aAAW,KAAK,gBAAiB,aAAY,IAAI,EAAE,YAAY,CAAC;AAChE,aAAW,KAAK,eAAgB,aAAY,IAAI,EAAE,YAAY,CAAC;AAE/D,QAAM,MAAM,MAAM,KAAK,YAAY,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MACpD,EAAE,UAAU,cAAc,EAAE,SAAS;AAAA,EACvC;AACA,SAAO,IAAI,SAAS,eAAe,IAAI,MAAM,IAAI,SAAS,YAAY,IAAI;AAC5E;AAQO,SAAS,oBACd,SAAkC,6BACO;AACzC,QAAM,YAAY,wBAAwB;AAC1C,QAAM,aAAa,uBAAuB;AAC1C,QAAM,cAAiB,cAAW,SAAS;AAC3C,QAAM,eAAkB,cAAW,UAAU;AAE7C,MAAI,CAAC,eAAe,CAAC,cAAc;AACjC,WAAO,IAAI,IAAI,MAAM,oCAAoC,SAAS,EAAE,CAAC;AAAA,EACvE;AAEA,QAAM,SAAS,wBAAwB;AACvC,QAAM,QAAQ,mBAAmB;AACjC,QAAM,YAAY,YAAY,QAAQ,OAAO,OAAO,YAAY;AAEhE,EAAAA,QAAO,KAAK,2BAA2B;AAAA,IACrC,aAAa,OAAO;AAAA,IACpB,YAAY,MAAM;AAAA,IAClB,YAAY,UAAU;AAAA,EACxB,CAAC;AAED,SAAO,GAAG;AAAA,IACR,SAAS;AAAA,IACT;AAAA,IACA,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,EAClC,CAAC;AACH;AA8DA,SAAS,gBACP,SACA,WACQ;AACR,MAAI,WAAW;AAEf,aAAW,YAAY,WAAW;AAChC,UAAM,QAAQ,oBAAI,IAAkB;AAEpC,eAAW,QAAQ,SAAS,OAAO;AACjC,YAAM,IAAI,KAAK,SAAS;AAAA,QACtB,UAAU,KAAK;AAAA,QACf,WAAW;AAAA,QACX,YAAY,KAAK;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,YAAQ,oBAAoB,SAAS,YAAY,OAAO,SAAS,OAAO;AACxE;AAAA,EACF;AAEA,SAAO;AACT;AAeO,SAAS,mCACd,QACqB;AACrB,QAAM,UAAU,yBAAyB,MAAM;AAE/C,QAAM,eAAe,EAAE,GAAG,6BAA6B,GAAG,OAAO;AACjE,QAAM,aAAa,oBAAoB,YAAY;AACnD,MAAI,CAAC,WAAW,IAAI;AAClB,IAAAE,QAAO,KAAK,2CAA2C;AAAA,MACrD,QAAQ,WAAW,MAAM;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,gBAAgB,SAAS,WAAW,MAAM,SAAS;AAEzE,EAAAA,QAAO,KAAK,iDAAiD;AAAA,IAC3D,mBAAmB;AAAA,IACnB,OAAO,QAAQ,SAAS;AAAA,EAC1B,CAAC;AAED,SAAO;AACT;AAgBO,SAAS,wBACd,YACA,OACA,SACmB;AACnB,QAAM,iBAAkC,CAAC;AAEzC,aAAW,CAAC,SAAS,IAAI,KAAK,OAAO;AACnC,mBAAe,KAAK;AAAA,MAClB;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;;;ACzeA,SAAS,KAAAC,UAAS;AAMX,IAAM,sBAAsB;AAwB5B,IAAM,uBAAuBC,GAAE,KAAK;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA0BM,IAAM,oBAAoBA,GAAE,KAAK,CAAC,sBAAsB,oBAAoB,aAAa,CAAC;AAe1F,IAAM,sBAAsBA,GAAE,KAAK,CAAC,YAAY,iBAAiB,WAAW,CAAC;AAQ7E,IAAM,uBAAuB;AAQ7B,SAAS,sBAAsB,UAAuC;AAC3E,MAAI,aAAa,eAAe,aAAa,eAAgB,QAAO;AACpE,SAAO;AACT;AAEO,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EAC/C,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,mBAAmB,EAAE,SAAS,0BAA0B;AAAA,EACxF,WAAW,oBAAoB,SAAS,EAAE;AAAA,IACxC;AAAA,EACF;AAAA,EACA,UAAU,qBAAqB,SAAS,EAAE;AAAA,IACxC;AAAA,EACF;AAAA,EACA,aAAa,kBAAkB,SAAS,EAAE;AAAA,IACxC;AAAA,EACF;AAAA,EACA,WAAWA,GACR,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,gDAAgD;AAAA,EAC5D,eAAeA,GACZ,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AA4DM,SAAS,mBAAmB,QAA2C;AAC5E,QAAM,WAAW,YAAY,OAAO,IAAI,EAAE,MAAM,KAAK,EAAE,CAAC,KAAK,OAAO;AACpE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,OAAO,KAAK;AAAA,IACtB,YAAY,OAAO,KAAK;AAAA,IACxB,WAAW,OAAO,KAAK;AAAA,IACvB,WAAW,OAAO,WAAW;AAAA,IAC7B,OAAO,OAAO,WAAW;AAAA,IACzB,GAAI,OAAO,KAAK,wBAAwB,SACpC,EAAE,qBAAqB,OAAO,KAAK,oBAAoB,IACvD,CAAC;AAAA,EACP;AACF;AAGO,SAAS,qBAAqB,SAAqC;AACxE,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAGO,SAAS,cACd,OACA,QACuB;AACvB,QAAM,oBACJ,MAAM,SAAS,SAAS,MAAM,MAAM,SAAS,MAAM,GAAG,GAAG,IAAI,QAAQ,MAAM;AAE7E,QAAM,aAAa,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAEpE,QAAM,YAAY,eAAe,OAAO,MAAM,UAAU,aAAa;AACrE,QAAM,WACJ,CAAC,OAAO,OAAO,iBAAiB,YAC5B,cACA,qBAAqB,OAAO,OAAO,OAAO;AAEhD,QAAM,WAAkC;AAAA,IACtC,UAAU;AAAA,IACV,UAAU,OAAO;AAAA,IACjB;AAAA,IACA,oBAAoB,OAAO,OAAO;AAAA,IAClC,YAAY;AAAA,MACV,SAAS,OAAO,OAAO,WAAW;AAAA,MAClC,QAAQ,OAAO,OAAO,WAAW;AAAA,MACjC,SAAS,OAAO,OAAO,WAAW;AAAA,MAClC,OAAO;AAAA,IACT;AAAA,IACA,OAAO,OAAO,MAAM,IAAI,kBAAkB;AAAA,IAC1C,YAAY,OAAO;AAAA,IACnB,eAAe,OAAO;AAAA,EACxB;AAEA,MAAI,MAAM,cAAc,QAAW;AACjC,aAAS,YAAY,MAAM;AAAA,EAC7B;AAEA,MAAI,OAAO,aAAa,kBAAkB,OAAO,mBAAmB;AAClE,aAAS,sBAAsB;AAAA,MAC7B,mBAAmB,OAAO,kBAAkB;AAAA,MAC5C,oBAAoB,OAAO,kBAAkB;AAAA,MAC7C,oBAAoB,OAAO,kBAAkB;AAAA,MAC7C,QAAQ,OAAO,kBAAkB;AAAA,MACjC,qBAAqB,OAAO,kBAAkB;AAAA,MAC9C,yBAAyB,OAAO,kBAAkB;AAAA,MAClD,oBAAoB,OAAO,kBAAkB;AAAA,MAC7C,WAAW,OAAO,kBAAkB;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;;;AChOA,SAAS,mBAAmB,YAAoB,YAA6B;AAC3E,MAAI,eAAe,EAAG,QAAO;AAC7B,SAAO,aAAa,aAAa;AACnC;AAeO,SAAS,iBACd,OACA,QACqB;AACrB,QAAM,aAAa,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAC3D,QAAM,aAAa,WAAW;AAC9B,QAAM,aAAa,MAAM;AAEzB,MAAI,mBAAmB,YAAY,UAAU,GAAG;AAC9C,WAAO;AAAA,MACL,cAAc;AAAA,MACd,QAAQ,mBAAmB,OAAO,KAAK,MAAM,uBAAuB,GAAG,CAAC,CAAC,gBAAgB,OAAO,UAAU,CAAC,IAAI,OAAO,UAAU,CAAC;AAAA,MACjI,aAAa,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,WAAW,iBAAiB,aAAa,GAAG;AAC9C,WAAO;AAAA,MACL,cAAc;AAAA,MACd,QAAQ,gBAAgB,OAAO,UAAU,CAAC;AAAA,MAC1C,aAAa,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,WAAW,oBAAoB;AAIjC,WAAO;AAAA,MACL,cAAc;AAAA,MACd,aAAa,MAAM;AAAA,QAAI,CAAC,MACtB,EAAE,WAAW,UAAU,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,UAAU,UAAmB,EAAE,IAAI;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,cAAc;AAAA,IACd,aAAa,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAAA,EACvD;AACF;;;AC5FA,SAAS,kBAAAC,iBAAgB,gBAAAC,eAAc,iBAAAC,gBAAe,cAAAC,mBAAkB;AAgCjE,IAAM,yBAAN,cAAqC,aAAa;AAAA,EACtC;AAAA,EACA;AAAA,EAEjB,YAAY,QAAuCC,SAAkB;AACnE,UAAM,MAAM;AACZ,SAAK,WAAW,QAAQ,YAAY,gBAAgB;AACpD,SAAK,SAASA,WAAU,aAAa,EAAE,WAAW,yBAAyB,CAAC;AAE5E,UAAM,UAAU,QAAQ;AACxB,sBAAkB,OAAO;AACzB,SAAK,QAAQ;AACb,SAAK,mBAAmB;AACxB,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA,EAGS,OAAO,SAA4B;AAC1C,UAAM,OAAO,OAAO;AACpB,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,wBAA8B;AACpC,QAAI,KAAK,SAAS,EAAG;AACrB,UAAM,SAAS,KAAK,oBAAoB;AACxC,QAAI,SAAS,GAAG;AACd,WAAK,OAAO,KAAK,qDAAqD,EAAE,OAAO,CAAC;AAChF,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,SAAS,EAAG;AACrB,UAAM,eAAe,KAAK,cAAc;AACxC,QAAI,eAAe,GAAG;AACpB,WAAK,OAAO,KAAK,0DAA0D;AAAA,QACzE;AAAA,MACF,CAAC;AACD,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,UAAgB;AACtB,QAAI,CAACC,YAAW,KAAK,QAAQ,GAAG;AAC9B,WAAK,OAAO,MAAM,0CAA0C;AAAA,QAC1D,MAAM,KAAK;AAAA,MACb,CAAC;AACD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAUC,cAAa,KAAK,UAAU,OAAO;AACnD,YAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC;AACzE,UAAI,SAAS;AACb,UAAI,UAAU;AAEd,iBAAW,QAAQ,OAAO;AACxB,YAAI;AACF,gBAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,gBAAM,SAAS,kBAAkB,UAAU,MAAM;AACjD,cAAI,OAAO,SAAS;AAClB,kBAAM,OAAO,OAAO,IAAI;AACxB;AAAA,UACF,OAAO;AACL;AAAA,UACF;AAAA,QACF,SAAS,UAAmB;AAC1B,eAAK,OAAO,MAAM,oDAAoD;AAAA,YACpE,OAAO,gBAAgB,QAAQ;AAAA,YAC/B,aAAa,KAAK,MAAM,GAAG,EAAE;AAAA,UAC/B,CAAC;AACD;AAAA,QACF;AAAA,MACF;AAEA,WAAK,OAAO,KAAK,+BAA+B;AAAA,QAC9C;AAAA,QACA;AAAA,QACA,OAAO,MAAM;AAAA,QACb,MAAM,KAAK;AAAA,MACb,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,YAAM,MAAM,gBAAgB,KAAK;AACjC,WAAK,OAAO,KAAK,wCAAwC;AAAA,QACvD,OAAO;AAAA,QACP,MAAM,KAAK;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAGQ,cAAoB;AAC1B,QAAI;AACF,YAAM,UAAU,KAAK,MAAM;AAC3B,YAAM,UAAU,QAAQ,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACnE,MAAAC,eAAc,KAAK,UAAU,SAAS,OAAO;AAAA,IAC/C,SAAS,OAAgB;AACvB,YAAM,MAAM,gBAAgB,KAAK;AACjC,WAAK,OAAO,KAAK,0DAA0D;AAAA,QACzE,OAAO;AAAA,QACP,MAAM,KAAK;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,YAAY,SAA4B;AAC9C,QAAI;AACF,MAAAC,gBAAe,KAAK,UAAU,KAAK,UAAU,OAAO,IAAI,MAAM,OAAO;AAAA,IACvE,SAAS,OAAgB;AACvB,YAAM,MAAM,gBAAgB,KAAK;AACjC,WAAK,OAAO,KAAK,qCAAqC;AAAA,QACpD,OAAO;AAAA,QACP,MAAM,KAAK;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAIA,sCAAsC,MAAM,IAAI,uBAAuB,CAAC;;;ACrJxE,IAAMC,UAAS,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAS/C,SAAS,kBACd,UACA,UACA,SACA,UACA,OACM;AACN,QAAM,eACJ,UAAU,UAAa,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,YAAY;AACzF,MAAI,cAAc;AAChB,IAAAA,QAAO,MAAM,gEAA2D;AACxE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,SAAS,cAAc;AAC7B,WAAO,WAAW;AAAA,MAChB,UAAU,mBAAmB,QAAQ,QAAQ,SAAS,MAAM,GAAG,EAAE,CAAC;AAAA,MAClE,YAAY,CAAC;AAAA,MACb,YAAY;AAAA,IACd,CAAC;AACD,WAAO,eAAe;AAAA,MACpB,SAAS,GAAG,QAAQ,gBAAW,OAAO;AAAA,MACtC,SAAS,aAAa,SAAS,MAAM,GAAG,EAAE,CAAC,cAAc,OAAO,QAAQ,CAAC;AAAA,MACzE,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,OAAO,qBAAqB,EAAE,MAAM,CAAC,UAAmB;AAC3D,MAAAA,QAAO,KAAK,6BAA6B,EAAE,MAAM,CAAC;AAAA,IACpD,CAAC;AAAA,EACH,SAAS,OAAgB;AACvB,IAAAA,QAAO,KAAK,2CAA2C,EAAE,OAAO,gBAAgB,KAAK,EAAE,CAAC;AAAA,EAC1F;AAKA,MAAI,UAAU,QAAW;AACvB,uBAAmB,KAAK;AAAA,EAC1B;AACF;AAGO,SAAS,gBAAgB,UAAkB,cAA4B;AAC5E,MAAI;AACF,UAAM,SAAS,cAAc;AAC7B,WAAO,YAAY;AAAA,MACjB,OAAO,0BAA0B,aAAa,MAAM,GAAG,GAAG,CAAC;AAAA,MAC3D,UAAU;AAAA,MACV,aAAa;AAAA,IACf,CAAC;AAAA,EACH,SAAS,OAAgB;AACvB,IAAAA,QAAO,KAAK,+BAA+B,EAAE,OAAO,gBAAgB,KAAK,EAAE,CAAC;AAAA,EAC9E;AACF;AAOO,SAAS,mBAAmB,OAAyC;AAC1E,MAAI;AACF,UAAM,QAAQ,gBAAgB;AAC9B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,WAAW,aAAc;AAClC,YAAM,UACJ,KAAK,QAAQ,UAAc,UAAgC,SAAS,KAAK,GAAG,IACvE,KAAK,MACN;AACN,YAAM,cAAc,KAAK,WAAW;AACpC,YAAM,OAAO;AAAA,QACX,IAAI,QAAQ,OAAO,gBAAgB,EAAE,IAAI,CAAC,CAAC,IAAI,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,QACpG,KAAK;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ;AAAA;AAAA;AAAA,QAGR,WAAW,KAAK;AAAA,QAChB,GAAI,CAAC,eAAe,KAAK,UAAU,SAC/B;AAAA,UACE,iBAAiB,8BAA8B,KAAK,KAAK;AAAA,UACzD,cAAc,KAAK,MAAM,MAAM,GAAG,GAAG;AAAA,QACvC,IACA,CAAC;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAgB;AACvB,IAAAA,QAAO,MAAM,6CAA6C,EAAE,OAAO,gBAAgB,KAAK,EAAE,CAAC;AAAA,EAC7F;AACF;;;ACvHA,IAAM,SAAS,oBAAI,IAAY;AAGxB,SAAS,eAAwB;AACtC,SAAO,QAAQ,IAAI,WAAW,UAAU,QAAQ,IAAI,aAAa;AACnE;AAYO,SAAS,4BAA4B,UAAkBC,SAAuB;AACnF,MAAI,aAAa,EAAG;AACpB,MAAI,OAAO,IAAI,QAAQ,EAAG;AAC1B,SAAO,IAAI,QAAQ;AACnB,EAAAA,QAAO;AAAA,IACL,IAAI,QAAQ;AAAA,EACd;AACF;;;ACEO,IAAM,mBAAoD;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/D,aAAa;AAAA,IACX,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,eAAe;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,gBAAgB;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,oBAAoB;AAAA,IAClB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,kBAAkB;AAAA,IAChB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,6BAA6B;AAAA,IAC3B,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,WAAW;AAAA,IACT,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB;AAAA,IACjB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,gBAAgB;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,kBAAkB;AAAA,IAChB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,qBAAqB;AAAA,IACnB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,mBAAmB;AAAA,IACjB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,qBAAqB;AAAA,IACnB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,yBAAyB;AAAA,IACvB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,sBAAsB;AAAA,IACpB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,yBAAyB;AAAA,IACvB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,oBAAoB;AAAA,IAClB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB;AAAA,IACd,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,aAAa;AAAA,IACX,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,kBAAkB;AAAA,IAChB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,oBAAoB;AAAA,IAClB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,oBAAoB;AAAA,IAClB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,oBAAoB;AAAA,IAClB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,iBAAiB;AAAA,IACf,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,iBAAiB;AAAA,IACf,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,iBAAiB;AAAA,IACf,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AACF;AAQO,SAAS,mBAAmB,MAA+B;AAChE,QAAM,IAAI,iBAAiB,IAAI;AAC/B,MAAI,MAAM,QAAW;AACnB,UAAM,IAAI;AAAA,MACR,0CAA0C,IAAI;AAAA,IAChD;AAAA,EACF;AACA,SAAO;AACT;;;ArE7SA,IAAI;AAGJ,SAAS,gCAAqD;AAC5D,mCAAiC,mCAAmC;AACpE,SAAO;AACT;AAGO,SAAS,0BAAgC;AAC9C,iCAA+B;AACjC;AASA,SAAS,gBAAgB,OAA2C;AAClE,MAAI,MAAM,aAAa,OAAW,QAAO,MAAM;AAC/C,MAAI,MAAM,cAAc,QAAW;AACjC,YAAQ,MAAM,WAAW;AAAA,MACvB,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,IACX;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,UAA8C;AACzE,MAAI,aAAa,eAAgB,QAAO;AACxC,MAAI,aAAa,eAAgB,QAAO;AACxC,SAAO;AACT;AAEA,SAAS,cAAc,WAA0C;AAI/D,SAAO,YACH,CAAC,aAAa,YAAY,eAAe,IACzC,CAAC,aAAa,YAAY,SAAS,SAAS,MAAM,WAAW,eAAe;AAClF;AAIA,SAAS,2BACP,UACA,WACiB;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,UAAU,EAAE,OAAO,sBAAsB,aAAa,UAAU,UAAU;AAAA,IAC1E,SAAS;AAAA,IACT,OAAO,oBAAI,IAAkB;AAAA,IAC7B,YAAY,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,IAC1D,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AACF;AASA,SAAS,yBACP,UACA,WACA,QACiB;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,UAAU,EAAE,OAAO,6BAAwB,MAAM,IAAI,aAAa,UAAU,UAAU;AAAA,IACtF,SAAS;AAAA,IACT,OAAO,oBAAI,IAAkB;AAAA,IAC7B,YAAY,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,IAC1D,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AACF;AAGA,IAAM,qBAA6C;AAAA,EACjD,UAAU;AAAA,EACV,eAAe;AAAA,EACf,WAAW;AACb;AAGA,SAAS,mBACP,WACA,WACA,YACA,OACsC;AACtC,QAAM,YAAY,mBAAmB,SAAS,KAAK;AACnD,MAAI,UAAU,EAAG,QAAO,EAAE,SAAS,OAAO,QAAQ,GAAG;AAGrD,MAAI,cAAc,eAAe,aAAa,GAAG;AAC/C,WAAO,EAAE,SAAS,MAAM,QAAQ,uBAAuB,OAAO,UAAU,CAAC,gBAAgB;AAAA,EAC3F;AAEA,MAAI,YAAY,QAAQ,WAAW;AACjC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,oBAAoB,OAAO,SAAS,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,IACvF;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,YAAY;AACtC,OAAK,YAAY,aAAa,QAAQ,WAAW;AAC/C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,kCAAkC,OAAO,YAAY,SAAS,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,OAAO,SAAS,CAAC;AAAA,IACjH;AAAA,EACF;AACA,SAAO,EAAE,SAAS,OAAO,QAAQ,GAAG;AACtC;AAWA,eAAe,0BACb,aACA,UACA,WAC0B;AAC1B,MAAI,YAAY,WAAW,EAAG,QAAO,2BAA2B,UAAU,SAAS;AAEnF,QAAM,SAAS,sBAAsB;AACrC,QAAM,iBAA2B;AAAA,IAC/B,OAAO;AAAA,IACP,aAAa;AAAA,IACb;AAAA,EACF;AACA,QAAM,iBAAiB,MAAM,OAAO,QAAQ,cAAc;AAC1D,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,8BAA8B,eAAe,MAAM,OAAO,IAAI;AAAA,MAC5E,OAAO,eAAe;AAAA,IACxB,CAAC;AAEH,QAAM,aAAa,eAAe;AAClC,aAAW,EAAE,MAAM,KAAK,KAAK,YAAa,OAAM,OAAO,KAAK,YAAY,MAAM,IAAI;AAElF,QAAM,YAAY,MAAM,OAAO,MAAM,UAAU;AAC/C,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,6BAA6B,UAAU,MAAM,OAAO,IAAI;AAAA,MACtE,OAAO,UAAU;AAAA,IACnB,CAAC;AACH,SAAO,UAAU;AACnB;AAEA,SAAS,qBACP,UACA,SACAC,SACqC;AACrC,MAAI,aAAa,eAAgB,QAAO;AACxC,QAAM,cAAc,IAAI,0BAA0B;AAClD,QAAM,UAAU,8BAA8B;AAC9C,QAAM,SAAS,YAAY,UAAU,SAAS,OAAO;AACrD,EAAAA,QAAO,KAAK,gCAAgC;AAAA,IAC1C,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,mBAAmB,OAAO,kBAAkB,QAAQ,CAAC;AAAA,EACvD,CAAC;AACD,SAAO;AACT;AAEA,SAAS,qBACP,OACA,SACA,SACAA,SACM;AACN,QAAM,eAAe,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,KAAK;AAC1D,MAAI,CAAC,cAAc;AACjB,IAAAA,QAAO,KAAK,uDAAuD;AAAA,MACjE,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,EAAE;AAAA,IACjD,CAAC;AACD;AAAA,EACF;AACA,QAAM,UAAU,8BAA8B;AAC9C,QAAM,KAAK,aAAa,OAAO,gBAAgB,EAAE,IAAI,CAAC,CAAC,IAAI,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAChH,UAAQ,oBAAoB,IAAI,SAAS,OAAO;AAChD,EAAAA,QAAO,MAAM,6BAA6B,EAAE,YAAY,IAAI,QAAQ,CAAC;AAErE,MAAI;AACF,UAAM,YAAY,wBAAwB,IAAI,SAAS,OAAO;AAC9D,UAAM,aAAa,oBAAoB,CAAC,SAAS,CAAC;AAClD,QAAI,CAAC,WAAW,IAAI;AAClB,MAAAA,QAAO,KAAK,sCAAsC,EAAE,OAAO,WAAW,MAAM,QAAQ,CAAC;AAAA,IACvF;AAAA,EACF,SAAS,OAAgB;AACvB,UAAM,UAAU,gBAAgB,KAAK;AACrC,IAAAA,QAAO,KAAK,qCAAqC,EAAE,OAAO,QAAQ,CAAC;AAAA,EACrE;AACF;AAYA,eAAe,wBACb,aACA,MAaC;AACD,QAAM,YAAY,YAAY,OAAO,CAAC,MAAM,EAAE,KAAK,aAAa,SAAS,EAAE;AAC3E,QAAM,aAAa,YAAY,OAAO,CAAC,MAAM,EAAE,KAAK,aAAa,QAAQ,EAAE;AAC3E,QAAM,cAAc,mBAAmB,KAAK,WAAW,WAAW,YAAY,KAAK,UAAU;AAE7F,MAAI,YAAY,SAAS;AACvB,SAAK,IAAI,KAAK,uCAAuC;AAAA,MACnD;AAAA,MACA;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,QAAQ,YAAY;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,MAAM,0BAA0B,aAAa,KAAK,UAAU,KAAK,SAAS;AAC/F,QAAM,UAAU,oBAAI,IAAkB;AACtC,aAAW,EAAE,MAAM,KAAK,KAAK,YAAa,SAAQ,IAAI,MAAM,IAAI;AAEhE,QAAM,oBAAoB,YAAY,UAClC,SACA,qBAAqB,KAAK,UAAU,SAAS,KAAK,GAAG;AACzD,QAAM,UACJ,aAAa,YAAY,aAAa,aAAa;AAErD,SAAO,EAAE,cAAc,SAAS,mBAAmB,SAAS,UAAU,YAAY,QAAQ;AAC5F;AAIA,IAAM,kCAAkC;AAGxC,eAAe,mBACb,UACA,KAC0E;AAC1E,MAAI;AACF,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,6BAAiC;AACxE,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,SAAS,MAAM,GAAG,GAAI,CAAC;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,SAAS,MAAM,cAAc,gBAAgB,MAAM;AACzD,QAAI,CAAC,OAAO,QAAS,QAAO,EAAE,gBAAgB,OAAO,QAAQ,IAAI,YAAY,EAAE;AAE/E,UAAM,YAAY,OAAO,KAAK,MAAM,aAAa;AACjD,QAAI,cAAc,KAAM,QAAO,EAAE,gBAAgB,OAAO,QAAQ,IAAI,YAAY,EAAE;AAElF,UAAM,SAAS,KAAK,MAAM,UAAU,CAAC,CAAC;AAMtC,UAAM,cAAc,OAAO,aAAa;AACxC,UAAM,aAAa,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa;AAC/E,UAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;AAE5E,QAAI,eAAe,cAAc,iCAAiC;AAChE,UAAI,KAAK,4CAA4C;AAAA,QACnD;AAAA,QACA,WAAW,UAAU,MAAM,GAAG,GAAG;AAAA,MACnC,CAAC;AACD,aAAO,EAAE,gBAAgB,MAAM,QAAQ,WAAW,WAAW;AAAA,IAC/D;AAEA,WAAO,EAAE,gBAAgB,OAAO,QAAQ,IAAI,WAAW;AAAA,EACzD,SAAS,OAAgB;AAOvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,QAAI,KAAK,wDAAwD,EAAE,OAAO,QAAQ,CAAC;AACnF,WAAO,EAAE,gBAAgB,OAAO,QAAQ,IAAI,YAAY,EAAE;AAAA,EAC5D;AACF;AAQA,SAAS,8BAA8B,MASd;AACvB,OAAK,OAAO,KAAK,kDAAkD;AAAA,IACjE,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK;AAAA,EACf,CAAC;AACD,QAAM,cAAc,gBAAgB,EAAE,IAAI,IAAI,KAAK;AACnD,SAAO;AAAA,IACL,UAAU,KAAK,MAAM;AAAA,IACrB,WAAW,KAAK;AAAA,IAChB,QAAQ,yBAAyB,KAAK,MAAM,UAAU,KAAK,WAAW,KAAK,MAAM;AAAA,IACjF,OAAO,KAAK;AAAA,IACZ;AAAA,IACA,eAAe,KAAK,MAAM;AAAA,IAC1B,UAAU,KAAK;AAAA,EACjB;AACF;AAWA,eAAe,wBACb,OACA,SACAA,SACA,MAC2C;AAC3C,MAAI,CAAC,MAAM,aAAa,YAAY,cAAc,MAAM,cAAe,QAAO;AAC9E,QAAM,aAAa,MAAM,mBAAmB,MAAM,UAAUA,OAAM;AAClE,MAAI,CAAC,WAAW,eAAgB,QAAO;AACvC,EAAAA,QAAO,KAAK,oDAAoD;AAAA,IAC9D,QAAQ,WAAW;AAAA,IACnB,YAAY,WAAW;AAAA,EACzB,CAAC;AACD,SAAO,cAAc,EAAE,GAAG,OAAO,WAAW,MAAM,GAAGA,SAAQ,IAAI;AACnE;AAUA,eAAsB,cACpB,OACAA,SACA,MAC+B;AAC/B,QAAM,WAAW,gBAAgB,KAAK;AACtC,QAAM,YAAY,oBAAoB,QAAQ;AAC9C,QAAM,QAAQ,cAAc,MAAM,SAAS;AAC3C,QAAM,YAAY,gBAAgB,EAAE,IAAI;AACxC,QAAM,cAAc,MAAM,eAAe,sBAAsB,QAAQ;AAEvE,EAAAA,QAAO,KAAK,2BAA2B;AAAA,IACrC;AAAA,IACA;AAAA,IACA,WAAW,MAAM;AAAA,IACjB;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,MAAM,iBAAiB;AAAA,IACnC;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,UAAU,MAAM;AAAA,IAChB,GAAI,MAAM,kBAAkB,UAAa,EAAE,WAAW,KAAK,cAAc;AAAA,EAC3E,CAAC;AAID,QAAM,iBAAiB,iBAAiB,OAAO,WAAW;AAC1D,MAAI,eAAe,cAAc;AAC/B,WAAO,8BAA8B;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,eAAe,UAAU;AAAA,MACjC;AAAA,MACA,QAAAA;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,EAAE,cAAc,SAAS,mBAAmB,SAAS,SAAS,IAClE,MAAM,wBAAwB,eAAe,aAAa;AAAA,IACxD,YAAY,MAAM;AAAA,IAClB,UAAU,MAAM;AAAA,IAChB;AAAA,IACA;AAAA,IACA,KAAKA;AAAA,EACP,CAAC;AAEH,uBAAqB,OAAO,SAAS,SAASA,OAAM;AAEpD,QAAM,YAAY,MAAM,wBAAwB,OAAO,SAASA,SAAQ,IAAI;AAC5E,MAAI,cAAc,OAAW,QAAO;AAEpC,SAAO,qBAAqB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAAA;AAAA,EACF,CAAC;AACH;AAGA,SAAS,qBAAqB,MAWL;AACvB,QAAM,cAAc,gBAAgB,EAAE,IAAI,IAAI,KAAK;AACnD,OAAK,OAAO,KAAK,4BAA4B;AAAA,IAC3C,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,IACd,YAAY;AAAA,IACZ,UAAU,KAAK;AAAA,EACjB,CAAC;AACD,QAAM,SAA+B;AAAA,IACnC,UAAU,KAAK,MAAM;AAAA,IACrB,WAAW,KAAK;AAAA,IAChB,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,IACZ;AAAA,IACA,eAAe,KAAK,MAAM;AAAA,IAC1B,UAAU,KAAK;AAAA,EACjB;AACA,MAAI,KAAK,sBAAsB,OAAW,QAAO,oBAAoB,KAAK;AAC1E,SAAO;AACT;AAGA,eAAe,oBACb,MACA,MACoF;AACpF,QAAMA,UAAS,KAAK,UAAU,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrE,MAAI,KAAK,cAAe,6BAA4B,kBAAkBA,OAAM;AAC5E,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,MAAMA,OAAM;AAC/C,UAAM,WAAW,KAAK,YAAY;AAGlC,UAAM,aAAa,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAClE,QAAI,WAAW,WAAW,OAAO,MAAM,UAAU,OAAO,MAAM,SAAS,GAAG;AACxE,YAAM,WAAW,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,SAAS,eAAe,EAAE,EAAE,KAAK,IAAI;AAC5F,MAAAA,QAAO,KAAK,qBAAqB,EAAE,cAAc,WAAW,QAAQ,SAAS,CAAC;AAC9E,sBAAgB,KAAK,UAAU,OAAO,OAAO,WAAW,MAAM,CAAC,mBAAmB,QAAQ,EAAE;AAC5F,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,OAAO,OAAO,WAAW,MAAM,CAAC,6BAA6B,QAAQ;AAAA,MAC9E;AAAA,IACF;AAEA;AAAA,MACE,KAAK;AAAA,MACL;AAAA,MACA,OAAO,OAAO;AAAA,MACd,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,WAAO,EAAE,IAAI,MAAM,OAAO,cAAc,MAAM,MAAM,EAAE;AAAA,EACxD,SAAS,OAAO;AACd,UAAM,UAAU,gBAAgB,KAAK;AACrC,UAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO;AAChE,IAAAA,QAAO,MAAM,yBAAyB,KAAK;AAC3C,oBAAgB,KAAK,UAAU,OAAO;AACtC,WAAO,EAAE,IAAI,OAAO,OAAO,kBAAkB,OAAO,GAAG;AAAA,EACzD;AACF;AAIA,SAAS,2BAA2B,MAAyB;AAC3D,QAAM,WAAW,KAAK,YAAY;AAClC,SAAO,OAAO,MAAe,QAA4D;AACvF,UAAM,mBAAmB,yBAAyB,UAAU,IAAI;AAChE,QAAI,CAAC,iBAAiB,SAAS;AAC7B,aAAO,oBAAoB;AAAA,QACzB,eAAe;AAAA,QACf,SAAS,qBAAqB,eAAe,iBAAiB,KAAK,CAAC;AAAA,MACtE,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,iBAAiB,KAAK,YAAY;AACnD,QAAI,OAAO,MAAM,2BAA2B;AAAA,MAC1C;AAAA,MACA,WAAW,iBAAiB,KAAK;AAAA,IACnC,CAAC;AACD,aAAS,KAAK,kBAAkB;AAAA,MAC9B,OAAO;AAAA,MACP,gBAAgB,iBAAiB,KAAK,SAAS;AAAA,MAC/C;AAAA,IACF,CAAC;AAED,UAAM,SAAS,MAAM;AAAA,MAAsB;AAAA,MAAkB;AAAA,MAAU,MACrE,oBAAoB,MAAM,iBAAiB,IAAI;AAAA,IACjD;AACA,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,oBAAoB,EAAE,eAAe,YAAY,SAAS,OAAO,MAAM,CAAC;AAAA,IACjF;AAEA,eAAW,QAAQ,OAAO,MAAM,OAAO;AACrC,eAAS,MAAM,kBAAkB;AAAA,QAC/B,OAAO;AAAA,QACP,MAAM,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AACA,aAAS,KAAK,kBAAkB;AAAA,MAC9B,OAAO;AAAA,MACP,UAAU,OAAO,MAAM;AAAA,MACvB,oBAAoB,OAAO,MAAM;AAAA,MACjC,WAAW,OAAO,MAAM,MAAM;AAAA,IAChC,CAAC;AACD,UAAM,OAAO,OAAO;AACpB,WAAO;AAAA,MACL,GAAG,YAAY,KAAK,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,MACpD,mBAAmB;AAAA,IACrB;AAAA,EACF;AACF;AAGO,IAAM,+BAA+B;AAAA,EAC1C,UAAUC,IAAE,OAAO;AAAA,EACnB,UAAU;AAAA,EACV,UAAUA,IAAE,KAAK,CAAC,YAAY,YAAY,WAAW,CAAC;AAAA,EACtD,oBAAoBA,IAAE,OAAO;AAAA,EAC7B,YAAYA,IAAE,OAAO;AAAA,IACnB,SAASA,IAAE,OAAO;AAAA,IAClB,QAAQA,IAAE,OAAO;AAAA,IACjB,SAASA,IAAE,OAAO;AAAA,IAClB,OAAOA,IAAE,OAAO;AAAA,EAClB,CAAC;AAAA,EACD,OAAOA,IAAE;AAAA,IACPA,IAAE,OAAO;AAAA,MACP,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,MACxB,UAAUA,IAAE,KAAK,CAAC,WAAW,UAAU,SAAS,CAAC;AAAA,MACjD,YAAYA,IAAE,OAAO;AAAA,MACrB,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAI;AAAA,MAC9B,WAAWA,IAAE,QAAQ;AAAA,MACrB,OAAOA,IAAE,QAAQ;AAAA,MACjB,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,MACxC,qBAAqBA,IAClB;AAAA,QACCA,IAAE,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH,EACC,SAAS;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EACA,WAAW,oBAAoB,SAAS;AAAA,EACxC,YAAYA,IAAE,OAAO;AAAA,EACrB,eAAeA,IAAE,QAAQ;AAAA,EACzB,qBAAqBA,IAClB,OAAO;AAAA,IACN,mBAAmBA,IAAE,OAAO;AAAA,IAC5B,oBAAoBA,IAAE,OAAO;AAAA,IAC7B,oBAAoBA,IAAE,OAAO;AAAA,IAC7B,QAAQA,IAAE,KAAK,CAAC,MAAM,OAAO,QAAQ,CAAC;AAAA,IACtC,qBAAqBA,IAAE,QAAQ;AAAA,IAC/B,yBAAyBA,IAAE,OAAO;AAAA,IAClC,oBAAoBA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE;AAAA,IACvD,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAI;AAAA,EAChC,CAAC,EACA,SAAS;AACd;AAOO,SAAS,0BAA0B,QAAmB,MAA+B;AAC1F,QAAMD,UAAS,KAAK,UAAU,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrE,QAAM,WAAW,KAAK,YAAY,kBAAkB,MAAM;AAC1D,QAAM,mBAAmB,EAAE,GAAG,MAAM,SAAS;AAC7C,QAAM,aAAa;AAAA,IACjB,UAAUC,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,mBAAmB,EAAE,SAAS,0BAA0B;AAAA,IACxF,WAAWA,IACR,KAAK,CAAC,YAAY,iBAAiB,WAAW,CAAC,EAC/C,SAAS,EACT,SAAS,kDAAkD;AAAA,IAC9D,UAAU,qBAAqB,SAAS,EAAE;AAAA,MACxC;AAAA,IACF;AAAA,IACA,WAAWA,IAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE,SAAS,2BAA2B;AAAA,IACrF,eAAeA,IACZ,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,8EAAyE;AAAA,EACvF;AAEA,QAAM,cACJ;AAKF,QAAM,gBAAgB,oBAAoB,2BAA2B,gBAAgB,GAAG;AAAA,IACtF,UAAU;AAAA,IACV,aAAa,KAAK;AAAA,IAClB,QAAAD;AAAA,EACF,CAAC;AAED,QAAM,YAAY,eAAe,kBAAkB,KAAK,QAAQ;AAChE,QAAM,iBAAiB,oBAAoB,kBAAkB,eAAe;AAAA,IAC1E;AAAA,IACA,QAAAA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA,aAAa;AAAA,MACb,cAAc;AAAA,MACd,aAAa,mBAAmB,gBAAgB;AAAA,IAClD;AAAA,IACA,6BAA6B,gBAAgB,kBAAkB,WAAWA,OAAM;AAAA,EAClF;AACA,EAAAA,QAAO,KAAK,2EAA2E;AACzF;","names":["z","logger","logger","READ_ONLY_TOOLS","AsyncLocalStorage","AsyncLocalStorage","z","logger","err","logger","logger","sanitizeOutput","logger","Anthropic","Anthropic","logger","logger","cliAdapter","randomUUID","randomUUID","z","z","logger","logger","defaultLogger","logger","z","z","z","TaskOutcomeSchema","z","logger","logger","err","logger","logger","logger","logger","z","logger","z","logger","z","z","appendFileSync","readFileSync","writeFileSync","existsSync","logger","existsSync","readFileSync","writeFileSync","appendFileSync","logger","logger","logger","z"]}