@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,613 @@
1
+ import {
2
+ MAP_DIRECTIVE_KEY_SET
3
+ } from "./chunk-DKEPS5LH.js";
4
+ import {
5
+ AUTO_TAG_COLOR_SENTINEL,
6
+ finalizeAutoTagColors,
7
+ matchTagBlockHeading,
8
+ stripDefaultModifier,
9
+ tagAttrKey,
10
+ validateTagGroupNames
11
+ } from "./chunk-QLCCJEJI.js";
12
+ import {
13
+ parseInArrowLabel
14
+ } from "./chunk-FFUN5D66.js";
15
+ import {
16
+ MAP_REGISTRY,
17
+ extractColor,
18
+ measureIndent,
19
+ peelRampColors,
20
+ splitNameAndMeta,
21
+ withTagAliases
22
+ } from "./chunk-Y3J7VR52.js";
23
+ import {
24
+ formatDgmoError,
25
+ makeDgmoError
26
+ } from "./chunk-CXK4DZH3.js";
27
+
28
+ // src/map/parser.ts
29
+ var COORD_RE = /^[+-]?\d+(?:\.\d+)?\s+[+-]?\d+(?:\.\d+)?$/;
30
+ var NUMERIC_LEAD_RE = /^[+-]?\d/;
31
+ var SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
32
+ var ARROW_TOKENS = "-[^>]*?->|->|~[^>]*?~>|~>|-[^>]*?-|~[^>]*?~";
33
+ var ARROW_SPLIT = new RegExp(`\\s+(${ARROW_TOKENS})\\s+`);
34
+ var HUB_RE = new RegExp(`^(${ARROW_TOKENS})\\s+(.+)$`);
35
+ var LEG_ARROW_RE = new RegExp(`^(${ARROW_TOKENS})\\s+(.+)$`);
36
+ var AT_RE = /(^|[\s,])at\s*:/i;
37
+ var CHANNEL_FOREIGN = {
38
+ heat: ["size", "width"],
39
+ size: ["heat", "width"],
40
+ width: ["heat", "size"]
41
+ };
42
+ var CHANNEL_HINT = {
43
+ heat: "regions take `heat:`",
44
+ size: "points take `size:`",
45
+ width: "edges take `width:`"
46
+ };
47
+ var MAP_DIRECTIVE_SET = MAP_DIRECTIVE_KEY_SET;
48
+ var DIRECTIVE_SET = MAP_DIRECTIVE_SET;
49
+ function looksLikeMap(content) {
50
+ for (const raw of content.split("\n")) {
51
+ const t = stripInlineComment(raw).trim();
52
+ if (!t || t.startsWith("//")) continue;
53
+ return /^map(\s|$)/.test(t);
54
+ }
55
+ return false;
56
+ }
57
+ function stripInlineComment(line) {
58
+ return line.replace(/(^|\s)\/\/.*$/, (_m, p1) => p1).replace(/\s+$/, "");
59
+ }
60
+ function parseMap(content, palette) {
61
+ const result = {
62
+ title: null,
63
+ titleLineNumber: null,
64
+ directives: {},
65
+ tagGroups: [],
66
+ regions: [],
67
+ pois: [],
68
+ routes: [],
69
+ edges: [],
70
+ options: {},
71
+ diagnostics: [],
72
+ error: null
73
+ };
74
+ const diagnostics = result.diagnostics;
75
+ const pushError = (line, message, code) => {
76
+ diagnostics.push(makeDgmoError(line, message, "error", code));
77
+ result.error ??= formatDgmoError(diagnostics[diagnostics.length - 1]);
78
+ };
79
+ const fail = (line, message) => {
80
+ pushError(line, message);
81
+ return result;
82
+ };
83
+ const pushWarning = (line, message) => {
84
+ diagnostics.push(makeDgmoError(line, message, "warning"));
85
+ };
86
+ const lines = content.split("\n");
87
+ let firstIdx = 0;
88
+ while (firstIdx < lines.length) {
89
+ const t = stripInlineComment(lines[firstIdx]).trim();
90
+ if (t && !t.startsWith("//")) break;
91
+ firstIdx++;
92
+ }
93
+ const firstLine = stripInlineComment(lines[firstIdx] ?? "").trim();
94
+ const firstTok = firstLine.split(/\s+/)[0] ?? "";
95
+ if (firstTok !== "map") {
96
+ return fail(
97
+ firstIdx + 1,
98
+ `Expected chart type "map" on the first line, got "${firstTok || "(empty)"}"`
99
+ );
100
+ }
101
+ const titleText = firstLine.slice(3).trim();
102
+ if (titleText) {
103
+ result.title = titleText;
104
+ result.titleLineNumber = firstIdx + 1;
105
+ }
106
+ const tagGroups = result.tagGroups;
107
+ const regions = result.regions;
108
+ const pois = result.pois;
109
+ const routes = result.routes;
110
+ const edges = result.edges;
111
+ const aliasMap = /* @__PURE__ */ new Map();
112
+ const open = { tag: null, route: null, poi: null };
113
+ const registry = () => withTagAliases(MAP_REGISTRY, new Set(aliasMap.keys()));
114
+ const tagGroupNames = () => new Set(tagGroups.map((g) => tagAttrKey(g.name)));
115
+ const closeBlocks = () => {
116
+ open.tag = null;
117
+ open.route = null;
118
+ open.poi = null;
119
+ };
120
+ for (let i = firstIdx + 1; i < lines.length; i++) {
121
+ const raw = lines[i];
122
+ const lineNumber = i + 1;
123
+ const cleaned = stripInlineComment(raw);
124
+ const trimmed = cleaned.trim();
125
+ const indent = measureIndent(raw);
126
+ if (!trimmed || trimmed.startsWith("//")) continue;
127
+ if (open.tag && indent > 0) {
128
+ addTagEntry(open.tag, trimmed, lineNumber);
129
+ continue;
130
+ }
131
+ if (open.route && indent > open.route.indent) {
132
+ const leg = parseLeg(trimmed, lineNumber);
133
+ if (leg) open.route.route.legs.push(leg);
134
+ continue;
135
+ }
136
+ if (open.poi && indent > open.poi.indent) {
137
+ const hub = trimmed.match(HUB_RE);
138
+ if (hub) {
139
+ const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos);
140
+ if (src) {
141
+ const arr = classifyArrow(hub[1], lineNumber);
142
+ const hubSplit = splitNameAndMeta(hub[2], registry(), aliasMap);
143
+ const { tags, meta } = partitionMeta(hubSplit.meta, tagGroupNames());
144
+ edges.push({
145
+ from: src,
146
+ to: hubSplit.name.trim(),
147
+ ...arr.label !== void 0 && { label: arr.label },
148
+ directed: arr.directed,
149
+ style: arr.style,
150
+ meta,
151
+ tags,
152
+ lineNumber
153
+ });
154
+ }
155
+ continue;
156
+ }
157
+ const split = splitNameAndMeta(trimmed, registry(), aliasMap);
158
+ if (Object.keys(split.meta).length && !split.name) {
159
+ Object.assign(open.poi.poi.meta, split.meta);
160
+ continue;
161
+ }
162
+ if (split.name) {
163
+ const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos) ?? "the poi";
164
+ pushError(
165
+ lineNumber,
166
+ `Malformed hub edge: "${trimmed}" \u2014 an indented line under a poi is an edge from "${src}" and needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\`). For a standalone place, declare it at the top level. (\xA724B.5)`
167
+ );
168
+ continue;
169
+ }
170
+ }
171
+ closeBlocks();
172
+ const firstWord = trimmed.split(/\s+/)[0];
173
+ if (firstWord === "tag") {
174
+ handleTag(trimmed, lineNumber);
175
+ continue;
176
+ }
177
+ if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
178
+ handleDirective(
179
+ firstWord,
180
+ trimmed.slice(firstWord.length).trim(),
181
+ lineNumber
182
+ );
183
+ continue;
184
+ }
185
+ if (firstWord === "poi") {
186
+ handlePoi(trimmed.slice(3).trim(), lineNumber, indent);
187
+ continue;
188
+ }
189
+ if (firstWord === "route") {
190
+ handleRoute(trimmed.slice(5).trim(), lineNumber, indent);
191
+ continue;
192
+ }
193
+ if (ARROW_SPLIT.test(" " + trimmed + " ") || ARROW_SPLIT.test(trimmed)) {
194
+ handleEdges(trimmed, lineNumber);
195
+ continue;
196
+ }
197
+ handleRegion(trimmed, lineNumber);
198
+ }
199
+ finalizeAutoTagColors(tagGroups, palette);
200
+ validateTagGroupNames(
201
+ tagGroups,
202
+ pushWarning,
203
+ (line, m) => pushError(line, m)
204
+ );
205
+ const at = result.directives.activeTag;
206
+ if (at && at.toLowerCase() !== "none") {
207
+ const names = tagGroupNames();
208
+ if (!names.has(at.toLowerCase())) {
209
+ const hint = tagGroups.length ? ` Declared groups: ${tagGroups.map((g) => g.name).join(", ")}.` : " No tag groups are declared.";
210
+ pushWarning(
211
+ 0,
212
+ `active-tag "${at}" does not match a declared tag group.${hint}`
213
+ );
214
+ }
215
+ }
216
+ return result;
217
+ function rejectForeignChannels(meta, own, line) {
218
+ for (const k of CHANNEL_FOREIGN[own]) {
219
+ if (meta[k] !== void 0) {
220
+ pushError(
221
+ line,
222
+ `\`${k}:\` is not a valid channel here \u2014 ${CHANNEL_HINT[own]} (\xA724B).`
223
+ );
224
+ delete meta[k];
225
+ }
226
+ }
227
+ }
228
+ function handleDirective(key, value, line) {
229
+ const d = result.directives;
230
+ const dup = (have) => {
231
+ if (have !== void 0)
232
+ pushWarning(line, `Duplicate directive "${key}" \u2014 last value wins.`);
233
+ };
234
+ switch (key) {
235
+ case "region-heat": {
236
+ dup(d.regionMetric);
237
+ const {
238
+ label: rmLabel,
239
+ low: rmLow,
240
+ high: rmHigh
241
+ } = peelRampColors(value);
242
+ d.regionMetric = rmLabel;
243
+ if (rmHigh) d.regionMetricColor = rmHigh;
244
+ if (rmLow) d.regionMetricLowColor = rmLow;
245
+ break;
246
+ }
247
+ case "poi-size":
248
+ dup(d.poiMetric);
249
+ d.poiMetric = value;
250
+ break;
251
+ case "flow-width":
252
+ dup(d.flowMetric);
253
+ d.flowMetric = value;
254
+ break;
255
+ case "locale":
256
+ dup(d.locale);
257
+ d.locale = value;
258
+ break;
259
+ case "active-tag":
260
+ dup(d.activeTag);
261
+ d.activeTag = value;
262
+ break;
263
+ case "caption":
264
+ dup(d.caption);
265
+ d.caption = value;
266
+ break;
267
+ // ── Cosmetic `no-*` opt-outs: bare flags, idempotent (mirror `no-legend`,
268
+ // no dup warning); each defaults the feature ON when absent. ──
269
+ case "no-title":
270
+ d.noTitle = true;
271
+ break;
272
+ case "no-legend":
273
+ d.noLegend = true;
274
+ break;
275
+ case "no-coastline":
276
+ d.noCoastline = true;
277
+ break;
278
+ case "no-relief":
279
+ d.noRelief = true;
280
+ break;
281
+ case "no-context-labels":
282
+ d.noContextLabels = true;
283
+ break;
284
+ case "no-region-labels":
285
+ d.noRegionLabels = true;
286
+ break;
287
+ case "no-region-heat-value":
288
+ d.noRegionValue = true;
289
+ break;
290
+ case "no-poi-labels":
291
+ d.noPoiLabels = true;
292
+ break;
293
+ case "no-colorize":
294
+ d.noColorize = true;
295
+ break;
296
+ case "no-cities":
297
+ d.noCities = true;
298
+ break;
299
+ case "no-cluster-pois":
300
+ d.noClusterPois = true;
301
+ break;
302
+ }
303
+ }
304
+ function handleTag(trimmed, line) {
305
+ const m = matchTagBlockHeading(trimmed);
306
+ if (!m) {
307
+ pushError(
308
+ line,
309
+ `Malformed tag declaration: "${trimmed}" \u2014 write 'tag <Group>' (optionally 'tag <Group> as <alias>'), e.g. 'tag Market as m', with indented 'Value color' entries below.`
310
+ );
311
+ return;
312
+ }
313
+ const group = {
314
+ name: m.name,
315
+ ...m.alias !== void 0 && { alias: m.alias },
316
+ entries: [],
317
+ lineNumber: line
318
+ };
319
+ if (m.alias) aliasMap.set(m.alias.toLowerCase(), tagAttrKey(m.name));
320
+ tagGroups.push(group);
321
+ open.tag = group;
322
+ if (m.inlineValues?.length) {
323
+ for (const seg of m.inlineValues) addTagEntry(group, seg.trim(), line);
324
+ open.tag = null;
325
+ }
326
+ }
327
+ function addTagEntry(group, text, line) {
328
+ const { text: clean, isDefault } = stripDefaultModifier(text);
329
+ const { label, color } = extractColor(clean, palette, diagnostics, line);
330
+ const entries = group.entries;
331
+ if (isDefault || entries.length === 0) group.defaultValue = label;
332
+ entries.push({
333
+ value: label,
334
+ color: color ?? AUTO_TAG_COLOR_SENTINEL,
335
+ lineNumber: line
336
+ });
337
+ }
338
+ function handleRegion(trimmed, line) {
339
+ if (AT_RE.test(trimmed))
340
+ pushError(
341
+ line,
342
+ "Coordinates are positional, not `at:` \u2014 write region names bare and POIs as `poi <lat> <lon>`."
343
+ );
344
+ const split = splitNameAndMeta(
345
+ trimmed,
346
+ registry(),
347
+ aliasMap,
348
+ void 0,
349
+ diagnostics,
350
+ line
351
+ );
352
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
353
+ rejectForeignChannels(meta, "heat", line);
354
+ let valueNum;
355
+ const value = meta["heat"];
356
+ if (value !== void 0) {
357
+ delete meta["heat"];
358
+ valueNum = Number(value);
359
+ if (!Number.isFinite(valueNum)) {
360
+ pushError(line, `heat must be a number (got "${value}").`);
361
+ valueNum = void 0;
362
+ }
363
+ }
364
+ let regionName = split.name;
365
+ let regionScope;
366
+ const rToks = regionName.split(/\s+/);
367
+ const rLast = rToks[rToks.length - 1];
368
+ if (rToks.length > 1 && SCOPE_RE.test(rLast)) {
369
+ regionName = rToks.slice(0, -1).join(" ");
370
+ regionScope = rLast;
371
+ }
372
+ const region = {
373
+ name: regionName,
374
+ tags,
375
+ meta,
376
+ lineNumber: line
377
+ };
378
+ if (regionScope !== void 0) region.scope = regionScope;
379
+ if (valueNum !== void 0) region.value = valueNum;
380
+ if (split.color) region.color = split.color;
381
+ regions.push(region);
382
+ }
383
+ function handlePoi(rest, line, indent) {
384
+ if (AT_RE.test(rest))
385
+ pushError(
386
+ line,
387
+ "Coordinates are positional, not `at:` \u2014 write `poi <lat> <lon>`."
388
+ );
389
+ const split = splitNameAndMeta(
390
+ rest,
391
+ registry(),
392
+ aliasMap,
393
+ void 0,
394
+ diagnostics,
395
+ line
396
+ );
397
+ const pos = parsePos(split.name, line);
398
+ if (!pos) return;
399
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
400
+ rejectForeignChannels(meta, "size", line);
401
+ const label = meta["label"];
402
+ if (label !== void 0) delete meta["label"];
403
+ const poi = { pos, tags, meta, lineNumber: line };
404
+ if (split.alias) poi.alias = split.alias;
405
+ if (label !== void 0) poi.label = label;
406
+ if (split.color) poi.color = split.color;
407
+ pois.push(poi);
408
+ open.poi = { poi, indent };
409
+ }
410
+ function handleRoute(rest, line, indent) {
411
+ const split = rest ? splitNameAndMeta(
412
+ rest,
413
+ registry(),
414
+ aliasMap,
415
+ void 0,
416
+ diagnostics,
417
+ line
418
+ ) : { name: "", meta: {}, alias: void 0 };
419
+ const pos = parsePos(split.name, line);
420
+ if (!pos || pos.kind === "name" && !pos.name) {
421
+ pushError(
422
+ line,
423
+ "route needs an origin place \u2014 `route <origin>` then indented legs (`-> dest`); origin may be a city name, IATA code, or `<lat> <lon>`. (\xA724B)"
424
+ );
425
+ return;
426
+ }
427
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
428
+ rejectForeignChannels(meta, "size", line);
429
+ const originLabel = meta["label"];
430
+ const originValue = meta["size"];
431
+ if (meta["style"] !== void 0) {
432
+ pushError(
433
+ line,
434
+ "route header no longer takes `style:` \u2014 set leg shape with the arrow glyph instead (`~\u2026~>` for an arc leg, `-\u2026->` for a straight one). (\xA724B.6)"
435
+ );
436
+ }
437
+ const route = {
438
+ origin: pos,
439
+ ...split.alias !== void 0 && { originAlias: split.alias },
440
+ ...originLabel !== void 0 && { originLabel },
441
+ ...originValue !== void 0 && { originValue },
442
+ originTags: tags,
443
+ legs: [],
444
+ lineNumber: line
445
+ };
446
+ routes.push(route);
447
+ open.route = { route, indent };
448
+ }
449
+ function parseLeg(trimmed, line) {
450
+ const m = trimmed.match(LEG_ARROW_RE);
451
+ if (!m) {
452
+ pushError(
453
+ line,
454
+ `Malformed route leg: "${trimmed}" \u2014 a leg needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\` / \`~label~> dest\`). (\xA724B.6)`
455
+ );
456
+ return null;
457
+ }
458
+ const arr = classifyArrow(m[1], line);
459
+ if (!arr.directed) {
460
+ pushError(
461
+ line,
462
+ `A route leg is directional \u2014 "${trimmed}" uses an undirected glyph; use \`-> \` (straight) or \`~> \` (arc). (\xA724B.6)`
463
+ );
464
+ return null;
465
+ }
466
+ const arrowStyle = arr.style;
467
+ const label = arr.label;
468
+ const rest = m[2];
469
+ const split = splitNameAndMeta(
470
+ rest,
471
+ registry(),
472
+ aliasMap,
473
+ void 0,
474
+ diagnostics,
475
+ line
476
+ );
477
+ const pos = parsePos(split.name, line) ?? {
478
+ kind: "name",
479
+ name: split.name
480
+ };
481
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
482
+ rejectForeignChannels(meta, "width", line);
483
+ const value = meta["width"];
484
+ const destLabel = meta["label"];
485
+ return {
486
+ ...label !== void 0 && { label },
487
+ style: arrowStyle,
488
+ ...value !== void 0 && { value },
489
+ dest: pos,
490
+ ...split.alias !== void 0 && { destAlias: split.alias },
491
+ ...destLabel !== void 0 && { destLabel },
492
+ tags,
493
+ // colour the LINE (§24B.6); stop tags go on the poi line
494
+ lineNumber: line
495
+ };
496
+ }
497
+ function handleEdges(trimmed, line) {
498
+ const parts = trimmed.split(ARROW_SPLIT);
499
+ if (parts.length < 3) {
500
+ pushError(
501
+ line,
502
+ `Malformed edge: "${trimmed}" \u2014 an edge is 'A -> B' (or 'A -label-> B', '~>' for arc, '--' undirected), both endpoints non-empty. (\xA724B)`
503
+ );
504
+ return;
505
+ }
506
+ const endpoints = [];
507
+ const links = [];
508
+ for (let k = 0; k < parts.length; k++) {
509
+ if (k % 2 === 0) endpoints.push(parts[k].trim());
510
+ else links.push(classifyArrow(parts[k], line));
511
+ }
512
+ const lastSplit = splitNameAndMeta(
513
+ endpoints[endpoints.length - 1],
514
+ registry(),
515
+ aliasMap
516
+ );
517
+ endpoints[endpoints.length - 1] = lastSplit.name;
518
+ const { tags: lastTags, meta: lastMeta } = partitionMeta(
519
+ lastSplit.meta,
520
+ tagGroupNames()
521
+ );
522
+ rejectForeignChannels(lastMeta, "width", line);
523
+ for (let k = 0; k < links.length; k++) {
524
+ const from = endpoints[k];
525
+ const to = endpoints[k + 1];
526
+ if (!from || !to) {
527
+ pushError(
528
+ line,
529
+ `Edge has an empty endpoint: "${trimmed}" \u2014 both sides of the arrow need a place, e.g. 'Paris -> Berlin'. (\xA724B)`
530
+ );
531
+ continue;
532
+ }
533
+ const isLast = k === links.length - 1;
534
+ const meta = isLast ? lastMeta : {};
535
+ const tags = isLast ? lastTags : {};
536
+ const style = links[k].style === "arc" ? "arc" : "straight";
537
+ edges.push({
538
+ from,
539
+ to,
540
+ ...links[k].label !== void 0 && { label: links[k].label },
541
+ directed: links[k].directed,
542
+ style,
543
+ meta,
544
+ tags,
545
+ lineNumber: line
546
+ });
547
+ }
548
+ }
549
+ function classifyArrow(tok, line) {
550
+ if (tok === "--") return { directed: false, style: "straight" };
551
+ if (tok === "~~") return { directed: false, style: "arc" };
552
+ if (tok === "->") return { directed: true, style: "straight" };
553
+ if (tok === "~>") return { directed: true, style: "arc" };
554
+ const directed = tok.endsWith(">");
555
+ const style = tok.startsWith("~") ? "arc" : "straight";
556
+ const inner = directed ? tok.slice(1, -2) : tok.slice(1, -1);
557
+ const lbl = parseInArrowLabel(inner, line);
558
+ lbl.diagnostics.forEach((d) => diagnostics.push(d));
559
+ return {
560
+ ...lbl.label !== void 0 && { label: lbl.label },
561
+ directed,
562
+ style
563
+ };
564
+ }
565
+ function parsePos(nameRegion, line) {
566
+ const n = nameRegion.trim();
567
+ if (COORD_RE.test(n)) {
568
+ const [latS, lonS] = n.split(/\s+/);
569
+ const lat = Number(latS);
570
+ const lon = Number(lonS);
571
+ if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
572
+ pushError(
573
+ line,
574
+ `Coordinates out of range: lat ${lat}, lon ${lon} (lat \u2208 [-90,90], lon \u2208 [-180,180]).`
575
+ );
576
+ return null;
577
+ }
578
+ return { kind: "coords", lat, lon };
579
+ }
580
+ if (NUMERIC_LEAD_RE.test(n)) {
581
+ pushError(
582
+ line,
583
+ `Malformed coordinates "${n}" \u2014 expected "<lat> <lon>" (two signed numbers).`
584
+ );
585
+ return null;
586
+ }
587
+ const toks = n.split(/\s+/);
588
+ const last = toks[toks.length - 1];
589
+ if (toks.length > 1 && SCOPE_RE.test(last)) {
590
+ return { kind: "name", name: toks.slice(0, -1).join(" "), scope: last };
591
+ }
592
+ return { kind: "name", name: n };
593
+ }
594
+ }
595
+ function partitionMeta(meta, tagGroupNames) {
596
+ const tags = {};
597
+ const inert = {};
598
+ for (const [k, v] of Object.entries(meta)) {
599
+ if (tagGroupNames.has(k)) tags[k] = v;
600
+ else inert[k] = v;
601
+ }
602
+ return { tags, meta: inert };
603
+ }
604
+ function poiName(pos) {
605
+ return pos.kind === "name" ? pos.name : void 0;
606
+ }
607
+
608
+ export {
609
+ MAP_DIRECTIVE_SET,
610
+ looksLikeMap,
611
+ parseMap
612
+ };
613
+ //# sourceMappingURL=chunk-BUPDIHML.js.map