@sudocode-ai/integration-speckit 0.1.14

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 (53) hide show
  1. package/dist/id-generator.d.ts +149 -0
  2. package/dist/id-generator.d.ts.map +1 -0
  3. package/dist/id-generator.js +197 -0
  4. package/dist/id-generator.js.map +1 -0
  5. package/dist/index.d.ts +33 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +1017 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/parser/index.d.ts +11 -0
  10. package/dist/parser/index.d.ts.map +1 -0
  11. package/dist/parser/index.js +16 -0
  12. package/dist/parser/index.js.map +1 -0
  13. package/dist/parser/markdown-utils.d.ts +138 -0
  14. package/dist/parser/markdown-utils.d.ts.map +1 -0
  15. package/dist/parser/markdown-utils.js +283 -0
  16. package/dist/parser/markdown-utils.js.map +1 -0
  17. package/dist/parser/plan-parser.d.ts +97 -0
  18. package/dist/parser/plan-parser.d.ts.map +1 -0
  19. package/dist/parser/plan-parser.js +286 -0
  20. package/dist/parser/plan-parser.js.map +1 -0
  21. package/dist/parser/spec-parser.d.ts +95 -0
  22. package/dist/parser/spec-parser.d.ts.map +1 -0
  23. package/dist/parser/spec-parser.js +250 -0
  24. package/dist/parser/spec-parser.js.map +1 -0
  25. package/dist/parser/supporting-docs.d.ts +119 -0
  26. package/dist/parser/supporting-docs.d.ts.map +1 -0
  27. package/dist/parser/supporting-docs.js +324 -0
  28. package/dist/parser/supporting-docs.js.map +1 -0
  29. package/dist/parser/tasks-parser.d.ts +171 -0
  30. package/dist/parser/tasks-parser.d.ts.map +1 -0
  31. package/dist/parser/tasks-parser.js +281 -0
  32. package/dist/parser/tasks-parser.js.map +1 -0
  33. package/dist/relationship-mapper.d.ts +165 -0
  34. package/dist/relationship-mapper.d.ts.map +1 -0
  35. package/dist/relationship-mapper.js +238 -0
  36. package/dist/relationship-mapper.js.map +1 -0
  37. package/dist/watcher.d.ts +137 -0
  38. package/dist/watcher.d.ts.map +1 -0
  39. package/dist/watcher.js +599 -0
  40. package/dist/watcher.js.map +1 -0
  41. package/dist/writer/index.d.ts +8 -0
  42. package/dist/writer/index.d.ts.map +1 -0
  43. package/dist/writer/index.js +10 -0
  44. package/dist/writer/index.js.map +1 -0
  45. package/dist/writer/spec-writer.d.ts +70 -0
  46. package/dist/writer/spec-writer.d.ts.map +1 -0
  47. package/dist/writer/spec-writer.js +261 -0
  48. package/dist/writer/spec-writer.js.map +1 -0
  49. package/dist/writer/tasks-writer.d.ts +47 -0
  50. package/dist/writer/tasks-writer.d.ts.map +1 -0
  51. package/dist/writer/tasks-writer.js +161 -0
  52. package/dist/writer/tasks-writer.js.map +1 -0
  53. package/package.json +42 -0
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Tasks Parser for Spec-Kit Integration
3
+ *
4
+ * Parses tasks.md files from spec-kit and extracts individual tasks.
5
+ *
6
+ * Expected format:
7
+ * ```markdown
8
+ * # Tasks
9
+ *
10
+ * ## Phase 1: Foundation
11
+ *
12
+ * - [ ] T001 [P] Setup project structure
13
+ * - [ ] T002 [US1] Create user model
14
+ * - [x] T003: Completed task
15
+ *
16
+ * ## Phase 2: Implementation
17
+ *
18
+ * - [ ] T004 [P] [US2] Implement authentication
19
+ * ```
20
+ *
21
+ * Task format: `- [ ] T001 [P?] [US?] Description`
22
+ * - Checkbox: `[ ]` (incomplete) or `[x]` (complete)
23
+ * - Task ID: T followed by digits (T001, T002, etc.)
24
+ * - Parallelizable: Optional `[P]` marker
25
+ * - User Story: Optional `[US1]`, `[US2]`, etc.
26
+ * - Description: Rest of the line
27
+ */
28
+ import { readFileSync, existsSync } from "fs";
29
+ import { PATTERNS, extractMetadata, extractTitle, cleanTaskDescription, } from "./markdown-utils.js";
30
+ /**
31
+ * Parse a tasks.md file and extract all tasks
32
+ *
33
+ * @param filePath - Absolute path to the tasks.md file
34
+ * @param options - Parsing options
35
+ * @returns Parsed tasks data or null if file doesn't exist
36
+ *
37
+ * @example
38
+ * const tasksFile = parseTasks("/project/.specify/specs/001-auth/tasks.md");
39
+ * console.log(tasksFile?.tasks.length); // 10
40
+ * console.log(tasksFile?.stats.completed); // 3
41
+ */
42
+ export function parseTasks(filePath, options = {}) {
43
+ if (!existsSync(filePath)) {
44
+ return null;
45
+ }
46
+ try {
47
+ const content = readFileSync(filePath, "utf-8");
48
+ return parseTasksContent(content, filePath, options);
49
+ }
50
+ catch (error) {
51
+ console.error(`[tasks-parser] Failed to parse ${filePath}:`, error);
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Parse tasks content from a string (for testing or in-memory parsing)
57
+ *
58
+ * @param content - Markdown content string
59
+ * @param filePath - Optional file path for reference
60
+ * @param options - Parsing options
61
+ * @returns Parsed tasks data or null
62
+ */
63
+ export function parseTasksContent(content, filePath = "<string>", options = {}) {
64
+ const lines = content.split("\n");
65
+ const tasks = [];
66
+ const phases = new Map();
67
+ // Extract title and metadata
68
+ const title = extractTitle(lines);
69
+ const metadata = extractMetadata(lines);
70
+ // Track current phase
71
+ let currentPhase = null;
72
+ let currentPhaseName = null;
73
+ // Parse each line
74
+ for (let i = 0; i < lines.length; i++) {
75
+ const line = lines[i];
76
+ const lineNumber = i + 1; // 1-indexed
77
+ // Check for phase header
78
+ const phaseMatch = line.match(PATTERNS.PHASE_HEADER);
79
+ if (phaseMatch) {
80
+ currentPhase = parseInt(phaseMatch[1], 10);
81
+ currentPhaseName = phaseMatch[2]?.trim() || null;
82
+ phases.set(currentPhase, currentPhaseName || `Phase ${currentPhase}`);
83
+ continue;
84
+ }
85
+ // Check for task line
86
+ const taskMatch = line.match(PATTERNS.TASK_LINE);
87
+ if (taskMatch) {
88
+ const task = parseTaskLine(line, taskMatch, lineNumber, currentPhase, currentPhaseName);
89
+ // Apply filters
90
+ if (shouldIncludeTask(task, options)) {
91
+ tasks.push(task);
92
+ }
93
+ }
94
+ }
95
+ // Calculate stats
96
+ const stats = {
97
+ total: tasks.length,
98
+ completed: tasks.filter((t) => t.completed).length,
99
+ incomplete: tasks.filter((t) => !t.completed).length,
100
+ parallelizable: tasks.filter((t) => t.parallelizable).length,
101
+ };
102
+ return {
103
+ title,
104
+ metadata,
105
+ tasks,
106
+ phases,
107
+ filePath,
108
+ stats,
109
+ };
110
+ }
111
+ /**
112
+ * Parse a single task line
113
+ */
114
+ function parseTaskLine(line, match, lineNumber, phase, phaseName) {
115
+ const [, leadingSpace, checkbox, taskId, rest] = match;
116
+ // Calculate indent level (2 spaces = 1 level)
117
+ const indentLevel = Math.floor(leadingSpace.replace("-", "").length / 2);
118
+ // Check for parallelizable marker
119
+ const parallelizable = PATTERNS.PARALLELIZABLE.test(rest);
120
+ // Check for user story marker
121
+ const userStoryMatch = rest.match(PATTERNS.USER_STORY);
122
+ const userStory = userStoryMatch ? userStoryMatch[1] : null;
123
+ // Clean description
124
+ const description = cleanTaskDescription(rest);
125
+ return {
126
+ taskId,
127
+ description,
128
+ completed: checkbox.toLowerCase() === "x",
129
+ parallelizable,
130
+ userStory,
131
+ phase,
132
+ phaseName,
133
+ lineNumber,
134
+ indentLevel,
135
+ rawLine: line,
136
+ };
137
+ }
138
+ /**
139
+ * Check if a task should be included based on filters
140
+ */
141
+ function shouldIncludeTask(task, options) {
142
+ // Phase filter
143
+ if (options.filterPhases && options.filterPhases.length > 0) {
144
+ if (task.phase === null || !options.filterPhases.includes(task.phase)) {
145
+ return false;
146
+ }
147
+ }
148
+ // Incomplete only filter
149
+ if (options.incompleteOnly && task.completed) {
150
+ return false;
151
+ }
152
+ // Parallelizable only filter
153
+ if (options.parallelizableOnly && !task.parallelizable) {
154
+ return false;
155
+ }
156
+ return true;
157
+ }
158
+ /**
159
+ * Get all tasks from a file as a simple array
160
+ *
161
+ * @param filePath - Path to the tasks file
162
+ * @returns Array of parsed tasks or empty array
163
+ */
164
+ export function getAllTasks(filePath) {
165
+ const result = parseTasks(filePath);
166
+ return result?.tasks || [];
167
+ }
168
+ /**
169
+ * Get a specific task by ID
170
+ *
171
+ * @param filePath - Path to the tasks file
172
+ * @param taskId - Task ID to find (e.g., "T001")
173
+ * @returns The task or null if not found
174
+ */
175
+ export function getTaskById(filePath, taskId) {
176
+ const tasks = getAllTasks(filePath);
177
+ return tasks.find((t) => t.taskId === taskId) || null;
178
+ }
179
+ /**
180
+ * Get incomplete tasks ready for work (not blocked by dependencies)
181
+ *
182
+ * @param filePath - Path to the tasks file
183
+ * @returns Array of incomplete tasks
184
+ */
185
+ export function getIncompleteTasks(filePath) {
186
+ const result = parseTasks(filePath, { incompleteOnly: true });
187
+ return result?.tasks || [];
188
+ }
189
+ /**
190
+ * Get tasks that can be worked on in parallel
191
+ *
192
+ * @param filePath - Path to the tasks file
193
+ * @returns Array of parallelizable incomplete tasks
194
+ */
195
+ export function getParallelizableTasks(filePath) {
196
+ const result = parseTasks(filePath, {
197
+ incompleteOnly: true,
198
+ parallelizableOnly: true,
199
+ });
200
+ return result?.tasks || [];
201
+ }
202
+ /**
203
+ * Get tasks grouped by phase
204
+ *
205
+ * @param filePath - Path to the tasks file
206
+ * @returns Map of phase number to tasks in that phase
207
+ */
208
+ export function getTasksByPhase(filePath) {
209
+ const result = parseTasks(filePath);
210
+ const byPhase = new Map();
211
+ if (!result)
212
+ return byPhase;
213
+ for (const task of result.tasks) {
214
+ const phase = task.phase ?? 0; // Default to phase 0 for tasks without phase
215
+ const phaseTasks = byPhase.get(phase) || [];
216
+ phaseTasks.push(task);
217
+ byPhase.set(phase, phaseTasks);
218
+ }
219
+ return byPhase;
220
+ }
221
+ /**
222
+ * Get tasks grouped by user story
223
+ *
224
+ * @param filePath - Path to the tasks file
225
+ * @returns Map of user story ID to tasks
226
+ */
227
+ export function getTasksByUserStory(filePath) {
228
+ const result = parseTasks(filePath);
229
+ const byUserStory = new Map();
230
+ if (!result)
231
+ return byUserStory;
232
+ for (const task of result.tasks) {
233
+ const storyTasks = byUserStory.get(task.userStory) || [];
234
+ storyTasks.push(task);
235
+ byUserStory.set(task.userStory, storyTasks);
236
+ }
237
+ return byUserStory;
238
+ }
239
+ /**
240
+ * Check if a file appears to be a valid tasks.md file
241
+ *
242
+ * @param filePath - Path to check
243
+ * @returns true if the file looks like a tasks file
244
+ */
245
+ export function isTasksFile(filePath) {
246
+ if (!existsSync(filePath)) {
247
+ return false;
248
+ }
249
+ try {
250
+ const content = readFileSync(filePath, "utf-8");
251
+ const lines = content.split("\n").slice(0, 30); // Check first 30 lines
252
+ // Look for task-like lines
253
+ for (const line of lines) {
254
+ if (PATTERNS.TASK_LINE.test(line)) {
255
+ return true;
256
+ }
257
+ }
258
+ return false;
259
+ }
260
+ catch {
261
+ return false;
262
+ }
263
+ }
264
+ /**
265
+ * Get task completion statistics
266
+ *
267
+ * @param filePath - Path to the tasks file
268
+ * @returns Statistics object or null
269
+ */
270
+ export function getTaskStats(filePath) {
271
+ const result = parseTasks(filePath);
272
+ if (!result)
273
+ return null;
274
+ return {
275
+ ...result.stats,
276
+ completionRate: result.stats.total > 0
277
+ ? Math.round((result.stats.completed / result.stats.total) * 100)
278
+ : 0,
279
+ };
280
+ }
281
+ //# sourceMappingURL=tasks-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-parser.js","sourceRoot":"","sources":["../../src/parser/tasks-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Relationship Mapping for Spec-Kit Integration
3
+ *
4
+ * Maps spec-kit file hierarchy to sudocode relationships.
5
+ *
6
+ * Spec-kit hierarchy:
7
+ * ```
8
+ * spec.md (root)
9
+ * └── plan.md (implements spec.md)
10
+ * ├── tasks (implement plan.md)
11
+ * ├── research.md (references plan.md)
12
+ * ├── data-model.md (references plan.md)
13
+ * └── contracts/* (references plan.md)
14
+ * ```
15
+ *
16
+ * This creates a clear dependency graph:
17
+ * - plan implements spec (spec defines WHAT, plan defines HOW)
18
+ * - tasks implement plan (tasks are actionable work items from the plan)
19
+ * - supporting docs reference plan (research, data models, contracts support the plan)
20
+ */
21
+ import type { RelationshipType, EntityType } from "@sudocode-ai/types";
22
+ /**
23
+ * A relationship to be created in sudocode
24
+ */
25
+ export interface MappedRelationship {
26
+ /** Source entity ID */
27
+ fromId: string;
28
+ /** Source entity type */
29
+ fromType: EntityType;
30
+ /** Target entity ID */
31
+ toId: string;
32
+ /** Target entity type */
33
+ toType: EntityType;
34
+ /** Relationship type */
35
+ relationshipType: RelationshipType;
36
+ }
37
+ /**
38
+ * Task information for relationship mapping
39
+ */
40
+ export interface TaskInfo {
41
+ /** Task ID from tasks.md (e.g., "T001", "T002") */
42
+ taskId: string;
43
+ /** Optional: task dependencies (other task IDs this task depends on) */
44
+ dependsOn?: string[];
45
+ }
46
+ /**
47
+ * Supporting document information
48
+ */
49
+ export interface SupportingDocInfo {
50
+ /** File type identifier (e.g., "research", "data-model", "contract-api-spec") */
51
+ fileType: string;
52
+ /** Entity type in sudocode */
53
+ entityType: EntityType;
54
+ }
55
+ /**
56
+ * Map all relationships for a spec-kit feature
57
+ *
58
+ * Creates the standard relationship hierarchy:
59
+ * 1. plan implements spec
60
+ * 2. each task implements plan
61
+ * 3. supporting docs reference plan
62
+ *
63
+ * @param featureNumber - Feature number (e.g., "001")
64
+ * @param prefix - Spec ID prefix (default: "sk")
65
+ * @param taskPrefix - Task issue ID prefix (default: "skt")
66
+ * @param tasks - Array of task information from tasks.md
67
+ * @param supportingDocs - Optional array of supporting documents to include
68
+ * @returns Array of relationships to create
69
+ *
70
+ * @example
71
+ * const relationships = mapFeatureRelationships("001", "sk", "skt", [
72
+ * { taskId: "T001" },
73
+ * { taskId: "T002", dependsOn: ["T001"] },
74
+ * ]);
75
+ * // Returns relationships:
76
+ * // - sk-001-plan implements sk-001-spec
77
+ * // - skt-001-T001 implements sk-001-plan
78
+ * // - skt-001-T002 implements sk-001-plan
79
+ * // - skt-001-T002 depends-on skt-001-T001
80
+ */
81
+ export declare function mapFeatureRelationships(featureNumber: string, prefix?: string, taskPrefix?: string, tasks?: TaskInfo[], supportingDocs?: SupportingDocInfo[]): MappedRelationship[];
82
+ /**
83
+ * Map relationships for task dependencies within a feature
84
+ *
85
+ * @param featureNumber - Feature number (e.g., "001")
86
+ * @param taskPrefix - Task issue ID prefix (default: "skt")
87
+ * @param tasks - Array of tasks with their dependencies
88
+ * @returns Array of depends-on relationships between tasks
89
+ *
90
+ * @example
91
+ * const deps = mapTaskDependencies("001", "skt", [
92
+ * { taskId: "T001" },
93
+ * { taskId: "T002", dependsOn: ["T001"] },
94
+ * { taskId: "T003", dependsOn: ["T001", "T002"] },
95
+ * ]);
96
+ * // Returns:
97
+ * // - skt-001-T002 depends-on skt-001-T001
98
+ * // - skt-001-T003 depends-on skt-001-T001
99
+ * // - skt-001-T003 depends-on skt-001-T002
100
+ */
101
+ export declare function mapTaskDependencies(featureNumber: string, taskPrefix: string | undefined, tasks: TaskInfo[]): MappedRelationship[];
102
+ /**
103
+ * Map relationships for supporting documents in a feature
104
+ *
105
+ * @param featureNumber - Feature number (e.g., "001")
106
+ * @param prefix - Spec ID prefix (default: "sk")
107
+ * @param supportingDocs - Array of supporting document information
108
+ * @returns Array of reference relationships to the plan
109
+ *
110
+ * @example
111
+ * const refs = mapSupportingDocRelationships("001", "sk", [
112
+ * { fileType: "research", entityType: "spec" },
113
+ * { fileType: "data-model", entityType: "spec" },
114
+ * { fileType: "contract-api-spec", entityType: "spec" },
115
+ * ]);
116
+ * // Returns:
117
+ * // - sk-001-research references sk-001-plan
118
+ * // - sk-001-data-model references sk-001-plan
119
+ * // - sk-001-contract-api-spec references sk-001-plan
120
+ */
121
+ export declare function mapSupportingDocRelationships(featureNumber: string, prefix: string | undefined, supportingDocs: SupportingDocInfo[]): MappedRelationship[];
122
+ /**
123
+ * Map the core spec->plan relationship for a feature
124
+ *
125
+ * @param featureNumber - Feature number (e.g., "001")
126
+ * @param prefix - Spec ID prefix (default: "sk")
127
+ * @returns The implements relationship from plan to spec
128
+ *
129
+ * @example
130
+ * const rel = mapPlanToSpecRelationship("001");
131
+ * // Returns: sk-001-plan implements sk-001-spec
132
+ */
133
+ export declare function mapPlanToSpecRelationship(featureNumber: string, prefix?: string): MappedRelationship;
134
+ /**
135
+ * Map a single task's relationship to its plan
136
+ *
137
+ * @param featureNumber - Feature number (e.g., "001")
138
+ * @param taskId - Task ID (e.g., "T001")
139
+ * @param prefix - Spec ID prefix (default: "sk")
140
+ * @param taskPrefix - Task issue ID prefix (default: "skt")
141
+ * @returns The implements relationship from task to plan
142
+ *
143
+ * @example
144
+ * const rel = mapTaskToPlanRelationship("001", "T001");
145
+ * // Returns: skt-001-T001 implements sk-001-plan
146
+ */
147
+ export declare function mapTaskToPlanRelationship(featureNumber: string, taskId: string, prefix?: string, taskPrefix?: string): MappedRelationship;
148
+ /**
149
+ * Determine the standard supporting doc types for a feature
150
+ *
151
+ * @returns Array of standard supporting document types
152
+ */
153
+ export declare function getStandardSupportingDocTypes(): SupportingDocInfo[];
154
+ /**
155
+ * Create a contract document info for relationship mapping
156
+ *
157
+ * @param contractName - Contract file name without extension (e.g., "api-spec")
158
+ * @returns Supporting doc info for the contract
159
+ *
160
+ * @example
161
+ * createContractDocInfo("api-spec")
162
+ * // Returns: { fileType: "contract-api-spec", entityType: "spec" }
163
+ */
164
+ export declare function createContractDocInfo(contractName: string): SupportingDocInfo;
165
+ //# sourceMappingURL=relationship-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationship-mapper.d.ts","sourceRoot":"","sources":["../src/relationship-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOvE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,QAAQ,EAAE,UAAU,CAAC;IACrB,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,wBAAwB;IACxB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,UAAU,EAAE,UAAU,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,MAAa,EACrB,UAAU,GAAE,MAAc,EAC1B,KAAK,GAAE,QAAQ,EAAO,EACtB,cAAc,GAAE,iBAAiB,EAAO,GACvC,kBAAkB,EAAE,CA+DtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,YAAQ,EAC1B,KAAK,EAAE,QAAQ,EAAE,GAChB,kBAAkB,EAAE,CA6BtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,YAAO,EACrB,cAAc,EAAE,iBAAiB,EAAE,GAClC,kBAAkB,EAAE,CAgBtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,MAAa,GACpB,kBAAkB,CAQpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAa,EACrB,UAAU,GAAE,MAAc,GACzB,kBAAkB,CAQpB;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,iBAAiB,EAAE,CAKnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAK7E"}