@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,647 @@
1
+ import {
2
+ layoutMap,
3
+ mapLegendConfig,
4
+ mapLegendGroups,
5
+ parsePathRings
6
+ } from "./chunk-IPWPWM6R.js";
7
+ import {
8
+ renderIntegratedLegend
9
+ } from "./chunk-PWIHZ6NJ.js";
10
+ import {
11
+ TITLE_FONT_SIZE,
12
+ TITLE_FONT_WEIGHT,
13
+ TITLE_Y
14
+ } from "./chunk-A4GOY3PE.js";
15
+ import {
16
+ FONT_FAMILY
17
+ } from "./chunk-6KFWC4CO.js";
18
+ import {
19
+ measureText
20
+ } from "./chunk-WCT3NYCV.js";
21
+ import {
22
+ mix
23
+ } from "./chunk-P6T66CCZ.js";
24
+
25
+ // src/map/renderer.ts
26
+ import * as d3Selection from "d3-selection";
27
+ var LABEL_FONT = 11;
28
+ function pointInRing(px, py, ring) {
29
+ let inside = false;
30
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
31
+ const [xi, yi] = ring[i];
32
+ const [xj, yj] = ring[j];
33
+ if (yi > py !== yj > py && px < (xj - xi) * (py - yi) / (yj - yi) + xi)
34
+ inside = !inside;
35
+ }
36
+ return inside;
37
+ }
38
+ function ringToPath(ring) {
39
+ let d = "";
40
+ for (let i = 0; i < ring.length; i++)
41
+ d += (i ? "L" : "M") + ring[i][0] + "," + ring[i][1];
42
+ return d + "Z";
43
+ }
44
+ function polylineToPath(pts) {
45
+ let d = "";
46
+ for (let i = 0; i < pts.length; i++)
47
+ d += (i ? "L" : "M") + pts[i][0] + "," + pts[i][1];
48
+ return d;
49
+ }
50
+ function ringToCoastPaths(ring, frame) {
51
+ if (!frame) return [ringToPath(ring)];
52
+ const n = ring.length;
53
+ const eps = 0.75;
54
+ const onL = (x) => Math.abs(x) <= eps;
55
+ const onR = (x) => Math.abs(x - frame.w) <= eps;
56
+ const onT = (y) => Math.abs(y) <= eps;
57
+ const onB = (y) => Math.abs(y - frame.h) <= eps;
58
+ const isFrameEdge = (a, b) => onL(a[0]) && onL(b[0]) || onR(a[0]) && onR(b[0]) || onT(a[1]) && onT(b[1]) || onB(a[1]) && onB(b[1]);
59
+ let firstBreak = -1;
60
+ for (let i = 0; i < n; i++)
61
+ if (isFrameEdge(ring[i], ring[(i + 1) % n])) {
62
+ firstBreak = i;
63
+ break;
64
+ }
65
+ if (firstBreak === -1) return [ringToPath(ring)];
66
+ const paths = [];
67
+ let cur = [];
68
+ const start = (firstBreak + 1) % n;
69
+ for (let k = 0; k < n; k++) {
70
+ const i = (start + k) % n;
71
+ const a = ring[i];
72
+ const b = ring[(i + 1) % n];
73
+ if (isFrameEdge(a, b)) {
74
+ if (cur.length >= 2) paths.push(polylineToPath(cur));
75
+ cur = [];
76
+ continue;
77
+ }
78
+ if (cur.length === 0) cur.push(a);
79
+ cur.push(b);
80
+ }
81
+ if (cur.length >= 2) paths.push(polylineToPath(cur));
82
+ return paths;
83
+ }
84
+ function coastlineOuterRings(regions, minExtent, frame) {
85
+ const paths = [];
86
+ for (const r of regions) {
87
+ const rings = r.rings ?? parsePathRings(r.d);
88
+ for (let i = 0; i < rings.length; i++) {
89
+ const ring = rings[i];
90
+ if (ring.length < 3) continue;
91
+ let minX = Infinity;
92
+ let minY = Infinity;
93
+ let maxX = -Infinity;
94
+ let maxY = -Infinity;
95
+ for (const [x, y] of ring) {
96
+ if (x < minX) minX = x;
97
+ if (x > maxX) maxX = x;
98
+ if (y < minY) minY = y;
99
+ if (y > maxY) maxY = y;
100
+ }
101
+ if (Math.max(maxX - minX, maxY - minY) < minExtent) continue;
102
+ const [fx, fy] = ring[0];
103
+ let depth = 0;
104
+ for (let j = 0; j < rings.length; j++)
105
+ if (j !== i && pointInRing(fx, fy, rings[j])) depth++;
106
+ if (depth % 2 === 1) continue;
107
+ paths.push(...ringToCoastPaths(ring, frame));
108
+ }
109
+ }
110
+ return paths;
111
+ }
112
+ function appendWaterLines(g, defs, coastId, outerRings, style, flatWater) {
113
+ const d = outerRings.join(" ");
114
+ if (!d) return;
115
+ defs.append("path").attr("id", coastId).attr("d", d).attr("fill", "none");
116
+ const ref = `#${coastId}`;
117
+ const linesOuterFirst = [...style.lines].sort((a, b) => b.d - a.d);
118
+ for (const line of linesOuterFirst) {
119
+ g.append("use").attr("href", ref).attr("stroke", style.color).attr("stroke-width", 2 * (line.d + line.thickness)).attr("stroke-opacity", line.opacity).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
120
+ g.append("use").attr("href", ref).attr("stroke", flatWater).attr("stroke-width", 2 * line.d).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
121
+ }
122
+ }
123
+ var mapInstanceCounter = 0;
124
+ function renderMap(container, resolved, data, palette, isDark, onClickItem, exportDims, activeGroupOverride) {
125
+ d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
126
+ const width = exportDims?.width ?? container.clientWidth;
127
+ const height = exportDims?.height ?? container.clientHeight;
128
+ if (width <= 0 || height <= 0) return;
129
+ const layout = layoutMap(
130
+ resolved,
131
+ data,
132
+ { width, height },
133
+ {
134
+ palette,
135
+ isDark,
136
+ // Export-only: forward the contain-fit request from mapExportDimensions so a
137
+ // clamped/floored (off-aspect) export canvas letterboxes instead of
138
+ // stretch-distorting. The in-app preview pane passes no exportDims → unset →
139
+ // keeps the global stretch-fill.
140
+ preferContain: exportDims?.preferContain ?? false,
141
+ // Reserve the legend band for the mode actually drawn below (export shows
142
+ // only the active group; preview keeps the inactive pills).
143
+ legendMode: exportDims ? "export" : "preview",
144
+ ...activeGroupOverride !== void 0 && {
145
+ activeGroup: activeGroupOverride
146
+ }
147
+ }
148
+ );
149
+ const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY).style("background", layout.background);
150
+ svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
151
+ const defs = svg.append("defs");
152
+ const uid = mapInstanceCounter++;
153
+ const nid = (base) => `${base}__m${uid}`;
154
+ const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
155
+ const haloColor = palette.bg;
156
+ const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
157
+ const drawRegion = (g, r, strokeWidth) => {
158
+ const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
159
+ if (r.label) p.attr("data-region-name", r.label);
160
+ if (r.id && r.id !== "lake") p.attr("data-iso", r.id);
161
+ if (r.labelX !== void 0 && r.labelY !== void 0) {
162
+ p.attr("data-label-x", r.labelX).attr("data-label-y", r.labelY);
163
+ }
164
+ if (r.layer !== "base") {
165
+ p.classed("dgmo-map-region", true).attr("data-region", r.id);
166
+ if (r.value !== void 0) p.attr("data-value", r.value);
167
+ if (r.tags) {
168
+ for (const [group, value] of Object.entries(r.tags)) {
169
+ p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
170
+ }
171
+ }
172
+ }
173
+ if (r.lineNumber >= 0) {
174
+ p.attr("data-line-number", r.lineNumber);
175
+ if (onClickItem) {
176
+ p.style("cursor", "pointer").on(
177
+ "click",
178
+ () => onClickItem(r.lineNumber)
179
+ );
180
+ }
181
+ }
182
+ };
183
+ for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
184
+ if (layout.relief.length && layout.reliefHatch) {
185
+ const h = layout.reliefHatch;
186
+ const rangeClipId = nid("dgmo-relief-clip");
187
+ const landClipId = nid("dgmo-relief-land");
188
+ const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
189
+ for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
190
+ const landClip = defs.append("clipPath").attr("id", landClipId);
191
+ for (const r of layout.regions)
192
+ if (r.id !== "lake") landClip.append("path").attr("d", r.d);
193
+ const gRelief = svg.append("g").attr("clip-path", `url(#${landClipId})`).style("pointer-events", "none").append("g").attr("class", "dgmo-map-relief").attr("clip-path", `url(#${rangeClipId})`).attr("stroke", h.color).attr("stroke-width", h.width).attr("vector-effect", "non-scaling-stroke");
194
+ for (let y = h.spacing; y < height; y += h.spacing) {
195
+ gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
196
+ }
197
+ }
198
+ if (layout.coastlineStyle) {
199
+ const cs = layout.coastlineStyle;
200
+ const maskId = nid("dgmo-map-water-mask");
201
+ const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
202
+ mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
203
+ const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
204
+ const lakeD = layout.regions.filter((r) => r.id === "lake").map((r) => r.d).join(" ");
205
+ if (landD) mask.append("path").attr("d", landD).attr("fill", "black");
206
+ if (lakeD) mask.append("path").attr("d", lakeD).attr("fill", "white");
207
+ if (layout.insets.length) {
208
+ const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
209
+ for (const box of layout.insets) {
210
+ const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
211
+ mask.append("path").attr("d", d).attr("fill", "black").attr("stroke", "black").attr("stroke-width", 2 * reach).attr("stroke-linejoin", "round");
212
+ }
213
+ }
214
+ const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
215
+ appendWaterLines(
216
+ gWater,
217
+ defs,
218
+ nid("dgmo-map-coast"),
219
+ // Pass the canvas frame so edges collinear with it (the antimeridian on a
220
+ // world map, regional clipExtent cuts) don't get ringed as fake coast —
221
+ // land runs cleanly to the render-area edge.
222
+ coastlineOuterRings(layout.regions, cs.minExtent, {
223
+ w: width,
224
+ h: height
225
+ }),
226
+ cs,
227
+ layout.background
228
+ );
229
+ const byStroke = /* @__PURE__ */ new Map();
230
+ for (const r of layout.regions) {
231
+ const arr = byStroke.get(r.stroke);
232
+ if (arr) arr.push(r.d);
233
+ else byStroke.set(r.stroke, [r.d]);
234
+ }
235
+ for (const [stroke, ds] of byStroke)
236
+ gWater.append("path").attr("d", ds.join(" ")).attr("stroke", stroke).attr("stroke-width", 0.5).attr("stroke-linejoin", "round");
237
+ }
238
+ if (layout.rivers.length) {
239
+ const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none").style("pointer-events", "none");
240
+ for (const r of layout.rivers) {
241
+ gRivers.append("path").attr("d", r.d).attr("stroke", r.color).attr("stroke-width", r.width).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
242
+ }
243
+ }
244
+ if (layout.cityDots.length) {
245
+ const gCities = svg.append("g").attr("class", "dgmo-map-cities").attr("fill", palette.textMuted).attr("fill-opacity", 0.28).style("pointer-events", "none");
246
+ for (const c of layout.cityDots) {
247
+ gCities.append("circle").attr("cx", c.cx).attr("cy", c.cy).attr("r", c.r);
248
+ }
249
+ }
250
+ const clusterUi = !exportDims && !resolved.directives.noClusterPois;
251
+ const poiLabels = layout.labels.filter(
252
+ (l) => l.poiId !== void 0 && !l.hidden
253
+ );
254
+ if (poiLabels.length) {
255
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
256
+ defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
257
+ const PAD = 8;
258
+ const buildPatch = (labels, maskId, decoCluster) => {
259
+ if (!labels.length) return;
260
+ const patchMask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
261
+ const blobs = patchMask.append("g").attr("filter", `url(#${patchBlurId})`);
262
+ const blobRects = [];
263
+ for (const l of labels) {
264
+ const multi = l.lines && l.lines.length > 1;
265
+ const tw = multi ? Math.max(...l.lines.map((s) => measureText(s, LABEL_FONT))) : measureText(l.text, LABEL_FONT);
266
+ const th = multi ? l.lines.length * (LABEL_FONT + 2) : LABEL_FONT;
267
+ const cx = l.anchor === "start" ? l.x + tw / 2 : l.anchor === "end" ? l.x - tw / 2 : l.x;
268
+ const cy = l.y - LABEL_FONT * 0.3;
269
+ const w = tw + 8;
270
+ const h = th + 6;
271
+ blobs.append("rect").attr("x", cx - w / 2).attr("y", cy - h / 2).attr("width", w).attr("height", h).attr("rx", h / 2).attr("fill", "white");
272
+ blobRects.push({
273
+ x0: cx - w / 2 - PAD,
274
+ y0: cy - h / 2 - PAD,
275
+ x1: cx + w / 2 + PAD,
276
+ y1: cy + h / 2 + PAD
277
+ });
278
+ }
279
+ const gPatch = svg.append("g").attr("class", "dgmo-map-label-patch").attr("mask", `url(#${maskId})`).style("pointer-events", "none");
280
+ if (decoCluster !== void 0)
281
+ gPatch.attr("data-cluster-deco", decoCluster);
282
+ for (const r of layout.regions) {
283
+ let minX, minY, maxX, maxY;
284
+ if (r.bbox) {
285
+ [minX, minY, maxX, maxY] = r.bbox;
286
+ } else {
287
+ minX = Infinity;
288
+ minY = Infinity;
289
+ maxX = -Infinity;
290
+ maxY = -Infinity;
291
+ for (const ring of parsePathRings(r.d))
292
+ for (const [px, py] of ring) {
293
+ if (px < minX) minX = px;
294
+ if (px > maxX) maxX = px;
295
+ if (py < minY) minY = py;
296
+ if (py > maxY) maxY = py;
297
+ }
298
+ }
299
+ const hit = blobRects.some(
300
+ (b) => minX <= b.x1 && maxX >= b.x0 && minY <= b.y1 && maxY >= b.y0
301
+ );
302
+ if (hit) gPatch.append("path").attr("d", r.d).attr("fill", r.fill);
303
+ }
304
+ };
305
+ if (clusterUi) {
306
+ buildPatch(
307
+ poiLabels.filter((l) => l.clusterMember === void 0),
308
+ nid("dgmo-map-label-patch")
309
+ );
310
+ const byCluster = /* @__PURE__ */ new Map();
311
+ for (const l of poiLabels) {
312
+ if (l.clusterMember === void 0) continue;
313
+ const arr = byCluster.get(l.clusterMember);
314
+ if (arr) arr.push(l);
315
+ else byCluster.set(l.clusterMember, [l]);
316
+ }
317
+ let ci = 0;
318
+ for (const [cid, labs] of byCluster)
319
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
320
+ } else {
321
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
322
+ }
323
+ }
324
+ if (layout.insets.length) {
325
+ const insetG = svg.append("g").attr("class", "dgmo-map-insets");
326
+ layout.insets.forEach((box, bi) => {
327
+ const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
328
+ insetG.append("path").attr("d", d).attr("fill", layout.background).attr("stroke", mix(palette.text, palette.bg, 55)).attr("stroke-width", 1).attr("stroke-linejoin", "round");
329
+ if (box.contextLand) {
330
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
331
+ defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
332
+ insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
333
+ }
334
+ });
335
+ for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
336
+ if (layout.coastlineStyle) {
337
+ const cs = layout.coastlineStyle;
338
+ const maskId = nid("dgmo-map-inset-water-mask");
339
+ const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
340
+ const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
341
+ for (const box of layout.insets) {
342
+ const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
343
+ mask.append("path").attr("d", d).attr("fill", "white").attr("stroke", "black").attr("stroke-width", 2 * reach).attr("stroke-linejoin", "round");
344
+ }
345
+ layout.insets.forEach((box, bi) => {
346
+ if (box.contextLand)
347
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
348
+ });
349
+ for (const r of layout.insetRegions)
350
+ if (r.id !== "lake")
351
+ mask.append("path").attr("d", r.d).attr("fill", "black");
352
+ for (const r of layout.insetRegions)
353
+ if (r.id === "lake")
354
+ mask.append("path").attr("d", r.d).attr("fill", "white");
355
+ const clipId = nid("dgmo-map-inset-water-clip");
356
+ const clip = defs.append("clipPath").attr("id", clipId);
357
+ for (const box of layout.insets) {
358
+ const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
359
+ clip.append("path").attr("d", d);
360
+ }
361
+ const gInsetWater = insetG.append("g").attr("clip-path", `url(#${clipId})`).append("g").attr("class", "dgmo-map-inset-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
362
+ appendWaterLines(
363
+ gInsetWater,
364
+ defs,
365
+ nid("dgmo-map-inset-coast"),
366
+ coastlineOuterRings(layout.insetRegions, cs.minExtent),
367
+ cs,
368
+ layout.background
369
+ );
370
+ for (const r of layout.insetRegions)
371
+ gInsetWater.append("path").attr("d", r.d).attr("stroke", r.stroke).attr("stroke-width", 0.5).attr("stroke-linejoin", "round");
372
+ }
373
+ for (const box of layout.insets) {
374
+ const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
375
+ insetG.append("path").attr("d", d).attr("fill", "none").attr("stroke", mix(palette.text, palette.bg, 55)).attr("stroke-width", 1).attr("stroke-linejoin", "round").style("pointer-events", "none");
376
+ }
377
+ }
378
+ const wireSync = (sel, lineNumber) => {
379
+ if (lineNumber < 1) return;
380
+ sel.attr("data-line-number", lineNumber);
381
+ if (onClickItem)
382
+ sel.style("cursor", "pointer").on("click", () => onClickItem(lineNumber));
383
+ };
384
+ const gLegs = svg.append("g").attr("class", "dgmo-map-legs").attr("fill", "none");
385
+ const legEnd = (d) => {
386
+ const m = /^M(-?[\d.]+),(-?[\d.]+)(?:L(-?[\d.]+),(-?[\d.]+)|Q(-?[\d.]+),(-?[\d.]+) (-?[\d.]+),(-?[\d.]+))$/.exec(
387
+ d
388
+ );
389
+ if (!m) return null;
390
+ const x0 = +m[1];
391
+ const y0 = +m[2];
392
+ let ex;
393
+ let ey;
394
+ let fromX;
395
+ let fromY;
396
+ if (m[3] !== void 0) {
397
+ ex = +m[3];
398
+ ey = +m[4];
399
+ fromX = x0;
400
+ fromY = y0;
401
+ } else {
402
+ ex = +m[7];
403
+ ey = +m[8];
404
+ fromX = +m[5];
405
+ fromY = +m[6];
406
+ }
407
+ const dx = ex - fromX;
408
+ const dy = ey - fromY;
409
+ const len = Math.hypot(dx, dy);
410
+ if (!(len > 0)) return null;
411
+ return { ex, ey, tx: dx / len, ty: dy / len };
412
+ };
413
+ layout.legs.forEach((leg) => {
414
+ const end = leg.arrow ? legEnd(leg.d) : null;
415
+ let drawD = leg.d;
416
+ let arrowTri = null;
417
+ if (end) {
418
+ const aLen = arrowSize(leg.width);
419
+ const aHalf = Math.max(aLen * 0.5, leg.width * 0.6 + 1);
420
+ const bx = end.ex - end.tx * aLen;
421
+ const by = end.ey - end.ty * aLen;
422
+ const px = -end.ty;
423
+ const py = end.tx;
424
+ arrowTri = `M${bx + px * aHalf},${by + py * aHalf}L${end.ex},${end.ey}L${bx - px * aHalf},${by - py * aHalf}z`;
425
+ drawD = leg.d.replace(
426
+ /(-?[\d.]+),(-?[\d.]+)$/,
427
+ `${bx.toFixed(2)},${by.toFixed(2)}`
428
+ );
429
+ }
430
+ const p = gLegs.append("path").attr("d", drawD).attr("stroke", leg.color).attr("stroke-width", leg.width).attr("stroke-linecap", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
431
+ if (leg.tags) {
432
+ for (const [group, value] of Object.entries(leg.tags)) {
433
+ p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
434
+ }
435
+ }
436
+ wireSync(p, leg.lineNumber);
437
+ if (leg.value !== void 0) {
438
+ p.attr("data-value", leg.value);
439
+ p.append("title").text(
440
+ leg.label !== void 0 ? `${leg.label}: ${leg.value}` : `${leg.value}`
441
+ );
442
+ }
443
+ if (arrowTri) {
444
+ const a = gLegs.append("path").attr("d", arrowTri).attr("fill", leg.color).attr("stroke", leg.color).attr("stroke-width", 1).attr("stroke-linejoin", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
445
+ if (leg.tags) {
446
+ for (const [group, value] of Object.entries(leg.tags)) {
447
+ a.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
448
+ }
449
+ }
450
+ }
451
+ if (leg.label !== void 0 && leg.labelX !== void 0) {
452
+ const lt = emitText(
453
+ gLegs,
454
+ leg.labelX,
455
+ leg.labelY ?? 0,
456
+ leg.label,
457
+ "middle",
458
+ leg.labelColor ?? palette.textMuted,
459
+ leg.labelHaloColor ?? haloColor,
460
+ leg.labelHalo ?? true,
461
+ LABEL_FONT - 1
462
+ );
463
+ wireSync(lt, leg.lineNumber);
464
+ }
465
+ });
466
+ const gSpider = svg.append("g").attr("class", "dgmo-map-spider");
467
+ for (const cl of layout.clusters) {
468
+ if (clusterUi) {
469
+ gSpider.append("circle").attr("cx", cl.cx).attr("cy", cl.cy).attr("r", cl.hitR).attr("fill", "transparent").attr("data-cluster-hit", cl.id).style("cursor", "pointer");
470
+ }
471
+ for (const leg of cl.legs) {
472
+ gSpider.append("line").attr("x1", cl.cx).attr("y1", cl.cy).attr("x2", leg.x2).attr("y2", leg.y2).attr("stroke", leg.color).attr("stroke-width", 1).attr("data-cluster-deco", cl.id).style("pointer-events", "none");
473
+ }
474
+ gSpider.append("circle").attr("cx", cl.cx).attr("cy", cl.cy).attr("r", 2).attr("fill", mix(palette.textMuted, palette.bg, 40)).attr("data-cluster-deco", cl.id).style("pointer-events", "none");
475
+ }
476
+ const gPois = svg.append("g").attr("class", "dgmo-map-pois");
477
+ for (const poi of layout.pois) {
478
+ if (poi.isOrigin) {
479
+ gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r + 3).attr("fill", "none").attr("stroke", poi.stroke).attr("stroke-width", 1.5);
480
+ }
481
+ const c = gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r).attr("fill", poi.fill).attr("fill-opacity", poi.fillOpacity).attr("stroke", poi.stroke).attr("stroke-width", 1).attr("data-line-number", poi.lineNumber).attr("data-poi", poi.id);
482
+ if (poi.clusterId !== void 0)
483
+ c.attr("data-cluster-member", poi.clusterId);
484
+ if (poi.tags) {
485
+ for (const [group, value] of Object.entries(poi.tags)) {
486
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
487
+ }
488
+ }
489
+ if (onClickItem) {
490
+ c.style("cursor", "pointer").on(
491
+ "click",
492
+ () => onClickItem(poi.lineNumber)
493
+ );
494
+ }
495
+ if (poi.routeNumber !== void 0) {
496
+ emitText(
497
+ gPois,
498
+ poi.cx,
499
+ poi.cy + 3,
500
+ String(poi.routeNumber),
501
+ "middle",
502
+ palette.bg,
503
+ poi.fill,
504
+ false,
505
+ LABEL_FONT - 2
506
+ );
507
+ }
508
+ }
509
+ const gLabels = svg.append("g").attr("class", "dgmo-map-labels");
510
+ for (const lab of layout.labels) {
511
+ if (lab.hidden) {
512
+ if (exportDims) continue;
513
+ emitText(
514
+ gLabels,
515
+ lab.x,
516
+ lab.y,
517
+ lab.text,
518
+ lab.anchor,
519
+ lab.color,
520
+ lab.haloColor,
521
+ lab.halo,
522
+ lab.fontSize ?? LABEL_FONT,
523
+ lab.italic,
524
+ lab.letterSpacing
525
+ ).attr("data-poi", lab.poiId ?? null).attr("data-poi-hidden", "").style("opacity", 0).style("pointer-events", "none");
526
+ continue;
527
+ }
528
+ if (lab.leader) {
529
+ const line = gLabels.append("line").attr("x1", lab.leader.x1).attr("y1", lab.leader.y1).attr("x2", lab.leader.x2).attr("y2", lab.leader.y2).attr(
530
+ "stroke",
531
+ lab.leaderColor ?? mix(palette.textMuted, palette.bg, 60)
532
+ ).attr("stroke-width", lab.leaderColor ? 1 : 0.75);
533
+ if (lab.poiId !== void 0) line.attr("data-poi", lab.poiId);
534
+ if (lab.clusterMember !== void 0)
535
+ line.attr("data-cluster-member", lab.clusterMember);
536
+ wireSync(line, lab.lineNumber);
537
+ }
538
+ if (lab.calloutDot) {
539
+ gLabels.append("circle").attr("cx", lab.calloutDot.x).attr("cy", lab.calloutDot.y).attr("r", 2.5).attr("fill", lab.calloutDot.color).attr("stroke", mix(palette.text, palette.bg, 55)).attr("stroke-width", 0.75);
540
+ }
541
+ const t = emitText(
542
+ gLabels,
543
+ lab.x,
544
+ lab.y,
545
+ lab.text,
546
+ lab.anchor,
547
+ lab.color,
548
+ lab.haloColor,
549
+ lab.halo,
550
+ lab.fontSize ?? LABEL_FONT,
551
+ lab.italic,
552
+ lab.letterSpacing,
553
+ lab.lines,
554
+ lab.valueLine
555
+ );
556
+ if (lab.poiId !== void 0) {
557
+ t.attr("data-poi", lab.poiId).style("cursor", "default");
558
+ }
559
+ if (lab.clusterMember !== void 0) {
560
+ t.attr("data-cluster-member", lab.clusterMember);
561
+ }
562
+ wireSync(t, lab.lineNumber);
563
+ }
564
+ if (clusterUi && layout.clusters.length) {
565
+ const gBadge = svg.append("g").attr("class", "dgmo-map-cluster-badges");
566
+ for (const cl of layout.clusters) {
567
+ const g = gBadge.append("g").attr("data-cluster", cl.id).style("opacity", 0).style("pointer-events", "none");
568
+ const R = 9;
569
+ g.append("circle").attr("cx", cl.cx).attr("cy", cl.cy).attr("r", R).attr("fill", mix(palette.textMuted, palette.bg, 35)).attr("stroke", palette.textMuted).attr("stroke-width", 1);
570
+ g.append("circle").attr("cx", cl.cx).attr("cy", cl.cy).attr("r", R + 2.5).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1);
571
+ const beadR = R + 2.5;
572
+ for (const leg of cl.legs) {
573
+ const a = Math.atan2(leg.y2 - cl.cy, leg.x2 - cl.cx);
574
+ g.append("circle").attr("class", "dgmo-map-cluster-bead").attr("cx", cl.cx + beadR * Math.cos(a)).attr("cy", cl.cy + beadR * Math.sin(a)).attr("r", 1.8).attr("fill", leg.color).attr("stroke", palette.bg).attr("stroke-width", 0.5);
575
+ }
576
+ emitText(
577
+ g,
578
+ cl.cx,
579
+ cl.cy + 3,
580
+ String(cl.count),
581
+ "middle",
582
+ palette.text,
583
+ palette.bg,
584
+ false,
585
+ LABEL_FONT
586
+ );
587
+ }
588
+ }
589
+ if (layout.legend) {
590
+ const legendY = (layout.title ? TITLE_Y + TITLE_FONT_SIZE : 0) + (layout.subtitle ? TITLE_FONT_SIZE : 0) + 8;
591
+ const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
592
+ const groups = mapLegendGroups(layout.legend);
593
+ if (groups.length > 0) {
594
+ const config = mapLegendConfig(
595
+ groups,
596
+ exportDims ? "export" : "preview"
597
+ );
598
+ renderIntegratedLegend(legendG, {
599
+ ...config,
600
+ palette,
601
+ isDark,
602
+ width,
603
+ activeGroup: layout.legend.activeGroup
604
+ });
605
+ }
606
+ }
607
+ if (layout.title) {
608
+ svg.append("text").attr("class", "dgmo-map-title").attr("x", width / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.title);
609
+ }
610
+ if (layout.subtitle) {
611
+ svg.append("text").attr("class", "dgmo-map-subtitle").attr("x", width / 2).attr("y", TITLE_Y + TITLE_FONT_SIZE).attr("text-anchor", "middle").attr("font-size", LABEL_FONT + 1).attr("fill", palette.textMuted).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 3).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.subtitle);
612
+ }
613
+ if (layout.caption) {
614
+ svg.append("text").attr("x", width / 2).attr("y", height - 8).attr("text-anchor", "middle").attr("font-size", LABEL_FONT).attr("fill", palette.textMuted).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 3).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.caption);
615
+ }
616
+ }
617
+ function renderMapForExport(container, resolved, data, palette, isDark, exportDims) {
618
+ renderMap(container, resolved, data, palette, isDark, void 0, exportDims);
619
+ }
620
+ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic, letterSpacing, lines, valueLine) {
621
+ const t = g.append("text").attr("x", x).attr("y", y).attr("text-anchor", anchor).attr("font-size", fontSize).attr("fill", color);
622
+ if (lines && lines.length > 1) {
623
+ const lineHeight = fontSize + 2;
624
+ const startDy = -((lines.length - 1) / 2) * lineHeight;
625
+ lines.forEach((ln, i) => {
626
+ t.append("tspan").attr("x", x).attr("dy", i === 0 ? startDy : lineHeight).text(ln);
627
+ });
628
+ } else if (valueLine !== void 0) {
629
+ const valueSize = Math.round(fontSize * 0.82);
630
+ t.append("tspan").attr("x", x).attr("dy", -fontSize * 0.28).text(text);
631
+ t.append("tspan").attr("x", x).attr("dy", fontSize * 0.92).attr("font-size", valueSize).attr("fill-opacity", 0.72).text(valueLine);
632
+ } else {
633
+ t.text(text);
634
+ }
635
+ if (italic) t.attr("font-style", "italic");
636
+ if (letterSpacing) t.attr("letter-spacing", letterSpacing);
637
+ if (withHalo) {
638
+ t.attr("paint-order", "stroke fill").attr("stroke", halo).attr("stroke-width", 2).attr("stroke-linejoin", "round").attr("stroke-linecap", "round").attr("stroke-opacity", 0.55);
639
+ }
640
+ return t;
641
+ }
642
+
643
+ export {
644
+ renderMap,
645
+ renderMapForExport
646
+ };
647
+ //# sourceMappingURL=chunk-Z5CGSFJB.js.map