@diegonogueiradev_/mcp-graph 1.0.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 (233) hide show
  1. package/dist/core/context/compact-context.d.ts +51 -0
  2. package/dist/core/context/compact-context.d.ts.map +1 -0
  3. package/dist/core/context/compact-context.js +115 -0
  4. package/dist/core/context/compact-context.js.map +1 -0
  5. package/dist/core/context/rag-context.d.ts +36 -0
  6. package/dist/core/context/rag-context.d.ts.map +1 -0
  7. package/dist/core/context/rag-context.js +69 -0
  8. package/dist/core/context/rag-context.js.map +1 -0
  9. package/dist/core/context/token-estimator.d.ts +7 -0
  10. package/dist/core/context/token-estimator.d.ts.map +1 -0
  11. package/dist/core/context/token-estimator.js +9 -0
  12. package/dist/core/context/token-estimator.js.map +1 -0
  13. package/dist/core/graph/graph-indexes.d.ts +3 -0
  14. package/dist/core/graph/graph-indexes.d.ts.map +1 -0
  15. package/dist/core/graph/graph-indexes.js +28 -0
  16. package/dist/core/graph/graph-indexes.js.map +1 -0
  17. package/dist/core/graph/graph-types.d.ts +72 -0
  18. package/dist/core/graph/graph-types.d.ts.map +1 -0
  19. package/dist/core/graph/graph-types.js +2 -0
  20. package/dist/core/graph/graph-types.js.map +1 -0
  21. package/dist/core/importer/import-prd.d.ts +7 -0
  22. package/dist/core/importer/import-prd.d.ts.map +1 -0
  23. package/dist/core/importer/import-prd.js +7 -0
  24. package/dist/core/importer/import-prd.js.map +1 -0
  25. package/dist/core/importer/prd-to-graph.d.ts +18 -0
  26. package/dist/core/importer/prd-to-graph.d.ts.map +1 -0
  27. package/dist/core/importer/prd-to-graph.js +188 -0
  28. package/dist/core/importer/prd-to-graph.js.map +1 -0
  29. package/dist/core/parser/classify.d.ts +31 -0
  30. package/dist/core/parser/classify.d.ts.map +1 -0
  31. package/dist/core/parser/classify.js +128 -0
  32. package/dist/core/parser/classify.js.map +1 -0
  33. package/dist/core/parser/extract.d.ts +21 -0
  34. package/dist/core/parser/extract.d.ts.map +1 -0
  35. package/dist/core/parser/extract.js +66 -0
  36. package/dist/core/parser/extract.js.map +1 -0
  37. package/dist/core/parser/normalize.d.ts +9 -0
  38. package/dist/core/parser/normalize.d.ts.map +1 -0
  39. package/dist/core/parser/normalize.js +22 -0
  40. package/dist/core/parser/normalize.js.map +1 -0
  41. package/dist/core/parser/read-file.d.ts +7 -0
  42. package/dist/core/parser/read-file.d.ts.map +1 -0
  43. package/dist/core/parser/read-file.js +17 -0
  44. package/dist/core/parser/read-file.js.map +1 -0
  45. package/dist/core/parser/segment.d.ts +13 -0
  46. package/dist/core/parser/segment.d.ts.map +1 -0
  47. package/dist/core/parser/segment.js +53 -0
  48. package/dist/core/parser/segment.js.map +1 -0
  49. package/dist/core/planner/decompose.d.ts +25 -0
  50. package/dist/core/planner/decompose.d.ts.map +1 -0
  51. package/dist/core/planner/decompose.js +100 -0
  52. package/dist/core/planner/decompose.js.map +1 -0
  53. package/dist/core/planner/dependency-chain.d.ts +20 -0
  54. package/dist/core/planner/dependency-chain.d.ts.map +1 -0
  55. package/dist/core/planner/dependency-chain.js +163 -0
  56. package/dist/core/planner/dependency-chain.js.map +1 -0
  57. package/dist/core/planner/next-task.d.ts +16 -0
  58. package/dist/core/planner/next-task.d.ts.map +1 -0
  59. package/dist/core/planner/next-task.js +76 -0
  60. package/dist/core/planner/next-task.js.map +1 -0
  61. package/dist/core/planner/velocity.d.ts +38 -0
  62. package/dist/core/planner/velocity.d.ts.map +1 -0
  63. package/dist/core/planner/velocity.js +92 -0
  64. package/dist/core/planner/velocity.js.map +1 -0
  65. package/dist/core/search/fts-search.d.ts +16 -0
  66. package/dist/core/search/fts-search.d.ts.map +1 -0
  67. package/dist/core/search/fts-search.js +57 -0
  68. package/dist/core/search/fts-search.js.map +1 -0
  69. package/dist/core/search/tfidf.d.ts +32 -0
  70. package/dist/core/search/tfidf.d.ts.map +1 -0
  71. package/dist/core/search/tfidf.js +67 -0
  72. package/dist/core/search/tfidf.js.map +1 -0
  73. package/dist/core/search/tokenizer.d.ts +9 -0
  74. package/dist/core/search/tokenizer.d.ts.map +1 -0
  75. package/dist/core/search/tokenizer.js +37 -0
  76. package/dist/core/search/tokenizer.js.map +1 -0
  77. package/dist/core/store/migrations.d.ts +4 -0
  78. package/dist/core/store/migrations.d.ts.map +1 -0
  79. package/dist/core/store/migrations.js +137 -0
  80. package/dist/core/store/migrations.js.map +1 -0
  81. package/dist/core/store/sqlite-store.d.ts +68 -0
  82. package/dist/core/store/sqlite-store.d.ts.map +1 -0
  83. package/dist/core/store/sqlite-store.js +608 -0
  84. package/dist/core/store/sqlite-store.js.map +1 -0
  85. package/dist/core/utils/errors.d.ts +20 -0
  86. package/dist/core/utils/errors.d.ts.map +1 -0
  87. package/dist/core/utils/errors.js +39 -0
  88. package/dist/core/utils/errors.js.map +1 -0
  89. package/dist/core/utils/fs.d.ts +2 -0
  90. package/dist/core/utils/fs.d.ts.map +1 -0
  91. package/dist/core/utils/fs.js +11 -0
  92. package/dist/core/utils/fs.js.map +1 -0
  93. package/dist/core/utils/id.d.ts +2 -0
  94. package/dist/core/utils/id.d.ts.map +1 -0
  95. package/dist/core/utils/id.js +6 -0
  96. package/dist/core/utils/id.js.map +1 -0
  97. package/dist/core/utils/logger.d.ts +7 -0
  98. package/dist/core/utils/logger.d.ts.map +1 -0
  99. package/dist/core/utils/logger.js +23 -0
  100. package/dist/core/utils/logger.js.map +1 -0
  101. package/dist/core/utils/time.d.ts +2 -0
  102. package/dist/core/utils/time.d.ts.map +1 -0
  103. package/dist/core/utils/time.js +4 -0
  104. package/dist/core/utils/time.js.map +1 -0
  105. package/dist/index.d.ts +10 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +9 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/mcp/init-project.d.ts +2 -0
  110. package/dist/mcp/init-project.d.ts.map +1 -0
  111. package/dist/mcp/init-project.js +104 -0
  112. package/dist/mcp/init-project.js.map +1 -0
  113. package/dist/mcp/server.d.ts +2 -0
  114. package/dist/mcp/server.d.ts.map +1 -0
  115. package/dist/mcp/server.js +30 -0
  116. package/dist/mcp/server.js.map +1 -0
  117. package/dist/mcp/stdio.d.ts +3 -0
  118. package/dist/mcp/stdio.d.ts.map +1 -0
  119. package/dist/mcp/stdio.js +20 -0
  120. package/dist/mcp/stdio.js.map +1 -0
  121. package/dist/mcp/tools/add-edge.d.ts +4 -0
  122. package/dist/mcp/tools/add-edge.d.ts.map +1 -0
  123. package/dist/mcp/tools/add-edge.js +62 -0
  124. package/dist/mcp/tools/add-edge.js.map +1 -0
  125. package/dist/mcp/tools/add-node.d.ts +4 -0
  126. package/dist/mcp/tools/add-node.d.ts.map +1 -0
  127. package/dist/mcp/tools/add-node.js +80 -0
  128. package/dist/mcp/tools/add-node.js.map +1 -0
  129. package/dist/mcp/tools/bulk-update-status.d.ts +4 -0
  130. package/dist/mcp/tools/bulk-update-status.d.ts.map +1 -0
  131. package/dist/mcp/tools/bulk-update-status.js +19 -0
  132. package/dist/mcp/tools/bulk-update-status.js.map +1 -0
  133. package/dist/mcp/tools/clone-node.d.ts +4 -0
  134. package/dist/mcp/tools/clone-node.d.ts.map +1 -0
  135. package/dist/mcp/tools/clone-node.js +107 -0
  136. package/dist/mcp/tools/clone-node.js.map +1 -0
  137. package/dist/mcp/tools/context.d.ts +4 -0
  138. package/dist/mcp/tools/context.d.ts.map +1 -0
  139. package/dist/mcp/tools/context.js +26 -0
  140. package/dist/mcp/tools/context.js.map +1 -0
  141. package/dist/mcp/tools/decompose.d.ts +4 -0
  142. package/dist/mcp/tools/decompose.d.ts.map +1 -0
  143. package/dist/mcp/tools/decompose.js +22 -0
  144. package/dist/mcp/tools/decompose.js.map +1 -0
  145. package/dist/mcp/tools/delete-edge.d.ts +4 -0
  146. package/dist/mcp/tools/delete-edge.d.ts.map +1 -0
  147. package/dist/mcp/tools/delete-edge.js +25 -0
  148. package/dist/mcp/tools/delete-edge.js.map +1 -0
  149. package/dist/mcp/tools/delete-node.d.ts +4 -0
  150. package/dist/mcp/tools/delete-node.d.ts.map +1 -0
  151. package/dist/mcp/tools/delete-node.js +25 -0
  152. package/dist/mcp/tools/delete-node.js.map +1 -0
  153. package/dist/mcp/tools/dependencies.d.ts +4 -0
  154. package/dist/mcp/tools/dependencies.d.ts.map +1 -0
  155. package/dist/mcp/tools/dependencies.js +42 -0
  156. package/dist/mcp/tools/dependencies.js.map +1 -0
  157. package/dist/mcp/tools/export-graph.d.ts +4 -0
  158. package/dist/mcp/tools/export-graph.d.ts.map +1 -0
  159. package/dist/mcp/tools/export-graph.js +14 -0
  160. package/dist/mcp/tools/export-graph.js.map +1 -0
  161. package/dist/mcp/tools/import-prd.d.ts +4 -0
  162. package/dist/mcp/tools/import-prd.d.ts.map +1 -0
  163. package/dist/mcp/tools/import-prd.js +72 -0
  164. package/dist/mcp/tools/import-prd.js.map +1 -0
  165. package/dist/mcp/tools/index.d.ts +4 -0
  166. package/dist/mcp/tools/index.d.ts.map +1 -0
  167. package/dist/mcp/tools/index.js +53 -0
  168. package/dist/mcp/tools/index.js.map +1 -0
  169. package/dist/mcp/tools/init.d.ts +4 -0
  170. package/dist/mcp/tools/init.d.ts.map +1 -0
  171. package/dist/mcp/tools/init.js +15 -0
  172. package/dist/mcp/tools/init.js.map +1 -0
  173. package/dist/mcp/tools/list-edges.d.ts +4 -0
  174. package/dist/mcp/tools/list-edges.d.ts.map +1 -0
  175. package/dist/mcp/tools/list-edges.js +49 -0
  176. package/dist/mcp/tools/list-edges.js.map +1 -0
  177. package/dist/mcp/tools/list.d.ts +4 -0
  178. package/dist/mcp/tools/list.d.ts.map +1 -0
  179. package/dist/mcp/tools/list.js +53 -0
  180. package/dist/mcp/tools/list.js.map +1 -0
  181. package/dist/mcp/tools/move-node.d.ts +4 -0
  182. package/dist/mcp/tools/move-node.d.ts.map +1 -0
  183. package/dist/mcp/tools/move-node.js +107 -0
  184. package/dist/mcp/tools/move-node.js.map +1 -0
  185. package/dist/mcp/tools/next.d.ts +4 -0
  186. package/dist/mcp/tools/next.d.ts.map +1 -0
  187. package/dist/mcp/tools/next.js +28 -0
  188. package/dist/mcp/tools/next.js.map +1 -0
  189. package/dist/mcp/tools/rag-context.d.ts +4 -0
  190. package/dist/mcp/tools/rag-context.d.ts.map +1 -0
  191. package/dist/mcp/tools/rag-context.js +25 -0
  192. package/dist/mcp/tools/rag-context.js.map +1 -0
  193. package/dist/mcp/tools/search.d.ts +4 -0
  194. package/dist/mcp/tools/search.d.ts.map +1 -0
  195. package/dist/mcp/tools/search.js +38 -0
  196. package/dist/mcp/tools/search.js.map +1 -0
  197. package/dist/mcp/tools/show.d.ts +4 -0
  198. package/dist/mcp/tools/show.d.ts.map +1 -0
  199. package/dist/mcp/tools/show.js +38 -0
  200. package/dist/mcp/tools/show.js.map +1 -0
  201. package/dist/mcp/tools/snapshot.d.ts +6 -0
  202. package/dist/mcp/tools/snapshot.d.ts.map +1 -0
  203. package/dist/mcp/tools/snapshot.js +43 -0
  204. package/dist/mcp/tools/snapshot.js.map +1 -0
  205. package/dist/mcp/tools/stats.d.ts +4 -0
  206. package/dist/mcp/tools/stats.d.ts.map +1 -0
  207. package/dist/mcp/tools/stats.js +43 -0
  208. package/dist/mcp/tools/stats.js.map +1 -0
  209. package/dist/mcp/tools/update-node.d.ts +4 -0
  210. package/dist/mcp/tools/update-node.d.ts.map +1 -0
  211. package/dist/mcp/tools/update-node.js +41 -0
  212. package/dist/mcp/tools/update-node.js.map +1 -0
  213. package/dist/mcp/tools/update-status.d.ts +4 -0
  214. package/dist/mcp/tools/update-status.d.ts.map +1 -0
  215. package/dist/mcp/tools/update-status.js +29 -0
  216. package/dist/mcp/tools/update-status.js.map +1 -0
  217. package/dist/mcp/tools/velocity.d.ts +4 -0
  218. package/dist/mcp/tools/velocity.d.ts.map +1 -0
  219. package/dist/mcp/tools/velocity.js +22 -0
  220. package/dist/mcp/tools/velocity.js.map +1 -0
  221. package/dist/schemas/edge.schema.d.ts +31 -0
  222. package/dist/schemas/edge.schema.d.ts.map +1 -0
  223. package/dist/schemas/edge.schema.js +16 -0
  224. package/dist/schemas/edge.schema.js.map +1 -0
  225. package/dist/schemas/graph.schema.d.ts +102 -0
  226. package/dist/schemas/graph.schema.d.ts.map +1 -0
  227. package/dist/schemas/graph.schema.js +28 -0
  228. package/dist/schemas/graph.schema.js.map +1 -0
  229. package/dist/schemas/node.schema.d.ts +80 -0
  230. package/dist/schemas/node.schema.d.ts.map +1 -0
  231. package/dist/schemas/node.schema.js +38 -0
  232. package/dist/schemas/node.schema.js.map +1 -0
  233. package/package.json +54 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Converts parser extraction results into graph nodes and edges.
