@slowcook-ai/cli 0.6.6 → 0.6.8

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.
@@ -23,13 +23,40 @@ This means: **you only keep changes that advance the green set.** Make real prog
23
23
 
24
24
  ## Tools
25
25
 
26
- - **read_file(path)** — read a file from the worktree. Use it before editing.
27
- - **list_directory(path)** — see what's in a directory.
28
- - **write_file(path, contents)** — create or fully replace a file. Prefer reading first + writing a complete updated file.
26
+ - **find_handler({ method, path })** — **call this FIRST for every \`api_contract\` entry in the spec.** Returns the exact handler file + function the brewing agent should edit (e.g. \`POST /api/rewos\` \`src/app/api/rewos/route.ts\` :: \`POST\`). Saves the exploratory iteration where you'd otherwise grep for the route.
27
+ - **outline_file(path)** — **prefer this over read_file for initial exploration.** Returns a compact outline (imports, top-level exports, signatures with line numbers) — ~200 tokens. Use this to decide whether a file is relevant before you read it fully.
28
+ - **read_file(path)** — read a file's full contents. Only call this when you need to see inside a specific function body that outline_file flagged. Reading a file you don't need is the single biggest driver of wasted budget.
29
+ - **list_directory(path)** — see what's in a directory. Useful when outline_file + find_handler don't give enough.
30
+ - **write_file(path, contents)** — create or fully replace a file. Always read or outline first, then write the complete updated contents.
29
31
  - **justify_diff_overflow({ reason_category, affected_scope, narrative, proposed_substories_if_split? })** — call ONLY if your intended change must exceed the graduality soft-cap (200 lines across ≤5 files). Explain why.
30
32
 
31
33
  You do NOT run tests. Slowcook runs them after your turn and tells you the result in the next turn's prompt.
32
34
 
35
+ ## Exploration strategy (cheap first, expensive last)
36
+
37
+ **Start every turn by reading \`.brewing/code-map.json\`** (or its rendered
38
+ sibling \`.brewing/code-map.md\`). Slowcook regenerates that file before
39
+ each iteration — it's the up-to-date list of every API route, page,
40
+ component, helper, and domain type in the project, with JSDoc summaries,
41
+ file paths, and signatures. Think of it as the project's self-updating
42
+ Swagger-for-everything. One \`read_file\` on it replaces a dozen exploratory
43
+ reads.
44
+
45
+ Then, in order:
46
+
47
+ 1. **Code map first** — \`read_file('.brewing/code-map.json')\`. Skim to
48
+ see what already exists.
49
+ 2. For each api_contract entry relevant to the target test, **find_handler**
50
+ to confirm the exact file + function (the code map also has this, but
51
+ find_handler is a one-call shortcut).
52
+ 3. **outline_file** on each file the code map / find_handler points to,
53
+ plus obvious neighbours (utils, types, helpers the spec references).
54
+ 4. **read_file** only the specific files + functions the outline flagged
55
+ as needing changes.
56
+ 5. **write_file** the minimum change.
57
+
58
+ A human doesn't read every file in a package to fix one test; neither should you.
59
+
33
60
  ## Constraints
34
61
 
35
62
  - **One target per turn.** The prompt names ONE failing test. Work on that one. Incidental green flips on other tests are fine but not the goal.
@@ -53,9 +80,41 @@ You do NOT run tests. Slowcook runs them after your turn and tells you the resul
53
80
  - On no-progress reverts, consider whether the target test is reachable from the code path you're editing, or whether it's testing a layer your code doesn't touch (e.g., the test calls \`fetch('http://localhost:3000')\` but no server is running).
54
81
  `;
