@entelligentsia/forgecli 0.6.6 → 0.7.7

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 (187) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +99 -190
  3. package/dist/bin/forge.js +20 -0
  4. package/dist/bin/forge.js.map +1 -1
  5. package/dist/extensions/forgecli/approve.d.ts +24 -0
  6. package/dist/extensions/forgecli/approve.js +202 -0
  7. package/dist/extensions/forgecli/approve.js.map +1 -0
  8. package/dist/extensions/forgecli/audience-gate.d.ts +4 -0
  9. package/dist/extensions/forgecli/audience-gate.js +8 -5
  10. package/dist/extensions/forgecli/audience-gate.js.map +1 -1
  11. package/dist/extensions/forgecli/collate.d.ts +24 -0
  12. package/dist/extensions/forgecli/collate.js +199 -0
  13. package/dist/extensions/forgecli/collate.js.map +1 -0
  14. package/dist/extensions/forgecli/commit.d.ts +24 -0
  15. package/dist/extensions/forgecli/commit.js +202 -0
  16. package/dist/extensions/forgecli/commit.js.map +1 -0
  17. package/dist/extensions/forgecli/fix-bug.d.ts +75 -0
  18. package/dist/extensions/forgecli/fix-bug.js +1133 -0
  19. package/dist/extensions/forgecli/fix-bug.js.map +1 -0
  20. package/dist/extensions/forgecli/forge-commands.js +7 -0
  21. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  22. package/dist/extensions/forgecli/forge-header.js +10 -4
  23. package/dist/extensions/forgecli/forge-header.js.map +1 -1
  24. package/dist/extensions/forgecli/forge-init.js +16 -8
  25. package/dist/extensions/forgecli/forge-init.js.map +1 -1
  26. package/dist/extensions/forgecli/forge-subagent.d.ts +29 -0
  27. package/dist/extensions/forgecli/forge-subagent.js +14 -1
  28. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  29. package/dist/extensions/forgecli/hook-dispatcher.d.ts +53 -1
  30. package/dist/extensions/forgecli/hook-dispatcher.js +47 -1
  31. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  32. package/dist/extensions/forgecli/hooks/post-init-hook.d.ts +15 -0
  33. package/dist/extensions/forgecli/hooks/post-init-hook.js +127 -0
  34. package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -0
  35. package/dist/extensions/forgecli/hooks/post-sprint-hook.d.ts +37 -0
  36. package/dist/extensions/forgecli/hooks/post-sprint-hook.js +166 -0
  37. package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -0
  38. package/dist/extensions/forgecli/index.js +56 -5
  39. package/dist/extensions/forgecli/index.js.map +1 -1
  40. package/dist/extensions/forgecli/review-code.d.ts +24 -0
  41. package/dist/extensions/forgecli/review-code.js +202 -0
  42. package/dist/extensions/forgecli/review-code.js.map +1 -0
  43. package/dist/extensions/forgecli/review-plan.d.ts +24 -0
  44. package/dist/extensions/forgecli/review-plan.js +203 -0
  45. package/dist/extensions/forgecli/review-plan.js.map +1 -0
  46. package/dist/extensions/forgecli/run-sprint.d.ts +18 -0
  47. package/dist/extensions/forgecli/run-sprint.js +33 -1
  48. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  49. package/dist/extensions/forgecli/run-task.d.ts +21 -2
  50. package/dist/extensions/forgecli/run-task.js +33 -9
  51. package/dist/extensions/forgecli/run-task.js.map +1 -1
  52. package/dist/extensions/forgecli/session-registry.d.ts +10 -0
  53. package/dist/extensions/forgecli/session-registry.js +9 -0
  54. package/dist/extensions/forgecli/session-registry.js.map +1 -1
  55. package/dist/extensions/forgecli/validate.d.ts +24 -0
  56. package/dist/extensions/forgecli/validate.js +202 -0
  57. package/dist/extensions/forgecli/validate.js.map +1 -0
  58. package/dist/extensions/forgecli/wf-engine/engine.d.ts +23 -0
  59. package/dist/extensions/forgecli/wf-engine/engine.js +384 -0
  60. package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -0
  61. package/dist/extensions/forgecli/wf-engine/event-parser.d.ts +6 -0
  62. package/dist/extensions/forgecli/wf-engine/event-parser.js +29 -0
  63. package/dist/extensions/forgecli/wf-engine/event-parser.js.map +1 -0
  64. package/dist/extensions/forgecli/wf-engine/id-gen.d.ts +6 -0
  65. package/dist/extensions/forgecli/wf-engine/id-gen.js +17 -0
  66. package/dist/extensions/forgecli/wf-engine/id-gen.js.map +1 -0
  67. package/dist/extensions/forgecli/wf-engine/loader.d.ts +2 -0
  68. package/dist/extensions/forgecli/wf-engine/loader.js +100 -0
  69. package/dist/extensions/forgecli/wf-engine/loader.js.map +1 -0
  70. package/dist/extensions/forgecli/wf-engine/predicate.d.ts +7 -0
  71. package/dist/extensions/forgecli/wf-engine/predicate.js +36 -0
  72. package/dist/extensions/forgecli/wf-engine/predicate.js.map +1 -0
  73. package/dist/extensions/forgecli/wf-engine/prompt-compiler.d.ts +15 -0
  74. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js +23 -0
  75. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js.map +1 -0
  76. package/dist/extensions/forgecli/wf-engine/register.d.ts +9 -0
  77. package/dist/extensions/forgecli/wf-engine/register.js +59 -0
  78. package/dist/extensions/forgecli/wf-engine/register.js.map +1 -0
  79. package/dist/extensions/forgecli/wf-engine/remit-check.d.ts +6 -0
  80. package/dist/extensions/forgecli/wf-engine/remit-check.js +42 -0
  81. package/dist/extensions/forgecli/wf-engine/remit-check.js.map +1 -0
  82. package/dist/extensions/forgecli/wf-engine/state-store.d.ts +13 -0
  83. package/dist/extensions/forgecli/wf-engine/state-store.js +43 -0
  84. package/dist/extensions/forgecli/wf-engine/state-store.js.map +1 -0
  85. package/dist/extensions/forgecli/wf-engine/types.d.ts +66 -0
  86. package/dist/extensions/forgecli/wf-engine/types.js +2 -0
  87. package/dist/extensions/forgecli/wf-engine/types.js.map +1 -0
  88. package/dist/extensions/forgecli/wf-engine/worker.d.ts +11 -0
  89. package/dist/extensions/forgecli/wf-engine/worker.js +50 -0
  90. package/dist/extensions/forgecli/wf-engine/worker.js.map +1 -0
  91. package/dist/forge-payload/.base-pack/workflows/_fragments/context-injection.md +10 -4
  92. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +12 -0
  93. package/dist/forge-payload/.schemas/bug.schema.json +4 -2
  94. package/dist/forge-payload/.schemas/event.schema.json +22 -3
  95. package/dist/forge-payload/commands/add-pipeline.md +342 -0
  96. package/dist/forge-payload/commands/add-task.md +269 -0
  97. package/dist/forge-payload/commands/ask.md +43 -0
  98. package/dist/forge-payload/commands/calibrate.md +356 -0
  99. package/dist/forge-payload/commands/config.md +202 -0
  100. package/dist/forge-payload/commands/enhance.md +38 -0
  101. package/dist/forge-payload/commands/health.md +225 -0
  102. package/dist/forge-payload/commands/init.md +165 -0
  103. package/dist/forge-payload/commands/materialize.md +119 -0
  104. package/dist/forge-payload/commands/migrate.md +160 -0
  105. package/dist/forge-payload/commands/quiz-agent.md +38 -0
  106. package/dist/forge-payload/commands/regenerate.md +673 -0
  107. package/dist/forge-payload/commands/remove.md +174 -0
  108. package/dist/forge-payload/commands/report-bug.md +191 -0
  109. package/dist/forge-payload/commands/store-query.md +73 -0
  110. package/dist/forge-payload/commands/store-repair.md +187 -0
  111. package/dist/forge-payload/commands/update-tools.md +56 -0
  112. package/dist/forge-payload/commands/update.md +1376 -0
  113. package/dist/forge-payload/tools/preflight-gate.cjs +2 -1
  114. package/dist/forge-payload/tools/read-verdict.cjs +41 -8
  115. package/dist/forge-payload/tools/store-cli.cjs +4 -3
  116. package/node_modules/argparse/CHANGELOG.md +216 -0
  117. package/node_modules/argparse/LICENSE +254 -0
  118. package/node_modules/argparse/README.md +84 -0
  119. package/node_modules/argparse/argparse.js +3707 -0
  120. package/node_modules/argparse/lib/sub.js +67 -0
  121. package/node_modules/argparse/lib/textwrap.js +440 -0
  122. package/node_modules/argparse/package.json +31 -0
  123. package/node_modules/cliui/CHANGELOG.md +121 -0
  124. package/node_modules/color-convert/CHANGELOG.md +54 -0
  125. package/node_modules/esprima/ChangeLog +235 -0
  126. package/node_modules/js-yaml/LICENSE +21 -0
  127. package/node_modules/js-yaml/README.md +247 -0
  128. package/node_modules/js-yaml/bin/js-yaml.js +126 -0
  129. package/node_modules/js-yaml/dist/js-yaml.js +3880 -0
  130. package/node_modules/js-yaml/dist/js-yaml.min.js +2 -0
  131. package/node_modules/js-yaml/dist/js-yaml.mjs +3856 -0
  132. package/node_modules/js-yaml/index.js +47 -0
  133. package/node_modules/js-yaml/lib/common.js +59 -0
  134. package/node_modules/js-yaml/lib/dumper.js +965 -0
  135. package/node_modules/js-yaml/lib/exception.js +55 -0
  136. package/node_modules/js-yaml/lib/loader.js +1733 -0
  137. package/node_modules/js-yaml/lib/schema/core.js +11 -0
  138. package/node_modules/js-yaml/lib/schema/default.js +22 -0
  139. package/node_modules/js-yaml/lib/schema/failsafe.js +17 -0
  140. package/node_modules/js-yaml/lib/schema/json.js +19 -0
  141. package/node_modules/js-yaml/lib/schema.js +121 -0
  142. package/node_modules/js-yaml/lib/snippet.js +101 -0
  143. package/node_modules/js-yaml/lib/type/binary.js +125 -0
  144. package/node_modules/js-yaml/lib/type/bool.js +35 -0
  145. package/node_modules/js-yaml/lib/type/float.js +97 -0
  146. package/node_modules/js-yaml/lib/type/int.js +156 -0
  147. package/node_modules/js-yaml/lib/type/map.js +8 -0
  148. package/node_modules/js-yaml/lib/type/merge.js +12 -0
  149. package/node_modules/js-yaml/lib/type/null.js +35 -0
  150. package/node_modules/js-yaml/lib/type/omap.js +44 -0
  151. package/node_modules/js-yaml/lib/type/pairs.js +53 -0
  152. package/node_modules/js-yaml/lib/type/seq.js +8 -0
  153. package/node_modules/js-yaml/lib/type/set.js +29 -0
  154. package/node_modules/js-yaml/lib/type/str.js +8 -0
  155. package/node_modules/js-yaml/lib/type/timestamp.js +88 -0
  156. package/node_modules/js-yaml/lib/type.js +66 -0
  157. package/node_modules/js-yaml/package.json +66 -0
  158. package/node_modules/mz/HISTORY.md +66 -0
  159. package/node_modules/proper-lockfile/CHANGELOG.md +108 -0
  160. package/node_modules/source-map/CHANGELOG.md +301 -0
  161. package/node_modules/thenify/History.md +11 -0
  162. package/node_modules/thenify-all/History.md +11 -0
  163. package/node_modules/y18n/CHANGELOG.md +100 -0
  164. package/node_modules/yargs/CHANGELOG.md +88 -0
  165. package/node_modules/yargs-parser/CHANGELOG.md +263 -0
  166. package/package.json +6 -2
  167. package/themes/forge-matrix.json +89 -0
  168. package/themes/forge-mono.json +86 -0
  169. package/workflows/lead-qualifier/prompts/digest.md +44 -0
  170. package/workflows/lead-qualifier/prompts/draft-outreach.md +44 -0
  171. package/workflows/lead-qualifier/prompts/enrich.md +52 -0
  172. package/workflows/lead-qualifier/prompts/intake.md +48 -0
  173. package/workflows/lead-qualifier/prompts/mark-cold.md +38 -0
  174. package/workflows/lead-qualifier/prompts/score.md +45 -0
  175. package/workflows/lead-qualifier/workflow.yaml +95 -0
  176. package/workflows/research-brief/prompts/brief-synthesize.md +43 -0
  177. package/workflows/research-brief/prompts/intake.md +51 -0
  178. package/workflows/research-brief/prompts/source-critique.md +38 -0
  179. package/workflows/research-brief/prompts/source-score.md +38 -0
  180. package/workflows/research-brief/prompts/source-summarize.md +54 -0
  181. package/workflows/research-brief/workflow.yaml +66 -0
  182. package/dist/extensions/forgecli/session-monitor-widget.d.ts +0 -37
  183. package/dist/extensions/forgecli/session-monitor-widget.js +0 -320
  184. package/dist/extensions/forgecli/session-monitor-widget.js.map +0 -1
  185. package/dist/extensions/forgecli/session-monitor.d.ts +0 -2
  186. package/dist/extensions/forgecli/session-monitor.js +0 -135
  187. package/dist/extensions/forgecli/session-monitor.js.map +0 -1