3
+ */
4
+ import { generateId } from "../utils/id.js";
5
+ import { now } from "../utils/time.js";
6
+ function mapBlockTypeToNodeType(blockType) {
7
+ const valid = [
8
+ "epic", "task", "subtask", "requirement", "constraint",
9
+ "milestone", "acceptance_criteria", "risk", "decision",
10
+ ];
11
+ if (valid.includes(blockType))
12
+ return blockType;
13
+ return null;
14
+ }
15
+ function defaultPriorityForType(type) {
16
+ switch (type) {
17
+ case "epic": return 2;
18
+ case "requirement": return 2;
19
+ case "constraint": return 1;
20
+ case "task": return 3;
21
+ case "subtask": return 3;
22
+ case "risk": return 2;
23
+ case "acceptance_criteria": return 4;
24
+ default: return 3;
25
+ }
26
+ }
27
+ function createNodeFromBlock(block, sourceFile, parentId = null) {
28
+ const nodeType = mapBlockTypeToNodeType(block.type);
29
+ if (!nodeType)
30
+ return null;
31
+ const timestamp = now();
32
+ return {
33
+ id: generateId("node"),
34
+ type: nodeType,
35
+ title: block.title,
36
+ description: block.description || undefined,
37
+ status: "backlog",
38
+ priority: defaultPriorityForType(nodeType),
39
+ parentId,
40
+ sourceRef: {
41
+ file: sourceFile,
42
+ startLine: block.startLine,
43
+ endLine: block.endLine,
44
+ confidence: block.confidence,
45
+ },
46
+ metadata: {
47
+ inferred: block.confidence < 0.7,
48
+ origin: "imported",
49
+ },
50
+ createdAt: timestamp,
51
+ updatedAt: timestamp,
52
+ };
53
+ }
54
+ function createEdge(from, to, relationType, reason, inferred = false, confidence = 1) {
55
+ return {
56
+ id: generateId("edge"),
57
+ from,
58
+ to,
59
+ relationType,
60
+ reason,
61
+ metadata: { inferred, confidence },
62
+ createdAt: now(),
63
+ };
64
+ }
65
+ /**
66
+ * Detect simple sequential dependencies between tasks.
67
+ * If tasks appear in a numbered list, each depends on the previous.
68
+ */
69
+ function inferSequentialDeps(taskNodes) {
70
+ const edges = [];
71
+ for (let i = 1; i < taskNodes.length; i++) {
72
+ edges.push(createEdge(taskNodes[i].id, taskNodes[i - 1].id, "depends_on", `Sequential order: "${taskNodes[i].title}" after "${taskNodes[i - 1].title}"`, true, 0.6));
73
+ }
74
+ return edges;
75
+ }
76
+ /**
77
+ * Detect keyword-based dependencies in descriptions.
78
+ */
79
+ function inferKeywordDeps(nodes) {
80
+ const edges = [];
81
+ const depKeywords = [
82
+ /antes de/i, /após/i, /depois de/i, /depende de/i,
83
+ /somente depois/i, /before/i, /after/i, /depends on/i,
84
+ ];
85
+ for (const node of nodes) {
86
+ if (!node.description)
87
+ continue;
88
+ for (const other of nodes) {
89
+ if (node.id === other.id)
90
+ continue;
91
+ // Check if node's description references other's title
92
+ const titleLower = other.title.toLowerCase();
93
+ const descLower = node.description.toLowerCase();
94
+ if (descLower.includes(titleLower) && depKeywords.some((p) => p.test(descLower))) {
95
+ edges.push(createEdge(node.id, other.id, "depends_on", `Keyword inference from description`, true, 0.5));
96
+ }
97
+ }
98
+ }
99
+ return edges;
100
+ }
101
+ export function convertToGraph(extraction, sourceFile) {
102
+ const nodes = [];
103
+ const edges = [];
104
+ let blockedTasks = 0;
105
+ // Pass 1: Create nodes from top-level blocks
106
+ for (const block of extraction.blocks) {
107
+ const node = createNodeFromBlock(block, sourceFile);
108
+ if (!node)
109
+ continue;
110
+ nodes.push(node);
111
+ // Pass 2: Create child nodes from block items
112
+ const childTaskNodes = [];
113
+ for (const item of block.items) {
114
+ const itemType = mapBlockTypeToNodeType(item.type);
115
+ if (!itemType)
116
+ continue;
117
+ const timestamp = now();
118
+ const childNode = {
119
+ id: generateId("node"),
120
+ type: itemType,
121
+ title: item.text,
122
+ status: "backlog",
123
+ priority: defaultPriorityForType(itemType),
124
+ parentId: node.id,
125
+ sourceRef: {
126
+ file: sourceFile,
127
+ startLine: item.line,
128
+ endLine: item.line,
129
+ confidence: item.confidence,
130
+ },
131
+ metadata: {
132
+ inferred: item.confidence < 0.7,
133
+ origin: "imported",
134
+ },
135
+ createdAt: timestamp,
136
+ updatedAt: timestamp,
137
+ };
138
+ nodes.push(childNode);
139
+ // Parent-child edge
140
+ edges.push(createEdge(node.id, childNode.id, "parent_of", undefined, false, 1));
141
+ if (itemType === "task" || itemType === "subtask") {
142
+ childTaskNodes.push(childNode);
143
+ }
144
+ }
145
+ // Infer sequential dependencies among sibling tasks
146
+ if (childTaskNodes.length > 1) {
147
+ edges.push(...inferSequentialDeps(childTaskNodes));
148
+ }
149
+ }
150
+ // Pass 3: Link constraints to tasks as blockers
151
+ const constraintNodes = nodes.filter((n) => n.type === "constraint");
152
+ const taskNodes = nodes.filter((n) => n.type === "task" || n.type === "subtask");
153
+ for (const constraint of constraintNodes) {
154
+ for (const task of taskNodes) {
155
+ // Only create block edges if constraint text seems related
156
+ // For now, constraints block all tasks (simple heuristic for MVP)
157
+ edges.push(createEdge(constraint.id, task.id, "related_to", "Constraint applies to task", true, 0.4));
158
+ }
159
+ }
160
+ // Pass 4: Link acceptance criteria to epic/parent
161
+ const acNodes = nodes.filter((n) => n.type === "acceptance_criteria");
162
+ const epicNodes = nodes.filter((n) => n.type === "epic");
163
+ for (const ac of acNodes) {
164
+ if (ac.parentId)
165
+ continue; // already linked
166
+ for (const epic of epicNodes) {
167
+ edges.push(createEdge(ac.id, epic.id, "implements", "Acceptance criteria for epic", true, 0.6));
168
+ }
169
+ }
170
+ // Pass 5: Keyword-based dependency inference across all task nodes
171
+ const allTaskNodes = nodes.filter((n) => n.type === "task");
172
+ edges.push(...inferKeywordDeps(allTaskNodes));
173
+ // Count blocked tasks (tasks that have incoming depends_on edges to non-done nodes)
174
+ const dependentNodeIds = new Set(edges.filter((e) => e.relationType === "depends_on").map((e) => e.from));
175
+ blockedTasks = dependentNodeIds.size;
176
+ const inferredDeps = edges.filter((e) => e.metadata?.inferred).length;
177
+ return {
178
+ nodes,
179
+ edges,
180
+ stats: {
181
+ nodesCreated: nodes.length,
182
+ edgesCreated: edges.length,
183
+ blockedTasks,
184
+ inferredDeps,
185
+ },
186
+ };
187
+ }
188
+ //# sourceMappingURL=prd-to-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prd-to-graph.js","sourceRoot":"","sources":["../../../src/core/importer/prd-to-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Stage 3: Heuristic classification.
3
+ * Classify sections and bullet items into semantic types.
4
+ */
5
+ import type { NodeType } from "../graph/graph-types.js";
6
+ export type BlockType = NodeType | "unknown";
7
+ export interface ClassifiedBlock {
8
+ type: BlockType;
9
+ title: string;
10
+ description: string;
11
+ items: ClassifiedItem[];
12
+ startLine: number;
13
+ endLine: number;
14
+ confidence: number;
15
+ }
16
+ export interface ClassifiedItem {
17
+ type: BlockType;
18
+ text: string;
19
+ line: number;
20
+ confidence: number;
21
+ }
22
+ export declare function classifyText(text: string): {
23
+ type: BlockType;
24
+ confidence: number;
25
+ };
26
+ export declare function classifySectionTitle(title: string, level: number): {
27
+ type: BlockType;
28
+ confidence: number;
29
+ };
30
+ export declare function classifySection(title: string, body: string, level: number, startLine: number, endLine: number): ClassifiedBlock;
31
+ //# sourceMappingURL=classify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../../src/core/parser/classify.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAwCD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAQlF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAY1G;AAgDD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,eAAe,CA4BjB"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Stage 3: Heuristic classification.
3
+ * Classify sections and bullet items into semantic types.
4
+ */
5
+ // --- Heuristic keyword patterns (Portuguese + English) ---
6
+ const REQUIREMENT_PATTERNS = [
7
+ /\bdeve\b/i, /\bprecisa\b/i, /\bnecessário\b/i, /\bmust\b/i,
8
+ /\bshould\b/i, /\brequired\b/i, /\brequisito/i, /\brequirement/i,
9
+ ];
10
+ const CONSTRAINT_PATTERNS = [
11
+ /\bnão deve\b/i, /\bsem\b/i, /\brestrição/i, /\bnão depender/i,
12
+ /\bnão exigir/i, /\bconstraint/i, /\bwithout\b/i, /\bnot allowed/i,
13
+ /\bfora do escopo/i,
14
+ ];
15
+ const TASK_PATTERNS = [
16
+ /\bimplementar\b/i, /\bcriar\b/i, /\badicionar\b/i, /\bdefinir\b/i,
17
+ /\bconstruir\b/i, /\bconfigurar\b/i, /\binstalar\b/i, /\bdesenvolver\b/i,
18
+ /\bimplement\b/i, /\bcreate\b/i, /\bbuild\b/i, /\bset up\b/i,
19
+ /\bdesign\b/i,
20
+ ];
21
+ const ACCEPTANCE_PATTERNS = [
22
+ /\baceite\b/i, /\bcritério/i, /\bdone\b/i, /\bacceptance/i,
23
+ /\bcriterion/i, /\bcriteria/i, /\bdefinition of done/i,
24
+ ];
25
+ const RISK_PATTERNS = [
26
+ /\brisco\b/i, /\brisk\b/i, /\bmitigação/i, /\bmitigation/i,
27
+ ];
28
+ const EPIC_TITLE_PATTERNS = [
29
+ /\bepic\b/i, /\bvisão\b/i, /\bvision\b/i, /\bobjetivo principal/i,
30
+ /\bproduto\b/i, /\bprojeto\b/i,
31
+ ];
32
+ function matchesAny(text, patterns) {
33
+ return patterns.some((p) => p.test(text));
34
+ }
35
+ export function classifyText(text) {
36
+ // Order matters: more specific checks first
37
+ if (matchesAny(text, CONSTRAINT_PATTERNS))
38
+ return { type: "constraint", confidence: 0.8 };
39
+ if (matchesAny(text, ACCEPTANCE_PATTERNS))
40
+ return { type: "acceptance_criteria", confidence: 0.8 };
41
+ if (matchesAny(text, RISK_PATTERNS))
42
+ return { type: "risk", confidence: 0.7 };
43
+ if (matchesAny(text, TASK_PATTERNS))
44
+ return { type: "task", confidence: 0.7 };
45
+ if (matchesAny(text, REQUIREMENT_PATTERNS))
46
+ return { type: "requirement", confidence: 0.7 };
47
+ return { type: "unknown", confidence: 0.3 };
48
+ }
49
+ export function classifySectionTitle(title, level) {
50
+ const lower = title.toLowerCase();
51
+ if (matchesAny(lower, ACCEPTANCE_PATTERNS))
52
+ return { type: "acceptance_criteria", confidence: 0.9 };
53
+ if (matchesAny(lower, RISK_PATTERNS))
54
+ return { type: "risk", confidence: 0.85 };
55
+ if (matchesAny(lower, CONSTRAINT_PATTERNS))
56
+ return { type: "constraint", confidence: 0.85 };
57
+ if (/\brequisito/i.test(lower) || /\brequirement/i.test(lower))
58
+ return { type: "requirement", confidence: 0.9 };
59
+ if (level === 1 || matchesAny(lower, EPIC_TITLE_PATTERNS))
60
+ return { type: "epic", confidence: 0.8 };
61
+ if (/\btask\b/i.test(lower) || /\bentrega/i.test(lower))
62
+ return { type: "task", confidence: 0.85 };
63
+ return { type: "unknown", confidence: 0.3 };
64
+ }
65
+ function parseBulletItems(body, startLine) {
66
+ const items = [];
67
+ const lines = body.split("\n");
68
+ for (let i = 0; i < lines.length; i++) {
69
+ const line = lines[i];
70
+ const bulletMatch = line.match(/^\s*[-]\s+(.+)$/);
71
+ if (!bulletMatch)
72
+ continue;
73
+ const text = bulletMatch[1].trim();
74
+ const { type, confidence } = classifyText(text);
75
+ items.push({
76
+ type,
77
+ text,
78
+ line: startLine + i,
79
+ confidence,
80
+ });
81
+ }
82
+ return items;
83
+ }
84
+ function parseNumberedItems(body, startLine) {
85
+ const items = [];
86
+ const lines = body.split("\n");
87
+ for (let i = 0; i < lines.length; i++) {
88
+ const line = lines[i];
89
+ const numMatch = line.match(/^\s*\d+[.)]\s+(.+)$/);
90
+ if (!numMatch)
91
+ continue;
92
+ const text = numMatch[1].trim();
93
+ const { type, confidence } = classifyText(text);
94
+ items.push({
95
+ type,
96
+ text,
97
+ line: startLine + i,
98
+ confidence,
99
+ });
100
+ }
101
+ return items;
102
+ }
103
+ export function classifySection(title, body, level, startLine, endLine) {
104
+ const { type: sectionType, confidence: sectionConf } = classifySectionTitle(title, level);
105
+ const bulletItems = parseBulletItems(body, startLine);
106
+ const numberedItems = parseNumberedItems(body, startLine);
107
+ const items = [...bulletItems, ...numberedItems];
108
+ // If the section is a generic "unknown" but its items are mostly tasks, promote it
109
+ let finalType = sectionType;
110
+ let finalConf = sectionConf;
111
+ if (sectionType === "unknown" && items.length > 0) {
112
+ const taskCount = items.filter((it) => it.type === "task").length;
113
+ if (taskCount > items.length / 2) {
114
+ finalType = "task";
115
+ finalConf = 0.6;
116
+ }
117
+ }
118
+ return {
119
+ type: finalType,
120
+ title,
121
+ description: body,
122
+ items,
123
+ startLine,
124
+ endLine,
125
+ confidence: finalConf,
126
+ };
127
+ }
128
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/core/parser/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Stage 4: Entity extraction.
3
+ * Combine normalize → segment → classify to produce structured extraction results.
4
+ */
5
+ import type { ClassifiedBlock } from "./classify.js";
6
+ export interface ExtractionResult {
7
+ blocks: ClassifiedBlock[];
8
+ summary: {
9
+ totalSections: number;
10
+ epics: number;
11
+ tasks: number;
12
+ subtasks: number;
13
+ requirements: number;
14
+ constraints: number;
15
+ acceptanceCriteria: number;
16
+ risks: number;
17
+ unknown: number;
18
+ };
19
+ }
20
+ export declare function extractEntities(rawText: string): ExtractionResult;
21
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../../src/core/parser/extract.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAA6B,MAAM,eAAe,CAAC;AAGhF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAQD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA2DjE"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Stage 4: Entity extraction.
3
+ * Combine normalize → segment → classify to produce structured extraction results.
4
+ */
5
+ import { normalize } from "./normalize.js";
6
+ import { segment } from "./segment.js";
7
+ import { classifySection, classifyText } from "./classify.js";
8
+ import { logger } from "../utils/logger.js";
9
+ function countByType(blocks, items, type) {
10
+ const blockCount = blocks.filter((b) => b.type === type).length;
11
+ const itemCount = items.filter((i) => i.type === type).length;
12
+ return blockCount + itemCount;
13
+ }
14
+ export function extractEntities(rawText) {
15
+ logger.info(`Extracting entities from ${rawText.length} chars`);
16
+ const normalized = normalize(rawText);
17
+ const sections = segment(normalized);
18
+ logger.info(`Segmented into ${sections.length} sections`);
19
+ const blocks = sections.map((sec) => classifySection(sec.title, sec.body, sec.level, sec.startLine, sec.endLine));
20
+ // Promote items inside task-sections to subtask if they're generic or tasks
21
+ for (const block of blocks) {
22
+ if (block.type === "task" || block.type === "epic") {
23
+ for (const item of block.items) {
24
+ if (item.type === "unknown" || item.type === "task") {
25
+ // Items inside a task/epic section are subtasks
26
+ if (block.type === "task") {
27
+ item.type = "subtask";
28
+ item.confidence = Math.max(item.confidence, 0.6);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ // Also classify numbered items inside sections that look like task lists
35
+ // (e.g., "Entregas" sections with numbered action items)
36
+ for (const block of blocks) {
37
+ if (block.type === "unknown") {
38
+ for (const item of block.items) {
39
+ if (item.type === "unknown") {
40
+ const reclassified = classifyText(item.text);
41
+ if (reclassified.type !== "unknown") {
42
+ item.type = reclassified.type;
43
+ item.confidence = reclassified.confidence;
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ const allItems = blocks.flatMap((b) => b.items);
50
+ logger.info(`Extraction complete: ${blocks.length} blocks, ${allItems.length} items`);
51
+ return {
52
+ blocks,
53
+ summary: {
54
+ totalSections: blocks.length,
55
+ epics: countByType(blocks, allItems, "epic"),
56
+ tasks: countByType(blocks, allItems, "task"),
57
+ subtasks: countByType(blocks, allItems, "subtask"),
58
+ requirements: countByType(blocks, allItems, "requirement"),
59
+ constraints: countByType(blocks, allItems, "constraint"),
60
+ acceptanceCriteria: countByType(blocks, allItems, "acceptance_criteria"),
61
+ risks: countByType(blocks, allItems, "risk"),
62
+ unknown: countByType(blocks, allItems, "unknown"),
63
+ },
64
+ };
65
+ }
66
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../src/core/parser/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Stage 1: Text normalization.
3
+ * - Standardize line endings
4
+ * - Remove duplicate blank lines
5
+ * - Trim whitespace
6
+ * - Standardize bullet markers to "-"
7
+ */
8
+ export declare function normalize(raw: string): string;
9
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/core/parser/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7C"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Stage 1: Text normalization.
3
+ * - Standardize line endings
4
+ * - Remove duplicate blank lines
5
+ * - Trim whitespace
6
+ * - Standardize bullet markers to "-"
7
+ */
8
+ export function normalize(raw) {
9
+ let text = raw.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
10
+ // Collapse 3+ consecutive blank lines into 2
11
+ text = text.replace(/\n{3,}/g, "\n\n");
12
+ // Standardize bullet markers: *, •, ● → -
13
+ text = text.replace(/^(\s*)[*•●]\s/gm, "$1- ");
14
+ // Trim trailing whitespace per line
15
+ text = text
16
+ .split("\n")
17
+ .map((line) => line.trimEnd())
18
+ .join("\n")
19
+ .trim();
20
+ return text;
21
+ }
22
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/parser/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE3D,6CAA6C;IAC7C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAEvC,0CAA0C;IAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAE/C,oCAAoC;IACpC,IAAI,GAAG,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SAC7B,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;IAEV,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface PrdFileResult {
2
+ content: string;
3
+ absolutePath: string;
4
+ sizeBytes: number;
5
+ }
6
+ export declare function readPrdFile(filePath: string): Promise<PrdFileResult>;
7
+ //# sourceMappingURL=read-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../../src/core/parser/read-file.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAc1E"}
@@ -0,0 +1,17 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileExists } from "../utils/fs.js";
4
+ import { FileNotFoundError } from "../utils/errors.js";
5
+ export async function readPrdFile(filePath) {
6
+ const absolutePath = path.resolve(filePath);
7
+ if (!(await fileExists(absolutePath))) {
8
+ throw new FileNotFoundError(absolutePath);
9
+ }
10
+ const content = await readFile(absolutePath, "utf-8");
11
+ return {
12
+ content,
13
+ absolutePath,
14
+ sizeBytes: Buffer.byteLength(content, "utf-8"),
15
+ };
16
+ }
17
+ //# sourceMappingURL=read-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/core/parser/read-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAQvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEtD,OAAO;QACL,OAAO;QACP,YAAY;QACZ,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC;KAC/C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Stage 2: Segmentation.
3
+ * Split normalized text into structural blocks by headings.
4
+ */
5
+ export interface Section {
6
+ level: number;
7
+ title: string;
8
+ body: string;
9
+ startLine: number;
10
+ endLine: number;
11
+ }
12
+ export declare function segment(text: string): Section[];
13
+ //# sourceMappingURL=segment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment.d.ts","sourceRoot":"","sources":["../../../src/core/parser/segment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAqD/C"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Stage 2: Segmentation.
3
+ * Split normalized text into structural blocks by headings.
4
+ */
5
+ export function segment(text) {
6
+ const lines = text.split("\n");
7
+ const sections = [];
8
+ let current = null;
9
+ let bodyLines = [];
10
+ for (let i = 0; i < lines.length; i++) {
11
+ const line = lines[i];
12
+ const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
13
+ if (headingMatch) {
14
+ // Close previous section
15
+ if (current) {
16
+ current.body = bodyLines.join("\n").trim();
17
+ current.endLine = i;
18
+ sections.push(current);
19
+ }
20
+ const level = headingMatch[1].length;
21
+ const title = headingMatch[2].trim();
22
+ current = {
23
+ level,
24
+ title,
25
+ body: "",
26
+ startLine: i + 1, // 1-indexed
27
+ endLine: i + 1,
28
+ };
29
+ bodyLines = [];
30
+ }
31
+ else {
32
+ bodyLines.push(line);
33
+ }
34
+ }
35
+ // Close last section
36
+ if (current) {
37
+ current.body = bodyLines.join("\n").trim();
38
+ current.endLine = lines.length;
39
+ sections.push(current);
40
+ }
41
+ // If no headings found, treat entire text as a single section
42
+ if (sections.length === 0 && text.trim()) {
43
+ sections.push({
44
+ level: 0,
45
+ title: "Untitled",
46
+ body: text.trim(),
47
+ startLine: 1,
48
+ endLine: lines.length,
49
+ });
50
+ }
51
+ return sections;
52
+ }
53
+ //# sourceMappingURL=segment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment.js","sourceRoot":"","sources":["../../../src/core/parser/segment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,OAAO,GAAmB,IAAI,CAAC;IACnC,IAAI,SAAS,GAAa,EAAE,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAErD,IAAI,YAAY,EAAE,CAAC;YACjB,yBAAyB;YACzB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3C,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;YAED,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACrC,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAErC,OAAO,GAAG;gBACR,KAAK;gBACL,KAAK;gBACL,IAAI,EAAE,EAAE;gBACR,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,YAAY;gBAC9B,OAAO,EAAE,CAAC,GAAG,CAAC;aACf,CAAC;YACF,SAAS,GAAG,EAAE,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;QAC/B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAED,8DAA8D;IAC9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YACjB,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,KAAK,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}