@diagrammo/dgmo 0.46.0 → 0.47.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 (232) hide show
  1. package/dist/advanced.d.cts +3 -855
  2. package/dist/advanced.d.ts +3 -855
  3. package/dist/advanced.js +541 -70107
  4. package/dist/analyzer-UYKBXAKR.js +15 -0
  5. package/dist/auto.cjs +1 -1
  6. package/dist/auto.js +1 -1
  7. package/dist/auto.mjs +1 -1
  8. package/dist/block.js +83 -69417
  9. package/dist/calculator-LDYQCDDY.js +11 -0
  10. package/dist/charts-d3-QOZHKTCT.js +25 -0
  11. package/dist/chunk-2DXMZRWJ.js +800 -0
  12. package/dist/chunk-2LACINWN.js +786 -0
  13. package/dist/chunk-33LCUH4H.js +893 -0
  14. package/dist/chunk-3CIOJ5YJ.js +35 -0
  15. package/dist/chunk-3HDBAXF5.js +86 -0
  16. package/dist/chunk-3JLKYGBQ.js +290 -0
  17. package/dist/chunk-3MQQNXPD.js +415 -0
  18. package/dist/chunk-3R5POCTZ.js +967 -0
  19. package/dist/chunk-3SMGIJDD.js +112 -0
  20. package/dist/chunk-44CM72SQ.js +409 -0
  21. package/dist/chunk-4GRI7MEB.js +1604 -0
  22. package/dist/chunk-4OHACBGX.js +606 -0
  23. package/dist/chunk-5DH3KYFH.js +21 -0
  24. package/dist/chunk-5MLYVTYM.js +76 -0
  25. package/dist/chunk-5QXL4NYS.js +553 -0
  26. package/dist/chunk-5WRI5ZAA.js +31 -0
  27. package/dist/chunk-6EK55ART.js +117 -0
  28. package/dist/chunk-6FZYCKXB.js +2065 -0
  29. package/dist/chunk-6HO5ZTXK.js +277 -0
  30. package/dist/chunk-6KFWC4CO.js +7 -0
  31. package/dist/chunk-6MTWIQVO.js +121 -0
  32. package/dist/chunk-6NYWYNBI.js +329 -0
  33. package/dist/chunk-6SM5NJQH.js +620 -0
  34. package/dist/chunk-725LDASD.js +422 -0
  35. package/dist/chunk-76OWZ3BA.js +130 -0
  36. package/dist/chunk-7JEGTRLD.js +338 -0
  37. package/dist/chunk-A44USUV7.js +923 -0
  38. package/dist/chunk-A4GOY3PE.js +25 -0
  39. package/dist/chunk-A4VFQH5G.js +251 -0
  40. package/dist/chunk-AELOBFW5.js +375 -0
  41. package/dist/chunk-AN2MOO5T.js +522 -0
  42. package/dist/chunk-BMR4CIEO.js +41 -0
  43. package/dist/chunk-BS7SV7C3.js +51 -0
  44. package/dist/chunk-BUPDIHML.js +613 -0
  45. package/dist/chunk-BUVJFRPY.js +887 -0
  46. package/dist/chunk-C3Z4DX3V.js +112 -0
  47. package/dist/chunk-CI2G3OEB.js +1818 -0
  48. package/dist/chunk-CKNVO24D.js +54 -0
  49. package/dist/chunk-CUVHQHZ7.js +391 -0
  50. package/dist/chunk-CXK4DZH3.js +114 -0
  51. package/dist/chunk-DKEPS5LH.js +315 -0
  52. package/dist/chunk-DU7W62N5.js +487 -0
  53. package/dist/chunk-DZAQBW35.js +751 -0
  54. package/dist/chunk-EB6FPQUP.js +316 -0
  55. package/dist/chunk-EMS2SK26.js +376 -0
  56. package/dist/chunk-ERLBPDGU.js +510 -0
  57. package/dist/chunk-EVCVDTXE.js +732 -0
  58. package/dist/chunk-FCIIHT24.js +384 -0
  59. package/dist/chunk-FFUN5D66.js +97 -0
  60. package/dist/chunk-FITOLXSX.js +714 -0
  61. package/dist/chunk-FMDSF3OV.js +68 -0
  62. package/dist/chunk-FNB3PNGF.js +410 -0
  63. package/dist/chunk-G2H74XJZ.js +2104 -0
  64. package/dist/chunk-GMR5MFHJ.js +339 -0
  65. package/dist/chunk-H6PI3KJT.js +305 -0
  66. package/dist/chunk-I46X5VUA.js +59 -0
  67. package/dist/chunk-I5IGB56C.js +255 -0
  68. package/dist/chunk-IH6ZMVQ5.js +3950 -0
  69. package/dist/chunk-IJZFN3HM.js +463 -0
  70. package/dist/chunk-IPWPWM6R.js +3079 -0
  71. package/dist/chunk-IYULMRBE.js +23 -0
  72. package/dist/chunk-IZMRON6C.js +167 -0
  73. package/dist/chunk-J5FIXQRT.js +813 -0
  74. package/dist/chunk-JED6ZDEE.js +73 -0
  75. package/dist/chunk-JEUJOX5X.js +136 -0
  76. package/dist/chunk-JM4LEPY3.js +436 -0
  77. package/dist/chunk-L3UHP6TD.js +101 -0
  78. package/dist/chunk-L66GEFB6.js +524 -0
  79. package/dist/chunk-LIOHW36Z.js +469 -0
  80. package/dist/chunk-LP7EC4MI.js +16 -0
  81. package/dist/chunk-MITI6NOL.js +548 -0
  82. package/dist/chunk-MO5YHHMQ.js +168 -0
  83. package/dist/chunk-MZSBFAPJ.js +885 -0
  84. package/dist/chunk-NNAAJVBU.js +9 -0
  85. package/dist/chunk-NOTA6TEI.js +47 -0
  86. package/dist/chunk-NURGB5Z4.js +335 -0
  87. package/dist/chunk-NX4EQS3U.js +1062 -0
  88. package/dist/chunk-NXMESY4J.js +1 -0
  89. package/dist/chunk-OJR3MQYV.js +1458 -0
  90. package/dist/chunk-OURHMODR.js +454 -0
  91. package/dist/chunk-P235SVAH.js +1057 -0
  92. package/dist/chunk-P4RH4OSP.js +1038 -0
  93. package/dist/chunk-P6T66CCZ.js +226 -0
  94. package/dist/chunk-PBAHEPLQ.js +223 -0
  95. package/dist/chunk-PBHE5UG6.js +1530 -0
  96. package/dist/chunk-PDKUANDZ.js +35 -0
  97. package/dist/chunk-PWIHZ6NJ.js +296 -0
  98. package/dist/chunk-QEBUY5NY.js +1685 -0
  99. package/dist/chunk-QLCCJEJI.js +253 -0
  100. package/dist/chunk-QOOUC2J5.js +52 -0
  101. package/dist/chunk-QYTPPDAO.js +402 -0
  102. package/dist/chunk-R3XI2VC7.js +801 -0
  103. package/dist/chunk-RCERWOJR.js +154 -0
  104. package/dist/chunk-RJE5JTVK.js +362 -0
  105. package/dist/chunk-RTLBSQ3G.js +1155 -0
  106. package/dist/chunk-RUNNI6VE.js +448 -0
  107. package/dist/chunk-RVMRZAPB.js +354 -0
  108. package/dist/chunk-RYEGFMUO.js +955 -0
  109. package/dist/chunk-RZCF2VVM.js +528 -0
  110. package/dist/chunk-SML67VPV.js +1025 -0
  111. package/dist/chunk-SQ7IY53Q.js +44 -0
  112. package/dist/chunk-SQAG3UXH.js +161 -0
  113. package/dist/chunk-SRTU6HMQ.js +1851 -0
  114. package/dist/chunk-T2OE3YQB.js +550 -0
  115. package/dist/chunk-T3UBLACL.js +299 -0
  116. package/dist/chunk-TLVIHFRO.js +296 -0
  117. package/dist/chunk-TYS6CSS5.js +52 -0
  118. package/dist/chunk-U6EQI3U6.js +130 -0
  119. package/dist/chunk-UJ4FJLBF.js +86 -0
  120. package/dist/chunk-ULOEATBZ.js +347 -0
  121. package/dist/chunk-UNCCZ3NU.js +127 -0
  122. package/dist/chunk-USZW2HHU.js +197 -0
  123. package/dist/chunk-UWN33VNX.js +1610 -0
  124. package/dist/chunk-UZ7EZW3B.js +40 -0
  125. package/dist/chunk-VOKGH627.js +37 -0
  126. package/dist/chunk-WBRZJOEC.js +204 -0
  127. package/dist/chunk-WCSOJFU3.js +380 -0
  128. package/dist/chunk-WCT3NYCV.js +160 -0
  129. package/dist/chunk-WVAJFAIA.js +529 -0
  130. package/dist/chunk-X5LCYCL5.js +394 -0
  131. package/dist/chunk-XAKEUMEJ.js +1256 -0
  132. package/dist/chunk-Y2ZE3MSG.js +590 -0
  133. package/dist/chunk-Y3J7VR52.js +646 -0
  134. package/dist/chunk-Y5QGVTVC.js +33 -0
  135. package/dist/chunk-YAA6IID3.js +548 -0
  136. package/dist/chunk-YGJTDXVR.js +692 -0
  137. package/dist/chunk-YRYKTYMQ.js +186 -0
  138. package/dist/chunk-YYVTBZZC.js +61 -0
  139. package/dist/chunk-Z5CGSFJB.js +647 -0
  140. package/dist/chunk-Z72XRXD4.js +787 -0
  141. package/dist/chunk-ZGR7ULFJ.js +978 -0
  142. package/dist/chunk-ZJEL4H2R.js +851 -0
  143. package/dist/chunk-ZO27FGJS.js +554 -0
  144. package/dist/collapse-CLPJD2RL.js +11 -0
  145. package/dist/collapse-SLINJQW6.js +9 -0
  146. package/dist/collapse-ZWUFFCK2.js +9 -0
  147. package/dist/compute-G55RG53N.js +8 -0
  148. package/dist/dgmo-router-DZCIDUO5.js +73 -0
  149. package/dist/dimensions-J3FHIMJ6.js +22 -0
  150. package/dist/element.cjs +1 -1
  151. package/dist/element.js +1 -1
  152. package/dist/element.mjs +1 -1
  153. package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
  154. package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
  155. package/dist/index.cjs +3 -3
  156. package/dist/index.d.cts +3 -469
  157. package/dist/index.d.ts +3 -469
  158. package/dist/index.js +137 -69685
  159. package/dist/layout-46N4JJYK.js +17 -0
  160. package/dist/layout-5RA6QWR6.js +26 -0
  161. package/dist/layout-5T6RH5M6.js +14 -0
  162. package/dist/layout-7QXCNOVS.js +13 -0
  163. package/dist/layout-EE6GE46Y.js +17 -0
  164. package/dist/layout-G23F7LDH.js +9 -0
  165. package/dist/layout-HRBZPFCN.js +23 -0
  166. package/dist/layout-HWDSRX5E.js +20 -0
  167. package/dist/layout-HYZPWAK5.js +18 -0
  168. package/dist/layout-N76NR4ZO.js +19 -0
  169. package/dist/layout-OB3RI63S.js +14 -0
  170. package/dist/layout-S2QBYSK2.js +15 -0
  171. package/dist/layout-UM5F4DJB.js +15 -0
  172. package/dist/layout-search-OYV77HHS.js +1655 -0
  173. package/dist/load-data-EHDDZ5ZS.js +8 -0
  174. package/dist/palettes-PRJ2RI6D.js +56 -0
  175. package/dist/parser-2MFP2H2E.js +11 -0
  176. package/dist/parser-3STE62GB.js +21 -0
  177. package/dist/parser-4FL2CMDG.js +18 -0
  178. package/dist/parser-4OGOBJJ4.js +13 -0
  179. package/dist/parser-6BTRLKRZ.js +15 -0
  180. package/dist/parser-AQETEVRW.js +21 -0
  181. package/dist/parser-CFZD5IBL.js +12 -0
  182. package/dist/parser-FUSKFGZN.js +16 -0
  183. package/dist/parser-I6KXEYFK.js +13 -0
  184. package/dist/parser-IXSZZQHY.js +18 -0
  185. package/dist/parser-JAL2HD4I.js +13 -0
  186. package/dist/parser-KNSQSKQO.js +20 -0
  187. package/dist/parser-N5O4IHUN.js +13 -0
  188. package/dist/parser-NGU3ETO6.js +16 -0
  189. package/dist/parser-NRAI6O25.js +19 -0
  190. package/dist/parser-O5J4VBII.js +11 -0
  191. package/dist/parser-OV7NOBW6.js +21 -0
  192. package/dist/parser-PQ3POX45.js +23 -0
  193. package/dist/parser-TFZFBVWN.js +11 -0
  194. package/dist/parser-TRTHDFPP.js +18 -0
  195. package/dist/parser-VQP2UJ6W.js +11 -0
  196. package/dist/parser-XDVELHRK.js +13 -0
  197. package/dist/parser-XKRP7QKP.js +11 -0
  198. package/dist/parser-Y6WTBU76.js +14 -0
  199. package/dist/parser-ZSDPZYQP.js +12 -0
  200. package/dist/renderer-2XQQQ6QR.js +28 -0
  201. package/dist/renderer-5NDVNDAZ.js +26 -0
  202. package/dist/renderer-6EEZHMH4.js +26 -0
  203. package/dist/renderer-6W5462RB.js +43 -0
  204. package/dist/renderer-7MVLWWQD.js +22 -0
  205. package/dist/renderer-AWWAF6XD.js +33 -0
  206. package/dist/renderer-BYCNMBF7.js +34 -0
  207. package/dist/renderer-CLJHQPBJ.js +29 -0
  208. package/dist/renderer-GHPZMFU2.js +15 -0
  209. package/dist/renderer-JGBKUCZD.js +16 -0
  210. package/dist/renderer-KQB7UGDS.js +19 -0
  211. package/dist/renderer-PGX2TKVS.js +24 -0
  212. package/dist/renderer-QIWVHWZO.js +15 -0
  213. package/dist/renderer-RPOA5YPZ.js +35 -0
  214. package/dist/renderer-SMIBCRVB.js +24 -0
  215. package/dist/renderer-T7YKC5VP.js +28 -0
  216. package/dist/renderer-TOCOVLHS.js +37 -0
  217. package/dist/renderer-UWA5XS74.js +39 -0
  218. package/dist/renderer-VACVQYML.js +25 -0
  219. package/dist/renderer-W4M6QLIJ.js +37 -0
  220. package/dist/renderer-WZRREQ2P.js +23 -0
  221. package/dist/renderer-YY2OSF6E.js +27 -0
  222. package/dist/renderer-Z7I3W2PP.js +24 -0
  223. package/dist/renderer-ZGNTUWC4.js +22 -0
  224. package/dist/renderer-ZTR3DER3.js +19 -0
  225. package/dist/renderer-radial-C32GPJQ7.js +21 -0
  226. package/dist/resolver-NOAA7ID7.js +13 -0
  227. package/dist/state-collapse-HCGD6IVJ.js +8 -0
  228. package/dist/state-parser-Z2V23ATR.js +18 -0
  229. package/dist/state-renderer-RFYHSP4K.js +34 -0
  230. package/dist/themes-1-CuKpeH.d.cts +908 -0
  231. package/dist/themes-1-CuKpeH.d.ts +908 -0
  232. package/package.json +1 -1
