@sdd-method/sdd-cli 1.36.1 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/lib/catalogue/aggregate.js +2 -2
  2. package/dist/lib/catalogue/aggregate.js.map +1 -1
  3. package/dist/lib/catalogue/baseline-check.d.ts.map +1 -1
  4. package/dist/lib/catalogue/baseline-check.js +17 -2
  5. package/dist/lib/catalogue/baseline-check.js.map +1 -1
  6. package/dist/lib/catalogue/build.js +23 -3
  7. package/dist/lib/catalogue/build.js.map +1 -1
  8. package/dist/lib/catalogue/builders/feature-tree-walker.d.ts +7 -0
  9. package/dist/lib/catalogue/builders/feature-tree-walker.d.ts.map +1 -1
  10. package/dist/lib/catalogue/builders/feature-tree-walker.js +16 -4
  11. package/dist/lib/catalogue/builders/feature-tree-walker.js.map +1 -1
  12. package/dist/lib/catalogue/builders/repositories.js +48 -13
  13. package/dist/lib/catalogue/builders/repositories.js.map +1 -1
  14. package/dist/lib/catalogue/canonical-schema.yaml +6 -3
  15. package/dist/lib/catalogue/coverage-render.d.ts.map +1 -1
  16. package/dist/lib/catalogue/coverage-render.js +30 -0
  17. package/dist/lib/catalogue/coverage-render.js.map +1 -1
  18. package/dist/lib/catalogue/engine-validator.d.ts +6 -0
  19. package/dist/lib/catalogue/engine-validator.d.ts.map +1 -1
  20. package/dist/lib/catalogue/engine-validator.js +17 -0
  21. package/dist/lib/catalogue/engine-validator.js.map +1 -1
  22. package/dist/lib/catalogue/graph-projection.d.ts +8 -0
  23. package/dist/lib/catalogue/graph-projection.d.ts.map +1 -1
  24. package/dist/lib/catalogue/graph-projection.js +10 -0
  25. package/dist/lib/catalogue/graph-projection.js.map +1 -1
  26. package/dist/lib/catalogue/graph-run.d.ts +2 -9
  27. package/dist/lib/catalogue/graph-run.d.ts.map +1 -1
  28. package/dist/lib/catalogue/graph-run.js +6 -11
  29. package/dist/lib/catalogue/graph-run.js.map +1 -1
  30. package/dist/lib/catalogue/impact-run.d.ts.map +1 -1
  31. package/dist/lib/catalogue/impact-run.js +1 -2
  32. package/dist/lib/catalogue/impact-run.js.map +1 -1
  33. package/dist/lib/catalogue/manifest-loader.d.ts +2 -0
  34. package/dist/lib/catalogue/manifest-loader.d.ts.map +1 -1
  35. package/dist/lib/catalogue/manifest-loader.js +9 -0
  36. package/dist/lib/catalogue/manifest-loader.js.map +1 -1
  37. package/dist/lib/catalogue/scores-coverage.d.ts +26 -1
  38. package/dist/lib/catalogue/scores-coverage.d.ts.map +1 -1
  39. package/dist/lib/catalogue/scores-coverage.js +38 -0
  40. package/dist/lib/catalogue/scores-coverage.js.map +1 -1
  41. package/dist/lib/catalogue/validate.js +4 -4
  42. package/dist/lib/catalogue/validate.js.map +1 -1
  43. package/dist/lib/conformance/index.d.ts.map +1 -1
  44. package/dist/lib/conformance/index.js +28 -3
  45. package/dist/lib/conformance/index.js.map +1 -1
  46. package/dist/lib/snapshot/catalogue-diff.d.ts.map +1 -1
  47. package/dist/lib/snapshot/catalogue-diff.js +15 -1
  48. package/dist/lib/snapshot/catalogue-diff.js.map +1 -1
  49. package/dist/lib/snapshot/fold.d.ts.map +1 -1
  50. package/dist/lib/snapshot/fold.js +3 -1
  51. package/dist/lib/snapshot/fold.js.map +1 -1
  52. package/dist/lib/snapshot/verify.d.ts.map +1 -1
  53. package/dist/lib/snapshot/verify.js +6 -0
  54. package/dist/lib/snapshot/verify.js.map +1 -1
  55. package/dist/lib/sync/adr-transitions.d.ts +25 -1
  56. package/dist/lib/sync/adr-transitions.d.ts.map +1 -1
  57. package/dist/lib/sync/adr-transitions.js +59 -5
  58. package/dist/lib/sync/adr-transitions.js.map +1 -1
  59. package/dist/lib/sync/index.d.ts.map +1 -1
  60. package/dist/lib/sync/index.js +31 -1
  61. package/dist/lib/sync/index.js.map +1 -1
  62. package/dist/lib/validate/aggregate.d.ts +4 -0
  63. package/dist/lib/validate/aggregate.d.ts.map +1 -1
  64. package/dist/lib/validate/aggregate.js +31 -15
  65. package/dist/lib/validate/aggregate.js.map +1 -1
  66. package/dist/lib/validate/bundle-coherence.d.ts.map +1 -1
  67. package/dist/lib/validate/bundle-coherence.js +7 -2
  68. package/dist/lib/validate/bundle-coherence.js.map +1 -1
  69. package/dist/lib/validate/dispatch.d.ts.map +1 -1
  70. package/dist/lib/validate/dispatch.js +25 -0
  71. package/dist/lib/validate/dispatch.js.map +1 -1
  72. package/dist/lib/validate/index.d.ts.map +1 -1
  73. package/dist/lib/validate/index.js +32 -10
  74. package/dist/lib/validate/index.js.map +1 -1
  75. package/dist/lib/validate/yaml-parse.d.ts +17 -0
  76. package/dist/lib/validate/yaml-parse.d.ts.map +1 -0
  77. package/dist/lib/validate/yaml-parse.js +112 -0
  78. package/dist/lib/validate/yaml-parse.js.map +1 -0
  79. package/package.json +2 -2
  80. package/scripts/validate-app-dependencies.sh +24 -4
  81. package/scripts/validate-app-docs.sh +18 -4