@@ -0,0 +1,202 @@
1
+ // forge:validate — native kickoff handler (FORGE-S21-T10).
2
+ //
3
+ // Replaces the auto-generated stub previously installed by
4
+ // registerAllForgeCommands (forge-commands.ts). Kickoff Shim archetype
5
+ // (Pack-04 + Pack-06): single LLM handoff in current context, no fork.
6
+ //
7
+ // Note: The materialized workflow (validate_task.md) declares
8
+ // `audience: subagent` — advisory only. Users may invoke this command
9
+ // manually from the CLI; assertAudience never refuses subagent-audience
10
+ // workflows. Orchestrator chains still dispatch via runForgeSubagent
11
+ // directly and do NOT route through this handler.
12
+ //
13
+ // Iron Laws:
14
+ // IL1 — code only under forge-cli/src/extensions/forgecli/.
15
+ // IL4 — no JSON.stringify-into-subagent dispatch.
16
+ // IL6 — no shell-string interpolation; no spawn calls here.
17
+ // IL7 — every failure path emits ctx.ui.notify and returns; no silent
18
+ // continuation.
19
+ import * as fs from "node:fs";
20
+ import * as path from "node:path";
21
+ import { assertAudience } from "./audience-gate.js";
22
+ import { sendKickoff } from "./kickoff.js";
23
+ import { loadPersona, PersonaSkillLoaderError } from "./loaders/persona-skill-loader.js";
24
+ import { loadWorkflow, WorkflowLoaderError } from "./loaders/workflow-loader.js";
25
+ export function parseValidateArgs(rawArgs, cwd) {
26
+ const trimmed = (rawArgs ?? "").trim();
27
+ if (trimmed === "") {
28
+ return { mode: "empty", taskRef: "", sourceLabel: "(no input — qa-engineer infers task from store/context)" };
29
+ }
30
+ if (trimmed.startsWith("@")) {
31
+ const ref = trimmed.slice(1).trim();
32
+ const filePath = path.isAbsolute(ref) ? ref : path.resolve(cwd, ref);
33
+ const seed = fs.readFileSync(filePath, "utf8");
34
+ return { mode: "file", taskRef: seed, sourceLabel: `(seed from file: ${ref})` };
35
+ }
36
+ return { mode: "text", taskRef: trimmed, sourceLabel: "(seed from inline text)" };
37
+ }
38
+ // Frontmatter persona extraction (permissive) ------------------------------
39
+ export function extractPersonaNames(workflowMd) {
40
+ const lines = workflowMd.split(/\r?\n/);
41
+ if (lines.length === 0 || lines[0] !== "---")
42
+ return [];
43
+ let inside = false;
44
+ let depsBlock = false;
45
+ for (let i = 0; i < lines.length; i++) {
46
+ const line = lines[i];
47
+ if (i === 0 && line === "---") {
48
+ inside = true;
49
+ continue;
50
+ }
51
+ if (!inside)
52
+ break;
53
+ if (line === "---")
54
+ break;
55
+ if (/^deps\s*:\s*$/.test(line)) {
56
+ depsBlock = true;
57
+ continue;
58
+ }
59
+ const m = /^\s*personas\s*:\s*\[([^\]]*)\]\s*$/.exec(line);
60
+ if (m && (depsBlock || /^\s/.test(line))) {
61
+ return m[1]
62
+ .split(",")
63
+ .map((s) => s.trim().replace(/^["']|["']$/g, ""))
64
+ .filter((s) => s.length > 0);
65
+ }
66
+ if (depsBlock && /^[A-Za-z0-9_-]+\s*:/.test(line) && !/^\s/.test(line)) {
67
+ depsBlock = false;
68
+ }
69
+ }
70
+ return [];
71
+ }
72
+ export function checkMaterialization(workflowPath, workflowMd) {
73
+ const missing = [];
74
+ if (!workflowMd.includes("Store-Write Verification")) {
75
+ missing.push("Store-Write Verification");
76
+ }
77
+ if (!workflowMd.includes("Iron Laws")) {
78
+ missing.push("Iron Laws");
79
+ }
80
+ if (!workflowMd.includes("forge_store")) {
81
+ missing.push("forge_store");
82
+ }
83
+ const personas = extractPersonaNames(workflowMd);
84
+ if (personas.length === 0) {
85
+ missing.push("deps.personas: declaration");
86
+ }
87
+ else {
88
+ const bodyStart = (() => {
89
+ if (!workflowMd.startsWith("---\n") && !workflowMd.startsWith("---\r\n"))
90
+ return 0;
91
+ const re = /\r?\n---\r?\n/;
92
+ const m = re.exec(workflowMd);
93
+ return m ? m.index + m[0].length : 0;
94
+ })();
95
+ const body = workflowMd.slice(bodyStart);
96
+ const anyHit = personas.some((name) => {
97
+ if (!name)
98
+ return false;
99
+ const tokenRegex = new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`);
100
+ return body.includes(`${name}.md`) || tokenRegex.test(body);
101
+ });
102
+ if (!anyHit) {
103
+ missing.push(`persona file path (${personas.join(", ")})`);
104
+ }
105
+ }
106
+ void workflowPath;
107
+ return { ok: missing.length === 0, missing };
108
+ }
109
+ export function composeKickoff(opts) {
110
+ const { workflowMd, personaIdentity, parsed } = opts;
111
+ const sections = ["# /forge:validate", ""];
112
+ if (personaIdentity.trim().length > 0) {
113
+ sections.push(personaIdentity.trim(), "");
114
+ }
115
+ sections.push("## Dispatch", "", "Run the workflow below. Specifically:", "", "1. Read the implementation artifacts for `engineering/sprints/<SPRINT_ID>/<TASK_ID>/` (PROGRESS.md, CODE_REVIEW.md).", "2. Query the store for the task and its sprint/feature context via `forge_store_query` — do NOT raw-read `.forge/store/`.", "3. Follow the workflow Algorithm verbatim: validate the implementation against acceptance criteria, run test commands, verify completeness.", "4. Write `VALIDATION_REPORT.md` and `VALIDATION-SUMMARY.json` to the task directory using the `write` tool.", "5. Update task status by calling the `forge_store` MCP tool: `{command:'update-status', args:['task','<TASK_ID>','status','<new-status>']}`. Never raw-write `.forge/store/`. Do NOT bash-shell `forge store ...`.", "6. Honour Pack-06 Read/Write/Ask/Store discipline: writes go via the `forge_store` MCP tool; in-conversation clarifications use `forge_ask_user`.");
116
+ sections.push("", "---", "", "## Workflow", "", workflowMd.trim(), "", "---");
117
+ if (parsed.mode === "empty") {
118
+ sections.push("", "## Input", "", "(no seed — infer task from sprint context and store)");
119
+ }
120
+ else {
121
+ sections.push("", `## Input — ${parsed.sourceLabel}`, "", parsed.taskRef.trim());
122
+ }
123
+ return sections.join("\n");
124
+ }
125
+ // Registration -------------------------------------------------------------
126
+ const WORKFLOW_REL_PATH = path.join(".forge", "workflows", "validate_task.md");
127
+ export function registerValidate(pi, options = {}) {
128
+ pi.registerCommand("forge:validate", {
129
+ description: "Run the validate-task workflow for a Forge task. " +
130
+ "Usage: /forge:validate [@<file> | <free-form text>]. " +
131
+ "Note: this workflow is subagent-only; standalone invocations are refused. " +
132
+ "Orchestrator chains dispatch directly via runForgeSubagent.",
133
+ async handler(args, ctx) {
134
+ const cwd = options.cwd ?? process.cwd();
135
+ const workflowPath = path.join(cwd, WORKFLOW_REL_PATH);
136
+ let workflowMd;
137
+ let workflowAudience;
138
+ try {
139
+ const loaded = loadWorkflow(workflowPath);
140
+ workflowMd = loaded.rawMarkdown;
141
+ workflowAudience = loaded.audience;
142
+ }
143
+ catch (err) {
144
+ if (err instanceof WorkflowLoaderError) {
145
+ if (err.code === "missing_file") {
146
+ ctx.ui.notify(`× forge:validate — workflow not found at ${WORKFLOW_REL_PATH}; run /forge:init or /forge:regenerate first.`, "error");
147
+ }
148
+ else {
149
+ ctx.ui.notify(`× forge:validate — workflow load failed (${err.code}): ${err.message}`, "error");
150
+ }
151
+ return;
152
+ }
153
+ const e = err;
154
+ ctx.ui.notify(`× forge:validate — failed to read workflow: ${e.message ?? "unknown"}`, "error");
155
+ return;
156
+ }
157
+ let parsed;
158
+ try {
159
+ parsed = parseValidateArgs(args, cwd);
160
+ }
161
+ catch (err) {
162
+ const e = err;
163
+ ctx.ui.notify(`× forge:validate — failed to read seed: ${e.message ?? "unknown"}`, "error");
164
+ return;
165
+ }
166
+ const check = checkMaterialization(workflowPath, workflowMd);
167
+ if (!check.ok) {
168
+ for (const marker of check.missing) {
169
+ ctx.ui.notify(`× workflow regression: ${marker} not found in ${workflowPath}`, "error");
170
+ }
171
+ return;
172
+ }
173
+ const personas = extractPersonaNames(workflowMd);
174
+ let personaIdentity = "";
175
+ if (personas.length > 0) {
176
+ try {
177
+ const persona = loadPersona(personas[0], { cwd });
178
+ personaIdentity = persona.identity;
179
+ }
180
+ catch (err) {
181
+ if (err instanceof PersonaSkillLoaderError) {
182
+ ctx.ui.notify(`× forge:validate — persona '${personas[0]}' load failed (${err.code}): ${err.message}`, "error");
183
+ return;
184
+ }
185
+ const e = err;
186
+ ctx.ui.notify(`× forge:validate — persona load error: ${e.message ?? "unknown"}`, "error");
187
+ return;
188
+ }
189
+ }
190
+ if (!assertAudience({ workflowName: "validate_task", audience: workflowAudience }, ctx)) {
191
+ return;
192
+ }
193
+ const kickoff = composeKickoff({
194
+ workflowMd,
195
+ personaIdentity,
196
+ parsed,
197
+ });
198
+ sendKickoff(pi, kickoff);
199
+ },
200
+ });
201
+ }
202
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type WorkerResult } from "./worker.js";
2
+ import type { SessionRegistry } from "../session-registry.js";
3
+ export interface RunWorkflowOptions {
4
+ workflowsDir: string;
5
+ workflowId: string;
6
+ cwd: string;
7
+ entryPrompt: string;
8
+ notify?: (line: string) => void;
9
+ workerFn?: (opts: {
10
+ compiledPrompt: string;
11
+ cwd: string;
12
+ onEvent?: (e: unknown) => void;
13
+ }) => Promise<WorkerResult>;
14
+ /** Optional live monitor sink. Receives startSession/startPhase/turn/tool/completePhase/completeSession calls. */
15
+ registry?: SessionRegistry;
16
+ }
17
+ export interface RunWorkflowResult {
18
+ status: "completed" | "halted";
19
+ instanceId: string;
20
+ workingDir: string;
21
+ haltReason?: string;
22
+ }
23
+ export declare function runWorkflow(opts: RunWorkflowOptions): Promise<RunWorkflowResult>;
@@ -0,0 +1,384 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { loadWorkflow } from "./loader.js";
4
+ import { makeInstanceId, makeNodeExecId, makeEventId } from "./id-gen.js";
5
+ import { parseEventsBlock } from "./event-parser.js";
6
+ import { checkRemit } from "./remit-check.js";
7
+ import { StateStore } from "./state-store.js";
8
+ import { compilePrompt } from "./prompt-compiler.js";
9
+ import { dispatchLlmWorker } from "./worker.js";
10
+ import { evalPredicate } from "./predicate.js";
11
+ import { extractTurnPreview } from "../run-task.js";
12
+ export async function runWorkflow(opts) {
13
+ const notify = opts.notify ?? (() => { });
14
+ const workflowDir = path.join(opts.workflowsDir, opts.workflowId);
15
+ const wf = loadWorkflow(workflowDir);
16
+ const instanceId = makeInstanceId(wf.id);
17
+ const workingDir = path.join(opts.cwd, ".forge-wf", "runs", instanceId);
18
+ const store = new StateStore(workingDir);
19
+ const firstNode = wf.nodes[0];
20
+ store.initialState({
21
+ cursor: firstNode.id,
22
+ loopCursor: {},
23
+ entryPrompt: opts.entryPrompt,
24
+ });
25
+ fs.writeFileSync(path.join(workingDir, "manifest.json"), JSON.stringify({
26
+ workflowId: wf.id,
27
+ version: wf.version,
28
+ instanceId,
29
+ startedAt: new Date().toISOString(),
30
+ entryPrompt: opts.entryPrompt,
31
+ }, null, 2));
32
+ store.appendEvents([{
33
+ eventId: makeEventId(instanceId, 0, "workflow.started"),
34
+ nodeExecId: instanceId,
35
+ type: "workflow.started",
36
+ ts: new Date().toISOString(),
37
+ workflowId: wf.id,
38
+ instanceId,
39
+ }]);
40
+ notify(`→ workflow ${wf.id} started: ${instanceId}`);
41
+ const registry = opts.registry;
42
+ registry?.startSession(instanceId);
43
+ const workerFn = opts.workerFn ?? dispatchLlmWorker;
44
+ let phaseIndex = 0;
45
+ // Build group-head lookup: group name -> head node id
46
+ const groupHeads = new Map();
47
+ for (const n of wf.nodes) {
48
+ if (n.loop?.group && n.loop?.head)
49
+ groupHeads.set(n.loop.group, n.id);
50
+ }
51
+ // Main loop
52
+ while (true) {
53
+ const state = store.readState();
54
+ const cursor = state.cursor;
55
+ const node = wf.nodes.find(n => n.id === cursor);
56
+ if (!node) {
57
+ throw new Error(`cursor references unknown node: ${cursor}`);
58
+ }
59
+ // Resolve loop context
60
+ let loopCtx;
61
+ if (node.loop) {
62
+ const group = node.loop.group;
63
+ const cursorKey = group ?? node.id;
64
+ const isHead = !group || node.loop.head === true;
65
+ const collection = resolvePath(state, node.loop.over);
66
+ if (!Array.isArray(collection)) {
67
+ throw new Error(`loop.over '${node.loop.over}' did not resolve to an array`);
68
+ }
69
+ const iter = state.loopCursor[cursorKey] ?? 0;
70
+ if (isHead && iter >= collection.length) {
71
+ // Loop exhausted — for grouped loops, use on:exhausted edge; for non-grouped, use advance: loop-or-next
72
+ let exitTarget;
73
+ if (group) {
74
+ const exitEdge = wf.edges.find(e => e.from === node.id && e.on === "exhausted");
75
+ exitTarget = exitEdge?.to;
76
+ }
77
+ else {
78
+ const exitEdge = wf.edges.find(e => e.from === node.id && e.advance === "loop-or-next");
79
+ exitTarget = exitEdge?.next;
80
+ }
81
+ if (!exitTarget) {
82
+ throw new Error(`loop exhausted but no exit target from ${node.id}`);
83
+ }
84
+ state.cursor = exitTarget;
85
+ store.writeState(state);
86
+ continue;
87
+ }
88
+ const item = collection[iter];
89
+ const itemId = item.id ?? String(iter);
90
+ loopCtx = { iter, itemId, item, cursorKey, group };
91
+ }
92
+ const nodeExecId = makeNodeExecId(instanceId, node.id, loopCtx);
93
+ store.appendEvents([{
94
+ eventId: makeEventId(nodeExecId, 0, "node.dispatched"),
95
+ nodeExecId,
96
+ type: "node.dispatched",
97
+ ts: new Date().toISOString(),
98
+ }]);
99
+ const role = loopCtx ? `${node.id}#${loopCtx.iter}` : node.id;
100
+ registry?.startPhase(instanceId, role, phaseIndex++);
101
+ registry?.appendTail(instanceId, role, `─── node ${node.id}${loopCtx ? ` [iter ${loopCtx.iter}, item ${loopCtx.itemId}]` : ""} begin ───`);
102
+ notify(`→ node ${node.id}${loopCtx ? ` [iter ${loopCtx.iter}]` : ""}`);
103
+ const promptFile = path.join(workflowDir, node.prompt);
104
+ const compiled = compilePrompt(promptFile, {
105
+ wf: { instanceId, workingDir },
106
+ node: { execId: nodeExecId, id: node.id },
107
+ state,
108
+ loop: loopCtx ? { item: loopCtx.item } : undefined,
109
+ });
110
+ // Capture first + last meaningful subagent line for the main-viewport narrative.
111
+ // Engine emits `↪ <role>: "<first line>"` on the first non-empty preview and
112
+ // `↩ <role>: "<last line>"` after terminal commit — so the user can watch the
113
+ // story of each phase scroll past chip[0]/main without expanding any chip.
114
+ let firstPreview;
115
+ let lastPreview;
116
+ const argsByCallId = new Map();
117
+ const onEvent = (event) => {
118
+ const e = event;
119
+ switch (e.type) {
120
+ case "turn_start":
121
+ registry?.bumpTurn(instanceId);
122
+ break;
123
+ case "turn_end": {
124
+ const preview = extractTurnPreview(e.message);
125
+ if (preview) {
126
+ if (firstPreview === undefined) {
127
+ firstPreview = preview;
128
+ notify(` ↪ ${role}: "${preview}"`);
129
+ }
130
+ lastPreview = preview;
131
+ registry?.setTurnPreview(instanceId, preview);
132
+ registry?.appendTail(instanceId, role, `» "${preview}"`);
133
+ }
134
+ break;
135
+ }
136
+ case "tool_execution_start": {
137
+ const toolName = e.toolName;
138
+ const callId = e.toolCallId;
139
+ argsByCallId.set(callId, e.args);
140
+ registry?.recordToolStart(instanceId, callId, toolName, e.args);
141
+ registry?.appendTail(instanceId, role, `→ ${toolName}`);
142
+ break;
143
+ }
144
+ case "tool_execution_end": {
145
+ const toolName = e.toolName;
146
+ const callId = e.toolCallId;
147
+ argsByCallId.delete(callId);
148
+ registry?.recordToolEnd(instanceId, callId, toolName, !!e.isError, e.result);
149
+ registry?.appendTail(instanceId, role, e.isError ? `⚠ ${toolName} failed` : `← ${toolName} ok`, e.isError ? { warning: true } : undefined);
150
+ break;
151
+ }
152
+ }
153
+ };
154
+ const result = await workerFn({ compiledPrompt: compiled, cwd: opts.cwd, onEvent });
155
+ store.writeNodeArchive(nodeExecId, {
156
+ "prompt.compiled.md": compiled,
157
+ "response.txt": result.responseText,
158
+ });
159
+ if (result.exitCode !== 0) {
160
+ const haltEvent = {
161
+ eventId: makeEventId(nodeExecId, 1, "failure"),
162
+ nodeExecId,
163
+ type: "failure",
164
+ ts: new Date().toISOString(),
165
+ reason: "worker-error",
166
+ details: result.errorMessage ?? "unknown",
167
+ };
168
+ store.appendEvents([haltEvent]);
169
+ store.appendEvents([{
170
+ eventId: makeEventId(instanceId, 999, "workflow.halted"),
171
+ nodeExecId: instanceId,
172
+ type: "workflow.halted",
173
+ ts: new Date().toISOString(),
174
+ reason: `worker-error in ${node.id}`,
175
+ }]);
176
+ notify(`× workflow halted: worker error in ${node.id}`);
177
+ registry?.appendTail(instanceId, role, `⚠ worker error: ${result.errorMessage ?? "unknown"}`, { warning: true });
178
+ registry?.completePhase(instanceId, role, "failed");
179
+ registry?.completeSession(instanceId, "failed");
180
+ return { status: "halted", instanceId, workingDir, haltReason: `worker-error in ${node.id}` };
181
+ }
182
+ // Parse emitted events
183
+ let parsed;
184
+ try {
185
+ parsed = parseEventsBlock(result.responseText);
186
+ }
187
+ catch (err) {
188
+ const haltReason = `events-block-parse-error in ${node.id}: ${err.message}`;
189
+ store.appendEvents([{
190
+ eventId: makeEventId(instanceId, 999, "workflow.halted"),
191
+ nodeExecId: instanceId,
192
+ type: "workflow.halted",
193
+ ts: new Date().toISOString(),
194
+ reason: haltReason,
195
+ }]);
196
+ notify(`× workflow halted: ${haltReason}`);
197
+ registry?.appendTail(instanceId, role, `⚠ ${haltReason}`, { warning: true });
198
+ registry?.completePhase(instanceId, role, "failed");
199
+ registry?.completeSession(instanceId, "failed");
200
+ return { status: "halted", instanceId, workingDir, haltReason };
201
+ }
202
+ // Stamp engine-side fields on emitted events
203
+ const stamped = parsed.events.map((e, i) => ({
204
+ ...e,
205
+ eventId: e.eventId ?? makeEventId(nodeExecId, i + 10, e.type),
206
+ nodeExecId: e.nodeExecId ?? nodeExecId,
207
+ ts: e.ts ?? new Date().toISOString(),
208
+ }));
209
+ fs.writeFileSync(path.join(workingDir, "nodes", nodeExecId, "events.emitted.jsonl"), stamped.map(e => JSON.stringify(e)).join("\n") + "\n");
210
+ // Remit check
211
+ const remit = checkRemit(stamped, node, loopCtx?.itemId);
212
+ if (!remit.ok) {
213
+ const haltEvent = {
214
+ eventId: makeEventId(nodeExecId, 998, "node.remit-violation"),
215
+ nodeExecId,
216
+ type: "node.remit-violation",
217
+ ts: new Date().toISOString(),
218
+ reason: "remit-violation",
219
+ details: remit.violations.join("; "),
220
+ };
221
+ store.appendEvents([haltEvent]);
222
+ store.appendEvents([{
223
+ eventId: makeEventId(instanceId, 999, "workflow.halted"),
224
+ nodeExecId: instanceId,
225
+ type: "workflow.halted",
226
+ ts: new Date().toISOString(),
227
+ reason: `remit-violation in ${node.id}`,
228
+ }]);
229
+ notify(`× workflow halted: remit-violation in ${node.id} — ${remit.violations.join("; ")}`);
230
+ registry?.appendTail(instanceId, role, `⚠ remit-violation: ${remit.violations.join("; ")}`, { warning: true });
231
+ registry?.completePhase(instanceId, role, "failed");
232
+ registry?.completeSession(instanceId, "failed");
233
+ return { status: "halted", instanceId, workingDir, haltReason: `remit-violation in ${node.id}` };
234
+ }
235
+ // Commit emitted events to log
236
+ store.appendEvents(stamped);
237
+ // Apply terminal event payload
238
+ const terminal = stamped.find(e => e.type === "success" || e.type === "failure");
239
+ if (terminal.type === "success") {
240
+ if (terminal.writes?.state) {
241
+ const updated = { ...state };
242
+ for (const [key, value] of Object.entries(terminal.writes.state)) {
243
+ setPath(updated, key, value);
244
+ }
245
+ store.writeState(updated);
246
+ }
247
+ if (terminal.writes?.artifact) {
248
+ store.writeArtifact(terminal.writes.artifact.path, terminal.writes.artifact.content);
249
+ }
250
+ }
251
+ store.appendEvents([{
252
+ eventId: makeEventId(nodeExecId, 999, "node.committed"),
253
+ nodeExecId,
254
+ type: "node.committed",
255
+ ts: new Date().toISOString(),
256
+ }]);
257
+ notify(`✓ node ${node.id}${loopCtx ? ` [iter ${loopCtx.iter}]` : ""} — ${terminal.type}`);
258
+ if (lastPreview && lastPreview !== firstPreview)
259
+ notify(` ↩ ${role}: "${lastPreview}"`);
260
+ if (terminal.summary) {
261
+ notify(` ◆ ${terminal.summary}`);
262
+ registry?.appendTail(instanceId, role, `✓ ${terminal.summary}`);
263
+ }
264
+ registry?.completePhase(instanceId, role, terminal.type === "success" ? "completed" : "failed");
265
+ // Loop iter advance OR cursor advance — first matching edge wins (conditional edges evaluated in YAML order)
266
+ const onKind = terminal.type === "success" ? "success" : "failure";
267
+ const candidates = wf.edges.filter(e => e.from === node.id && e.on === onKind);
268
+ let edge;
269
+ const postState = store.readState(); // reflects state writes just applied
270
+ for (const e of candidates) {
271
+ if (!e.when) {
272
+ edge = e;
273
+ break;
274
+ }
275
+ try {
276
+ if (evalPredicate(e.when, { state: postState, loop: loopCtx ? { item: loopCtx.item } : undefined })) {
277
+ edge = e;
278
+ break;
279
+ }
280
+ }
281
+ catch (err) {
282
+ const haltReason = `predicate-error in ${node.id} '${e.when}': ${err.message}`;
283
+ store.appendEvents([{
284
+ eventId: makeEventId(instanceId, 999, "workflow.halted"),
285
+ nodeExecId: instanceId,
286
+ type: "workflow.halted",
287
+ ts: new Date().toISOString(),
288
+ reason: haltReason,
289
+ }]);
290
+ notify(`× workflow halted: ${haltReason}`);
291
+ registry?.completeSession(instanceId, "failed");
292
+ return { status: "halted", instanceId, workingDir, haltReason };
293
+ }
294
+ }
295
+ if (!edge) {
296
+ throw new Error(`no matching edge from ${node.id} on ${onKind}`);
297
+ }
298
+ if (edge.terminal === "complete") {
299
+ store.appendEvents([{
300
+ eventId: makeEventId(instanceId, 999, "workflow.completed"),
301
+ nodeExecId: instanceId,
302
+ type: "workflow.completed",
303
+ ts: new Date().toISOString(),
304
+ }]);
305
+ notify(`✓ workflow ${wf.id} complete: ${instanceId}`);
306
+ registry?.completeSession(instanceId, "completed");
307
+ return { status: "completed", instanceId, workingDir };
308
+ }
309
+ if (edge.halt) {
310
+ store.appendEvents([{
311
+ eventId: makeEventId(instanceId, 999, "workflow.halted"),
312
+ nodeExecId: instanceId,
313
+ type: "workflow.halted",
314
+ ts: new Date().toISOString(),
315
+ reason: edge.halt,
316
+ }]);
317
+ notify(`× workflow halted: ${edge.halt}`);
318
+ registry?.completeSession(instanceId, "failed");
319
+ return { status: "halted", instanceId, workingDir, haltReason: edge.halt };
320
+ }
321
+ if (edge.advance === "loop-or-next") {
322
+ const newState = store.readState();
323
+ const cursorKey = loopCtx?.cursorKey ?? node.id;
324
+ newState.loopCursor[cursorKey] = (newState.loopCursor[cursorKey] ?? 0) + 1;
325
+ if (loopCtx?.group) {
326
+ const head = groupHeads.get(loopCtx.group);
327
+ if (!head)
328
+ throw new Error(`group ${loopCtx.group} has no head`);
329
+ newState.cursor = head;
330
+ }
331
+ store.writeState(newState);
332
+ continue;
333
+ }
334
+ if (edge.to) {
335
+ const newState = store.readState();
336
+ newState.cursor = edge.to;
337
+ store.writeState(newState);
338
+ continue;
339
+ }
340
+ throw new Error(`edge from ${node.id} has no resolvable continuation`);
341
+ }
342
+ }
343
+ function resolvePath(obj, dotted) {
344
+ const parts = dotted.split(".");
345
+ let cur = obj;
346
+ for (const p of parts) {
347
+ if (cur === null || typeof cur !== "object")
348
+ return undefined;
349
+ cur = cur[p];
350
+ }
351
+ return cur;
352
+ }
353
+ function setPath(obj, dotted, value) {
354
+ const parts = dotted.split(".");
355
+ let cur = obj;
356
+ for (let i = 0; i < parts.length - 1; i++) {
357
+ const p = parts[i];
358
+ if (Array.isArray(cur)) {
359
+ // Navigate into array by matching item.id — avoids setting named properties
360
+ // on the Array object (which JSON.stringify drops silently, FORGE-BUG-033).
361
+ const arr = cur;
362
+ let item = arr.find(el => String(el.id) === p);
363
+ if (!item) {
364
+ item = { id: p };
365
+ arr.push(item);
366
+ }
367
+ cur = item;
368
+ }
369
+ else if (cur !== null && typeof cur === "object") {
370
+ const rec = cur;
371
+ if (typeof rec[p] !== "object" || rec[p] === null)
372
+ rec[p] = {};
373
+ cur = rec[p];
374
+ }
375
+ else {
376
+ throw new Error(`setPath: cannot traverse into ${typeof cur} at segment '${p}' (path: ${dotted})`);
377
+ }
378
+ }
379
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) {
380
+ throw new Error(`setPath: terminal position is not an object (path: ${dotted})`);
381
+ }
382
+ cur[parts[parts.length - 1]] = value;
383
+ }
384
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/wf-engine/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAqB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAoBpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAwB;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAErC,MAAM,UAAU,GAAG,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9B,KAAK,CAAC,YAAY,CAAC;QACjB,MAAM,EAAO,SAAS,CAAC,EAAE;QACzB,UAAU,EAAG,EAAE;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CAAC;IAEH,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,EACtC,IAAI,CAAC,SAAS,CAAC;QACb,UAAU,EAAE,EAAE,CAAC,EAAE;QACjB,OAAO,EAAK,EAAE,CAAC,OAAO;QACtB,UAAU;QACV,SAAS,EAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,EAAE,IAAI,EAAE,CAAC,CAAC,CACZ,CAAC;IAEF,KAAK,CAAC,YAAY,CAAC,CAAC;YAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,kBAAkB,CAAC;YAC1D,UAAU,EAAE,UAAU;YACtB,IAAI,EAAQ,kBAAkB;YAC9B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,UAAU,EAAE,EAAE,CAAC,EAAE;YACjB,UAAU;SACX,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,aAAa,UAAU,EAAE,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACpD,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,sDAAsD;IACtD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI;YAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,YAAY;IACZ,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,uBAAuB;QACvB,IAAI,OAAuG,CAAC;QAC5G,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAC9B,MAAM,SAAS,GAAG,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;YACjD,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAsC,CAAC;YAC3F,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,IAAI,+BAA+B,CAAC,CAAC;YAC/E,CAAC;YACD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC9C,IAAI,MAAM,IAAI,IAAI,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACxC,wGAAwG;gBACxG,IAAI,UAA8B,CAAC;gBACnC,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;oBAChF,UAAU,GAAG,QAAQ,EAAE,EAAE,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,cAAc,CAAC,CAAC;oBACxF,UAAU,GAAG,QAAQ,EAAE,IAAI,CAAC;gBAC9B,CAAC;gBACD,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvE,CAAC;gBACD,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;gBAC1B,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAI,IAAI,CAAC,EAAa,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;YACnD,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhE,KAAK,CAAC,YAAY,CAAC,CAAC;gBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,iBAAiB,CAAC;gBACzD,UAAU;gBACV,IAAI,EAAQ,iBAAiB;gBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC,CAAC,CAAC,CAAC;QAEJ,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,YAAY,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,UAAU,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QAE3I,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEvE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,EAAE;YACzC,EAAE,EAAK,EAAE,UAAU,EAAE,UAAU,EAAE;YACjC,IAAI,EAAG,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YAC1C,KAAK;YACL,IAAI,EAAG,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;SACpD,CAAC,CAAC;QAEH,iFAAiF;QACjF,6EAA6E;QAC7E,8EAA8E;QAC9E,2EAA2E;QAC3E,IAAI,YAAgC,CAAC;QACrC,IAAI,WAAgC,CAAC;QAErC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAmB,CAAC;QAChD,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,KAA+C,CAAC;YAC1D,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;gBACf,KAAK,YAAY;oBACf,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAC/B,MAAM;gBACR,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,OAAO,GAAG,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;oBAC9C,IAAI,OAAO,EAAE,CAAC;wBACZ,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;4BAC/B,YAAY,GAAG,OAAO,CAAC;4BACvB,MAAM,CAAC,OAAO,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;wBACtC,CAAC;wBACD,WAAW,GAAG,OAAO,CAAC;wBACtB,QAAQ,EAAE,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;wBAC9C,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,OAAO,GAAG,CAAC,CAAC;oBAC3D,CAAC;oBACD,MAAM;gBACR,CAAC;gBACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;oBAC5B,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAkB,CAAC;oBACtC,MAAM,MAAM,GAAG,CAAC,CAAC,UAAoB,CAAC;oBACtC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;oBACjC,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;oBAChE,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;oBACxD,MAAM;gBACR,CAAC;gBACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;oBAC1B,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAkB,CAAC;oBACtC,MAAM,MAAM,GAAG,CAAC,CAAC,UAAoB,CAAC;oBACtC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC5B,QAAQ,EAAE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC7E,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,KAAK,EAC5F,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBAC7C,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE;YACjC,oBAAoB,EAAE,QAAQ;YAC9B,cAAc,EAAQ,MAAM,CAAC,YAAY;SAC1C,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAU;gBACvB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,SAAS,CAAC;gBACjD,UAAU;gBACV,IAAI,EAAQ,SAAS;gBACrB,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,MAAM,EAAM,cAAc;gBAC1B,OAAO,EAAK,MAAM,CAAC,YAAY,IAAI,SAAS;aAC7C,CAAC;YACF,KAAK,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YAChC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC;oBAC3D,UAAU,EAAE,UAAU;oBACtB,IAAI,EAAQ,iBAAiB;oBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpC,MAAM,EAAM,mBAAmB,IAAI,CAAC,EAAE,EAAE;iBACzC,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,sCAAsC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACxD,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,mBAAmB,MAAM,CAAC,YAAY,IAAI,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACjH,QAAQ,EAAE,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpD,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;QAChG,CAAC;QAED,uBAAuB;QACvB,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,+BAA+B,IAAI,CAAC,EAAE,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC;YACvF,KAAK,CAAC,YAAY,CAAC,CAAC;oBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC;oBAC3D,UAAU,EAAE,UAAU;oBACtB,IAAI,EAAQ,iBAAiB;oBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpC,MAAM,EAAM,UAAU;iBACvB,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;YAC3C,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7E,QAAQ,EAAE,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpD,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;QAClE,CAAC;QAED,6CAA6C;QAC7C,MAAM,OAAO,GAAY,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC;YACJ,OAAO,EAAK,CAAC,CAAC,OAAO,IAAO,WAAW,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;YACnE,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,UAAU;YACtC,EAAE,EAAU,CAAC,CAAC,EAAE,IAAY,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrD,CAAC,CAAC,CAAC;QAEJ,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,sBAAsB,CAAC,EAClE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CACtD,CAAC;QAEF,cAAc;QACd,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,SAAS,GAAU;gBACvB,OAAO,EAAO,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,sBAAsB,CAAC;gBAClE,UAAU;gBACV,IAAI,EAAU,sBAAsB;gBACpC,EAAE,EAAY,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACtC,MAAM,EAAQ,iBAAiB;gBAC/B,OAAO,EAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;aAC1C,CAAC;YACF,KAAK,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YAChC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC;oBAC3D,UAAU,EAAE,UAAU;oBACtB,IAAI,EAAQ,iBAAiB;oBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpC,MAAM,EAAM,sBAAsB,IAAI,CAAC,EAAE,EAAE;iBAC5C,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,yCAAyC,IAAI,CAAC,EAAE,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5F,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,sBAAsB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/G,QAAQ,EAAE,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpD,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,sBAAsB,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;QACnG,CAAC;QAED,+BAA+B;QAC/B,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAE5B,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAE,CAAC;QAElF,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;gBAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC/B,CAAC;gBACD,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;gBAC9B,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;gBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,gBAAgB,CAAC;gBAC1D,UAAU;gBACV,IAAI,EAAQ,gBAAgB;gBAC5B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC,CAAC,CAAC,CAAC;QAEJ,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1F,IAAI,WAAW,IAAI,WAAW,KAAK,YAAY;YAAE,MAAM,CAAC,OAAO,IAAI,MAAM,WAAW,GAAG,CAAC,CAAC;QACzF,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;YAClC,QAAQ,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,QAAQ,EAAE,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEhG,6GAA6G;QAC7G,MAAM,MAAM,GAA0B,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QAC/E,IAAI,IAAyB,CAAC;QAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,CAAG,qCAAqC;QAC5E,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAAC,IAAI,GAAG,CAAC,CAAC;gBAAC,MAAM;YAAC,CAAC;YACjC,IAAI,CAAC;gBACH,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;oBACpG,IAAI,GAAG,CAAC,CAAC;oBACT,MAAM;gBACR,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,UAAU,GAAG,sBAAsB,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC;gBAC1F,KAAK,CAAC,YAAY,CAAC,CAAC;wBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC;wBAC3D,UAAU,EAAE,UAAU;wBACtB,IAAI,EAAQ,iBAAiB;wBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACpC,MAAM,EAAM,UAAU;qBACvB,CAAC,CAAC,CAAC;gBACJ,MAAM,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;gBAC3C,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;YAClE,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACjC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,oBAAoB,CAAC;oBAC9D,UAAU,EAAE,UAAU;oBACtB,IAAI,EAAQ,oBAAoB;oBAChC,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACrC,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,cAAc,UAAU,EAAE,CAAC,CAAC;YACtD,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACnD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;QACzD,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,KAAK,CAAC,YAAY,CAAC,CAAC;oBAClB,OAAO,EAAK,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC;oBAC3D,UAAU,EAAE,UAAU;oBACtB,IAAI,EAAQ,iBAAiB;oBAC7B,EAAE,EAAU,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACpC,MAAM,EAAM,IAAI,CAAC,IAAI;iBACtB,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,sBAAsB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1C,QAAQ,EAAE,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7E,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,KAAK,cAAc,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,EAAE,CAAC;YAChD,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3E,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;gBACnB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3C,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,CAAC,KAAK,cAAc,CAAC,CAAC;gBACjE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACnC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,EAAE,iCAAiC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,MAAc;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,GAAY,GAAG,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC9D,GAAG,GAAI,GAA+B,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,GAA4B,EAAE,MAAc,EAAE,KAAc;IAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,GAAY,GAAG,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,4EAA4E;YAC5E,4EAA4E;YAC5E,MAAM,GAAG,GAAG,GAAqC,CAAC;YAClD,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;YACD,GAAG,GAAG,IAAI,CAAC;QACb,CAAC;aAAM,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,GAA8B,CAAC;YAC3C,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAC/D,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,GAAG,gBAAgB,CAAC,YAAY,MAAM,GAAG,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,sDAAsD,MAAM,GAAG,CAAC,CAAC;IACnF,CAAC;IACA,GAA+B,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AACpE,CAAC"}