@diagrammo/dgmo 0.45.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 (250) hide show
  1. package/dist/advanced.cjs +31 -25
  2. package/dist/advanced.d.cts +3 -855
  3. package/dist/advanced.d.ts +3 -855
  4. package/dist/advanced.js +541 -70101
  5. package/dist/analyzer-UYKBXAKR.js +15 -0
  6. package/dist/auto.cjs +500 -341
  7. package/dist/auto.css +342 -159
  8. package/dist/auto.d.cts +10 -8
  9. package/dist/auto.d.ts +10 -8
  10. package/dist/auto.js +373 -265
  11. package/dist/auto.mjs +500 -341
  12. package/dist/block.cjs +31 -25
  13. package/dist/block.js +83 -69411
  14. package/dist/calculator-LDYQCDDY.js +11 -0
  15. package/dist/charts-d3-QOZHKTCT.js +25 -0
  16. package/dist/chunk-2DXMZRWJ.js +800 -0
  17. package/dist/chunk-2LACINWN.js +786 -0
  18. package/dist/chunk-33LCUH4H.js +893 -0
  19. package/dist/chunk-3CIOJ5YJ.js +35 -0
  20. package/dist/chunk-3HDBAXF5.js +86 -0
  21. package/dist/chunk-3JLKYGBQ.js +290 -0
  22. package/dist/chunk-3MQQNXPD.js +415 -0
  23. package/dist/chunk-3R5POCTZ.js +967 -0
  24. package/dist/chunk-3SMGIJDD.js +112 -0
  25. package/dist/chunk-44CM72SQ.js +409 -0
  26. package/dist/chunk-4GRI7MEB.js +1604 -0
  27. package/dist/chunk-4OHACBGX.js +606 -0
  28. package/dist/chunk-5DH3KYFH.js +21 -0
  29. package/dist/chunk-5MLYVTYM.js +76 -0
  30. package/dist/chunk-5QXL4NYS.js +553 -0
  31. package/dist/chunk-5WRI5ZAA.js +31 -0
  32. package/dist/chunk-6EK55ART.js +117 -0
  33. package/dist/chunk-6FZYCKXB.js +2065 -0
  34. package/dist/chunk-6HO5ZTXK.js +277 -0
  35. package/dist/chunk-6KFWC4CO.js +7 -0
  36. package/dist/chunk-6MTWIQVO.js +121 -0
  37. package/dist/chunk-6NYWYNBI.js +329 -0
  38. package/dist/chunk-6SM5NJQH.js +620 -0
  39. package/dist/chunk-725LDASD.js +422 -0
  40. package/dist/chunk-76OWZ3BA.js +130 -0
  41. package/dist/chunk-7JEGTRLD.js +338 -0
  42. package/dist/chunk-A44USUV7.js +923 -0
  43. package/dist/chunk-A4GOY3PE.js +25 -0
  44. package/dist/chunk-A4VFQH5G.js +251 -0
  45. package/dist/chunk-AELOBFW5.js +375 -0
  46. package/dist/chunk-AN2MOO5T.js +522 -0
  47. package/dist/chunk-BMR4CIEO.js +41 -0
  48. package/dist/chunk-BS7SV7C3.js +51 -0
  49. package/dist/chunk-BUPDIHML.js +613 -0
  50. package/dist/chunk-BUVJFRPY.js +887 -0
  51. package/dist/chunk-C3Z4DX3V.js +112 -0
  52. package/dist/chunk-CI2G3OEB.js +1818 -0
  53. package/dist/chunk-CKNVO24D.js +54 -0
  54. package/dist/chunk-CUVHQHZ7.js +391 -0
  55. package/dist/chunk-CXK4DZH3.js +114 -0
  56. package/dist/chunk-DKEPS5LH.js +315 -0
  57. package/dist/chunk-DU7W62N5.js +487 -0
  58. package/dist/chunk-DZAQBW35.js +751 -0
  59. package/dist/chunk-EB6FPQUP.js +316 -0
  60. package/dist/chunk-EMS2SK26.js +376 -0
  61. package/dist/chunk-ERLBPDGU.js +510 -0
  62. package/dist/chunk-EVCVDTXE.js +732 -0
  63. package/dist/chunk-FCIIHT24.js +384 -0
  64. package/dist/chunk-FFUN5D66.js +97 -0
  65. package/dist/chunk-FITOLXSX.js +714 -0
  66. package/dist/chunk-FMDSF3OV.js +68 -0
  67. package/dist/chunk-FNB3PNGF.js +410 -0
  68. package/dist/chunk-G2H74XJZ.js +2104 -0
  69. package/dist/chunk-GMR5MFHJ.js +339 -0
  70. package/dist/chunk-H6PI3KJT.js +305 -0
  71. package/dist/chunk-I46X5VUA.js +59 -0
  72. package/dist/chunk-I5IGB56C.js +255 -0
  73. package/dist/chunk-IH6ZMVQ5.js +3950 -0
  74. package/dist/chunk-IJZFN3HM.js +463 -0
  75. package/dist/chunk-IPWPWM6R.js +3079 -0
  76. package/dist/chunk-IYULMRBE.js +23 -0
  77. package/dist/chunk-IZMRON6C.js +167 -0
  78. package/dist/chunk-J5FIXQRT.js +813 -0
  79. package/dist/chunk-JED6ZDEE.js +73 -0
  80. package/dist/chunk-JEUJOX5X.js +136 -0
  81. package/dist/chunk-JM4LEPY3.js +436 -0
  82. package/dist/chunk-L3UHP6TD.js +101 -0
  83. package/dist/chunk-L66GEFB6.js +524 -0
  84. package/dist/chunk-LIOHW36Z.js +469 -0
  85. package/dist/chunk-LP7EC4MI.js +16 -0
  86. package/dist/chunk-MITI6NOL.js +548 -0
  87. package/dist/chunk-MO5YHHMQ.js +168 -0
  88. package/dist/chunk-MZSBFAPJ.js +885 -0
  89. package/dist/chunk-NNAAJVBU.js +9 -0
  90. package/dist/chunk-NOTA6TEI.js +47 -0
  91. package/dist/chunk-NURGB5Z4.js +335 -0
  92. package/dist/chunk-NX4EQS3U.js +1062 -0
  93. package/dist/chunk-NXMESY4J.js +1 -0
  94. package/dist/chunk-OJR3MQYV.js +1458 -0
  95. package/dist/chunk-OURHMODR.js +454 -0
  96. package/dist/chunk-P235SVAH.js +1057 -0
  97. package/dist/chunk-P4RH4OSP.js +1038 -0
  98. package/dist/chunk-P6T66CCZ.js +226 -0
  99. package/dist/chunk-PBAHEPLQ.js +223 -0
  100. package/dist/chunk-PBHE5UG6.js +1530 -0
  101. package/dist/chunk-PDKUANDZ.js +35 -0
  102. package/dist/chunk-PWIHZ6NJ.js +296 -0
  103. package/dist/chunk-QEBUY5NY.js +1685 -0
  104. package/dist/chunk-QLCCJEJI.js +253 -0
  105. package/dist/chunk-QOOUC2J5.js +52 -0
  106. package/dist/chunk-QYTPPDAO.js +402 -0
  107. package/dist/chunk-R3XI2VC7.js +801 -0
  108. package/dist/chunk-RCERWOJR.js +154 -0
  109. package/dist/chunk-RJE5JTVK.js +362 -0
  110. package/dist/chunk-RTLBSQ3G.js +1155 -0
  111. package/dist/chunk-RUNNI6VE.js +448 -0
  112. package/dist/chunk-RVMRZAPB.js +354 -0
  113. package/dist/chunk-RYEGFMUO.js +955 -0
  114. package/dist/chunk-RZCF2VVM.js +528 -0
  115. package/dist/chunk-SML67VPV.js +1025 -0
  116. package/dist/chunk-SQ7IY53Q.js +44 -0
  117. package/dist/chunk-SQAG3UXH.js +161 -0
  118. package/dist/chunk-SRTU6HMQ.js +1851 -0
  119. package/dist/chunk-T2OE3YQB.js +550 -0
  120. package/dist/chunk-T3UBLACL.js +299 -0
  121. package/dist/chunk-TLVIHFRO.js +296 -0
  122. package/dist/chunk-TYS6CSS5.js +52 -0
  123. package/dist/chunk-U6EQI3U6.js +130 -0
  124. package/dist/chunk-UJ4FJLBF.js +86 -0
  125. package/dist/chunk-ULOEATBZ.js +347 -0
  126. package/dist/chunk-UNCCZ3NU.js +127 -0
  127. package/dist/chunk-USZW2HHU.js +197 -0
  128. package/dist/chunk-UWN33VNX.js +1610 -0
  129. package/dist/chunk-UZ7EZW3B.js +40 -0
  130. package/dist/chunk-VOKGH627.js +37 -0
  131. package/dist/chunk-WBRZJOEC.js +204 -0
  132. package/dist/chunk-WCSOJFU3.js +380 -0
  133. package/dist/chunk-WCT3NYCV.js +160 -0
  134. package/dist/chunk-WVAJFAIA.js +529 -0
  135. package/dist/chunk-X5LCYCL5.js +394 -0
  136. package/dist/chunk-XAKEUMEJ.js +1256 -0
  137. package/dist/chunk-Y2ZE3MSG.js +590 -0
  138. package/dist/chunk-Y3J7VR52.js +646 -0
  139. package/dist/chunk-Y5QGVTVC.js +33 -0
  140. package/dist/chunk-YAA6IID3.js +548 -0
  141. package/dist/chunk-YGJTDXVR.js +692 -0
  142. package/dist/chunk-YRYKTYMQ.js +186 -0
  143. package/dist/chunk-YYVTBZZC.js +61 -0
  144. package/dist/chunk-Z5CGSFJB.js +647 -0
  145. package/dist/chunk-Z72XRXD4.js +787 -0
  146. package/dist/chunk-ZGR7ULFJ.js +978 -0
  147. package/dist/chunk-ZJEL4H2R.js +851 -0
  148. package/dist/chunk-ZO27FGJS.js +554 -0
  149. package/dist/cli.cjs +112 -112
  150. package/dist/collapse-CLPJD2RL.js +11 -0
  151. package/dist/collapse-SLINJQW6.js +9 -0
  152. package/dist/collapse-ZWUFFCK2.js +9 -0
  153. package/dist/compute-G55RG53N.js +8 -0
  154. package/dist/dgmo-router-DZCIDUO5.js +73 -0
  155. package/dist/dimensions-J3FHIMJ6.js +22 -0
  156. package/dist/element.cjs +492 -325
  157. package/dist/element.js +367 -259
  158. package/dist/element.mjs +492 -325
  159. package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
  160. package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
  161. package/dist/index.cjs +34 -28
  162. package/dist/index.d.cts +3 -469
  163. package/dist/index.d.ts +3 -469
  164. package/dist/index.js +137 -69679
  165. package/dist/layout-46N4JJYK.js +17 -0
  166. package/dist/layout-5RA6QWR6.js +26 -0
  167. package/dist/layout-5T6RH5M6.js +14 -0
  168. package/dist/layout-7QXCNOVS.js +13 -0
  169. package/dist/layout-EE6GE46Y.js +17 -0
  170. package/dist/layout-G23F7LDH.js +9 -0
  171. package/dist/layout-HRBZPFCN.js +23 -0
  172. package/dist/layout-HWDSRX5E.js +20 -0
  173. package/dist/layout-HYZPWAK5.js +18 -0
  174. package/dist/layout-N76NR4ZO.js +19 -0
  175. package/dist/layout-OB3RI63S.js +14 -0
  176. package/dist/layout-S2QBYSK2.js +15 -0
  177. package/dist/layout-UM5F4DJB.js +15 -0
  178. package/dist/layout-search-OYV77HHS.js +1655 -0
  179. package/dist/load-data-EHDDZ5ZS.js +8 -0
  180. package/dist/palettes-PRJ2RI6D.js +56 -0
  181. package/dist/parser-2MFP2H2E.js +11 -0
  182. package/dist/parser-3STE62GB.js +21 -0
  183. package/dist/parser-4FL2CMDG.js +18 -0
  184. package/dist/parser-4OGOBJJ4.js +13 -0
  185. package/dist/parser-6BTRLKRZ.js +15 -0
  186. package/dist/parser-AQETEVRW.js +21 -0
  187. package/dist/parser-CFZD5IBL.js +12 -0
  188. package/dist/parser-FUSKFGZN.js +16 -0
  189. package/dist/parser-I6KXEYFK.js +13 -0
  190. package/dist/parser-IXSZZQHY.js +18 -0
  191. package/dist/parser-JAL2HD4I.js +13 -0
  192. package/dist/parser-KNSQSKQO.js +20 -0
  193. package/dist/parser-N5O4IHUN.js +13 -0
  194. package/dist/parser-NGU3ETO6.js +16 -0
  195. package/dist/parser-NRAI6O25.js +19 -0
  196. package/dist/parser-O5J4VBII.js +11 -0
  197. package/dist/parser-OV7NOBW6.js +21 -0
  198. package/dist/parser-PQ3POX45.js +23 -0
  199. package/dist/parser-TFZFBVWN.js +11 -0
  200. package/dist/parser-TRTHDFPP.js +18 -0
  201. package/dist/parser-VQP2UJ6W.js +11 -0
  202. package/dist/parser-XDVELHRK.js +13 -0
  203. package/dist/parser-XKRP7QKP.js +11 -0
  204. package/dist/parser-Y6WTBU76.js +14 -0
  205. package/dist/parser-ZSDPZYQP.js +12 -0
  206. package/dist/renderer-2XQQQ6QR.js +28 -0
  207. package/dist/renderer-5NDVNDAZ.js +26 -0
  208. package/dist/renderer-6EEZHMH4.js +26 -0
  209. package/dist/renderer-6W5462RB.js +43 -0
  210. package/dist/renderer-7MVLWWQD.js +22 -0
  211. package/dist/renderer-AWWAF6XD.js +33 -0
  212. package/dist/renderer-BYCNMBF7.js +34 -0
  213. package/dist/renderer-CLJHQPBJ.js +29 -0
  214. package/dist/renderer-GHPZMFU2.js +15 -0
  215. package/dist/renderer-JGBKUCZD.js +16 -0
  216. package/dist/renderer-KQB7UGDS.js +19 -0
  217. package/dist/renderer-PGX2TKVS.js +24 -0
  218. package/dist/renderer-QIWVHWZO.js +15 -0
  219. package/dist/renderer-RPOA5YPZ.js +35 -0
  220. package/dist/renderer-SMIBCRVB.js +24 -0
  221. package/dist/renderer-T7YKC5VP.js +28 -0
  222. package/dist/renderer-TOCOVLHS.js +37 -0
  223. package/dist/renderer-UWA5XS74.js +39 -0
  224. package/dist/renderer-VACVQYML.js +25 -0
  225. package/dist/renderer-W4M6QLIJ.js +37 -0
  226. package/dist/renderer-WZRREQ2P.js +23 -0
  227. package/dist/renderer-YY2OSF6E.js +27 -0
  228. package/dist/renderer-Z7I3W2PP.js +24 -0
  229. package/dist/renderer-ZGNTUWC4.js +22 -0
  230. package/dist/renderer-ZTR3DER3.js +19 -0
  231. package/dist/renderer-radial-C32GPJQ7.js +21 -0
  232. package/dist/resolver-NOAA7ID7.js +13 -0
  233. package/dist/state-collapse-HCGD6IVJ.js +8 -0
  234. package/dist/state-parser-Z2V23ATR.js +18 -0
  235. package/dist/state-renderer-RFYHSP4K.js +34 -0
  236. package/dist/themes-1-CuKpeH.d.cts +908 -0
  237. package/dist/themes-1-CuKpeH.d.ts +908 -0
  238. package/package.json +1 -1
  239. package/src/auto/index.ts +55 -57
  240. package/src/auto/shared.ts +142 -142
  241. package/src/auto/styles.ts +44 -199
  242. package/src/c4/renderer.ts +2 -2
  243. package/src/element/index.ts +29 -21
  244. package/src/infra/renderer.ts +1 -1
  245. package/src/render.ts +34 -14
  246. package/src/sitemap/renderer.ts +1 -1
  247. package/src/timeline/renderer.ts +1 -1
  248. package/src/utils/hover-styles.ts +6 -1
  249. package/src/utils/legend-d3.ts +1 -4
  250. package/src/utils/legend-svg.ts +1 -1