@@ -1,5 +1,5 @@
1
1
  import { profileFromRepoKind, readRepoKind } from "../repo-kind.js";
2
- import { aggregateResults } from "./aggregate.js";
2
+ import { aggregateResults, classifyResult } from "./aggregate.js";
3
3
  import { selectValidators } from "./dispatch.js";
4
4
  import { runValidator } from "./runner.js";
5
5
  const SECTION_RULE = "═".repeat(59);
@@ -35,13 +35,17 @@ export async function runValidate(opts, stdout = (line) => process.stdout.write(
35
35
  stdout(result.stdout);
36
36
  if (result.stderr)
37
37
  stdout(result.stderr);
38
- if (result.exitCode === 0)
39
- stdout(pass(`${cfg.name}: ok`));
40
- else
38
+ if (result.exitCode !== 0)
41
39
  stdout(fail(`${cfg.name}: exit ${result.exitCode}`));
40
+ else if (classifyResult(result, { strict: opts.strict }) === "not-measured") {
41
+ stdout(na(`${cfg.name}: nothing measured — its population is empty`));
42
+ }
43
+ else
44
+ stdout(pass(`${cfg.name}: ok`));
42
45
  }
43
46
  const summary = aggregateResults(results, { strict: opts.strict });
44
- stdout(info(`Summary: passed=${summary.passed} failed=${summary.failed} skipped=${summary.skipped} warned=${summary.warned}${opts.strict ? " (strict)" : ""}`));
47
+ stdout(info(`Summary: passed=${summary.passed} failed=${summary.failed} skipped=${summary.skipped} ` +
48
+ `not-measured=${summary.notMeasured} warned=${summary.warned}${opts.strict ? " (strict)" : ""}`));
45
49
  stdout(verdict(summary, validators.length));
46
50
  return { exitCode: summary.exitCode, summary };
47
51
  }
