@cogitato/kit-cli 0.0.0-stage → 0.2.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 (76) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +34 -2
  3. package/bin/kit.js +4 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +245 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/doctor.d.ts +23 -0
  8. package/dist/doctor.js +86 -0
  9. package/dist/doctor.js.map +1 -0
  10. package/dist/errors.d.ts +8 -0
  11. package/dist/errors.js +9 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/export-flows.d.ts +8 -0
  14. package/dist/export-flows.js +15 -0
  15. package/dist/export-flows.js.map +1 -0
  16. package/dist/flows.d.ts +38 -0
  17. package/dist/flows.js +141 -0
  18. package/dist/flows.js.map +1 -0
  19. package/dist/format.d.ts +3 -0
  20. package/dist/format.js +27 -0
  21. package/dist/format.js.map +1 -0
  22. package/dist/gaps.d.ts +21 -0
  23. package/dist/gaps.js +52 -0
  24. package/dist/gaps.js.map +1 -0
  25. package/dist/hook.d.ts +33 -0
  26. package/dist/hook.js +114 -0
  27. package/dist/hook.js.map +1 -0
  28. package/dist/hosting.d.ts +18 -0
  29. package/dist/hosting.js +51 -0
  30. package/dist/hosting.js.map +1 -0
  31. package/dist/index.d.ts +19 -0
  32. package/dist/index.js +21 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/issue.d.ts +17 -0
  35. package/dist/issue.js +65 -0
  36. package/dist/issue.js.map +1 -0
  37. package/dist/links.d.ts +15 -0
  38. package/dist/links.js +60 -0
  39. package/dist/links.js.map +1 -0
  40. package/dist/preview.d.ts +16 -0
  41. package/dist/preview.js +38 -0
  42. package/dist/preview.js.map +1 -0
  43. package/dist/project.d.ts +55 -0
  44. package/dist/project.js +145 -0
  45. package/dist/project.js.map +1 -0
  46. package/dist/registry.d.ts +67 -0
  47. package/dist/registry.js +227 -0
  48. package/dist/registry.js.map +1 -0
  49. package/dist/rules/css-values.d.ts +31 -0
  50. package/dist/rules/css-values.js +185 -0
  51. package/dist/rules/css-values.js.map +1 -0
  52. package/dist/rules/css.d.ts +4 -0
  53. package/dist/rules/css.js +39 -0
  54. package/dist/rules/css.js.map +1 -0
  55. package/dist/rules/tsx.d.ts +26 -0
  56. package/dist/rules/tsx.js +191 -0
  57. package/dist/rules/tsx.js.map +1 -0
  58. package/dist/save.d.ts +30 -0
  59. package/dist/save.js +164 -0
  60. package/dist/save.js.map +1 -0
  61. package/dist/scaffold.d.ts +42 -0
  62. package/dist/scaffold.js +232 -0
  63. package/dist/scaffold.js.map +1 -0
  64. package/dist/snapshots.d.ts +43 -0
  65. package/dist/snapshots.js +140 -0
  66. package/dist/snapshots.js.map +1 -0
  67. package/dist/status.d.ts +14 -0
  68. package/dist/status.js +38 -0
  69. package/dist/status.js.map +1 -0
  70. package/dist/validate.d.ts +18 -0
  71. package/dist/validate.js +72 -0
  72. package/dist/validate.js.map +1 -0
  73. package/dist/workspace.d.ts +18 -0
  74. package/dist/workspace.js +119 -0
  75. package/dist/workspace.js.map +1 -0
  76. package/package.json +52 -3