55
82
  export const BREW_TOOLS = [
83
+ {
84
+ name: "find_handler",
85
+ description: "Resolve an API spec entry (method + path) to its concrete handler file + function. Use this FIRST for every api_contract entry in the spec — it replaces an exploratory read/list cycle. Today supports Next.js App Router (detected by `src/app/`); other frameworks return `framework: 'unknown'`. Returns JSON with { framework, file, function, exists, note? }.",
86
+ input_schema: {
87
+ type: "object",
88
+ properties: {
89
+ method: {
90
+ type: "string",
91
+ description: "HTTP method, e.g. 'POST', 'GET', 'DELETE'.",
92
+ },
93
+ path: {
94
+ type: "string",
95
+ description: "URL path, with params as `:id` or `{id}` — both are normalised (e.g. '/api/rewos/:rewo_id/reports' → 'src/app/api/rewos/[rewo_id]/reports/route.ts').",
96
+ },
97
+ },
98
+ required: ["method", "path"],
99
+ },
100
+ },
101
+ {
102
+ name: "outline_file",
103
+ description: "Return a compact outline of a TypeScript/JavaScript file: imports, top-level exports, signatures with line numbers. ~200 tokens. PREFER this over read_file for initial exploration — only call read_file when the outline tells you a specific function body needs to be inspected.",
104
+ input_schema: {
105
+ type: "object",
106
+ properties: {
107
+ path: {
108
+ type: "string",
109
+ description: "Repo-relative path (e.g., 'src/app/api/reactions/route.ts').",
110
+ },
111
+ },
112
+ required: ["path"],
113
+ },
114
+ },
56
115
  {
57
116
  name: "read_file",
58
- description: "Read a file from the worktree. Returns the file's current contents as a string. Throws if the file doesn't exist.",
117
+ description: "Read a file's full contents. Call this AFTER outline_file tells you a specific file / function body needs to be inspected — reading files you don't need is the single biggest driver of wasted budget. Returns the full file (up to 20k chars).",
59
118
  input_schema: {
60
119
  type: "object",
61
120
  properties: {
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/brew/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/brew/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { CodeMap } from "./scan.js";
2
+ export declare function map(argv: string[], cliVersion: string): Promise<void>;
3
+ export declare function writeFreshMap(repoRoot: string, outJson: string, outMd: string, fresh: CodeMap): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/map/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+DzC,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C3E;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,GACb,IAAI,CAMN"}
@@ -0,0 +1,120 @@
1
+ import { writeFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { generateMap } from "./scan.js";
4
+ import { renderJson, renderMarkdown, mapsEqual, CODE_MAP_JSON_PATH, CODE_MAP_MD_PATH, } from "./render.js";
5
+ function parseArgs(argv) {
6
+ const args = {
7
+ subcommand: "generate",
8
+ repoRoot: process.cwd(),
9
+ out: CODE_MAP_JSON_PATH,
10
+ md: CODE_MAP_MD_PATH,
11
+ };
12
+ const first = argv[0];
13
+ if (first === "generate" || first === "check") {
14
+ args.subcommand = first;
15
+ argv = argv.slice(1);
16
+ }
17
+ else if (first === "--help" || first === "-h") {
18
+ printHelp();
19
+ process.exit(0);
20
+ }
21
+ else if (first && !first.startsWith("-")) {
22
+ console.error(`Unknown subcommand: ${first}`);
23
+ printHelp();
24
+ process.exit(64);
25
+ }
26
+ for (let i = 0; i < argv.length; i++) {
27
+ const a = argv[i];
28
+ const next = argv[i + 1];
29
+ if (a === "--cwd" && next) {
30
+ args.repoRoot = next;
31
+ i++;
32
+ }
33
+ else if (a === "--out" && next) {
34
+ args.out = next;
35
+ i++;
36
+ }
37
+ else if (a === "--md" && next) {
38
+ args.md = next;
39
+ i++;
40
+ }
41
+ else if (a === "--help" || a === "-h") {
42
+ printHelp();
43
+ process.exit(0);
44
+ }
45
+ }
46
+ return args;
47
+ }
48
+ function printHelp() {
49
+ console.log(`
50
+ slowcook map — generate / check the repo-wide code map
51
+
52
+ The map is a structured list of API routes, pages, React components,
53
+ helper functions, and domain types. Lives at \`.brewing/code-map.json\`
54
+ (+ rendered \`.brewing/code-map.md\`). The brewing agent reads it as
55
+ context so it doesn't have to re-read files every iteration.
56
+
57
+ Usage:
58
+ slowcook map generate [--cwd <path>] [--out <path>] [--md <path>]
59
+ slowcook map check [--cwd <path>] [--out <path>]
60
+
61
+ generate Write a fresh map to .brewing/code-map.{json,md}.
62
+ check Fail with exit 1 if the committed map differs from a fresh
63
+ generation. Meant for CI — keeps the map honest.
64
+
65
+ Options:
66
+ --cwd <path> Repo root (default: cwd).
67
+ --out <path> JSON output path (default: .brewing/code-map.json).
68
+ --md <path> Markdown output path (default: .brewing/code-map.md).
69
+ `);
70
+ }
71
+ export async function map(argv, cliVersion) {
72
+ const args = parseArgs(argv);
73
+ const fresh = generateMap({
74
+ repoRoot: args.repoRoot,
75
+ slowcookVersion: cliVersion,
76
+ });
77
+ if (args.subcommand === "generate") {
78
+ writeFreshMap(args.repoRoot, args.out, args.md, fresh);
79
+ summary(fresh);
80
+ return;
81
+ }
82
+ // check: compare existing committed map to a fresh regen
83
+ const existingPath = join(args.repoRoot, args.out);
84
+ if (!existsSync(existingPath)) {
85
+ console.error(`Map check failed: no map found at ${args.out}. Run \`slowcook map generate\` and commit the result.`);
86
+ process.exit(1);
87
+ }
88
+ let existing;
89
+ try {
90
+ existing = JSON.parse(readFileSync(existingPath, "utf8"));
91
+ }
92
+ catch (e) {
93
+ console.error(`Map check failed: could not parse ${args.out} — ${e.message}. Run \`slowcook map generate\` to refresh.`);
94
+ process.exit(1);
95
+ }
96
+ if (mapsEqual(existing, fresh)) {
97
+ console.log(`✓ Map is up to date (${summaryCounts(fresh)}).`);
98
+ return;
99
+ }
100
+ console.error(`✗ Map is stale. The committed \`${args.out}\` does not match what would be generated from the current source tree.\n\n` +
101
+ ` Committed: ${summaryCounts(existing)}\n` +
102
+ ` Fresh: ${summaryCounts(fresh)}\n\n` +
103
+ `Fix by running:\n npx slowcook map generate\nThen commit the updated ${args.out} + ${args.md}.`);
104
+ process.exit(1);
105
+ }
106
+ export function writeFreshMap(repoRoot, outJson, outMd, fresh) {
107
+ const jsonPath = join(repoRoot, outJson);
108
+ const mdPath = join(repoRoot, outMd);
109
+ mkdirSync(dirname(jsonPath), { recursive: true });
110
+ writeFileSync(jsonPath, renderJson(fresh), "utf8");
111
+ writeFileSync(mdPath, renderMarkdown(fresh), "utf8");
112
+ }
113
+ function summary(map) {
114
+ console.log(`Wrote ${CODE_MAP_JSON_PATH} + ${CODE_MAP_MD_PATH}`);
115
+ console.log(` ${summaryCounts(map)}`);
116
+ }
117
+ function summaryCounts(m) {
118
+ return `${m.api_routes.length} routes, ${m.pages.length} pages, ${m.components.length} components, ${m.helpers.length} helpers, ${m.types.length} types`;
119
+ }
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/map/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { CodeMap } from "./scan.js";
2
+ export declare const CODE_MAP_JSON_PATH = ".brewing/code-map.json";
3
+ export declare const CODE_MAP_MD_PATH = ".brewing/code-map.md";
4
+ export declare function renderJson(map: CodeMap): string;
5
+ /**
6
+ * Render a human-readable markdown view. Optimised for two audiences:
7
+ * - contributors skimming the map via the PR diff view, and
8
+ * - the brewing agent reading it as a flat context block.
9
+ *
10
+ * Keep sections compact; JSDoc summaries are trimmed to a single line.
11
+ */
12
+ export declare function renderMarkdown(map: CodeMap): string;
13
+ /**
14
+ * Compare two maps for content equality (ignoring `generated_at`, which
15
+ * changes every regen). Used by `slowcook map check`.
16
+ */
17
+ export declare function mapsEqual(a: CodeMap, b: CodeMap): boolean;
18
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/commands/map/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,eAAO,MAAM,kBAAkB,2BAA2B,CAAC;AAC3D,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CA+EnD;AAgBD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAGzD"}
@@ -0,0 +1,97 @@
1
+ export const CODE_MAP_JSON_PATH = ".brewing/code-map.json";
2
+ export const CODE_MAP_MD_PATH = ".brewing/code-map.md";
3
+ export function renderJson(map) {
4
+ return JSON.stringify(map, null, 2) + "\n";
5
+ }
6
+ /**
7
+ * Render a human-readable markdown view. Optimised for two audiences:
8
+ * - contributors skimming the map via the PR diff view, and
9
+ * - the brewing agent reading it as a flat context block.
10
+ *
11
+ * Keep sections compact; JSDoc summaries are trimmed to a single line.
12
+ */
13
+ export function renderMarkdown(map) {
14
+ const lines = [];
15
+ lines.push(`# Code Map`);
16
+ lines.push("");
17
+ lines.push(`_Generated by slowcook ${map.slowcook_version} at ${map.generated_at}. Regenerate with \`npx slowcook map generate\`. Do not hand-edit._`);
18
+ lines.push("");
19
+ section(lines, "API routes", map.api_routes.length);
20
+ if (map.api_routes.length > 0) {
21
+ lines.push("");
22
+ lines.push("| Method | Path | File | Function | Summary |");
23
+ lines.push("|---|---|---|---|---|");
24
+ for (const r of map.api_routes) {
25
+ lines.push(`| \`${r.method}\` | \`${r.path}\` | \`${r.file}\` | \`${r.function}\` | ${oneLine(r.jsdoc)} |`);
26
+ }
27
+ }
28
+ lines.push("");
29
+ section(lines, "Pages", map.pages.length);
30
+ if (map.pages.length > 0) {
31
+ lines.push("");
32
+ lines.push("| Path | Component | File | Summary |");
33
+ lines.push("|---|---|---|---|");
34
+ for (const p of map.pages) {
35
+ lines.push(`| \`${p.path}\` | ${p.component ? `\`${p.component}\`` : "—"} | \`${p.file}\` | ${oneLine(p.jsdoc)} |`);
36
+ }
37
+ }
38
+ lines.push("");
39
+ section(lines, "Components", map.components.length);
40
+ if (map.components.length > 0) {
41
+ lines.push("");
42
+ lines.push("| Name | Export | Props | File | Summary |");
43
+ lines.push("|---|---|---|---|---|");
44
+ for (const c of map.components) {
45
+ lines.push(`| \`${c.name}\` | ${c.exportKind} | ${c.props_type ? `\`${c.props_type}\`` : "—"} | \`${c.file}\` | ${oneLine(c.jsdoc)} |`);
46
+ }
47
+ }
48
+ lines.push("");
49
+ section(lines, "Helpers", map.helpers.length);
50
+ if (map.helpers.length > 0) {
51
+ lines.push("");
52
+ lines.push("| Name | Kind | File | Signature | Summary |");
53
+ lines.push("|---|---|---|---|---|");
54
+ for (const h of map.helpers) {
55
+ lines.push(`| \`${h.name}\` | ${h.kind} | \`${h.file}\` | \`${escapeTable(h.signature)}\` | ${oneLine(h.jsdoc)} |`);
56
+ }
57
+ }
58
+ lines.push("");
59
+ section(lines, "Types", map.types.length);
60
+ if (map.types.length > 0) {
61
+ lines.push("");
62
+ for (const t of map.types) {
63
+ lines.push(`### ${t.name} (${t.kind}) — \`${t.file}\``);
64
+ if (t.jsdoc) {
65
+ lines.push("");
66
+ lines.push(`> ${oneLine(t.jsdoc)}`);
67
+ }
68
+ lines.push("");
69
+ lines.push("```ts");
70
+ lines.push(t.declaration);
71
+ lines.push("```");
72
+ lines.push("");
73
+ }
74
+ }
75
+ return lines.join("\n");
76
+ }
77
+ function section(lines, label, count) {
78
+ lines.push(`## ${label} (${count})`);
79
+ }
80
+ function oneLine(s) {
81
+ if (!s)
82
+ return "";
83
+ const first = s.split("\n")[0] ?? "";
84
+ return first.replace(/\|/g, "\\|").trim();
85
+ }
86
+ function escapeTable(s) {
87
+ return s.replace(/\|/g, "\\|");
88
+ }
89
+ /**
90
+ * Compare two maps for content equality (ignoring `generated_at`, which
91
+ * changes every regen). Used by `slowcook map check`.
92
+ */
93
+ export function mapsEqual(a, b) {
94
+ const stripTime = (m) => ({ ...m, generated_at: "__ignored__" });
95
+ return JSON.stringify(stripTime(a)) === JSON.stringify(stripTime(b));
96
+ }
97
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/map/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * ts-morph scanner. Walks a consumer's `src/` tree and produces a structured
3
+ * CodeMap. Covers five entity kinds the brewing agent benefits from seeing
4
+ * without having to open every file:
5
+ *
6
+ * 1. API routes — Next.js App Router (`src/app/**\/route.ts(x)`)
7
+ * 2. Pages — Next.js App Router (`src/app/**\/page.tsx`)
8
+ * 3. Components — `src/components/**\/*.tsx` (exported React components)
9
+ * 4. Helpers — `src/lib/**\/*.ts`, `src/utils/**\/*.ts` (exported fns/consts/classes)
10
+ * 5. Types — `src/types/**\/*.ts` (exported types/interfaces/enums)
11
+ *
12
+ * Scope is deliberately Next.js + TypeScript-centric for v1 — the engine is
13
+ * general enough to extend (different frameworks would register their own
14
+ * route-URL derivation), but today we only ship Next.js App Router detection.
15
+ *
16
+ * Output is a plain object — the CLI entry serialises to JSON + renders
17
+ * Markdown. No I/O here beyond reading source files via ts-morph.
18
+ */
19
+ export interface ApiRouteEntry {
20
+ method: string;
21
+ path: string;
22
+ file: string;
23
+ function: string;
24
+ jsdoc?: string;
25
+ imports: string[];
26
+ }
27
+ export interface PageEntry {
28
+ path: string;
29
+ file: string;
30
+ component?: string;
31
+ jsdoc?: string;
32
+ }
33
+ export interface ComponentEntry {
34
+ name: string;
35
+ file: string;
36
+ exportKind: "default" | "named";
37
+ props_type?: string;
38
+ jsdoc?: string;
39
+ }
40
+ export interface HelperEntry {
41
+ name: string;
42
+ kind: "function" | "const" | "class";
43
+ file: string;
44
+ signature: string;
45
+ jsdoc?: string;
46
+ }
47
+ export interface TypeEntry {
48
+ name: string;
49
+ kind: "interface" | "type" | "enum";
50
+ file: string;
51
+ declaration: string;
52
+ jsdoc?: string;
53
+ }
54
+ export interface CodeMap {
55
+ schema_version: 1;
56
+ slowcook_version: string;
57
+ generated_at: string;
58
+ repo_root: string;
59
+ api_routes: ApiRouteEntry[];
60
+ pages: PageEntry[];
61
+ components: ComponentEntry[];
62
+ helpers: HelperEntry[];
63
+ types: TypeEntry[];
64
+ }
65
+ export interface GenerateMapOptions {
66
+ repoRoot: string;
67
+ slowcookVersion: string;
68
+ now?: Date;
69
+ }
70
+ export declare function generateMap(opts: GenerateMapOptions): CodeMap;
71
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/commands/map/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAiBH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,CAAC,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAiE7D"}