@@ -55,14 +59,29 @@ function verdict(summary, selected) {
55
59
  if (summary.exitCode !== 0)
56
60
  return fail("One or more validators failed");
57
61
  const ran = summary.passed + summary.failed;
58
- if (summary.skipped === 0)
62
+ const nm = summary.notMeasured;
63
+ if (summary.skipped === 0 && nm === 0)
59
64
  return pass("All validators passed");
60
- if (ran === 0) {
65
+ if (ran === 0 && nm === 0) {
61
66
  return warn(`0 of ${selected} validators ran — all ${summary.skipped} skipped. ` +
62
67
  `This is an absence of evidence, not a pass.`);
63
68
  }
64
- return warn(`${ran} of ${selected} validators passed — ${summary.skipped} skipped, ` +
65
- `and a skipped validator is not covered by this verdict.`);
69
+ if (nm === 0) {
70
+ return warn(`${ran} of ${selected} validators passed — ${summary.skipped} skipped, ` +
71
+ `and a skipped validator is not covered by this verdict.`);
72
+ }
73
+ const uncovered = [
74
+ summary.skipped > 0 ? `${summary.skipped} skipped` : "",
75
+ nm > 0 ? `${nm} measured nothing (an empty population)` : "",
76
+ ]
77
+ .filter(Boolean)
78
+ .join(", ");
79
+ if (ran === 0) {
80
+ return warn(`0 of ${selected} validators measured anything — ${uncovered}. ` +
81
+ `This is an absence of evidence, not a pass.`);
82
+ }
83
+ return warn(`${ran} of ${selected} validators passed — ${uncovered}; ` +
84
+ `neither is covered by this verdict.`);
66
85
  }
67
86
  function section(title) {
68
87
  return `\n${SECTION_RULE}\n ${title}\n${SECTION_RULE}\n\n`;
@@ -79,10 +98,13 @@ function fail(msg) {
79
98
  function skip(msg) {
80
99
  return `[SKIP] ${msg}\n`;
81
100
  }
101
+ function na(msg) {
102
+ return `[N/A] ${msg}\n`;
103
+ }
82
104
  function warn(msg) {
83
105
  return `[WARN] ${msg}\n`;
84
106
  }
85
107
  function emptySummary() {
86
- return { exitCode: 1, passed: 0, failed: 0, skipped: 0, warned: 0 };
108
+ return { exitCode: 1, passed: 0, failed: 0, skipped: 0, warned: 0, notMeasured: 0 };
87
109
  }
88
110
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/validate/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/validate/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface YamlParseResult {
2
+ exitCode: number;
3
+ stdout: string;
4
+ skipped?: string;
5
+ }
6
+ export interface YamlParseError {
7
+ readonly file: string;
8
+ readonly code: string;
9
+ readonly message: string;
10
+ }
11
+ /** Strict-parse one YAML text; returns the errors (empty = parses). */
12
+ export declare function strictYamlErrors(text: string): Array<{
13
+ code: string;
14
+ message: string;
15
+ }>;
16
+ export declare function checkYamlParse(targetRepo: string): Promise<YamlParseResult>;
17
+ //# sourceMappingURL=yaml-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-parse.d.ts","sourceRoot":"","sources":["../../../src/lib/validate/yaml-parse.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAOvF;AAeD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAsEjF"}
@@ -0,0 +1,112 @@
1
+ // YAML parse gate — every tracked YAML source must parse STRICTLY.
2
+ //
3
+ // The catalogue builders read YAML file by file and, for most sources, log
4
+ // `invalid YAML` and move on: the file becomes wholly invisible to the
5
+ // catalogue and nothing ever fails. Measured: 19 unparseable files across 4
6
+ // SDDs, 16 in one repo, accumulated that way.
7
+ //
8
+ // THE LOADER IS THE GATE. PyYAML (and any last-key-wins loader) accepts a
9
+ // duplicate key and silently keeps the second value, so a parse-only check
10
+ // with it certifies exactly the corruption a line-surgery transformer
11
+ // produces. `yaml` v2 refuses duplicate keys (DUPLICATE_KEY) and the other
12
+ // malformations a lenient parse glosses — e.g. a `: ` inside an unquoted
13
+ // scalar (`path: (none — tel: URL)`), which no pattern rule catches.
14
+ //
15
+ // Scope: the YAML files git TRACKS (`*.yaml`, `*.yml`) — the repo's sources,
16
+ // not build output or dependencies. Outside a git work tree there is no
17
+ // honest scope, so the check reports a SKIP rather than a pass.
18
+ //
19
+ // A TEMPLATE is not YAML until rendered (Helm/Go `{{- … -}}`, Handlebars).
20
+ // A file that fails to parse AND carries a template directive is listed as
21
+ // templated and not failed — UNLESS one of its errors is a duplicate key: a
22
+ // duplicate key is a duplicate however the file is produced, and exempting it
23
+ // would let any `{{ }}` in a value hide exactly the defect this gate exists for.
24
+ import { execFile } from "node:child_process";
25
+ import { readFile } from "node:fs/promises";
26
+ import { join } from "node:path";
27
+ import { promisify } from "node:util";
28
+ import { parseAllDocuments } from "yaml";
29
+ const execFileAsync = promisify(execFile);
30
+ const TEMPLATE_DIRECTIVE_RE = /\{\{[\s\S]*?\}\}/;
31
+ /** Strict-parse one YAML text; returns the errors (empty = parses). */
32
+ export function strictYamlErrors(text) {
33
+ return parseAllDocuments(text).flatMap((doc) => doc.errors.map((e) => ({
34
+ code: e.code,
35
+ message: e.message.split("\n")[0] ?? e.message,
36
+ })));
37
+ }
38
+ async function trackedYamlFiles(repo) {
39
+ try {
40
+ const { stdout } = await execFileAsync("git", ["-C", repo, "ls-files", "-z", "--", "*.yaml", "*.yml"], { maxBuffer: 64 * 1024 * 1024 });
41
+ return stdout.split("\0").filter((p) => p !== "");
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ export async function checkYamlParse(targetRepo) {
48
+ const files = await trackedYamlFiles(targetRepo);
49
+ if (files === null) {
50
+ return {
51
+ exitCode: 0,
52
+ stdout: "",
53
+ skipped: "not a git work tree — no tracked-file scope to check",
54
+ };
55
+ }
56
+ const failures = [];
57
+ const templated = [];
58
+ let read = 0;
59
+ for (const file of files) {
60
+ let text;
61
+ try {
62
+ text = await readFile(join(targetRepo, file), "utf-8");
63
+ }
64
+ catch {
65
+ continue; // tracked but deleted in the work tree: not a parse question
66
+ }
67
+ read += 1;
68
+ const errors = strictYamlErrors(text);
69
+ if (errors.length > 0 &&
70
+ !errors.some((e) => e.code === "DUPLICATE_KEY") &&
71
+ TEMPLATE_DIRECTIVE_RE.test(text)) {
72
+ templated.push(file);
73
+ continue;
74
+ }
75
+ for (const e of errors) {
76
+ failures.push({ file, code: e.code, message: e.message });
77
+ }
78
+ }
79
+ const checked = read - templated.length;
80
+ const templatedNote = templated.length === 0
81
+ ? ""
82
+ : `[INFO] yaml-parse: ${templated.length} templated file(s) not checked — they do not parse ` +
83
+ `until rendered and carry a {{ … }} directive: ${templated.join(", ")}\n`;
84
+ if (failures.length === 0 && checked === 0) {
85
+ // Zero files checked is absence of evidence, never a pass.
86
+ return {
87
+ exitCode: 0,
88
+ stdout: templatedNote,
89
+ skipped: "no tracked YAML files to parse — nothing to check",
90
+ };
91
+ }
92
+ if (failures.length === 0) {
93
+ return {
94
+ exitCode: 0,
95
+ stdout: templatedNote +
96
+ `[PASS] yaml-parse: ${checked} tracked YAML file(s) parse strictly (duplicate keys refused)\n`,
97
+ };
98
+ }
99
+ const failedFiles = new Set(failures.map((f) => f.file)).size;
100
+ const byCode = new Map();
101
+ for (const f of failures)
102
+ byCode.set(f.code, (byCode.get(f.code) ?? 0) + 1);
103
+ const lines = failures.map((f) => `[FAIL] yaml-parse: ${f.file}: ${f.code}: ${f.message}\n`);
104
+ if (templatedNote !== "")
105
+ lines.unshift(templatedNote);
106
+ lines.push(`[FAIL] yaml-parse: ${failedFiles} of ${checked} tracked YAML file(s) do not parse strictly ` +
107
+ `(${[...byCode].map(([c, n]) => `${c} ×${n}`).join(", ")}). ` +
108
+ `A file that does not parse is invisible to the catalogue; a duplicate key keeps only one ` +
109
+ `of its values under a lenient loader. Fix the file — do not relax the loader.\n`);
110
+ return { exitCode: 1, stdout: lines.join("") };
111
+ }
112
+ //# sourceMappingURL=yaml-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-parse.js","sourceRoot":"","sources":["../../../src/lib/validate/yaml-parse.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,4EAA4E;AAC5E,8CAA8C;AAC9C,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,sEAAsE;AACtE,2EAA2E;AAC3E,yEAAyE;AACzE,qEAAqE;AACrE,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,gEAAgE;AAChE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,iFAAiF;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEzC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAcjD,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO;KAC/C,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EACvD,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAChC,CAAC;QACF,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,sDAAsD;SAChE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,6DAA6D;QACzE,CAAC;QACD,IAAI,IAAI,CAAC,CAAC;QACV,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtC,IACE,MAAM,CAAC,MAAM,GAAG,CAAC;YACjB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC;YAC/C,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAChC,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC;IACxC,MAAM,aAAa,GACjB,SAAS,CAAC,MAAM,KAAK,CAAC;QACpB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,sBAAsB,SAAS,CAAC,MAAM,qDAAqD;YAC3F,iDAAiD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAEhF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAC3C,2DAA2D;QAC3D,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,mDAAmD;SAC7D,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,MAAM,EACJ,aAAa;gBACb,sBAAsB,OAAO,iEAAiE;SACjG,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;IAC7F,IAAI,aAAa,KAAK,EAAE;QAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CACR,sBAAsB,WAAW,OAAO,OAAO,8CAA8C;QAC3F,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;QAC7D,2FAA2F;QAC3F,iFAAiF,CACpF,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACjD,CAAC"}