@@ -0,0 +1,191 @@
1
+ import { posix } from "node:path";
2
+ import ts from "typescript";
3
+ import { issueAt, literalText, propertyName } from "../issue.js";
4
+ import { WORKSPACE_LAYOUT } from "../project.js";
5
+ import { ID_PATTERNS } from "../registry.js";
6
+ import { FINDING_CODES, SUBSTITUTION, checkCssNumber, checkCssValue } from "./css-values.js";
7
+ const NATIVE_INTERACTIVE = new Set(["button", "a", "input", "select", "textarea"]);
8
+ /** Kit component name for an import specifier, or undefined if it doesn't point into the shared kit. */
9
+ function kitImportName(file, specifier) {
10
+ let rest;
11
+ if (specifier.startsWith("@/kit/"))
12
+ rest = specifier.slice("@/kit/".length);
13
+ else if (specifier.startsWith(".")) {
14
+ const target = posix.normalize(posix.join(posix.dirname(file), specifier));
15
+ const kit = `../../${WORKSPACE_LAYOUT.kit}/`;
16
+ if (target.startsWith(kit))
17
+ rest = target.slice(kit.length);
18
+ }
19
+ const name = rest?.split("/")[0]?.replace(/\.(tsx?|jsx?)$/, "");
20
+ // Lowercase files and stylesheets in the kit folder are helpers, not components.
21
+ return name && /^[A-Z][A-Za-z0-9]*$/.test(name) ? name : undefined;
22
+ }
23
+ const slugify = (s) => s
24
+ .toLowerCase()
25
+ .replace(/[^a-z0-9]+/g, "-")
26
+ .replace(/^-+|-+$/g, "")
27
+ .slice(0, 30)
28
+ .replace(/-+$/, "");
29
+ // A readable element name for a suggested id: from its label, aria-label, name or text.
30
+ function suggestElementName(el, sf) {
31
+ for (const attr of el.attributes.properties) {
32
+ if (!ts.isJsxAttribute(attr) || !attr.initializer)
33
+ continue;
34
+ const name = attr.name.getText(sf);
35
+ if (!["label", "aria-label", "name", "placeholder", "title"].includes(name))
36
+ continue;
37
+ const text = ts.isStringLiteral(attr.initializer) ? attr.initializer.text : undefined;
38
+ if (text && slugify(text))
39
+ return slugify(text);
40
+ }
41
+ const parent = el.parent;
42
+ if (ts.isJsxElement(parent)) {
43
+ const text = parent.children
44
+ .filter(ts.isJsxText)
45
+ .map((c) => c.text)
46
+ .join(" ")
47
+ .trim();
48
+ if (text && slugify(text))
49
+ return slugify(text);
50
+ }
51
+ return slugify(el.tagName.getText(sf)) || "element";
52
+ }
53
+ /** Token, component and data-kit-id rules for one .ts/.tsx file. */
54
+ export function checkTsxFile(sf, ctx) {
55
+ const issues = [];
56
+ const kitIds = [];
57
+ const file = sf.fileName;
58
+ const { contract, owner } = ctx;
59
+ const inKit = ctx.inKit === true;
60
+ // Local identifier -> kit component name, from this file's imports.
61
+ const kitLocals = new Map();
62
+ const styleFindings = (prop, node) => {
63
+ const findings = ts.isNumericLiteral(node)
64
+ ? checkCssNumber(contract, prop, Number(node.text))
65
+ : ts.isTemplateExpression(node)
66
+ ? checkCssValue(contract, prop, [node.head.text, ...node.templateSpans.map((s) => s.literal.text)].join(SUBSTITUTION))
67
+ : literalText(node) !== undefined
68
+ ? checkCssValue(contract, prop, literalText(node))
69
+ : [];
70
+ for (const f of findings) {
71
+ issues.push(issueAt(FINDING_CODES[f.kind], sf, node, f.message, f.suggestion ? { suggestion: f.suggestion } : {}));
72
+ }
73
+ };
74
+ const checkKitId = (el, what) => {
75
+ let idAttr;
76
+ let hasSpread = false;
77
+ for (const a of el.attributes.properties) {
78
+ if (ts.isJsxSpreadAttribute(a))
79
+ hasSpread = true;
80
+ else if (a.name.getText(sf) === "data-kit-id")
81
+ idAttr = a;
82
+ }
83
+ const prefix = owner?.id;
84
+ const example = `${prefix ?? "screen.id"}.${suggestElementName(el, sf)}`;
85
+ if (!idAttr) {
86
+ // A spread may be passing the id through; that's the kit-wrapper pattern.
87
+ if (hasSpread)
88
+ return;
89
+ issues.push(issueAt("code-missing-kit-id", sf, el, `This ${what} needs a data-kit-id so comments can be pinned to it. Add data-kit-id="${example}".`, {
90
+ suggestion: example,
91
+ }));
92
+ return;
93
+ }
94
+ const init = idAttr.initializer;
95
+ const expr = init && ts.isJsxExpression(init) ? init.expression : init;
96
+ const id = literalText(expr);
97
+ if (id === undefined) {
98
+ if (expr && ts.isTemplateExpression(expr) && prefix && !expr.head.text.startsWith(`${prefix}.`)) {
99
+ issues.push(issueAt("code-invalid-kit-id", sf, expr, `This element id doesn't start with "${prefix}.", the ${owner.title} screen's id. Element ids start with their screen's id.`));
100
+ }
101
+ else if (!expr || !ts.isTemplateExpression(expr)) {
102
+ issues.push(issueAt("code-kit-id-unchecked", sf, idAttr, `This data-kit-id is computed, so Cogitato can't check it. Prefer plain text, like data-kit-id="${example}".`, {
103
+ severity: "warning",
104
+ }));
105
+ }
106
+ return;
107
+ }
108
+ if (!ID_PATTERNS.kitId.test(id)) {
109
+ issues.push(issueAt("code-invalid-kit-id", sf, idAttr, `"${id}" isn't a valid element id. Element ids are the screen id plus an element name, lowercase and dot-separated, like "${example}".`, {
110
+ suggestion: example,
111
+ }));
112
+ return;
113
+ }
114
+ if (prefix && !id.startsWith(`${prefix}.`)) {
115
+ const fixed = `${prefix}.${id.slice(id.lastIndexOf(".") + 1)}`;
116
+ issues.push(issueAt("code-invalid-kit-id", sf, idAttr, `"${id}" doesn't start with this screen's id. Elements on the ${owner.title} screen need ids starting with "${prefix}.", like "${fixed}".`, {
117
+ suggestion: fixed,
118
+ }));
119
+ return;
120
+ }
121
+ const { line, character } = sf.getLineAndCharacterOfPosition(idAttr.getStart(sf));
122
+ kitIds.push({ id, owner, file, line: line + 1, column: character + 1 });
123
+ };
124
+ const visit = (node) => {
125
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
126
+ const name = kitImportName(file, node.moduleSpecifier.text);
127
+ if (name && !inKit) {
128
+ if (!contract.manifests.has(name)) {
129
+ issues.push(issueAt("code-unknown-component", sf, node, `${name} isn't in the design system yet, so it can't be used here. Use an existing component from the kit, or record it as a gap so the team can add it.`));
130
+ }
131
+ const clause = node.importClause;
132
+ if (clause?.name)
133
+ kitLocals.set(clause.name.text, name);
134
+ if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
135
+ for (const el of clause.namedBindings.elements) {
136
+ kitLocals.set(el.name.text, (el.propertyName ?? el.name).text);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if ((ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) && !inKit) {
142
+ const tag = node.tagName.getText(sf);
143
+ const handlers = node.attributes.properties.some((a) => ts.isJsxAttribute(a) && /^on[A-Z]/.test(a.name.getText(sf)));
144
+ const kitName = kitLocals.get(tag);
145
+ const manifest = kitName ? contract.manifests.get(kitName) : undefined;
146
+ const kitInteractive = manifest ? Object.values(manifest.props).some((p) => p?.type === "event") : false;
147
+ if (NATIVE_INTERACTIVE.has(tag) || handlers || kitInteractive) {
148
+ checkKitId(node, kitName ? `${kitName}` : /^[a-z]/.test(tag) ? `<${tag}>` : `${tag}`);
149
+ }
150
+ }
151
+ if (ts.isJsxAttribute(node) && node.name.getText(sf) === "style" && node.initializer && ts.isJsxExpression(node.initializer)) {
152
+ const obj = node.initializer.expression;
153
+ if (obj && ts.isObjectLiteralExpression(obj)) {
154
+ for (const p of obj.properties) {
155
+ if (!ts.isPropertyAssignment(p))
156
+ continue;
157
+ const prop = propertyName(p.name);
158
+ if (prop)
159
+ styleFindings(prop, p.initializer);
160
+ }
161
+ }
162
+ }
163
+ ts.forEachChild(node, visit);
164
+ };
165
+ visit(sf);
166
+ return { issues, kitIds };
167
+ }
168
+ /** Duplicate data-kit-ids within one screen. Reported where the later use is. */
169
+ export function duplicateKitIds(uses) {
170
+ const first = new Map();
171
+ const issues = [];
172
+ for (const u of uses) {
173
+ const key = `${u.owner?.id ?? ""}|${u.id}`;
174
+ const prev = first.get(key);
175
+ if (!prev) {
176
+ first.set(key, u);
177
+ continue;
178
+ }
179
+ issues.push({
180
+ code: "code-duplicate-kit-id",
181
+ severity: "error",
182
+ file: u.file,
183
+ path: "",
184
+ line: u.line,
185
+ column: u.column,
186
+ message: `"${u.id}" is used twice${u.owner ? ` on the ${u.owner.title} screen` : ""} (also at ${prev.file}, line ${prev.line}). Each element needs its own id so comments land on the right one.`,
187
+ });
188
+ }
189
+ return issues;
190
+ }
191
+ //# sourceMappingURL=tsx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsx.js","sourceRoot":"","sources":["../../src/rules/tsx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAmB7F,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAEnF,wGAAwG;AACxG,SAAS,aAAa,CAAC,IAAY,EAAE,SAAiB;IACpD,IAAI,IAAwB,CAAC;IAC7B,IAAI,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACvE,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,SAAS,gBAAgB,CAAC,GAAG,GAAG,CAAC;QAC7C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAChE,iFAAiF;IACjF,OAAO,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAC5B,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;KACZ,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAExB,wFAAwF;AACxF,SAAS,kBAAkB,CAAC,EAA4B,EAAE,EAAiB;IACzE,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAS;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QACtF,MAAM,IAAI,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;IACzB,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ;aACzB,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC;aACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,GAAG,CAAC;aACT,IAAI,EAAE,CAAC;QACV,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC;AACtD,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,EAAiB,EAAE,GAAe;IAC7D,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC;IACzB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC;IACjC,oEAAoE;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAmB,EAAE,EAAE;QAC1D,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACxC,CAAC,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC7B,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACtH,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,SAAS;oBAC/B,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAE,CAAC;oBACnD,CAAC,CAAC,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,EAA4B,EAAE,IAAY,EAAE,EAAE;QAChE,IAAI,MAAmC,CAAC;QACxC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACzC,IAAI,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;gBAAE,SAAS,GAAG,IAAI,CAAC;iBAC5C,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,aAAa;gBAAE,MAAM,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,EAAE,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,MAAM,IAAI,WAAW,IAAI,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QACzE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,0EAA0E;YAC1E,IAAI,SAAS;gBAAE,OAAO;YACtB,MAAM,CAAC,IAAI,CACT,OAAO,CAAC,qBAAqB,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,IAAI,0EAA0E,OAAO,IAAI,EAAE;gBACxI,UAAU,EAAE,OAAO;aACpB,CAAC,CACH,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,IAAI,IAAI,IAAI,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,EAAE,IAAI,EAAE,uCAAuC,MAAM,WAAW,KAAM,CAAC,KAAK,yDAAyD,CAAC,CAAC,CAAC;YACvL,CAAC;iBAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,MAAM,CAAC,IAAI,CACT,OAAO,CAAC,uBAAuB,EAAE,EAAE,EAAE,MAAM,EAAE,kGAAkG,OAAO,IAAI,EAAE;oBAC1J,QAAQ,EAAE,SAAS;iBACpB,CAAC,CACH,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CACT,OAAO,CAAC,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,sHAAsH,OAAO,IAAI,EAAE;gBAClL,UAAU,EAAE,OAAO;aACpB,CAAC,CACH,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,CAAC,IAAI,CACT,OAAO,CAAC,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,0DAA0D,KAAM,CAAC,KAAK,mCAAmC,MAAM,aAAa,KAAK,IAAI,EAAE;gBACtL,UAAU,EAAE,KAAK;aAClB,CAAC,CACH,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,6BAA6B,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QAClF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,IAAa,EAAE,EAAE;QAC9B,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,MAAM,CAAC,IAAI,CACT,OAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,kJAAkJ,CAAC,CACvM,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;gBACjC,IAAI,MAAM,EAAE,IAAI;oBAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACxD,IAAI,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;oBACrE,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;wBAC/C,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;oBACjE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACjF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CACnE,CAAC;YACF,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACzG,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,IAAI,cAAc,EAAE,CAAC;gBAC9D,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7H,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;YACxC,IAAI,GAAG,IAAI,EAAE,CAAC,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;oBAC/B,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;wBAAE,SAAS;oBAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBAClC,IAAI,IAAI;wBAAE,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IACF,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,IAAI,qEAAqE;SAClM,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/save.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import type { FlowManifest, Issue } from "@cogitato/contract";
2
+ import { type Workspace } from "./project.js";
3
+ export interface SaveOptions {
4
+ /** Replaces the generated first line of the commit message. */
5
+ message?: string;
6
+ /** For tests. */
7
+ now?: Date;
8
+ }
9
+ export interface SaveResult {
10
+ saved: boolean;
11
+ branch?: string;
12
+ /** Short commit id. */
13
+ commit?: string;
14
+ /** The commit message's first line. */
15
+ summary?: string;
16
+ pushed: boolean;
17
+ /** A hosted canvas for each prototype the branch changed, when hosting is set up and the push worked. */
18
+ previews: {
19
+ prototype: string;
20
+ url: string;
21
+ }[];
22
+ /** One or two plain sentences for the designer. */
23
+ message: string;
24
+ /** Validation problems at the time of saving. They don't stop the save. */
25
+ issues: Issue[];
26
+ }
27
+ /** What changed between two flows.json versions, as short phrases: "add screen checkout.review". */
28
+ export declare function describeChanges(before: FlowManifest | undefined, after: FlowManifest): string[];
29
+ /** Saves a version of the workspace: commit on a design branch, then push if there's a remote. */
30
+ export declare function saveVersion(ws: Workspace, opts?: SaveOptions): SaveResult;
package/dist/save.js ADDED
@@ -0,0 +1,164 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { KitError } from "./errors.js";
3
+ import { exportFlows } from "./export-flows.js";
4
+ import { sameManifest } from "./flows.js";
5
+ import { affectedPrototypes } from "./hosting.js";
6
+ import { previewLink } from "./links.js";
7
+ import { LAYOUT, WORKSPACE_LAYOUT, listPrototypes, projectIn } from "./project.js";
8
+ import { statusLabel } from "./status.js";
9
+ import { validateWorkspace } from "./workspace.js";
10
+ function git(ws, args, raw = false) {
11
+ const r = spawnSync("git", args, { cwd: ws.root, encoding: "utf8" });
12
+ return { ok: r.status === 0, out: raw ? (r.stdout ?? "") : (r.stdout ?? "").trim(), err: (r.stderr ?? "").trim() };
13
+ }
14
+ const flowsPath = (name) => `${WORKSPACE_LAYOUT.prototypes}/${name}/${LAYOUT.flowsJson}`;
15
+ const slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "designer";
16
+ /** What changed between two flows.json versions, as short phrases: "add screen checkout.review". */
17
+ export function describeChanges(before, after) {
18
+ const states = (m) => new Map((m?.screens ?? []).flatMap((s) => s.states.map((st) => [`${s.id}.${st.id}`, s.id])));
19
+ const screens = (m) => new Set((m?.screens ?? []).map((s) => s.id));
20
+ const [s0, s1, st0, st1] = [screens(before), screens(after), states(before), states(after)];
21
+ const out = [];
22
+ for (const id of s1)
23
+ if (!s0.has(id))
24
+ out.push(`add screen ${id}`);
25
+ for (const [node, screen] of st1)
26
+ if (!st0.has(node) && s0.has(screen))
27
+ out.push(`add state ${node}`);
28
+ for (const id of s0)
29
+ if (!s1.has(id))
30
+ out.push(`remove screen ${id}`);
31
+ for (const [node, screen] of st0)
32
+ if (!st1.has(node) && s1.has(screen))
33
+ out.push(`remove state ${node}`);
34
+ for (const [node, status] of Object.entries(after.status ?? {})) {
35
+ if (st1.has(node) && before?.status?.[node] !== status)
36
+ out.push(`mark ${node} ${statusLabel(status ?? "exploring").toLowerCase()}`);
37
+ }
38
+ const edges = (m) => new Set((m?.flows ?? []).flatMap((f) => f.edges.map((e) => `${e.from}>${e.to}`)));
39
+ const [e0, e1] = [edges(before), edges(after)];
40
+ const newEdges = [...e1].filter((e) => !e0.has(e)).length;
41
+ if (newEdges && !out.length)
42
+ out.push(`connect ${newEdges} step${newEdges === 1 ? "" : "s"} in the flow`);
43
+ return out;
44
+ }
45
+ function summarize(changes, files, multiple) {
46
+ if (changes.length) {
47
+ const line = changes.join("; ");
48
+ const text = line.length <= 68 ? line : `${changes[0]} and ${changes.length - 1} more change${changes.length === 2 ? "" : "s"}`;
49
+ return text.charAt(0).toUpperCase() + text.slice(1);
50
+ }
51
+ const screens = [
52
+ ...new Set(files
53
+ .map((f) => /^prototypes\/([^/]+)\/src\/screens\/(.+)\/[^/]+$/.exec(f))
54
+ .filter((m) => !!m)
55
+ .map((m) => (multiple ? `${m[1]}: ${m[2].split("/").join(".")}` : m[2].split("/").join(".")))),
56
+ ];
57
+ if (screens.length === 1)
58
+ return `Update ${screens[0]}`;
59
+ if (screens.length > 1)
60
+ return `Update ${screens.length} screens`;
61
+ if (files.some((f) => f.startsWith(`${WORKSPACE_LAYOUT.contract}/`) || f.startsWith(`${WORKSPACE_LAYOUT.kit}/`)))
62
+ return "Update the design kit";
63
+ const touched = new Set(files.map((f) => new RegExp(`^${WORKSPACE_LAYOUT.prototypes}/([^/]+)/`).exec(f)?.[1]).filter(Boolean));
64
+ return touched.size > 1 ? "Update the prototypes" : "Update the prototype";
65
+ }
66
+ /** The branch design branches start from: the remote's HEAD, else main or master. Undefined if none exists. */
67
+ function defaultBranch(ws, remote) {
68
+ const head = git(ws, ["symbolic-ref", "--short", `refs/remotes/${remote}/HEAD`]);
69
+ const candidates = [...(head.ok && head.out ? [head.out] : []), `${remote}/main`, `${remote}/master`, "main", "master"];
70
+ return candidates.find((ref) => git(ws, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`]).ok);
71
+ }
72
+ function previewsFor(ws, remote, branch) {
73
+ const names = listPrototypes(ws);
74
+ const base = defaultBranch(ws, remote);
75
+ const diff = base ? git(ws, ["diff", "--name-only", `${base}...HEAD`]) : undefined;
76
+ // When it's unclear what the branch changed, link every prototype rather than none.
77
+ const affected = diff?.ok ? affectedPrototypes(diff.out.split("\n").filter(Boolean), names) : names;
78
+ return affected.flatMap((name) => {
79
+ const url = previewLink(projectIn(ws, name), branch);
80
+ return url ? [{ prototype: name, url }] : [];
81
+ });
82
+ }
83
+ /** Saves a version of the workspace: commit on a design branch, then push if there's a remote. */
84
+ export function saveVersion(ws, opts = {}) {
85
+ if (!git(ws, ["rev-parse", "--is-inside-work-tree"]).ok) {
86
+ throw new KitError("This workspace doesn't keep a history yet, so versions can't be saved. Ask a developer to set it up with git.");
87
+ }
88
+ const names = listPrototypes(ws);
89
+ const multiple = names.length > 1;
90
+ const manifests = new Map();
91
+ const previous = new Map();
92
+ for (const name of names) {
93
+ manifests.set(name, exportFlows(projectIn(ws, name)).manifest);
94
+ const before = git(ws, ["show", `HEAD:${flowsPath(name)}`]);
95
+ try {
96
+ previous.set(name, before.ok ? JSON.parse(before.out) : undefined);
97
+ }
98
+ catch {
99
+ previous.set(name, undefined);
100
+ }
101
+ }
102
+ const status = git(ws, ["status", "--porcelain", "--untracked-files=all"], true);
103
+ const files = status.out
104
+ .split("\n")
105
+ .filter(Boolean)
106
+ .map((l) => l.slice(3).replace(/^"|"$/g, "").split(" -> ").pop())
107
+ // A flows.json whose only change is the commit it was exported at isn't worth a version.
108
+ .filter((f) => {
109
+ const name = names.find((n) => f === flowsPath(n));
110
+ const before = name && previous.get(name);
111
+ const stampOnly = !!(name && before && sameManifest(before, manifests.get(name), { status: true }));
112
+ // Put the saved copy back, so the stamp doesn't ride along in the commit and mark the prototype as changed.
113
+ // If that fails, the file just goes into the save.
114
+ return !(stampOnly && git(ws, ["checkout", "HEAD", "--", f]).ok);
115
+ });
116
+ const issues = validateWorkspace(ws).issues.filter((i) => i.severity === "error");
117
+ if (!files.length)
118
+ return { saved: false, pushed: false, previews: [], message: "Nothing new to save: everything is already saved.", issues };
119
+ const user = git(ws, ["config", "user.name"]).out;
120
+ if (!user || !git(ws, ["config", "user.email"]).out) {
121
+ throw new KitError("Saving needs your name and email set up once on this computer. Ask Claude to set them (git config user.name and user.email).");
122
+ }
123
+ let branch = git(ws, ["rev-parse", "--abbrev-ref", "HEAD"]).out;
124
+ if (branch === "main" || branch === "master" || branch === "HEAD") {
125
+ const d = (opts.now ?? new Date()).toISOString().slice(0, 10).replace(/-/g, "");
126
+ const base = `design/${slug(user)}-${d}`;
127
+ branch = base;
128
+ for (let n = 2; git(ws, ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`]).ok; n++)
129
+ branch = `${base}-${n}`;
130
+ const sw = git(ws, ["switch", "-c", branch]);
131
+ if (!sw.ok)
132
+ throw new KitError(`Couldn't start a design branch for your work (${sw.err}).`);
133
+ }
134
+ const changes = names.flatMap((name) => describeChanges(previous.get(name), manifests.get(name)).map((c) => (multiple ? `${name}: ${c}` : c)));
135
+ const summary = opts.message?.trim() || summarize(changes, files, multiple);
136
+ const body = [
137
+ ...(changes.length > 1 ? changes.map((c) => `- ${c}`) : []),
138
+ ...(issues.length ? [`Saved with ${issues.length} validation problem${issues.length === 1 ? "" : "s"} still open.`] : []),
139
+ ].join("\n");
140
+ if (!git(ws, ["add", "-A"]).ok)
141
+ throw new KitError("Couldn't collect your changes to save them.");
142
+ const commit = git(ws, ["commit", "-q", "-m", summary, ...(body ? ["-m", body] : [])]);
143
+ if (!commit.ok)
144
+ throw new KitError(`Couldn't save the version (${commit.err || commit.out}).`);
145
+ const sha = git(ws, ["rev-parse", "--short", "HEAD"]).out;
146
+ const remote = git(ws, ["remote"]).out.split("\n").filter(Boolean)[0];
147
+ let pushed = false;
148
+ let where = "Saved on this computer (there's no shared copy to send it to yet).";
149
+ if (remote) {
150
+ const push = git(ws, ["push", "-u", remote, branch]);
151
+ pushed = push.ok;
152
+ where = push.ok
153
+ ? `Saved and shared on the "${branch}" branch.`
154
+ : `Saved on this computer, but sharing it failed (${push.err.split("\n")[0]}). Try saving again later.`;
155
+ }
156
+ const previews = pushed && remote ? previewsFor(ws, remote, branch) : [];
157
+ if (previews.length === 1)
158
+ where += ` Your preview will be at ${previews[0].url} in a minute or two.`;
159
+ else if (previews.length > 1)
160
+ where += ` Your previews will be ready in a minute or two: ${previews.map((p) => `${p.prototype}: ${p.url}`).join("; ")}.`;
161
+ const problems = issues.length ? ` Heads up: ${issues.length} validation problem${issues.length === 1 ? " is" : "s are"} still open.` : "";
162
+ return { saved: true, branch, commit: sha, summary, pushed, previews, message: `${where} Version: "${summary}".${problems}`, issues };
163
+ }
164
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,cAAc,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA4BnD,SAAS,GAAG,CAAC,EAAa,EAAE,IAAc,EAAE,GAAG,GAAG,KAAK;IACrD,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACrE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AACrH,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,gBAAgB,CAAC,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;AAEjG,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC;AAE9G,oGAAoG;AACpG,MAAM,UAAU,eAAe,CAAC,MAAgC,EAAE,KAAmB;IACnF,MAAM,MAAM,GAAG,CAAC,CAA2B,EAAE,EAAE,CAC7C,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAU,CAAC,CAAC,CAAC,CAAC;IACxG,MAAM,OAAO,GAAG,CAAC,CAA2B,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5F,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACtG,KAAK,MAAM,EAAE,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IACzG,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAkD,EAAE,CAAC;QACjH,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAK,MAAM,EAAE,MAA6C,EAAE,CAAC,IAAI,CAAC,KAAK,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/K,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAA2B,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACjI,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,QAAQ,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,GAAG,CAAC,IAAI,CAAC,WAAW,QAAQ,QAAQ,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;IAC1G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,OAAiB,EAAE,KAAe,EAAE,QAAiB;IACtE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,GAAG,CAAC,eAAe,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAChI,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,OAAO,GAAG;QACd,GAAG,IAAI,GAAG,CACR,KAAK;aACF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kDAAkD,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACtE,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAClG;KACF,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,UAAU,OAAO,CAAC,MAAM,UAAU,CAAC;IAClE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,gBAAgB,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,gBAAgB,CAAC,GAAG,GAAG,CAAC,CAAC;QAAE,OAAO,uBAAuB,CAAC;IACjJ,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,gBAAgB,CAAC,UAAU,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/H,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB,CAAC;AAC7E,CAAC;AAED,+GAA+G;AAC/G,SAAS,aAAa,CAAC,EAAa,EAAE,MAAc;IAClD,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,gBAAgB,MAAM,OAAO,CAAC,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,MAAM,OAAO,EAAE,GAAG,MAAM,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxH,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACvG,CAAC;AAED,SAAS,WAAW,CAAC,EAAa,EAAE,MAAc,EAAE,MAAc;IAChE,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,oFAAoF;IACpF,MAAM,QAAQ,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACpG,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,WAAW,CAAC,EAAa,EAAE,OAAoB,EAAE;IAC/D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,QAAQ,CAAC,+GAA+G,CAAC,CAAC;IACtI,CAAC;IACD,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoC,CAAC;IAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvF,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,uBAAuB,CAAC,EAAE,IAAI,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG;SACrB,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAG,CAAC;QAClE,yFAAyF;SACxF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACrG,4GAA4G;QAC5G,mDAAmD;QACnD,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IACL,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAClF,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,mDAAmD,EAAE,MAAM,EAAE,CAAC;IAE9I,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;IAClD,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACpD,MAAM,IAAI,QAAQ,CAAC,8HAA8H,CAAC,CAAC;IACrJ,CAAC;IAED,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAChE,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,IAAI,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;YAAE,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QACvH,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,IAAI,QAAQ,CAAC,iDAAiD,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACrC,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACvG,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG;QACX,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,MAAM,sBAAsB,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1H,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,MAAM,IAAI,QAAQ,CAAC,6CAA6C,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,IAAI,QAAQ,CAAC,8BAA8B,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/F,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;IAE1D,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,KAAK,GAAG,oEAAoE,CAAC;IACjF,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrD,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QACjB,KAAK,GAAG,IAAI,CAAC,EAAE;YACb,CAAC,CAAC,4BAA4B,MAAM,WAAW;YAC/C,CAAC,CAAC,kDAAkD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC;IAC5G,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,IAAI,4BAA4B,QAAQ,CAAC,CAAC,CAAE,CAAC,GAAG,sBAAsB,CAAC;SAClG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,IAAI,oDAAoD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACzJ,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,MAAM,sBAAsB,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3I,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,cAAc,OAAO,KAAK,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC;AACxI,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { ValidationResult } from "@cogitato/contract";
2
+ import { type Project } from "./project.js";
3
+ export interface ScaffoldResult extends ValidationResult {
4
+ /** Project-relative files that were created or changed. */
5
+ files: string[];
6
+ /** The new screen or state, as "{screen id}.{state}". */
7
+ node: string;
8
+ /** Where to see it in the running prototype. */
9
+ link: string;
10
+ /** Its frame on the local canvas, among the rest of the flow. */
11
+ canvas: string;
12
+ }
13
+ export interface CreateScreenOptions {
14
+ id: string;
15
+ title?: string;
16
+ route?: string;
17
+ /** Add an arrow to the new screen from this state ("{screen id}.{state}"). */
18
+ from?: string;
19
+ label?: string;
20
+ /** Flow to add the arrow to. Defaults to the flow that already has `from`. */
21
+ flow?: string;
22
+ }
23
+ export interface AddStateOptions {
24
+ screen: string;
25
+ state: string;
26
+ title?: string;
27
+ from?: string;
28
+ label?: string;
29
+ flow?: string;
30
+ }
31
+ export interface AddEdgeOptions {
32
+ from: string;
33
+ to: string;
34
+ label?: string;
35
+ flow?: string;
36
+ }
37
+ /** Creates src/screens/<id as folders>/screen.tsx with a default state, and optionally an arrow to it. */
38
+ export declare function createScreen(project: Project, opts: CreateScreenOptions): ScaffoldResult;
39
+ /** Adds a state (fixture) to an existing screen, and optionally an arrow to it. */
40
+ export declare function addState(project: Project, opts: AddStateOptions): ScaffoldResult;
41
+ /** Adds an arrow between two existing states in src/flows.ts. */
42
+ export declare function addEdge(project: Project, opts: AddEdgeOptions): ScaffoldResult;