@@ -0,0 +1,787 @@
1
+ import {
2
+ addGanttDuration,
3
+ buildHolidaySet,
4
+ parseGanttDate
5
+ } from "./chunk-USZW2HHU.js";
6
+ import {
7
+ normalizeName
8
+ } from "./chunk-NOTA6TEI.js";
9
+ import {
10
+ makeDgmoError
11
+ } from "./chunk-CXK4DZH3.js";
12
+
13
+ // src/gantt/resolver.ts
14
+ function isResolverError(r) {
15
+ return "kind" in r;
16
+ }
17
+ function collectTasks(nodes) {
18
+ const tasks = [];
19
+ function walk(children) {
20
+ for (const node of children) {
21
+ if (node.kind === "task") {
22
+ tasks.push(node);
23
+ } else if (node.kind === "group" || node.kind === "parallel") {
24
+ walk(node.children);
25
+ }
26
+ }
27
+ }
28
+ walk(nodes);
29
+ return tasks;
30
+ }
31
+ var BRACKET_GROUP_RE = /^\[(.+?)\]\.(.+)$/;
32
+ function ambiguousTaskMessage(trimmed, suggestions) {
33
+ return `Multiple tasks match "${trimmed}". Did you mean ${suggestions.map((s) => `\`${s}\``).join(" or ")}?`;
34
+ }
35
+ function resolveTaskName(name, allTasks) {
36
+ let trimmed = name.trim();
37
+ const bracketMatch = trimmed.match(BRACKET_GROUP_RE);
38
+ if (bracketMatch) {
39
+ trimmed = `${bracketMatch[1]}.${bracketMatch[2]}`;
40
+ }
41
+ const normTrimmed = normalizeName(trimmed);
42
+ const exactMatches = allTasks.filter(
43
+ (t) => normalizeName(t.label) === normTrimmed
44
+ );
45
+ if (exactMatches.length === 1) {
46
+ return { task: exactMatches[0] };
47
+ }
48
+ if (exactMatches.length > 1) {
49
+ const suggestions = exactMatches.map(
50
+ (t) => t.groupPath.length > 0 ? `${t.groupPath.join(".")}.${t.label}` : t.label
51
+ );
52
+ return {
53
+ kind: "ambiguous",
54
+ message: ambiguousTaskMessage(trimmed, suggestions)
55
+ };
56
+ }
57
+ const lastDotIdx = trimmed.lastIndexOf(".");
58
+ if (lastDotIdx > 0) {
59
+ const groupPrefix = trimmed.substring(0, lastDotIdx);
60
+ const taskLabel = trimmed.substring(lastDotIdx + 1);
61
+ const normTaskLabel = normalizeName(taskLabel);
62
+ const matches = allTasks.filter((t) => {
63
+ if (normalizeName(t.label) !== normTaskLabel) return false;
64
+ return matchesGroupPath(t.groupPath, groupPrefix);
65
+ });
66
+ if (matches.length === 1) {
67
+ return { task: matches[0] };
68
+ }
69
+ if (matches.length > 1) {
70
+ const suggestions = matches.map(
71
+ (t) => t.groupPath.length > 0 ? `${t.groupPath.join(".")}.${t.label}` : t.label
72
+ );
73
+ return {
74
+ kind: "ambiguous",
75
+ message: ambiguousTaskMessage(trimmed, suggestions)
76
+ };
77
+ }
78
+ }
79
+ return {
80
+ kind: "not_found",
81
+ message: `No task found with name "${trimmed}".`
82
+ };
83
+ }
84
+ function matchesGroupPath(groupPath, prefix) {
85
+ const normPrefix = normalizeName(prefix);
86
+ if (!prefix.includes(".")) {
87
+ return groupPath.some((g) => normalizeName(g) === normPrefix);
88
+ }
89
+ const pathStr = groupPath.map((g) => normalizeName(g)).join(".");
90
+ return pathStr === normPrefix || pathStr.endsWith("." + normPrefix) || pathStr.startsWith(normPrefix + ".") || pathStr.includes("." + normPrefix + ".");
91
+ }
92
+
93
+ // src/gantt/calculator.ts
94
+ function calculateSchedule(parsed) {
95
+ const diagnostics = [...parsed.diagnostics];
96
+ const result = {
97
+ tasks: [],
98
+ groups: [],
99
+ startDate: /* @__PURE__ */ new Date(),
100
+ endDate: /* @__PURE__ */ new Date(),
101
+ holidays: parsed.holidays,
102
+ tagGroups: parsed.tagGroups.slice(),
103
+ eras: [],
104
+ markers: [],
105
+ sprints: [],
106
+ options: parsed.options,
107
+ diagnostics,
108
+ error: parsed.error
109
+ };
110
+ if (parsed.error) return result;
111
+ const warn = (line, message) => {
112
+ diagnostics.push(makeDgmoError(line, message, "warning"));
113
+ };
114
+ const holidaySet = buildHolidaySet(parsed.holidays);
115
+ let projectStart;
116
+ if (parsed.options.start) {
117
+ projectStart = parseGanttDate(parsed.options.start);
118
+ } else {
119
+ projectStart = new Date(2e3, 0, 1);
120
+ }
121
+ result.eras = parsed.eras.map((era) => {
122
+ if (era.offsetStart && era.offsetEnd) {
123
+ const start = addGanttDuration(
124
+ projectStart,
125
+ era.offsetStart.duration,
126
+ parsed.holidays,
127
+ /* @__PURE__ */ new Set(),
128
+ era.offsetStart.direction
129
+ );
130
+ const end = addGanttDuration(
131
+ projectStart,
132
+ era.offsetEnd.duration,
133
+ parsed.holidays,
134
+ /* @__PURE__ */ new Set(),
135
+ era.offsetEnd.direction
136
+ );
137
+ return { ...era, startDate: formatDate(start), endDate: formatDate(end) };
138
+ }
139
+ return era;
140
+ });
141
+ result.markers = parsed.markers.map((m) => {
142
+ if (m.offsetDate) {
143
+ const d = addGanttDuration(
144
+ projectStart,
145
+ m.offsetDate.duration,
146
+ parsed.holidays,
147
+ /* @__PURE__ */ new Set(),
148
+ m.offsetDate.direction
149
+ );
150
+ return { ...m, date: formatDate(d) };
151
+ }
152
+ return m;
153
+ });
154
+ const sprintOpts = parsed.options.sprintLength ? { sprintLength: parsed.options.sprintLength } : void 0;
155
+ const depOffsetMap = /* @__PURE__ */ new Map();
156
+ const allTasks = collectTasks(parsed.nodes);
157
+ if (allTasks.length === 0) {
158
+ return result;
159
+ }
160
+ const taskMap = /* @__PURE__ */ new Map();
161
+ for (const task of allTasks) {
162
+ taskMap.set(task.id, {
163
+ task,
164
+ predecessors: [],
165
+ startDate: null,
166
+ endDate: null
167
+ });
168
+ }
169
+ if (parsed.syntaxMode === "legacy") {
170
+ buildImplicitDeps(parsed.nodes, taskMap);
171
+ }
172
+ for (const task of allTasks) {
173
+ for (const dep of task.dependencies) {
174
+ const resolved = resolveTaskName(dep.targetName, allTasks);
175
+ if (isResolverError(resolved)) {
176
+ warn(dep.lineNumber, `\`-> ${dep.targetName}\` \u2014 ${resolved.message}`);
177
+ continue;
178
+ }
179
+ const targetNode = taskMap.get(resolved.task.id);
180
+ if (targetNode) {
181
+ if (targetNode.predecessors.includes(task.id)) {
182
+ warn(
183
+ dep.lineNumber,
184
+ parsed.syntaxMode === "new" ? `Redundant dependency: "${dep.targetName}" already follows "${task.label}".` : `Redundant dependency: "${dep.targetName}" already follows "${task.label}" sequentially. Did you mean to wrap groups in \`parallel\`?`
185
+ );
186
+ } else {
187
+ targetNode.predecessors.push(task.id);
188
+ if (dep.offset) {
189
+ depOffsetMap.set(`${task.id}->${resolved.task.id}`, dep.offset);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ let sortedIds = topologicalSort(taskMap);
196
+ if (!sortedIds) {
197
+ const cycle = findCycle(taskMap);
198
+ const cycleStr = cycle.map((id) => taskMap.get(id).task.label).join(" \u2192 ");
199
+ warn(
200
+ // Cycle is non-empty when topo sort failed; preserves prior crash-on-empty behavior.
201
+ taskMap.get(cycle[0]).task.lineNumber,
202
+ `Circular dependency detected: ${cycleStr}. The cycle-creating dependency was dropped.`
203
+ );
204
+ breakCycle(cycle, taskMap, depOffsetMap);
205
+ sortedIds = topologicalSort(taskMap);
206
+ let safety = 10;
207
+ while (!sortedIds && safety-- > 0) {
208
+ const nextCycle = findCycle(taskMap);
209
+ if (nextCycle.length === 0) break;
210
+ breakCycle(nextCycle, taskMap, depOffsetMap);
211
+ sortedIds = topologicalSort(taskMap);
212
+ }
213
+ if (!sortedIds) {
214
+ sortedIds = [...taskMap.keys()];
215
+ }
216
+ }
217
+ for (const taskId of sortedIds) {
218
+ const node = taskMap.get(taskId);
219
+ const task = node.task;
220
+ let start;
221
+ if (task.explicitStart) {
222
+ start = parseGanttDate(task.explicitStart);
223
+ } else if (node.predecessors.length === 0) {
224
+ start = new Date(projectStart);
225
+ } else {
226
+ start = /* @__PURE__ */ new Date(-864e13);
227
+ for (const predId of node.predecessors) {
228
+ const predNode = taskMap.get(predId);
229
+ if (!predNode.endDate) continue;
230
+ let predEnd = new Date(predNode.endDate);
231
+ const depOffset = depOffsetMap.get(`${predId}->${taskId}`);
232
+ if (depOffset) {
233
+ predEnd = addGanttDuration(
234
+ predEnd,
235
+ depOffset.duration,
236
+ parsed.holidays,
237
+ holidaySet,
238
+ depOffset.direction,
239
+ sprintOpts
240
+ );
241
+ }
242
+ if (predEnd.getTime() > start.getTime()) {
243
+ start = predEnd;
244
+ }
245
+ }
246
+ }
247
+ if (parsed.syntaxMode === "new" && task.groupPath.length > 0) {
248
+ const groupOffset = findGroupOffset(parsed.nodes, task.groupPath);
249
+ if (groupOffset) {
250
+ const groupFloor = addGanttDuration(
251
+ new Date(projectStart),
252
+ groupOffset.duration,
253
+ parsed.holidays,
254
+ holidaySet,
255
+ groupOffset.direction,
256
+ sprintOpts
257
+ );
258
+ if (groupFloor.getTime() > start.getTime()) {
259
+ start = groupFloor;
260
+ }
261
+ }
262
+ }
263
+ if (task.offset) {
264
+ start = addGanttDuration(
265
+ start,
266
+ task.offset.duration,
267
+ parsed.holidays,
268
+ holidaySet,
269
+ task.offset.direction,
270
+ sprintOpts
271
+ );
272
+ if (start.getTime() < projectStart.getTime()) {
273
+ warn(
274
+ task.lineNumber,
275
+ `Negative offset on task '${task.label}' exceeds available range; start clamped to project start.`
276
+ );
277
+ start = new Date(projectStart);
278
+ }
279
+ } else if (start.getTime() < projectStart.getTime()) {
280
+ warn(
281
+ task.lineNumber,
282
+ `Negative offset on dependency exceeds available range; start of '${task.label}' clamped to project start.`
283
+ );
284
+ start = new Date(projectStart);
285
+ }
286
+ if (task.explicitStart && node.predecessors.length > 0) {
287
+ let maxPredEnd = /* @__PURE__ */ new Date(-864e13);
288
+ for (const predId of node.predecessors) {
289
+ const predNode = taskMap.get(predId);
290
+ if (predNode.endDate && predNode.endDate.getTime() > maxPredEnd.getTime()) {
291
+ maxPredEnd = predNode.endDate;
292
+ }
293
+ }
294
+ if (start.getTime() < maxPredEnd.getTime()) {
295
+ warn(
296
+ task.lineNumber,
297
+ `Explicit date ${task.explicitStart}${task.offset ? " (with offset)" : ""} overlaps with predecessor ending ${formatDate(maxPredEnd)}. Using explicit date.`
298
+ );
299
+ }
300
+ }
301
+ let end;
302
+ if (task.duration) {
303
+ if (task.duration.amount === 0) {
304
+ end = new Date(start);
305
+ } else {
306
+ end = addGanttDuration(
307
+ start,
308
+ task.duration,
309
+ parsed.holidays,
310
+ holidaySet,
311
+ 1,
312
+ sprintOpts
313
+ );
314
+ }
315
+ } else {
316
+ end = new Date(start);
317
+ }
318
+ node.startDate = start;
319
+ node.endDate = end;
320
+ }
321
+ const criticalSet = parsed.options.criticalPath ? computeCriticalPath(
322
+ sortedIds,
323
+ taskMap,
324
+ depOffsetMap,
325
+ parsed.holidays,
326
+ holidaySet,
327
+ sprintOpts
328
+ ) : /* @__PURE__ */ new Set();
329
+ const uncertainSet = /* @__PURE__ */ new Set();
330
+ for (const taskId of sortedIds) {
331
+ const node = taskMap.get(taskId);
332
+ if (node.task.uncertain) {
333
+ uncertainSet.add(taskId);
334
+ } else {
335
+ for (const predId of node.predecessors) {
336
+ if (uncertainSet.has(predId)) {
337
+ uncertainSet.add(taskId);
338
+ break;
339
+ }
340
+ }
341
+ }
342
+ }
343
+ for (const taskId of sortedIds) {
344
+ const node = taskMap.get(taskId);
345
+ result.tasks.push({
346
+ task: node.task,
347
+ startDate: node.startDate,
348
+ endDate: node.endDate,
349
+ isCriticalPath: criticalSet.has(taskId),
350
+ isUncertain: uncertainSet.has(taskId),
351
+ isMilestone: node.task.duration?.amount === 0 || !node.task.duration && !node.task.explicitStart,
352
+ groupPath: node.task.groupPath.slice(),
353
+ effectiveMetadata: { ...node.task.metadata }
354
+ });
355
+ }
356
+ buildResolvedGroups(parsed.nodes, taskMap, result.groups, 0);
357
+ if (result.tasks.length > 0) {
358
+ let minDate = result.tasks[0].startDate;
359
+ let maxDate = result.tasks[0].endDate;
360
+ for (const t of result.tasks) {
361
+ if (t.startDate.getTime() < minDate.getTime()) minDate = t.startDate;
362
+ if (t.endDate.getTime() > maxDate.getTime()) maxDate = t.endDate;
363
+ }
364
+ result.startDate = minDate;
365
+ result.endDate = maxDate;
366
+ }
367
+ if (parsed.options.sprintMode && parsed.options.sprintLength && result.tasks.length > 0) {
368
+ result.sprints = generateSprintBands(
369
+ parsed.options,
370
+ result.startDate,
371
+ result.endDate,
372
+ projectStart
373
+ );
374
+ if (result.sprints.length > 0) {
375
+ const lastSprintEnd = result.sprints[result.sprints.length - 1].endDate;
376
+ if (lastSprintEnd.getTime() > result.endDate.getTime()) {
377
+ result.endDate = lastSprintEnd;
378
+ }
379
+ }
380
+ }
381
+ if (parsed.syntaxMode === "legacy") {
382
+ const topLevelGroups = parsed.nodes.filter((n) => n.kind === "group");
383
+ if (topLevelGroups.length >= 2) {
384
+ const names = topLevelGroups.map(
385
+ (g) => g.name
386
+ );
387
+ warn(
388
+ topLevelGroups[0].lineNumber,
389
+ `${names.join(" and ")} are sequential. Wrap in \`parallel\` if they should run concurrently.`
390
+ );
391
+ }
392
+ }
393
+ return result;
394
+ }
395
+ function buildImplicitDeps(nodes, taskMap) {
396
+ walkChildren(nodes, null);
397
+ function walkChildren(children, afterTaskId) {
398
+ let prevTaskId = afterTaskId;
399
+ for (const node of children) {
400
+ if (node.kind === "task") {
401
+ if (prevTaskId) {
402
+ const taskNode = taskMap.get(node.id);
403
+ if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
404
+ taskNode.predecessors.push(prevTaskId);
405
+ }
406
+ }
407
+ prevTaskId = node.id;
408
+ } else if (node.kind === "group") {
409
+ const lastId = walkSequential(node.children, prevTaskId);
410
+ if (lastId) prevTaskId = lastId;
411
+ } else if (node.kind === "parallel") {
412
+ const branchLastIds = [];
413
+ for (const child of node.children) {
414
+ if (child.kind === "task") {
415
+ if (prevTaskId) {
416
+ const taskNode = taskMap.get(child.id);
417
+ if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
418
+ taskNode.predecessors.push(prevTaskId);
419
+ }
420
+ }
421
+ branchLastIds.push(child.id);
422
+ } else if (child.kind === "group") {
423
+ const firstId = findFirstTask(child.children);
424
+ if (firstId && prevTaskId) {
425
+ const taskNode = taskMap.get(firstId);
426
+ if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
427
+ taskNode.predecessors.push(prevTaskId);
428
+ }
429
+ }
430
+ walkSequential(child.children, null);
431
+ const lastId = findLastTask(child.children);
432
+ if (lastId) branchLastIds.push(lastId);
433
+ } else if (child.kind === "parallel") {
434
+ walkChildren([child], prevTaskId);
435
+ const lastId = findLastTask(child.children);
436
+ if (lastId) branchLastIds.push(lastId);
437
+ }
438
+ }
439
+ if (branchLastIds.length > 0) {
440
+ prevTaskId = null;
441
+ const nextIdx = children.indexOf(node) + 1;
442
+ if (nextIdx < children.length) {
443
+ const nextFirstId = findFirstTask([children[nextIdx]]);
444
+ if (nextFirstId) {
445
+ const nextNode = taskMap.get(nextFirstId);
446
+ if (nextNode) {
447
+ for (const branchId of branchLastIds) {
448
+ if (!nextNode.predecessors.includes(branchId)) {
449
+ nextNode.predecessors.push(branchId);
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ function walkSequential(children, afterTaskId) {
460
+ let prevTaskId = afterTaskId;
461
+ for (const node of children) {
462
+ if (node.kind === "task") {
463
+ if (prevTaskId) {
464
+ const taskNode = taskMap.get(node.id);
465
+ if (taskNode && !taskNode.predecessors.includes(prevTaskId)) {
466
+ taskNode.predecessors.push(prevTaskId);
467
+ }
468
+ }
469
+ prevTaskId = node.id;
470
+ } else if (node.kind === "group") {
471
+ const lastId = walkSequential(node.children, prevTaskId);
472
+ if (lastId) prevTaskId = lastId;
473
+ } else if (node.kind === "parallel") {
474
+ walkChildren([node], prevTaskId);
475
+ const lastId = findLastTask(node.children);
476
+ if (lastId) prevTaskId = lastId;
477
+ }
478
+ }
479
+ return prevTaskId;
480
+ }
481
+ }
482
+ function findFirstTask(nodes) {
483
+ for (const node of nodes) {
484
+ if (node.kind === "task") return node.id;
485
+ if (node.kind === "group" || node.kind === "parallel") {
486
+ const found = findFirstTask(node.children);
487
+ if (found) return found;
488
+ }
489
+ }
490
+ return null;
491
+ }
492
+ function findLastTask(nodes) {
493
+ for (let i = nodes.length - 1; i >= 0; i--) {
494
+ const node = nodes[i];
495
+ if (node.kind === "task") return node.id;
496
+ if (node.kind === "group" || node.kind === "parallel") {
497
+ const found = findLastTask(node.children);
498
+ if (found) return found;
499
+ }
500
+ }
501
+ return null;
502
+ }
503
+ function topologicalSort(taskMap) {
504
+ const inDegree = /* @__PURE__ */ new Map();
505
+ const adjacency = /* @__PURE__ */ new Map();
506
+ for (const [id, node] of taskMap) {
507
+ inDegree.set(id, node.predecessors.length);
508
+ for (const pred of node.predecessors) {
509
+ const adj = adjacency.get(pred) ?? [];
510
+ adj.push(id);
511
+ adjacency.set(pred, adj);
512
+ }
513
+ }
514
+ const queue = [];
515
+ for (const [id, degree] of inDegree) {
516
+ if (degree === 0) queue.push(id);
517
+ }
518
+ const sorted = [];
519
+ while (queue.length > 0) {
520
+ const current = queue.shift();
521
+ sorted.push(current);
522
+ for (const succ of adjacency.get(current) ?? []) {
523
+ const newDegree = (inDegree.get(succ) ?? 1) - 1;
524
+ inDegree.set(succ, newDegree);
525
+ if (newDegree === 0) queue.push(succ);
526
+ }
527
+ }
528
+ return sorted.length === taskMap.size ? sorted : null;
529
+ }
530
+ function findCycle(taskMap) {
531
+ const visited = /* @__PURE__ */ new Set();
532
+ const onStack = /* @__PURE__ */ new Set();
533
+ const parent = /* @__PURE__ */ new Map();
534
+ for (const id of taskMap.keys()) {
535
+ if (!visited.has(id)) {
536
+ const cycle = dfs(id);
537
+ if (cycle) return cycle;
538
+ }
539
+ }
540
+ return [];
541
+ function dfs(id) {
542
+ visited.add(id);
543
+ onStack.add(id);
544
+ const successors = [];
545
+ for (const [otherId, otherNode] of taskMap) {
546
+ if (otherNode.predecessors.includes(id)) {
547
+ successors.push(otherId);
548
+ }
549
+ }
550
+ for (const succ of successors) {
551
+ if (!visited.has(succ)) {
552
+ parent.set(succ, id);
553
+ const cycle = dfs(succ);
554
+ if (cycle) return cycle;
555
+ } else if (onStack.has(succ)) {
556
+ const cycle = [succ];
557
+ let current = id;
558
+ while (current !== succ) {
559
+ cycle.push(current);
560
+ current = parent.get(current);
561
+ }
562
+ cycle.push(succ);
563
+ return cycle.reverse();
564
+ }
565
+ }
566
+ onStack.delete(id);
567
+ return null;
568
+ }
569
+ }
570
+ function breakCycle(cycle, taskMap, depOffsetMap) {
571
+ if (cycle.length < 3) return;
572
+ const fromId = cycle[cycle.length - 2];
573
+ const toId = cycle[0];
574
+ const toNode = taskMap.get(toId);
575
+ if (toNode) {
576
+ const idx = toNode.predecessors.indexOf(fromId);
577
+ if (idx !== -1) {
578
+ toNode.predecessors.splice(idx, 1);
579
+ depOffsetMap.delete(`${fromId}->${toId}`);
580
+ }
581
+ }
582
+ }
583
+ function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet, sprintOpts) {
584
+ if (sortedIds.length === 0) return /* @__PURE__ */ new Set();
585
+ const latestEnd = /* @__PURE__ */ new Map();
586
+ const latestStart = /* @__PURE__ */ new Map();
587
+ let projectEnd = 0;
588
+ for (const id of sortedIds) {
589
+ const node = taskMap.get(id);
590
+ if (node.endDate && node.endDate.getTime() > projectEnd) {
591
+ projectEnd = node.endDate.getTime();
592
+ }
593
+ }
594
+ const successors = /* @__PURE__ */ new Map();
595
+ for (const [id, node] of taskMap) {
596
+ for (const pred of node.predecessors) {
597
+ const succs = successors.get(pred) ?? [];
598
+ succs.push(id);
599
+ successors.set(pred, succs);
600
+ }
601
+ }
602
+ for (let i = sortedIds.length - 1; i >= 0; i--) {
603
+ const id = sortedIds[i];
604
+ const node = taskMap.get(id);
605
+ const succs = successors.get(id) ?? [];
606
+ if (succs.length === 0) {
607
+ latestEnd.set(id, projectEnd);
608
+ } else {
609
+ let minVal = Infinity;
610
+ for (const succId of succs) {
611
+ let succLS = latestStart.get(succId);
612
+ if (succLS === void 0) continue;
613
+ const succTask = taskMap.get(succId).task;
614
+ if (succTask.offset) {
615
+ const reverseDir = succTask.offset.direction * -1;
616
+ const adjusted = addGanttDuration(
617
+ new Date(succLS),
618
+ succTask.offset.duration,
619
+ holidays,
620
+ holidaySet,
621
+ reverseDir,
622
+ sprintOpts
623
+ );
624
+ succLS = adjusted.getTime();
625
+ }
626
+ const depOffset = depOffsetMap.get(`${id}->${succId}`);
627
+ if (depOffset) {
628
+ const reverseDir = depOffset.direction * -1;
629
+ const adjusted = addGanttDuration(
630
+ new Date(succLS),
631
+ depOffset.duration,
632
+ holidays,
633
+ holidaySet,
634
+ reverseDir,
635
+ sprintOpts
636
+ );
637
+ succLS = adjusted.getTime();
638
+ }
639
+ if (succLS < minVal) {
640
+ minVal = succLS;
641
+ }
642
+ }
643
+ latestEnd.set(id, minVal);
644
+ }
645
+ const duration = node.endDate.getTime() - node.startDate.getTime();
646
+ latestStart.set(id, latestEnd.get(id) - duration);
647
+ }
648
+ const critical = /* @__PURE__ */ new Set();
649
+ for (const id of sortedIds) {
650
+ const node = taskMap.get(id);
651
+ const slack = (latestStart.get(id) ?? 0) - node.startDate.getTime();
652
+ if (Math.abs(slack) < 864e5) {
653
+ critical.add(id);
654
+ }
655
+ }
656
+ return critical;
657
+ }
658
+ function buildResolvedGroups(nodes, taskMap, groups, depth) {
659
+ for (const node of nodes) {
660
+ if (node.kind === "group") {
661
+ const childTasks = collectTasks(node.children);
662
+ if (childTasks.length === 0) {
663
+ groups.push({
664
+ name: node.name,
665
+ color: node.color,
666
+ metadata: node.metadata,
667
+ startDate: /* @__PURE__ */ new Date(),
668
+ endDate: /* @__PURE__ */ new Date(),
669
+ progress: null,
670
+ lineNumber: node.lineNumber,
671
+ depth,
672
+ ...node.collapsed && { collapsed: true }
673
+ });
674
+ continue;
675
+ }
676
+ let minStart = Infinity;
677
+ let maxEnd = -Infinity;
678
+ let totalProgress = 0;
679
+ let totalDuration = 0;
680
+ let hasProgress = false;
681
+ for (const task of childTasks) {
682
+ const resolved = taskMap.get(task.id);
683
+ if (!resolved?.startDate || !resolved?.endDate) continue;
684
+ if (resolved.startDate.getTime() < minStart)
685
+ minStart = resolved.startDate.getTime();
686
+ if (resolved.endDate.getTime() > maxEnd)
687
+ maxEnd = resolved.endDate.getTime();
688
+ const dur = resolved.endDate.getTime() - resolved.startDate.getTime();
689
+ totalDuration += dur;
690
+ if (task.progress !== null) {
691
+ totalProgress += task.progress * dur;
692
+ hasProgress = true;
693
+ }
694
+ }
695
+ groups.push({
696
+ name: node.name,
697
+ color: node.color,
698
+ metadata: node.metadata,
699
+ startDate: new Date(minStart === Infinity ? 0 : minStart),
700
+ endDate: new Date(maxEnd === -Infinity ? 0 : maxEnd),
701
+ progress: hasProgress && totalDuration > 0 ? totalProgress / totalDuration : null,
702
+ lineNumber: node.lineNumber,
703
+ depth,
704
+ ...node.collapsed && { collapsed: true }
705
+ });
706
+ buildResolvedGroups(node.children, taskMap, groups, depth + 1);
707
+ } else if (node.kind === "parallel") {
708
+ buildResolvedGroups(node.children, taskMap, groups, depth);
709
+ }
710
+ }
711
+ }
712
+ function generateSprintBands(options, chartStart, chartEnd, projectStart) {
713
+ const sprintLength = options.sprintLength;
714
+ const sprintNumber = options.sprintNumber ?? 1;
715
+ let anchorDate;
716
+ if (options.sprintStart) {
717
+ anchorDate = /* @__PURE__ */ new Date(options.sprintStart + "T00:00:00");
718
+ } else if (options.start) {
719
+ anchorDate = new Date(projectStart);
720
+ } else {
721
+ const now = /* @__PURE__ */ new Date();
722
+ anchorDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
723
+ }
724
+ anchorDate.setHours(0, 0, 0, 0);
725
+ const sprintDays = Math.round(
726
+ sprintLength.amount * (sprintLength.unit === "w" ? 7 : 1)
727
+ );
728
+ if (sprintDays <= 0) return [];
729
+ if (Number.isNaN(anchorDate.getTime())) return [];
730
+ const chartStartTime = new Date(chartStart);
731
+ chartStartTime.setHours(0, 0, 0, 0);
732
+ const chartEndTime = new Date(chartEnd);
733
+ chartEndTime.setHours(0, 0, 0, 0);
734
+ const msPerDay = 864e5;
735
+ const dayDiff = Math.floor(
736
+ (chartStartTime.getTime() - anchorDate.getTime()) / msPerDay
737
+ );
738
+ const startSprintIndex = Math.floor(dayDiff / sprintDays);
739
+ const sprints = [];
740
+ const maxSprints = 1e3;
741
+ for (let i = startSprintIndex; sprints.length < maxSprints; i++) {
742
+ const sprintStartDate = new Date(anchorDate);
743
+ sprintStartDate.setDate(sprintStartDate.getDate() + i * sprintDays);
744
+ sprintStartDate.setHours(0, 0, 0, 0);
745
+ const sprintEndDate = new Date(sprintStartDate);
746
+ sprintEndDate.setDate(sprintEndDate.getDate() + sprintDays);
747
+ sprintEndDate.setHours(0, 0, 0, 0);
748
+ if (sprintStartDate.getTime() >= chartEndTime.getTime() + msPerDay) break;
749
+ sprints.push({
750
+ number: sprintNumber + i,
751
+ startDate: sprintStartDate,
752
+ endDate: sprintEndDate
753
+ });
754
+ }
755
+ return sprints;
756
+ }
757
+ function formatDate(d) {
758
+ const y = d.getFullYear();
759
+ const m = String(d.getMonth() + 1).padStart(2, "0");
760
+ const day = String(d.getDate()).padStart(2, "0");
761
+ return `${y}-${m}-${day}`;
762
+ }
763
+ function findGroupOffset(nodes, groupPath) {
764
+ if (groupPath.length === 0) return null;
765
+ const groupName = groupPath[groupPath.length - 1];
766
+ function search(children) {
767
+ for (const node of children) {
768
+ if (node.kind === "group") {
769
+ if (node.name === groupName && node.offset) return node.offset;
770
+ const found = search(node.children);
771
+ if (found) return found;
772
+ } else if (node.kind === "parallel") {
773
+ const found = search(node.children);
774
+ if (found) return found;
775
+ }
776
+ }
777
+ return null;
778
+ }
779
+ return search(nodes);
780
+ }
781
+
782
+ export {
783
+ collectTasks,
784
+ resolveTaskName,
785
+ calculateSchedule
786
+ };
787
+ //# sourceMappingURL=chunk-Z72XRXD4.js.map