@@ -0,0 +1,316 @@
1
+ import {
2
+ tryStripDescriptionKeyword
3
+ } from "./chunk-IYULMRBE.js";
4
+ import {
5
+ AUTO_TAG_COLOR_SENTINEL,
6
+ cascadeTagMetadata,
7
+ finalizeAutoTagColors,
8
+ matchTagBlockHeading,
9
+ stripDefaultModifier,
10
+ tagAttrKey,
11
+ validateTagGroupNames,
12
+ validateTagValues
13
+ } from "./chunk-QLCCJEJI.js";
14
+ import {
15
+ MINDMAP_REGISTRY,
16
+ OPTION_NOCOLON_RE,
17
+ extractColor,
18
+ measureIndent,
19
+ parseFirstLine,
20
+ splitNameAndMeta,
21
+ tryParseSharedOption,
22
+ warnUnknownMetaKeys,
23
+ withTagAliases
24
+ } from "./chunk-Y3J7VR52.js";
25
+ import {
26
+ formatDgmoError,
27
+ makeDgmoError,
28
+ makeFail,
29
+ suggest
30
+ } from "./chunk-CXK4DZH3.js";
31
+
32
+ // src/mindmap/parser.ts
33
+ var KNOWN_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
34
+ function parseMindmap(content, palette) {
35
+ const options = {};
36
+ const result = {
37
+ title: null,
38
+ titleLineNumber: null,
39
+ roots: [],
40
+ tagGroups: [],
41
+ options,
42
+ diagnostics: [],
43
+ error: null
44
+ };
45
+ const fail = makeFail(result);
46
+ const pushError = (line, message) => {
47
+ const diag = makeDgmoError(line, message);
48
+ result.diagnostics.push(diag);
49
+ if (!result.error) result.error = formatDgmoError(diag);
50
+ };
51
+ const pushWarning = (line, message) => {
52
+ result.diagnostics.push(makeDgmoError(line, message, "warning"));
53
+ };
54
+ if (!content?.trim()) {
55
+ return fail(0, "No content provided");
56
+ }
57
+ const lines = content.split("\n");
58
+ let contentStarted = false;
59
+ let nodeCounter = 0;
60
+ let currentTagGroup = null;
61
+ const aliasMap = /* @__PURE__ */ new Map();
62
+ const indentStack = [];
63
+ const nodesWithChildren = /* @__PURE__ */ new Set();
64
+ let titleRoot = null;
65
+ for (let i = 0; i < lines.length; i++) {
66
+ const line = lines[i];
67
+ const lineNumber = i + 1;
68
+ const trimmed = line.trim();
69
+ if (!trimmed) {
70
+ if (currentTagGroup) {
71
+ currentTagGroup = null;
72
+ }
73
+ continue;
74
+ }
75
+ if (trimmed.startsWith("//")) continue;
76
+ if (!contentStarted) {
77
+ const firstLine = parseFirstLine(trimmed);
78
+ if (firstLine) {
79
+ if (firstLine.chartType !== "mindmap") {
80
+ let msg = `Expected chart type "mindmap", got "${firstLine.chartType}"`;
81
+ const hint = suggest(firstLine.chartType, ["mindmap"]);
82
+ if (hint) msg += `. ${hint}`;
83
+ return fail(lineNumber, msg);
84
+ }
85
+ if (firstLine.title) {
86
+ const label = firstLine.title;
87
+ result.title = label;
88
+ result.titleLineNumber = lineNumber;
89
+ nodeCounter++;
90
+ const titleMetadata = {};
91
+ titleRoot = {
92
+ id: `node-${nodeCounter}`,
93
+ label,
94
+ metadata: titleMetadata,
95
+ children: [],
96
+ parentId: null,
97
+ lineNumber
98
+ };
99
+ result.roots.push(titleRoot);
100
+ indentStack.push({ node: titleRoot, indent: -1 });
101
+ }
102
+ continue;
103
+ }
104
+ }
105
+ const tagBlockMatch = matchTagBlockHeading(trimmed);
106
+ if (tagBlockMatch) {
107
+ if (contentStarted) {
108
+ pushError(lineNumber, "Tag groups must appear before mindmap content");
109
+ continue;
110
+ }
111
+ currentTagGroup = {
112
+ name: tagBlockMatch.name,
113
+ ...tagBlockMatch.alias !== void 0 && {
114
+ alias: tagBlockMatch.alias
115
+ },
116
+ entries: [],
117
+ lineNumber
118
+ };
119
+ if (tagBlockMatch.alias) {
120
+ aliasMap.set(
121
+ tagBlockMatch.alias.toLowerCase(),
122
+ tagAttrKey(tagBlockMatch.name)
123
+ );
124
+ }
125
+ aliasMap.set(
126
+ tagAttrKey(tagBlockMatch.name),
127
+ tagAttrKey(tagBlockMatch.name)
128
+ );
129
+ result.tagGroups.push(currentTagGroup);
130
+ continue;
131
+ }
132
+ if (!contentStarted && !currentTagGroup && measureIndent(line) === 0) {
133
+ const optMatch = trimmed.match(OPTION_NOCOLON_RE);
134
+ if (optMatch) {
135
+ const key = optMatch[1].trim().toLowerCase();
136
+ if (KNOWN_OPTIONS.has(key)) {
137
+ options[key] = optMatch[2].trim();
138
+ continue;
139
+ }
140
+ }
141
+ const lower = trimmed.toLowerCase();
142
+ if (lower === "no-descriptions") {
143
+ pushWarning(
144
+ lineNumber,
145
+ '"no-descriptions" has been removed \u2014 delete description lines from your source instead.'
146
+ );
147
+ continue;
148
+ }
149
+ if (lower === "color-by-depth") {
150
+ options["color-by-depth"] = "on";
151
+ continue;
152
+ }
153
+ if (tryParseSharedOption(trimmed, options)) {
154
+ continue;
155
+ }
156
+ }
157
+ if (currentTagGroup && !contentStarted) {
158
+ const indent2 = measureIndent(line);
159
+ if (indent2 > 0) {
160
+ const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
161
+ const { label, color } = extractColor(
162
+ cleanEntry,
163
+ palette,
164
+ result.diagnostics,
165
+ lineNumber
166
+ );
167
+ if (isDefault) {
168
+ currentTagGroup.defaultValue = label;
169
+ } else if (currentTagGroup.entries.length === 0) {
170
+ currentTagGroup.defaultValue = label;
171
+ }
172
+ currentTagGroup.entries.push({
173
+ value: label,
174
+ color: color ?? AUTO_TAG_COLOR_SENTINEL,
175
+ lineNumber
176
+ });
177
+ continue;
178
+ }
179
+ currentTagGroup = null;
180
+ }
181
+ contentStarted = true;
182
+ currentTagGroup = null;
183
+ const indent = measureIndent(line);
184
+ if (indent > 0) {
185
+ const descResult = tryStripDescriptionKeyword(trimmed);
186
+ if (descResult.isKeyword && !descResult.needsColon) {
187
+ const parent = findMetadataParent(indent, indentStack);
188
+ if (parent) {
189
+ const descValue = descResult.text.trim();
190
+ if (!descValue) {
191
+ continue;
192
+ }
193
+ if (nodesWithChildren.has(parent.id)) {
194
+ pushWarning(
195
+ lineNumber,
196
+ `description after child nodes under "${parent.label}" \u2014 should precede children`
197
+ );
198
+ continue;
199
+ }
200
+ const existing = parent.description ? [...parent.description] : [];
201
+ existing.push(descValue);
202
+ parent.description = existing;
203
+ continue;
204
+ }
205
+ }
206
+ }
207
+ const node = parseNodeLine(
208
+ trimmed,
209
+ lineNumber,
210
+ palette,
211
+ ++nodeCounter,
212
+ aliasMap,
213
+ result.diagnostics
214
+ );
215
+ attachNode(node, indent, indentStack, result, nodesWithChildren);
216
+ }
217
+ if (result.title === null && result.roots.length > 0) {
218
+ result.title = result.roots[0].label;
219
+ result.titleLineNumber = result.roots[0].lineNumber;
220
+ }
221
+ finalizeAutoTagColors(result.tagGroups, palette);
222
+ if (result.tagGroups.length > 0) {
223
+ const allNodes = [];
224
+ const collectAll = (nodes) => {
225
+ for (const node of nodes) {
226
+ allNodes.push(node);
227
+ collectAll(node.children);
228
+ }
229
+ };
230
+ collectAll(result.roots);
231
+ validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
232
+ validateTagGroupNames(result.tagGroups, pushWarning);
233
+ cascadeTagMetadata(result.roots, result.tagGroups);
234
+ }
235
+ if (result.roots.length === 0 && !result.error) {
236
+ const diag = makeDgmoError(1, "No nodes found in mindmap");
237
+ result.diagnostics.push(diag);
238
+ result.error = formatDgmoError(diag);
239
+ } else if (titleRoot?.children.length === 0 && result.roots.length === 1 && !result.error) {
240
+ }
241
+ return result;
242
+ }
243
+ function parseNodeLine(trimmed, lineNumber, _palette, counter, aliasMap, diagnostics) {
244
+ const registry = withTagAliases(MINDMAP_REGISTRY, new Set(aliasMap.keys()));
245
+ const split = splitNameAndMeta(
246
+ trimmed,
247
+ registry,
248
+ aliasMap,
249
+ void 0,
250
+ diagnostics,
251
+ lineNumber
252
+ );
253
+ warnUnknownMetaKeys(
254
+ split.meta,
255
+ registry,
256
+ (msg) => diagnostics.push(makeDgmoError(lineNumber, msg, "warning")),
257
+ split.name
258
+ );
259
+ const label = split.name;
260
+ const metadata = { ...split.meta };
261
+ if (split.color !== void 0) metadata["color"] = split.color;
262
+ let description;
263
+ if ("description" in metadata) {
264
+ const descVal = metadata["description"].trim();
265
+ if (descVal) description = [descVal];
266
+ delete metadata["description"];
267
+ }
268
+ let collapsed;
269
+ if ("collapsed" in metadata) {
270
+ collapsed = metadata["collapsed"].toLowerCase() === "true";
271
+ delete metadata["collapsed"];
272
+ }
273
+ return {
274
+ id: `node-${counter}`,
275
+ label,
276
+ ...description !== void 0 && { description },
277
+ metadata,
278
+ children: [],
279
+ parentId: null,
280
+ lineNumber,
281
+ ...collapsed !== void 0 && { collapsed }
282
+ };
283
+ }
284
+ function attachNode(node, indent, indentStack, result, nodesWithChildren) {
285
+ while (indentStack.length > 0) {
286
+ const top = indentStack[indentStack.length - 1];
287
+ if (top.indent < indent) break;
288
+ indentStack.pop();
289
+ }
290
+ if (indentStack.length > 0) {
291
+ const parent = indentStack[indentStack.length - 1].node;
292
+ node.parentId = parent.id;
293
+ parent.children.push(node);
294
+ nodesWithChildren.add(parent.id);
295
+ } else {
296
+ result.roots.push(node);
297
+ }
298
+ indentStack.push({ node, indent });
299
+ }
300
+ function findMetadataParent(indent, indentStack) {
301
+ for (let i = indentStack.length - 1; i >= 0; i--) {
302
+ const entry = indentStack[i];
303
+ if (entry.indent < indent) {
304
+ return entry.node;
305
+ }
306
+ }
307
+ if (indentStack.length > 0) {
308
+ return indentStack[indentStack.length - 1].node;
309
+ }
310
+ return null;
311
+ }
312
+
313
+ export {
314
+ parseMindmap
315
+ };
316
+ //# sourceMappingURL=chunk-EB6FPQUP.js.map
@@ -0,0 +1,376 @@
1
+ import {
2
+ edgeSplinePath,
3
+ fitDiagramToCanvas
4
+ } from "./chunk-PDKUANDZ.js";
5
+ import {
6
+ layoutGraph
7
+ } from "./chunk-T3UBLACL.js";
8
+ import {
9
+ appendArrowheadMarkers
10
+ } from "./chunk-LP7EC4MI.js";
11
+ import {
12
+ NOTE_BADGE_RADIUS,
13
+ noteConnectorPoints,
14
+ renderNoteBadge,
15
+ renderNoteBox,
16
+ renderNoteConnector
17
+ } from "./chunk-JEUJOX5X.js";
18
+ import {
19
+ EDGE_STROKE_WIDTH,
20
+ NODE_STROKE_WIDTH
21
+ } from "./chunk-3CIOJ5YJ.js";
22
+ import {
23
+ ScaleContext
24
+ } from "./chunk-YYVTBZZC.js";
25
+ import {
26
+ TITLE_FONT_SIZE,
27
+ TITLE_FONT_WEIGHT,
28
+ TITLE_Y
29
+ } from "./chunk-A4GOY3PE.js";
30
+ import {
31
+ FONT_FAMILY
32
+ } from "./chunk-6KFWC4CO.js";
33
+ import {
34
+ measureText
35
+ } from "./chunk-WCT3NYCV.js";
36
+ import {
37
+ contrastText,
38
+ mix,
39
+ shapeFill,
40
+ themeBaseBg
41
+ } from "./chunk-P6T66CCZ.js";
42
+ import {
43
+ parseState
44
+ } from "./chunk-3MQQNXPD.js";
45
+
46
+ // src/graph/state-renderer.ts
47
+ import * as d3Selection from "d3-selection";
48
+ var DIAGRAM_PADDING = 20;
49
+ var MAX_SCALE = 3;
50
+ var NODE_FONT_SIZE = 13;
51
+ var EDGE_LABEL_FONT_SIZE = 11;
52
+ var GROUP_LABEL_FONT_SIZE = 11;
53
+ var ARROWHEAD_W = 10;
54
+ var ARROWHEAD_H = 7;
55
+ var PSEUDOSTATE_RADIUS = 10;
56
+ var STATE_CORNER_RADIUS = 10;
57
+ var GROUP_EXTRA_PADDING = 12;
58
+ function stateDefaultColor(palette, colorOff) {
59
+ return colorOff ? palette.textMuted : palette.colors.blue;
60
+ }
61
+ function stateFill(palette, isDark, nodeColor, colorOff, solid) {
62
+ const color = nodeColor ?? stateDefaultColor(palette, colorOff);
63
+ return shapeFill(palette, color, isDark, {
64
+ ...solid !== void 0 && { solid }
65
+ });
66
+ }
67
+ function stateStroke(palette, nodeColor, colorOff) {
68
+ return nodeColor ?? stateDefaultColor(palette, colorOff);
69
+ }
70
+ function selfLoopPath(node) {
71
+ const cx = node.x;
72
+ const cy = node.y;
73
+ const r = node.width / 2;
74
+ const startX = cx + r;
75
+ const startY = cy - 5;
76
+ const endX = cx + r;
77
+ const endY = cy + 5;
78
+ const loopR = 25;
79
+ return `M ${startX} ${startY} C ${startX + loopR * 2} ${startY - loopR * 2}, ${endX + loopR * 2} ${endY + loopR * 2}, ${endX} ${endY}`;
80
+ }
81
+ function renderState(container, graph, layout, palette, isDark, onClickItem, exportDims) {
82
+ d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
83
+ const width = exportDims?.width ?? container.clientWidth;
84
+ const height = exportDims?.height ?? container.clientHeight;
85
+ if (width <= 0 || height <= 0) return;
86
+ const ctx = ScaleContext.identity();
87
+ const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING);
88
+ const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
89
+ const sTitleY = ctx.structural(TITLE_Y);
90
+ const sNodeFontSize = ctx.text(NODE_FONT_SIZE);
91
+ const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
92
+ const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE);
93
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
94
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
95
+ const sArrowheadW = ctx.structural(ARROWHEAD_W);
96
+ const sArrowheadH = ctx.structural(ARROWHEAD_H);
97
+ const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
98
+ const sStateCornerRadius = ctx.structural(STATE_CORNER_RADIUS);
99
+ const sGroupExtraPadding = ctx.aesthetic(GROUP_EXTRA_PADDING);
100
+ const showTitle = !!graph.title && graph.options["no-title"] !== "on";
101
+ const titleHeight = showTitle ? 40 : 0;
102
+ const diagramW = layout.width;
103
+ const diagramH = layout.height;
104
+ const { scale, offsetX, offsetY, canvasHeight } = fitDiagramToCanvas({
105
+ width,
106
+ height,
107
+ diagramW,
108
+ diagramH,
109
+ padding: sDiagramPadding,
110
+ titleHeight,
111
+ maxScale: MAX_SCALE,
112
+ exportMode: !!exportDims
113
+ });
114
+ const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", canvasHeight).attr("viewBox", `0 0 ${width} ${canvasHeight}`).attr("preserveAspectRatio", "xMidYMin meet").style("font-family", FONT_FAMILY);
115
+ if (ctx.isBelowFloor) {
116
+ svg.attr("width", "100%");
117
+ }
118
+ const defs = svg.append("defs");
119
+ const edgeColors = /* @__PURE__ */ new Set();
120
+ appendArrowheadMarkers(defs, {
121
+ idPrefix: "st",
122
+ width: sArrowheadW,
123
+ height: sArrowheadH,
124
+ baseFill: palette.textMuted,
125
+ colors: edgeColors
126
+ });
127
+ if (showTitle) {
128
+ const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", sTitleY).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).style(
129
+ "cursor",
130
+ onClickItem && graph.titleLineNumber ? "pointer" : "default"
131
+ ).text(graph.title);
132
+ if (graph.titleLineNumber) {
133
+ titleEl.attr("data-line-number", graph.titleLineNumber);
134
+ if (onClickItem) {
135
+ titleEl.on("click", () => onClickItem(graph.titleLineNumber)).on("mouseenter", function() {
136
+ d3Selection.select(this).attr("opacity", 0.7);
137
+ }).on("mouseleave", function() {
138
+ d3Selection.select(this).attr("opacity", 1);
139
+ });
140
+ }
141
+ }
142
+ }
143
+ const contentG = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY}) scale(${scale})`);
144
+ for (const group of layout.groups) {
145
+ if (group.collapsed) continue;
146
+ if (group.width === 0 && group.height === 0) continue;
147
+ const gx = group.x - sGroupExtraPadding;
148
+ const gy = group.y - sGroupExtraPadding - sGroupLabelFontSize - 4;
149
+ const gw = group.width + sGroupExtraPadding * 2;
150
+ const gh = group.height + sGroupExtraPadding * 2 + sGroupLabelFontSize + 4;
151
+ const fillColor = group.color ? mix(group.color, themeBaseBg(palette, isDark), 10) : isDark ? palette.surface : mix(palette.border, palette.bg, 30);
152
+ const strokeColor = group.color ?? palette.textMuted;
153
+ const groupWrapper = contentG.append("g").attr("class", "st-group-wrapper").attr("data-line-number", String(group.lineNumber)).attr("data-group-id", group.id).attr("data-group-toggle", group.id).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", "true").attr("aria-label", `Collapse group ${group.label}`).style("cursor", "pointer");
154
+ groupWrapper.append("rect").attr("x", gx).attr("y", gy).attr("width", gw).attr("height", gh).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "st-group");
155
+ groupWrapper.append("text").attr("x", gx + 8).attr("y", gy + sGroupLabelFontSize + 4).attr("fill", strokeColor).attr("font-size", sGroupLabelFontSize).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "st-group-label").text(group.label);
156
+ }
157
+ const selfLoopEdges = /* @__PURE__ */ new Set();
158
+ for (const edge of layout.edges) {
159
+ if (edge.source === edge.target) selfLoopEdges.add(edge.lineNumber);
160
+ }
161
+ const nodePositionMap = /* @__PURE__ */ new Map();
162
+ for (const node of layout.nodes) {
163
+ nodePositionMap.set(node.id, node);
164
+ }
165
+ const LABEL_PAD = 8;
166
+ const LABEL_H = 16;
167
+ const PERP_OFFSET = 10;
168
+ const labelPositions = [];
169
+ for (let ei = 0; ei < layout.edges.length; ei++) {
170
+ const edge = layout.edges[ei];
171
+ if (!edge.label) continue;
172
+ const bgW = measureText(edge.label, sEdgeLabelFontSize) + LABEL_PAD;
173
+ let lx, ly;
174
+ if (edge.source === edge.target) {
175
+ const node = nodePositionMap.get(edge.source);
176
+ if (!node) continue;
177
+ lx = node.x + node.width / 2 + 30;
178
+ ly = node.y;
179
+ } else if (edge.points.length >= 2) {
180
+ const midIdx = Math.floor(edge.points.length / 2);
181
+ const midPt = edge.points[midIdx];
182
+ const prev = edge.points[Math.max(0, midIdx - 1)];
183
+ const next = edge.points[Math.min(edge.points.length - 1, midIdx + 1)];
184
+ const dx = next.x - prev.x;
185
+ const dy = next.y - prev.y;
186
+ const len = Math.sqrt(dx * dx + dy * dy);
187
+ if (len > 0) {
188
+ lx = midPt.x + -dy / len * PERP_OFFSET;
189
+ ly = midPt.y + dx / len * PERP_OFFSET;
190
+ } else {
191
+ lx = midPt.x;
192
+ ly = midPt.y;
193
+ }
194
+ } else {
195
+ continue;
196
+ }
197
+ labelPositions.push({ x: lx, y: ly, w: bgW, h: LABEL_H, edgeIdx: ei });
198
+ }
199
+ labelPositions.sort((a, b) => a.y - b.y);
200
+ for (let i = 0; i < labelPositions.length; i++) {
201
+ for (let j = i + 1; j < labelPositions.length; j++) {
202
+ const a = labelPositions[i];
203
+ const b = labelPositions[j];
204
+ const overlapX = Math.abs(a.x - b.x) < (a.w + b.w) / 2;
205
+ const overlapY = Math.abs(a.y - b.y) < (a.h + b.h) / 2;
206
+ if (overlapX && overlapY) {
207
+ b.y = a.y + (a.h + b.h) / 2 + 2;
208
+ }
209
+ }
210
+ }
211
+ const labelPosMap = /* @__PURE__ */ new Map();
212
+ for (const lp of labelPositions) labelPosMap.set(lp.edgeIdx, lp);
213
+ for (let ei = 0; ei < layout.edges.length; ei++) {
214
+ const edge = layout.edges[ei];
215
+ const edgeG = contentG.append("g").attr("class", "st-edge-group").attr("data-line-number", String(edge.lineNumber)).attr("data-source", edge.source).attr("data-target", edge.target);
216
+ const edgeColor = palette.textMuted;
217
+ const markerId = "st-arrow";
218
+ if (edge.source === edge.target) {
219
+ const node = nodePositionMap.get(edge.source);
220
+ if (node) {
221
+ edgeG.append("path").attr("d", selfLoopPath(node)).attr("fill", "none").attr("stroke", edgeColor).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`).attr("class", "st-edge");
222
+ const lp = labelPosMap.get(ei);
223
+ if (edge.label && lp) {
224
+ edgeG.append("rect").attr("x", lp.x - lp.w / 2).attr("y", lp.y - lp.h / 2 - 1).attr("width", lp.w).attr("height", lp.h).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85).attr("class", "st-edge-label-bg");
225
+ edgeG.append("text").attr("x", lp.x).attr("y", lp.y + 4).attr("text-anchor", "middle").attr("fill", edgeColor).attr("font-size", sEdgeLabelFontSize).attr("class", "st-edge-label").text(edge.label);
226
+ }
227
+ }
228
+ } else if (edge.points.length >= 2) {
229
+ const pathD = edgeSplinePath(edge.points);
230
+ if (pathD) {
231
+ edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`).attr("class", "st-edge");
232
+ }
233
+ const lp = labelPosMap.get(ei);
234
+ if (edge.label && lp) {
235
+ edgeG.append("rect").attr("x", lp.x - lp.w / 2).attr("y", lp.y - lp.h / 2 - 1).attr("width", lp.w).attr("height", lp.h).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85).attr("class", "st-edge-label-bg");
236
+ edgeG.append("text").attr("x", lp.x).attr("y", lp.y + 4).attr("text-anchor", "middle").attr("fill", edgeColor).attr("font-size", sEdgeLabelFontSize).attr("class", "st-edge-label").text(edge.label);
237
+ }
238
+ }
239
+ }
240
+ const collapsedGroupIds = /* @__PURE__ */ new Set();
241
+ for (const group of layout.groups) {
242
+ if (group.collapsed) collapsedGroupIds.add(group.id);
243
+ }
244
+ const colorOff = graph.options?.["color"] === "off";
245
+ const solid = graph.options?.["solid-fill"] === "on";
246
+ const noNotes = graph.options?.["no-notes"] === "on";
247
+ for (const node of layout.nodes) {
248
+ const isCollapsedGroup = collapsedGroupIds.has(node.id);
249
+ const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", isCollapsedGroup ? "st-group-wrapper st-node" : "st-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id).style("cursor", "pointer");
250
+ if (isCollapsedGroup) {
251
+ nodeG.attr("data-group-toggle", node.id).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", "false").attr("aria-label", `Expand group ${node.label}`);
252
+ }
253
+ if (onClickItem && !isCollapsedGroup) {
254
+ nodeG.on("click", () => {
255
+ onClickItem(node.lineNumber);
256
+ });
257
+ }
258
+ const hasNote = !!node.note && !noNotes;
259
+ if (node.shape === "pseudostate") {
260
+ nodeG.append("circle").attr("cx", 0).attr("cy", 0).attr("r", sPseudostateRadius).attr("fill", palette.text).attr("stroke", "none");
261
+ } else if (isCollapsedGroup) {
262
+ const w = node.width;
263
+ const h = node.height;
264
+ const groupColor = node.color ?? stateDefaultColor(palette, colorOff);
265
+ const fillColor = shapeFill(palette, groupColor, isDark, { solid });
266
+ const strokeColor = groupColor;
267
+ const COLLAPSE_BAR_H = 6;
268
+ nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", sStateCornerRadius).attr("ry", sStateCornerRadius).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", sNodeStrokeWidth);
269
+ const clipId = `st-clip-${node.id.replace(/[[\]:\s]/g, "")}`;
270
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", sStateCornerRadius);
271
+ nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - COLLAPSE_BAR_H).attr("width", w).attr("height", COLLAPSE_BAR_H).attr("fill", strokeColor).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
272
+ nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr(
273
+ "fill",
274
+ contrastText(
275
+ fillColor,
276
+ palette.textOnFillLight,
277
+ palette.textOnFillDark
278
+ )
279
+ ).attr("font-size", sNodeFontSize).text(node.label);
280
+ } else {
281
+ const w = node.width;
282
+ const h = node.height;
283
+ const resolvedFill = stateFill(
284
+ palette,
285
+ isDark,
286
+ node.color,
287
+ colorOff,
288
+ solid
289
+ );
290
+ nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", sStateCornerRadius).attr("ry", sStateCornerRadius).attr("fill", resolvedFill).attr("stroke", stateStroke(palette, node.color, colorOff)).attr("stroke-width", sNodeStrokeWidth);
291
+ nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr(
292
+ "fill",
293
+ contrastText(
294
+ resolvedFill,
295
+ palette.textOnFillLight,
296
+ palette.textOnFillDark
297
+ )
298
+ ).attr("font-size", sNodeFontSize).text(node.label);
299
+ }
300
+ if (hasNote && node.note) {
301
+ if (node.note.collapsed) {
302
+ renderNoteBadge(
303
+ nodeG,
304
+ {
305
+ x: node.width / 2 - NOTE_BADGE_RADIUS - 3,
306
+ y: -node.height / 2 + NOTE_BADGE_RADIUS + 3
307
+ },
308
+ palette,
309
+ {
310
+ isDark,
311
+ ...node.note.color && { color: node.note.color },
312
+ lineNumber: node.note.lineNumber,
313
+ endLineNumber: node.note.endLineNumber
314
+ }
315
+ );
316
+ } else {
317
+ const [cx1, cy1, cx2, cy2] = noteConnectorPoints(node, node.note);
318
+ renderNoteConnector(nodeG, cx1, cy1, cx2, cy2, palette);
319
+ renderNoteBox(
320
+ nodeG,
321
+ {
322
+ x: node.note.x,
323
+ y: node.note.y,
324
+ width: node.note.width,
325
+ height: node.note.height
326
+ },
327
+ node.note.lines,
328
+ palette,
329
+ {
330
+ isDark,
331
+ ...node.note.color && { color: node.note.color },
332
+ lineNumber: node.note.lineNumber,
333
+ endLineNumber: node.note.endLineNumber,
334
+ interactive: true
335
+ }
336
+ );
337
+ }
338
+ }
339
+ }
340
+ }
341
+ function renderStateForExport(content, theme, palette) {
342
+ const parsed = parseState(content, palette);
343
+ if (parsed.error || parsed.nodes.length === 0) return "";
344
+ const layout = layoutGraph(parsed);
345
+ const isDark = theme === "dark";
346
+ const container = document.createElement("div");
347
+ const exportWidth = layout.width + DIAGRAM_PADDING * 2;
348
+ const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title && parsed.options["no-title"] !== "on" ? 40 : 0);
349
+ container.style.width = `${exportWidth}px`;
350
+ container.style.height = `${exportHeight}px`;
351
+ container.style.position = "absolute";
352
+ container.style.left = "-9999px";
353
+ document.body.appendChild(container);
354
+ try {
355
+ renderState(container, parsed, layout, palette, isDark, void 0, {
356
+ width: exportWidth,
357
+ height: exportHeight
358
+ });
359
+ const svgEl = container.querySelector("svg");
360
+ if (!svgEl) return "";
361
+ if (theme === "transparent") {
362
+ svgEl.style.background = "none";
363
+ }
364
+ svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
365
+ svgEl.style.fontFamily = FONT_FAMILY;
366
+ return svgEl.outerHTML;
367
+ } finally {
368
+ document.body.removeChild(container);
369
+ }
370
+ }
371
+
372
+ export {
373
+ renderState,
374
+ renderStateForExport
375
+ };
376
+ //# sourceMappingURL=chunk-EMS2SK26.js.map