@diagrammo/dgmo 0.22.0 → 0.24.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.
- package/dist/advanced.cjs +372 -103
- package/dist/advanced.d.cts +52 -19
- package/dist/advanced.d.ts +52 -19
- package/dist/advanced.js +372 -103
- package/dist/auto.cjs +370 -97
- package/dist/auto.js +117 -117
- package/dist/auto.mjs +370 -97
- package/dist/cli.cjs +151 -151
- package/dist/editor.cjs +3 -0
- package/dist/editor.js +3 -0
- package/dist/highlight.cjs +3 -0
- package/dist/highlight.js +3 -0
- package/dist/index.cjs +498 -96
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +496 -96
- package/dist/internal.cjs +372 -103
- package/dist/internal.d.cts +52 -19
- package/dist/internal.d.ts +52 -19
- package/dist/internal.js +372 -103
- package/dist/map-data/PROVENANCE.json +1 -1
- package/dist/map-data/gazetteer.json +1 -1
- package/dist/map-data/mountain-ranges.json +1 -1
- package/dist/map-data/water-bodies.json +1 -1
- package/dist/map-data/world-coarse.json +1 -1
- package/dist/map-data/world-detail.json +1 -1
- package/docs/language-reference.md +38 -2
- package/gallery/fixtures/boxes-and-lines.dgmo +6 -4
- package/package.json +1 -1
- package/src/boxes-and-lines/parser.ts +39 -0
- package/src/boxes-and-lines/renderer.ts +219 -14
- package/src/boxes-and-lines/types.ts +9 -0
- package/src/completion.ts +4 -5
- package/src/d3.ts +26 -6
- package/src/editor/keywords.ts +3 -0
- package/src/index.ts +8 -0
- package/src/map/data/PROVENANCE.json +1 -1
- package/src/map/data/README.md +6 -0
- package/src/map/data/gazetteer.json +1 -1
- package/src/map/data/mountain-ranges.json +1 -1
- package/src/map/data/water-bodies.json +1 -1
- package/src/map/data/world-coarse.json +1 -1
- package/src/map/data/world-detail.json +1 -1
- package/src/map/dimensions.ts +21 -5
- package/src/map/layout.ts +167 -63
- package/src/map/legend-band.ts +99 -0
- package/src/map/renderer.ts +105 -32
- package/src/map/resolver.ts +43 -1
- package/src/map/types.ts +20 -0
- package/src/utils/reserved-key-registry.ts +5 -3
- package/src/utils/svg-embed.ts +193 -0
package/dist/index.js
CHANGED
|
@@ -893,9 +893,7 @@ var init_reserved_key_registry = __esm({
|
|
|
893
893
|
BOXES_AND_LINES_REGISTRY = staticRegistry([
|
|
894
894
|
"color",
|
|
895
895
|
"description",
|
|
896
|
-
"
|
|
897
|
-
"split",
|
|
898
|
-
"fanout"
|
|
896
|
+
"value"
|
|
899
897
|
]);
|
|
900
898
|
TIMELINE_REGISTRY = staticRegistry([
|
|
901
899
|
"color",
|
|
@@ -16915,6 +16913,21 @@ function parseBoxesAndLines(content) {
|
|
|
16915
16913
|
}
|
|
16916
16914
|
continue;
|
|
16917
16915
|
}
|
|
16916
|
+
if (!contentStarted) {
|
|
16917
|
+
const metricMatch = trimmed.match(/^box-metric\s+(.+)$/i);
|
|
16918
|
+
if (metricMatch) {
|
|
16919
|
+
const { label, colorName } = peelTrailingColorName(
|
|
16920
|
+
metricMatch[1].trim()
|
|
16921
|
+
);
|
|
16922
|
+
result.boxMetric = label;
|
|
16923
|
+
if (colorName !== void 0) result.boxMetricColor = colorName;
|
|
16924
|
+
continue;
|
|
16925
|
+
}
|
|
16926
|
+
if (/^show-values$/i.test(trimmed)) {
|
|
16927
|
+
result.showValues = true;
|
|
16928
|
+
continue;
|
|
16929
|
+
}
|
|
16930
|
+
}
|
|
16918
16931
|
if (!contentStarted) {
|
|
16919
16932
|
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
16920
16933
|
if (optMatch) {
|
|
@@ -17293,6 +17306,19 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17293
17306
|
description = [metadata["description"]];
|
|
17294
17307
|
delete metadata["description"];
|
|
17295
17308
|
}
|
|
17309
|
+
let value;
|
|
17310
|
+
if (metadata["value"] !== void 0) {
|
|
17311
|
+
const raw = metadata["value"];
|
|
17312
|
+
const num = Number(raw);
|
|
17313
|
+
if (Number.isFinite(num)) {
|
|
17314
|
+
value = num;
|
|
17315
|
+
} else {
|
|
17316
|
+
diagnostics.push(
|
|
17317
|
+
makeDgmoError(lineNum, `value must be a number (got "${raw}")`, "error")
|
|
17318
|
+
);
|
|
17319
|
+
}
|
|
17320
|
+
delete metadata["value"];
|
|
17321
|
+
}
|
|
17296
17322
|
if (split.alias) {
|
|
17297
17323
|
nameAliasMap?.set(normalizeName(split.alias), label);
|
|
17298
17324
|
}
|
|
@@ -17301,7 +17327,8 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17301
17327
|
label,
|
|
17302
17328
|
lineNumber: lineNum,
|
|
17303
17329
|
metadata,
|
|
17304
|
-
...description !== void 0 && { description }
|
|
17330
|
+
...description !== void 0 && { description },
|
|
17331
|
+
...value !== void 0 && { value }
|
|
17305
17332
|
};
|
|
17306
17333
|
}
|
|
17307
17334
|
function splitTargetAndMeta(rest, metaAliasMap) {
|
|
@@ -26423,7 +26450,18 @@ function fitLabelToHeader(label, nodeWidth, maxLines) {
|
|
|
26423
26450
|
const truncated = label.length > maxChars ? label.slice(0, maxChars - 1) + "\u2026" : label;
|
|
26424
26451
|
return { lines: [truncated], fontSize: MIN_NODE_FONT_SIZE };
|
|
26425
26452
|
}
|
|
26426
|
-
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, solid) {
|
|
26453
|
+
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, solid) {
|
|
26454
|
+
const neutralFill = mix(palette.bg, palette.text, isDark ? 90 : 95);
|
|
26455
|
+
if (value.active) {
|
|
26456
|
+
const fill3 = node.value !== void 0 ? value.fillForValue(node.value) : neutralFill;
|
|
26457
|
+
const stroke3 = value.hue;
|
|
26458
|
+
const text2 = contrastText(
|
|
26459
|
+
fill3,
|
|
26460
|
+
palette.textOnFillLight,
|
|
26461
|
+
palette.textOnFillDark
|
|
26462
|
+
);
|
|
26463
|
+
return { fill: fill3, stroke: stroke3, text: text2 };
|
|
26464
|
+
}
|
|
26427
26465
|
const tagColor = resolveTagColor(
|
|
26428
26466
|
node.metadata,
|
|
26429
26467
|
[...tagGroups],
|
|
@@ -26532,25 +26570,65 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26532
26570
|
const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
|
|
26533
26571
|
const sTitleFontSize = sctx.text(TITLE_FONT_SIZE);
|
|
26534
26572
|
const sTitleY = sctx.structural(TITLE_Y);
|
|
26573
|
+
const nodeValues = parsed.nodes.filter((n) => n.value !== void 0).map((n) => n.value);
|
|
26574
|
+
const hasRamp = nodeValues.length > 0;
|
|
26575
|
+
const allNonNegative = hasRamp && nodeValues.every((v) => v >= 0);
|
|
26576
|
+
const rampMin = allNonNegative ? 0 : Math.min(...nodeValues);
|
|
26577
|
+
const rampMax = Math.max(...nodeValues);
|
|
26578
|
+
const rampHue = resolveColor(parsed.boxMetricColor ?? "", palette) ?? palette.primary;
|
|
26579
|
+
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
26580
|
+
const fillForValue = (v) => {
|
|
26581
|
+
const t = rampMax > rampMin ? (v - rampMin) / (rampMax - rampMin) : 1;
|
|
26582
|
+
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
26583
|
+
return mix(rampHue, rampBase, pct);
|
|
26584
|
+
};
|
|
26585
|
+
const VALUE_NAME = hasRamp ? parsed.boxMetric?.trim() || "Value" : null;
|
|
26586
|
+
const matchColorGroup = (v) => {
|
|
26587
|
+
const lv = v.trim().toLowerCase();
|
|
26588
|
+
if (lv === "" || lv === "none") return null;
|
|
26589
|
+
const tg = parsed.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
26590
|
+
if (tg) return tg.name;
|
|
26591
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
26592
|
+
return v;
|
|
26593
|
+
};
|
|
26594
|
+
const override = activeTagGroup;
|
|
26595
|
+
let activeGroup;
|
|
26596
|
+
if (override !== void 0) {
|
|
26597
|
+
activeGroup = override === null ? null : matchColorGroup(override);
|
|
26598
|
+
} else if (parsed.options["active-tag"] !== void 0) {
|
|
26599
|
+
activeGroup = matchColorGroup(parsed.options["active-tag"]);
|
|
26600
|
+
} else {
|
|
26601
|
+
activeGroup = VALUE_NAME ?? (parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null);
|
|
26602
|
+
}
|
|
26603
|
+
const activeIsValue = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
26604
|
+
const valueGroup = VALUE_NAME !== null ? {
|
|
26605
|
+
name: VALUE_NAME,
|
|
26606
|
+
entries: [],
|
|
26607
|
+
gradient: {
|
|
26608
|
+
min: rampMin,
|
|
26609
|
+
max: rampMax,
|
|
26610
|
+
hue: rampHue,
|
|
26611
|
+
base: rampBase
|
|
26612
|
+
}
|
|
26613
|
+
} : null;
|
|
26614
|
+
const legendGroups = [
|
|
26615
|
+
...valueGroup ? [valueGroup] : [],
|
|
26616
|
+
...parsed.tagGroups
|
|
26617
|
+
];
|
|
26535
26618
|
const reserveHasDescriptions = parsed.nodes.some(
|
|
26536
26619
|
(n) => n.description && n.description.length > 0
|
|
26537
26620
|
);
|
|
26538
|
-
const willRenderLegend =
|
|
26621
|
+
const willRenderLegend = legendGroups.length > 0 || reserveHasDescriptions && controlsHost !== "app";
|
|
26539
26622
|
const sLegendHeight = willRenderLegend ? sctx.structural(
|
|
26540
26623
|
getMaxLegendReservedHeight(
|
|
26541
26624
|
{
|
|
26542
|
-
groups:
|
|
26625
|
+
groups: legendGroups,
|
|
26543
26626
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26544
26627
|
mode: exportMode ? "export" : "preview"
|
|
26545
26628
|
},
|
|
26546
26629
|
width
|
|
26547
26630
|
)
|
|
26548
26631
|
) : 0;
|
|
26549
|
-
const activeGroup = resolveActiveTagGroup(
|
|
26550
|
-
parsed.tagGroups,
|
|
26551
|
-
parsed.options["active-tag"],
|
|
26552
|
-
activeTagGroup
|
|
26553
|
-
);
|
|
26554
26632
|
const hidden = hiddenTagValues ?? parsed.initialHiddenTagValues;
|
|
26555
26633
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
26556
26634
|
for (const node of parsed.nodes) nodeMap.set(node.label, node);
|
|
@@ -26561,7 +26639,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26561
26639
|
const hasAnyDescriptions = parsed.nodes.some(
|
|
26562
26640
|
(n) => n.description && n.description.length > 0
|
|
26563
26641
|
);
|
|
26564
|
-
const needsLegend =
|
|
26642
|
+
const needsLegend = legendGroups.length > 0 || hasAnyDescriptions && onToggleDescriptions;
|
|
26565
26643
|
const legendH = needsLegend ? sLegendHeight + 8 : 0;
|
|
26566
26644
|
const groupLabelsSet = new Set(layout.groups.map((g) => g.label));
|
|
26567
26645
|
let labelZoneExtension = 0;
|
|
@@ -26767,12 +26845,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26767
26845
|
activeGroup,
|
|
26768
26846
|
palette,
|
|
26769
26847
|
isDark,
|
|
26848
|
+
{ active: activeIsValue, hue: rampHue, fillForValue },
|
|
26770
26849
|
parsed.options["solid-fill"] === "on"
|
|
26771
26850
|
);
|
|
26772
26851
|
const nodeG = diagramG.append("g").attr("class", "bl-node").attr("transform", `translate(${ln.x},${ln.y})`).attr("data-line-number", node.lineNumber).attr("data-node-id", node.label).style("cursor", onClickItem ? "pointer" : "default").style("--bl-node-stroke", colors.stroke);
|
|
26773
26852
|
for (const [key, val] of Object.entries(node.metadata)) {
|
|
26774
26853
|
nodeG.attr(`data-tag-${key.toLowerCase()}`, val.toLowerCase());
|
|
26775
26854
|
}
|
|
26855
|
+
if (node.value !== void 0) {
|
|
26856
|
+
nodeG.attr("data-value", node.value);
|
|
26857
|
+
}
|
|
26776
26858
|
if (onClickItem) {
|
|
26777
26859
|
nodeG.on("click", (event) => {
|
|
26778
26860
|
const target = event.target;
|
|
@@ -26844,6 +26926,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26844
26926
|
const tooltipText = fullText.length > 200 ? fullText.slice(0, 199) + "\u2026" : fullText;
|
|
26845
26927
|
nodeG.append("title").text(tooltipText);
|
|
26846
26928
|
}
|
|
26929
|
+
} else if (parsed.showValues && node.value !== void 0) {
|
|
26930
|
+
const valueLabel = parsed.boxMetric ? `${parsed.boxMetric}: ${node.value}` : String(node.value);
|
|
26931
|
+
const headerH = ln.height / 2;
|
|
26932
|
+
const sepY = -ln.height / 2 + headerH;
|
|
26933
|
+
const fitted = fitLabelToHeader(node.label, ln.width, 2);
|
|
26934
|
+
const labelLineH = fitted.fontSize * 1.3;
|
|
26935
|
+
const labelTotalH = fitted.lines.length * labelLineH;
|
|
26936
|
+
const headerCenterY = -ln.height / 2 + headerH / 2;
|
|
26937
|
+
for (let li = 0; li < fitted.lines.length; li++) {
|
|
26938
|
+
nodeG.append("text").attr("x", 0).attr(
|
|
26939
|
+
"y",
|
|
26940
|
+
headerCenterY - labelTotalH / 2 + labelLineH / 2 + li * labelLineH
|
|
26941
|
+
).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", colors.text).text(fitted.lines[li]);
|
|
26942
|
+
}
|
|
26943
|
+
nodeG.append("line").attr("x1", -ln.width / 2).attr("y1", sepY).attr("x2", ln.width / 2).attr("y2", sepY).attr("stroke", colors.stroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
26944
|
+
nodeG.append("text").attr("class", "bl-node-value").attr("x", 0).attr("y", (sepY + ln.height / 2) / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("fill", colors.text).attr("opacity", 0.85).text(valueLabel);
|
|
26847
26945
|
} else {
|
|
26848
26946
|
const maxLabelLines = Math.max(
|
|
26849
26947
|
2,
|
|
@@ -26856,11 +26954,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26856
26954
|
nodeG.append("text").attr("x", 0).attr("y", -totalH / 2 + lineH / 2 + li * lineH).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", colors.text).text(fitted.lines[li]);
|
|
26857
26955
|
}
|
|
26858
26956
|
}
|
|
26957
|
+
if (parsed.showValues && node.value !== void 0 && desc && desc.length > 0 && !hideDescriptions) {
|
|
26958
|
+
const valueText = String(node.value);
|
|
26959
|
+
const padX = 6;
|
|
26960
|
+
const padY = 5;
|
|
26961
|
+
const bw = valueText.length * VALUE_FONT_SIZE * CHAR_WIDTH_RATIO2 + 8;
|
|
26962
|
+
const bh = VALUE_FONT_SIZE + 4;
|
|
26963
|
+
const bx = Math.max(-ln.width / 2 + 4, ln.width / 2 - bw - 4);
|
|
26964
|
+
const by = -ln.height / 2 + 4;
|
|
26965
|
+
nodeG.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85);
|
|
26966
|
+
nodeG.append("text").attr("class", "bl-node-value").attr("x", bx + bw - padX).attr("y", by + padY).attr("text-anchor", "end").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.textMuted).text(valueText);
|
|
26967
|
+
}
|
|
26859
26968
|
}
|
|
26860
26969
|
const hasDescriptions = parsed.nodes.some(
|
|
26861
26970
|
(n) => n.description && n.description.length > 0
|
|
26862
26971
|
);
|
|
26863
|
-
const hasLegend =
|
|
26972
|
+
const hasLegend = legendGroups.length > 0 || hasDescriptions && controlsHost !== "app";
|
|
26864
26973
|
if (hasLegend) {
|
|
26865
26974
|
let controlsGroup;
|
|
26866
26975
|
if (hasDescriptions && (onToggleDescriptions || controlsHost === "app")) {
|
|
@@ -26878,7 +26987,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26878
26987
|
};
|
|
26879
26988
|
}
|
|
26880
26989
|
const legendConfig = {
|
|
26881
|
-
groups:
|
|
26990
|
+
groups: legendGroups,
|
|
26882
26991
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26883
26992
|
mode: exportMode ? "export" : "preview",
|
|
26884
26993
|
// Keep inactive sibling tag groups visible as collapsed pills so the user
|
|
@@ -26933,7 +27042,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
26933
27042
|
}
|
|
26934
27043
|
});
|
|
26935
27044
|
}
|
|
26936
|
-
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
|
|
27045
|
+
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
|
|
26937
27046
|
var init_renderer6 = __esm({
|
|
26938
27047
|
"src/boxes-and-lines/renderer.ts"() {
|
|
26939
27048
|
"use strict";
|
|
@@ -26942,12 +27051,13 @@ var init_renderer6 = __esm({
|
|
|
26942
27051
|
init_legend_layout();
|
|
26943
27052
|
init_title_constants();
|
|
26944
27053
|
init_color_utils();
|
|
27054
|
+
init_colors();
|
|
26945
27055
|
init_tag_groups();
|
|
26946
27056
|
init_inline_markdown();
|
|
26947
27057
|
init_wrapped_desc();
|
|
26948
27058
|
init_scaling();
|
|
26949
27059
|
DIAGRAM_PADDING6 = 20;
|
|
26950
|
-
NODE_FONT_SIZE =
|
|
27060
|
+
NODE_FONT_SIZE = 11;
|
|
26951
27061
|
MIN_NODE_FONT_SIZE = 9;
|
|
26952
27062
|
EDGE_LABEL_FONT_SIZE4 = 11;
|
|
26953
27063
|
EDGE_STROKE_WIDTH5 = 1.5;
|
|
@@ -26964,6 +27074,8 @@ var init_renderer6 = __esm({
|
|
|
26964
27074
|
GROUP_RX = 8;
|
|
26965
27075
|
GROUP_LABEL_FONT_SIZE = 14;
|
|
26966
27076
|
GROUP_LABEL_ZONE = 32;
|
|
27077
|
+
RAMP_FLOOR = 15;
|
|
27078
|
+
VALUE_FONT_SIZE = 11;
|
|
26967
27079
|
lineGeneratorLR = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26968
27080
|
lineGeneratorTB = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26969
27081
|
}
|
|
@@ -46682,7 +46794,11 @@ function resolveMap(parsed, data) {
|
|
|
46682
46794
|
if (bb && !isWholeSphere(bb)) containerBoxes.push(bb);
|
|
46683
46795
|
}
|
|
46684
46796
|
const containerUnion = unionExtent(containerBoxes, points);
|
|
46685
|
-
if (containerUnion)
|
|
46797
|
+
if (containerUnion)
|
|
46798
|
+
extent2 = pad(
|
|
46799
|
+
clampContainerToCluster(containerUnion, points),
|
|
46800
|
+
PAD_FRACTION
|
|
46801
|
+
);
|
|
46686
46802
|
}
|
|
46687
46803
|
if (isPoiOnly) {
|
|
46688
46804
|
const cx = (extent2[0][0] + extent2[1][0]) / 2;
|
|
@@ -46763,6 +46879,22 @@ function mostCommonCountry(regions, poiCountries) {
|
|
|
46763
46879
|
}
|
|
46764
46880
|
return best;
|
|
46765
46881
|
}
|
|
46882
|
+
function clampContainerToCluster(container, points) {
|
|
46883
|
+
const poi = unionExtent([], points);
|
|
46884
|
+
if (!poi) return container;
|
|
46885
|
+
let [[west, south], [east, north]] = container;
|
|
46886
|
+
const [[pWest, pSouth], [pEast, pNorth]] = poi;
|
|
46887
|
+
south = Math.max(south, pSouth - CONTAINER_OVERSHOOT_DEG);
|
|
46888
|
+
north = Math.min(north, pNorth + CONTAINER_OVERSHOOT_DEG);
|
|
46889
|
+
if (east <= 180 && pEast <= 180) {
|
|
46890
|
+
west = Math.max(west, pWest - CONTAINER_OVERSHOOT_DEG);
|
|
46891
|
+
east = Math.min(east, pEast + CONTAINER_OVERSHOOT_DEG);
|
|
46892
|
+
}
|
|
46893
|
+
return [
|
|
46894
|
+
[west, south],
|
|
46895
|
+
[east, north]
|
|
46896
|
+
];
|
|
46897
|
+
}
|
|
46766
46898
|
function pad(e, frac) {
|
|
46767
46899
|
const dLon = (e[1][0] - e[0][0]) * frac || 1;
|
|
46768
46900
|
const dLat = (e[1][1] - e[0][1]) * frac || 1;
|
|
@@ -46775,7 +46907,7 @@ function firstError(diags) {
|
|
|
46775
46907
|
const e = diags.find((d) => d.severity === "error");
|
|
46776
46908
|
return e ? formatDgmoError(e) : null;
|
|
46777
46909
|
}
|
|
46778
|
-
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, REGION_PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, POI_ZOOM_FLOOR_DEG, US_NATIONAL_LON_SPAN, REGION_ALIASES, US_STATE_POSTAL;
|
|
46910
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, REGION_PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, POI_ZOOM_FLOOR_DEG, CONTAINER_OVERSHOOT_DEG, US_NATIONAL_LON_SPAN, REGION_ALIASES, US_STATE_POSTAL;
|
|
46779
46911
|
var init_resolver2 = __esm({
|
|
46780
46912
|
"src/map/resolver.ts"() {
|
|
46781
46913
|
"use strict";
|
|
@@ -46788,6 +46920,7 @@ var init_resolver2 = __esm({
|
|
|
46788
46920
|
WORLD_LAT_SOUTH = -58;
|
|
46789
46921
|
WORLD_LAT_NORTH = 78;
|
|
46790
46922
|
POI_ZOOM_FLOOR_DEG = 7;
|
|
46923
|
+
CONTAINER_OVERSHOOT_DEG = 8;
|
|
46791
46924
|
US_NATIONAL_LON_SPAN = 48;
|
|
46792
46925
|
REGION_ALIASES = {
|
|
46793
46926
|
// Common everyday names → the Natural-Earth display name actually shipped.
|
|
@@ -46866,6 +46999,55 @@ var init_resolver2 = __esm({
|
|
|
46866
46999
|
}
|
|
46867
47000
|
});
|
|
46868
47001
|
|
|
47002
|
+
// src/map/legend-band.ts
|
|
47003
|
+
function mapLegendGroups(legend) {
|
|
47004
|
+
const ramp = legend.ramp;
|
|
47005
|
+
const scoreGroup = ramp ? {
|
|
47006
|
+
name: ramp.metric?.trim() || "Value",
|
|
47007
|
+
entries: [],
|
|
47008
|
+
gradient: {
|
|
47009
|
+
min: ramp.min,
|
|
47010
|
+
max: ramp.max,
|
|
47011
|
+
hue: ramp.hue,
|
|
47012
|
+
base: ramp.base
|
|
47013
|
+
}
|
|
47014
|
+
} : null;
|
|
47015
|
+
const tagGroups = legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
47016
|
+
return [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
47017
|
+
}
|
|
47018
|
+
function mapLegendConfig(groups, mode) {
|
|
47019
|
+
return {
|
|
47020
|
+
groups,
|
|
47021
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47022
|
+
mode,
|
|
47023
|
+
showEmptyGroups: false,
|
|
47024
|
+
showInactivePills: true
|
|
47025
|
+
};
|
|
47026
|
+
}
|
|
47027
|
+
function mapLegendTop(hasTitle, hasSubtitle) {
|
|
47028
|
+
return (hasTitle ? TITLE_Y + TITLE_FONT_SIZE : 0) + (hasSubtitle ? TITLE_FONT_SIZE : 0) + LEGEND_TOP_GAP2;
|
|
47029
|
+
}
|
|
47030
|
+
function mapLegendBand(legend, opts) {
|
|
47031
|
+
if (!legend) return 0;
|
|
47032
|
+
const groups = mapLegendGroups(legend);
|
|
47033
|
+
if (groups.length === 0) return 0;
|
|
47034
|
+
const config = mapLegendConfig(groups, opts.mode);
|
|
47035
|
+
const state = { activeGroup: legend.activeGroup };
|
|
47036
|
+
const { height } = computeLegendLayout(config, state, opts.width);
|
|
47037
|
+
if (height <= 0) return 0;
|
|
47038
|
+
return mapLegendTop(opts.hasTitle, opts.hasSubtitle) + height + LEGEND_BOTTOM_GAP2;
|
|
47039
|
+
}
|
|
47040
|
+
var LEGEND_TOP_GAP2, LEGEND_BOTTOM_GAP2;
|
|
47041
|
+
var init_legend_band = __esm({
|
|
47042
|
+
"src/map/legend-band.ts"() {
|
|
47043
|
+
"use strict";
|
|
47044
|
+
init_legend_layout();
|
|
47045
|
+
init_title_constants();
|
|
47046
|
+
LEGEND_TOP_GAP2 = 8;
|
|
47047
|
+
LEGEND_BOTTOM_GAP2 = 10;
|
|
47048
|
+
}
|
|
47049
|
+
});
|
|
47050
|
+
|
|
46869
47051
|
// src/map/colorize.ts
|
|
46870
47052
|
function assignColors(isos, adjacency) {
|
|
46871
47053
|
const sorted = [...isos].sort();
|
|
@@ -47306,6 +47488,38 @@ function parsePathRings(d) {
|
|
|
47306
47488
|
if (cur.length) rings.push(cur);
|
|
47307
47489
|
return rings;
|
|
47308
47490
|
}
|
|
47491
|
+
function dropAntimeridianWrapSlivers(d, width, height) {
|
|
47492
|
+
const rings = parsePathRings(d);
|
|
47493
|
+
if (rings.length <= 1) return d;
|
|
47494
|
+
const eps = 0.75;
|
|
47495
|
+
const minArea = 3e-3 * width * height;
|
|
47496
|
+
const ringArea = (r) => {
|
|
47497
|
+
let s = 0;
|
|
47498
|
+
for (let i = 0; i < r.length; i++) {
|
|
47499
|
+
const a = r[i];
|
|
47500
|
+
const b = r[(i + 1) % r.length];
|
|
47501
|
+
s += a[0] * b[1] - b[0] * a[1];
|
|
47502
|
+
}
|
|
47503
|
+
return Math.abs(s) / 2;
|
|
47504
|
+
};
|
|
47505
|
+
const areas = rings.map(ringArea);
|
|
47506
|
+
const maxArea = Math.max(...areas);
|
|
47507
|
+
const onVEdge = (a, b) => Math.abs(a[0]) <= eps && Math.abs(b[0]) <= eps || Math.abs(a[0] - width) <= eps && Math.abs(b[0] - width) <= eps;
|
|
47508
|
+
let dropped = false;
|
|
47509
|
+
const kept = rings.filter((r, idx) => {
|
|
47510
|
+
if (areas[idx] >= maxArea || areas[idx] >= minArea) return true;
|
|
47511
|
+
const touches = r.some((p, i) => onVEdge(p, r[(i + 1) % r.length]));
|
|
47512
|
+
if (touches) {
|
|
47513
|
+
dropped = true;
|
|
47514
|
+
return false;
|
|
47515
|
+
}
|
|
47516
|
+
return true;
|
|
47517
|
+
});
|
|
47518
|
+
if (!dropped) return d;
|
|
47519
|
+
return kept.map(
|
|
47520
|
+
(r) => r.map((p, i) => (i ? "L" : "M") + p[0] + "," + p[1]).join("") + "Z"
|
|
47521
|
+
).join("");
|
|
47522
|
+
}
|
|
47309
47523
|
function layoutMap(resolved, data, size, opts) {
|
|
47310
47524
|
const { palette, isDark } = opts;
|
|
47311
47525
|
const { width, height } = size;
|
|
@@ -47389,7 +47603,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47389
47603
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
47390
47604
|
const fillForValue = (s) => {
|
|
47391
47605
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
47392
|
-
const pct =
|
|
47606
|
+
const pct = RAMP_FLOOR2 + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR2);
|
|
47393
47607
|
return mix(rampHue, rampBase, pct);
|
|
47394
47608
|
};
|
|
47395
47609
|
const tagFill = (tags, groupName) => {
|
|
@@ -47425,12 +47639,43 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47425
47639
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
47426
47640
|
};
|
|
47427
47641
|
const regionById = new Map(resolved.regions.map((r) => [r.iso, r]));
|
|
47642
|
+
let legend = null;
|
|
47643
|
+
if (!resolved.directives.noLegend) {
|
|
47644
|
+
const legendTagGroups = resolved.tagGroups.map((g) => ({
|
|
47645
|
+
name: g.name,
|
|
47646
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
47647
|
+
}));
|
|
47648
|
+
if (legendTagGroups.length > 0 || hasRamp) {
|
|
47649
|
+
legend = {
|
|
47650
|
+
tagGroups: legendTagGroups,
|
|
47651
|
+
activeGroup,
|
|
47652
|
+
...hasRamp && {
|
|
47653
|
+
ramp: {
|
|
47654
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47655
|
+
metric: resolved.directives.regionMetric
|
|
47656
|
+
},
|
|
47657
|
+
min: rampMin,
|
|
47658
|
+
max: rampMax,
|
|
47659
|
+
hue: rampHue,
|
|
47660
|
+
base: rampBase
|
|
47661
|
+
}
|
|
47662
|
+
}
|
|
47663
|
+
};
|
|
47664
|
+
}
|
|
47665
|
+
}
|
|
47428
47666
|
const TITLE_GAP2 = 16;
|
|
47429
47667
|
let topPad = FIT_PAD;
|
|
47430
47668
|
if (resolved.title && resolved.pois.length > 0) {
|
|
47431
47669
|
const bannerBottom = (resolved.subtitle ? TITLE_Y + TITLE_FONT_SIZE : TITLE_Y) + TITLE_FONT_SIZE / 2;
|
|
47432
47670
|
topPad = Math.max(FIT_PAD, bannerBottom + TITLE_GAP2);
|
|
47433
47671
|
}
|
|
47672
|
+
const legendBand = mapLegendBand(legend, {
|
|
47673
|
+
width,
|
|
47674
|
+
mode: opts.legendMode ?? "preview",
|
|
47675
|
+
hasTitle: Boolean(resolved.title),
|
|
47676
|
+
hasSubtitle: Boolean(resolved.subtitle)
|
|
47677
|
+
});
|
|
47678
|
+
if (legendBand > topPad) topPad = legendBand;
|
|
47434
47679
|
const fitBox = [
|
|
47435
47680
|
[FIT_PAD, topPad],
|
|
47436
47681
|
[
|
|
@@ -47448,10 +47693,11 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47448
47693
|
const by0 = cb[0][1];
|
|
47449
47694
|
const cw = cb[1][0] - bx0;
|
|
47450
47695
|
const ch = cb[1][1] - by0;
|
|
47451
|
-
const
|
|
47452
|
-
const
|
|
47453
|
-
const
|
|
47454
|
-
const
|
|
47696
|
+
const topReserve = resolved.title && resolved.pois.length > 0 || legendBand > 0 ? topPad : 0;
|
|
47697
|
+
const ox = 0;
|
|
47698
|
+
const oy = topReserve;
|
|
47699
|
+
const sx = cw > 0 ? width / cw : 1;
|
|
47700
|
+
const sy = ch > 0 ? (height - topReserve) / ch : 1;
|
|
47455
47701
|
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
47456
47702
|
const stretch = (x, y) => [
|
|
47457
47703
|
ox + (x - bx0) * sx,
|
|
@@ -47724,7 +47970,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47724
47970
|
const r = regionById.get(iso);
|
|
47725
47971
|
const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
|
|
47726
47972
|
if (!viewF) continue;
|
|
47727
|
-
const
|
|
47973
|
+
const raw = path(viewF) ?? "";
|
|
47974
|
+
const d = fitIsGlobal ? dropAntimeridianWrapSlivers(raw, width, height) : raw;
|
|
47728
47975
|
if (!d) continue;
|
|
47729
47976
|
const isThisLayer = r?.layer === layerKind;
|
|
47730
47977
|
const isForeign = layerKind === "country" && usContext && iso !== "US";
|
|
@@ -47741,6 +47988,9 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47741
47988
|
} else {
|
|
47742
47989
|
label = f.properties?.name;
|
|
47743
47990
|
}
|
|
47991
|
+
const labelAnchor = WORLD_LABEL_ANCHORS[iso];
|
|
47992
|
+
const c = labelAnchor ? project(labelAnchor[0], labelAnchor[1]) : path.centroid(viewF);
|
|
47993
|
+
const hasCentroid = c != null && Number.isFinite(c[0]) && Number.isFinite(c[1]);
|
|
47744
47994
|
regions.push({
|
|
47745
47995
|
id: iso,
|
|
47746
47996
|
d,
|
|
@@ -47749,6 +47999,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47749
47999
|
lineNumber,
|
|
47750
48000
|
layer,
|
|
47751
48001
|
...label !== void 0 && { label },
|
|
48002
|
+
...hasCentroid && { labelX: c[0], labelY: c[1] },
|
|
47752
48003
|
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
47753
48004
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
47754
48005
|
});
|
|
@@ -48189,10 +48440,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48189
48440
|
lineNumber
|
|
48190
48441
|
});
|
|
48191
48442
|
};
|
|
48192
|
-
const WORLD_LABEL_ANCHORS = {
|
|
48193
|
-
US: [-98.5, 39.5]
|
|
48194
|
-
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48195
|
-
};
|
|
48196
48443
|
const REGION_LABEL_GAP = 2;
|
|
48197
48444
|
const regionLabelRect = (cx, cy, text) => {
|
|
48198
48445
|
const w = measureLegendText(text, FONT2) + 2 * REGION_LABEL_GAP;
|
|
@@ -48510,30 +48757,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48510
48757
|
});
|
|
48511
48758
|
labels.push(...contextLabels);
|
|
48512
48759
|
}
|
|
48513
|
-
let legend = null;
|
|
48514
|
-
if (!resolved.directives.noLegend) {
|
|
48515
|
-
const tagGroups = resolved.tagGroups.map((g) => ({
|
|
48516
|
-
name: g.name,
|
|
48517
|
-
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
48518
|
-
}));
|
|
48519
|
-
if (tagGroups.length > 0 || hasRamp) {
|
|
48520
|
-
legend = {
|
|
48521
|
-
tagGroups,
|
|
48522
|
-
activeGroup,
|
|
48523
|
-
...hasRamp && {
|
|
48524
|
-
ramp: {
|
|
48525
|
-
...resolved.directives.regionMetric !== void 0 && {
|
|
48526
|
-
metric: resolved.directives.regionMetric
|
|
48527
|
-
},
|
|
48528
|
-
min: rampMin,
|
|
48529
|
-
max: rampMax,
|
|
48530
|
-
hue: rampHue,
|
|
48531
|
-
base: rampBase
|
|
48532
|
-
}
|
|
48533
|
-
}
|
|
48534
|
-
};
|
|
48535
|
-
}
|
|
48536
|
-
}
|
|
48537
48760
|
return {
|
|
48538
48761
|
width,
|
|
48539
48762
|
height,
|
|
@@ -48558,7 +48781,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48558
48781
|
diagnostics: []
|
|
48559
48782
|
};
|
|
48560
48783
|
}
|
|
48561
|
-
var FIT_PAD,
|
|
48784
|
+
var FIT_PAD, RAMP_FLOOR2, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT2, WORLD_LABEL_ANCHORS, MAX_CLUSTER_EXTENT_FACTOR, MAX_COLUMN_ROWS, REGION_LABEL_HALO_RATIO, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT_LIGHT, WATER_TINT_DARK, RIVER_WIDTH, COMPACT_WIDTH_PX, RELIEF_MIN_AREA, RELIEF_MIN_DIM, RELIEF_HATCH_SPACING, RELIEF_HATCH_WIDTH, RELIEF_HATCH_STRENGTH, COASTLINE_RING_COUNT, COASTLINE_D0, COASTLINE_STEP, COASTLINE_THICKNESS, COASTLINE_OPACITY_NEAR, COASTLINE_OPACITY_FAR, COASTLINE_MIN_EXTENT, COASTLINE_MIN_EXTENT_GLOBAL, COASTLINE_STROKE_MIX, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, COLO_R, GOLDEN_ANGLE, STACK_OVERLAP, STACK_RING_MAX, STACK_RING_GAP, FAN_STEP, ARC_CURVE_FRAC, decodeCache, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, inAlaska, inHawaii, FOREIGN_BORDER, US_NON_CONUS;
|
|
48562
48785
|
var init_layout15 = __esm({
|
|
48563
48786
|
"src/map/layout.ts"() {
|
|
48564
48787
|
"use strict";
|
|
@@ -48569,15 +48792,20 @@ var init_layout15 = __esm({
|
|
|
48569
48792
|
init_label_layout();
|
|
48570
48793
|
init_legend_constants();
|
|
48571
48794
|
init_title_constants();
|
|
48795
|
+
init_legend_band();
|
|
48572
48796
|
init_context_labels();
|
|
48573
48797
|
FIT_PAD = 24;
|
|
48574
|
-
|
|
48798
|
+
RAMP_FLOOR2 = 15;
|
|
48575
48799
|
R_DEFAULT = 6;
|
|
48576
48800
|
R_MIN = 4;
|
|
48577
48801
|
R_MAX = 22;
|
|
48578
48802
|
W_MIN = 1.25;
|
|
48579
48803
|
W_MAX = 8;
|
|
48580
48804
|
FONT2 = 11;
|
|
48805
|
+
WORLD_LABEL_ANCHORS = {
|
|
48806
|
+
US: [-98.5, 39.5]
|
|
48807
|
+
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48808
|
+
};
|
|
48581
48809
|
MAX_CLUSTER_EXTENT_FACTOR = 0.18;
|
|
48582
48810
|
MAX_COLUMN_ROWS = 7;
|
|
48583
48811
|
REGION_LABEL_HALO_RATIO = 4.5;
|
|
@@ -48591,9 +48819,9 @@ var init_layout15 = __esm({
|
|
|
48591
48819
|
COMPACT_WIDTH_PX = 480;
|
|
48592
48820
|
RELIEF_MIN_AREA = 12;
|
|
48593
48821
|
RELIEF_MIN_DIM = 2;
|
|
48594
|
-
RELIEF_HATCH_SPACING =
|
|
48595
|
-
RELIEF_HATCH_WIDTH = 0.
|
|
48596
|
-
RELIEF_HATCH_STRENGTH =
|
|
48822
|
+
RELIEF_HATCH_SPACING = 1.5;
|
|
48823
|
+
RELIEF_HATCH_WIDTH = 0.2;
|
|
48824
|
+
RELIEF_HATCH_STRENGTH = 26;
|
|
48597
48825
|
COASTLINE_RING_COUNT = 5;
|
|
48598
48826
|
COASTLINE_D0 = 16e-4;
|
|
48599
48827
|
COASTLINE_STEP = 28e-4;
|
|
@@ -48672,7 +48900,47 @@ function ringToPath(ring) {
|
|
|
48672
48900
|
d += (i ? "L" : "M") + ring[i][0] + "," + ring[i][1];
|
|
48673
48901
|
return d + "Z";
|
|
48674
48902
|
}
|
|
48675
|
-
function
|
|
48903
|
+
function polylineToPath(pts) {
|
|
48904
|
+
let d = "";
|
|
48905
|
+
for (let i = 0; i < pts.length; i++)
|
|
48906
|
+
d += (i ? "L" : "M") + pts[i][0] + "," + pts[i][1];
|
|
48907
|
+
return d;
|
|
48908
|
+
}
|
|
48909
|
+
function ringToCoastPaths(ring, frame) {
|
|
48910
|
+
if (!frame) return [ringToPath(ring)];
|
|
48911
|
+
const n = ring.length;
|
|
48912
|
+
const eps = 0.75;
|
|
48913
|
+
const onL = (x) => Math.abs(x) <= eps;
|
|
48914
|
+
const onR = (x) => Math.abs(x - frame.w) <= eps;
|
|
48915
|
+
const onT = (y) => Math.abs(y) <= eps;
|
|
48916
|
+
const onB = (y) => Math.abs(y - frame.h) <= eps;
|
|
48917
|
+
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]);
|
|
48918
|
+
let firstBreak = -1;
|
|
48919
|
+
for (let i = 0; i < n; i++)
|
|
48920
|
+
if (isFrameEdge(ring[i], ring[(i + 1) % n])) {
|
|
48921
|
+
firstBreak = i;
|
|
48922
|
+
break;
|
|
48923
|
+
}
|
|
48924
|
+
if (firstBreak === -1) return [ringToPath(ring)];
|
|
48925
|
+
const paths = [];
|
|
48926
|
+
let cur = [];
|
|
48927
|
+
const start = (firstBreak + 1) % n;
|
|
48928
|
+
for (let k = 0; k < n; k++) {
|
|
48929
|
+
const i = (start + k) % n;
|
|
48930
|
+
const a = ring[i];
|
|
48931
|
+
const b = ring[(i + 1) % n];
|
|
48932
|
+
if (isFrameEdge(a, b)) {
|
|
48933
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48934
|
+
cur = [];
|
|
48935
|
+
continue;
|
|
48936
|
+
}
|
|
48937
|
+
if (cur.length === 0) cur.push(a);
|
|
48938
|
+
cur.push(b);
|
|
48939
|
+
}
|
|
48940
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48941
|
+
return paths;
|
|
48942
|
+
}
|
|
48943
|
+
function coastlineOuterRings(regions, minExtent, frame) {
|
|
48676
48944
|
const paths = [];
|
|
48677
48945
|
for (const r of regions) {
|
|
48678
48946
|
const rings = parsePathRings(r.d);
|
|
@@ -48695,7 +48963,7 @@ function coastlineOuterRings(regions, minExtent) {
|
|
|
48695
48963
|
for (let j = 0; j < rings.length; j++)
|
|
48696
48964
|
if (j !== i && pointInRing2(fx, fy, rings[j])) depth++;
|
|
48697
48965
|
if (depth % 2 === 1) continue;
|
|
48698
|
-
paths.push(
|
|
48966
|
+
paths.push(...ringToCoastPaths(ring, frame));
|
|
48699
48967
|
}
|
|
48700
48968
|
}
|
|
48701
48969
|
return paths;
|
|
@@ -48725,6 +48993,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48725
48993
|
// stretch-distorting. The in-app preview pane passes no exportDims → unset →
|
|
48726
48994
|
// keeps the global stretch-fill.
|
|
48727
48995
|
preferContain: exportDims?.preferContain ?? false,
|
|
48996
|
+
// Reserve the legend band for the mode actually drawn below (export shows
|
|
48997
|
+
// only the active group; preview keeps the inactive pills).
|
|
48998
|
+
legendMode: exportDims ? "export" : "preview",
|
|
48728
48999
|
...activeGroupOverride !== void 0 && {
|
|
48729
49000
|
activeGroup: activeGroupOverride
|
|
48730
49001
|
}
|
|
@@ -48739,6 +49010,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48739
49010
|
const drawRegion = (g, r, strokeWidth) => {
|
|
48740
49011
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
48741
49012
|
if (r.label) p.attr("data-region-name", r.label);
|
|
49013
|
+
if (r.id && r.id !== "lake") p.attr("data-iso", r.id);
|
|
49014
|
+
if (r.labelX !== void 0 && r.labelY !== void 0) {
|
|
49015
|
+
p.attr("data-label-x", r.labelX).attr("data-label-y", r.labelY);
|
|
49016
|
+
}
|
|
48742
49017
|
if (r.layer !== "base") {
|
|
48743
49018
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
48744
49019
|
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
@@ -48768,7 +49043,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48768
49043
|
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
48769
49044
|
for (const r of layout.regions)
|
|
48770
49045
|
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
48771
|
-
const gRelief = svg.append("g").attr("clip-path", `url(#${landClipId})`).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");
|
|
49046
|
+
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");
|
|
48772
49047
|
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
48773
49048
|
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
48774
49049
|
}
|
|
@@ -48789,10 +49064,16 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48789
49064
|
mask.append("path").attr("d", d).attr("fill", "black").attr("stroke", "black").attr("stroke-width", 2 * reach).attr("stroke-linejoin", "round");
|
|
48790
49065
|
}
|
|
48791
49066
|
}
|
|
48792
|
-
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").attr("mask", `url(#${maskId})`);
|
|
49067
|
+
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
|
|
48793
49068
|
appendWaterLines(
|
|
48794
49069
|
gWater,
|
|
48795
|
-
|
|
49070
|
+
// Pass the canvas frame so edges collinear with it (the antimeridian on a
|
|
49071
|
+
// world map, regional clipExtent cuts) don't get ringed as fake coast —
|
|
49072
|
+
// land runs cleanly to the render-area edge.
|
|
49073
|
+
coastlineOuterRings(layout.regions, cs.minExtent, {
|
|
49074
|
+
w: width,
|
|
49075
|
+
h: height
|
|
49076
|
+
}),
|
|
48796
49077
|
cs,
|
|
48797
49078
|
layout.background
|
|
48798
49079
|
);
|
|
@@ -48806,7 +49087,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48806
49087
|
gWater.append("path").attr("d", ds.join(" ")).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-linejoin", "round");
|
|
48807
49088
|
}
|
|
48808
49089
|
if (layout.rivers.length) {
|
|
48809
|
-
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
49090
|
+
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none").style("pointer-events", "none");
|
|
48810
49091
|
for (const r of layout.rivers) {
|
|
48811
49092
|
gRivers.append("path").attr("d", r.d).attr("stroke", r.color).attr("stroke-width", r.width).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
48812
49093
|
}
|
|
@@ -48847,7 +49128,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48847
49128
|
const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
|
|
48848
49129
|
clip.append("path").attr("d", d);
|
|
48849
49130
|
}
|
|
48850
|
-
const gInsetWater = insetG.append("g").attr("clip-path", `url(#${clipId})`).append("g").attr("class", "dgmo-map-inset-water-lines").attr("fill", "none").attr("mask", `url(#${maskId})`);
|
|
49131
|
+
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})`);
|
|
48851
49132
|
appendWaterLines(
|
|
48852
49133
|
gInsetWater,
|
|
48853
49134
|
coastlineOuterRings(layout.insetRegions, cs.minExtent),
|
|
@@ -49006,30 +49287,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
49006
49287
|
if (layout.legend) {
|
|
49007
49288
|
const legendY = (layout.title ? TITLE_Y + TITLE_FONT_SIZE : 0) + (layout.subtitle ? TITLE_FONT_SIZE : 0) + 8;
|
|
49008
49289
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
49009
|
-
const
|
|
49010
|
-
const scoreGroup = ramp ? {
|
|
49011
|
-
name: ramp.metric?.trim() || "Value",
|
|
49012
|
-
entries: [],
|
|
49013
|
-
gradient: {
|
|
49014
|
-
min: ramp.min,
|
|
49015
|
-
max: ramp.max,
|
|
49016
|
-
hue: ramp.hue,
|
|
49017
|
-
base: ramp.base
|
|
49018
|
-
}
|
|
49019
|
-
} : null;
|
|
49020
|
-
const tagGroups = layout.legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
49021
|
-
const groups = [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
49290
|
+
const groups = mapLegendGroups(layout.legend);
|
|
49022
49291
|
if (groups.length > 0) {
|
|
49023
|
-
const config =
|
|
49292
|
+
const config = mapLegendConfig(
|
|
49024
49293
|
groups,
|
|
49025
|
-
|
|
49026
|
-
|
|
49027
|
-
showEmptyGroups: false,
|
|
49028
|
-
// Keep inactive siblings visible as pills so the user can click to flip
|
|
49029
|
-
// the active colouring dimension (preview only — export shows just the
|
|
49030
|
-
// active group).
|
|
49031
|
-
showInactivePills: true
|
|
49032
|
-
};
|
|
49294
|
+
exportDims ? "export" : "preview"
|
|
49295
|
+
);
|
|
49033
49296
|
const state = { activeGroup: layout.legend.activeGroup };
|
|
49034
49297
|
renderLegendD3(legendG, config, state, palette, isDark, void 0, width);
|
|
49035
49298
|
}
|
|
@@ -49073,6 +49336,7 @@ var init_renderer16 = __esm({
|
|
|
49073
49336
|
init_title_constants();
|
|
49074
49337
|
init_color_utils();
|
|
49075
49338
|
init_legend_d3();
|
|
49339
|
+
init_legend_band();
|
|
49076
49340
|
init_layout15();
|
|
49077
49341
|
LABEL_FONT = 11;
|
|
49078
49342
|
}
|
|
@@ -49094,9 +49358,10 @@ function mapContentAspect(resolved, data, ref = REF) {
|
|
|
49094
49358
|
const aspect = w / h;
|
|
49095
49359
|
return Number.isFinite(aspect) && aspect > 0 ? aspect : FALLBACK_ASPECT;
|
|
49096
49360
|
}
|
|
49097
|
-
function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
49098
|
-
const
|
|
49099
|
-
const
|
|
49361
|
+
function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
49362
|
+
const useOverride = aspectOverride !== void 0 && Number.isFinite(aspectOverride) && aspectOverride > 0;
|
|
49363
|
+
const raw = useOverride ? aspectOverride : mapContentAspect(resolved, data);
|
|
49364
|
+
const clamped = useOverride ? raw : Math.max(ASPECT_MIN, Math.min(ASPECT_MAX, raw));
|
|
49100
49365
|
const width = baseWidth;
|
|
49101
49366
|
let height = Math.round(width / clamped);
|
|
49102
49367
|
let chromeReserve = 0;
|
|
@@ -49109,7 +49374,7 @@ function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
|
49109
49374
|
height = Math.round(chromeReserve + MIN_MAP_BAND);
|
|
49110
49375
|
floored = true;
|
|
49111
49376
|
}
|
|
49112
|
-
const preferContain = clamped !== raw || floored;
|
|
49377
|
+
const preferContain = useOverride ? floored : clamped !== raw || floored;
|
|
49113
49378
|
return { width, height, preferContain };
|
|
49114
49379
|
}
|
|
49115
49380
|
var FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
@@ -54819,7 +55084,6 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
54819
55084
|
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
54820
55085
|
const {
|
|
54821
55086
|
width,
|
|
54822
|
-
height,
|
|
54823
55087
|
tooltip,
|
|
54824
55088
|
solid,
|
|
54825
55089
|
textColor,
|
|
@@ -54868,10 +55132,11 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
|
|
|
54868
55132
|
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
54869
55133
|
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
54870
55134
|
const innerWidth = width - margin.left - margin.right;
|
|
54871
|
-
const
|
|
54872
|
-
const
|
|
55135
|
+
const rowH = ctx.structural(28);
|
|
55136
|
+
const innerHeight = rowH * sorted.length;
|
|
55137
|
+
const usedHeight = margin.top + innerHeight + margin.bottom;
|
|
54873
55138
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
54874
|
-
const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height",
|
|
55139
|
+
const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height", usedHeight).attr("viewBox", `0 0 ${width} ${usedHeight}`).attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
54875
55140
|
if (ctx.isBelowFloor) {
|
|
54876
55141
|
svg.attr("width", "100%");
|
|
54877
55142
|
}
|
|
@@ -57392,7 +57657,12 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
57392
57657
|
}
|
|
57393
57658
|
}
|
|
57394
57659
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
57395
|
-
const dims2 = mapExportDimensions2(
|
|
57660
|
+
const dims2 = mapExportDimensions2(
|
|
57661
|
+
mapResolved,
|
|
57662
|
+
mapData,
|
|
57663
|
+
EXPORT_WIDTH,
|
|
57664
|
+
options?.mapAspect
|
|
57665
|
+
);
|
|
57396
57666
|
const container2 = createExportContainer(dims2.width, dims2.height);
|
|
57397
57667
|
renderMapForExport2(
|
|
57398
57668
|
container2,
|
|
@@ -58536,6 +58806,134 @@ function extractInfraCounts(content) {
|
|
|
58536
58806
|
return { nodes: parsed.nodes.length };
|
|
58537
58807
|
}
|
|
58538
58808
|
|
|
58809
|
+
// src/utils/svg-embed.ts
|
|
58810
|
+
function normalizeSvgForEmbed(input) {
|
|
58811
|
+
let svg = input;
|
|
58812
|
+
const rootMatch = svg.match(/<svg[^>]*>/);
|
|
58813
|
+
const rootTag = rootMatch?.[0] ?? "";
|
|
58814
|
+
if (rootTag && !rootTag.includes("viewBox")) {
|
|
58815
|
+
const wh = rootTag.match(/width="(\d+)"[^>]*height="(\d+)"/);
|
|
58816
|
+
if (wh) {
|
|
58817
|
+
svg = svg.replace(/<svg/, `<svg viewBox="0 0 ${wh[1]} ${wh[2]}"`);
|
|
58818
|
+
}
|
|
58819
|
+
}
|
|
58820
|
+
const tight = computeBBox(svg);
|
|
58821
|
+
if (tight && tight.width > 0 && tight.height > 0) {
|
|
58822
|
+
const pad2 = 16;
|
|
58823
|
+
const vb = `${tight.x - pad2} ${tight.y - pad2} ${tight.width + pad2 * 2} ${tight.height + pad2 * 2}`;
|
|
58824
|
+
svg = svg.replace(/(<svg[^>]*?)viewBox="[^"]*"/, `$1viewBox="${vb}"`);
|
|
58825
|
+
}
|
|
58826
|
+
svg = svg.replace(/(<svg[^>]*?) width="[^"]*"/g, "$1");
|
|
58827
|
+
svg = svg.replace(/(<svg[^>]*?) height="[^"]*"/g, "$1");
|
|
58828
|
+
svg = svg.replace(/(<svg[^>]*?style="[^"]*?)background:[^;"]*;?\s*/g, "$1");
|
|
58829
|
+
svg = svg.replace(/<svg\s{2,}/g, "<svg ");
|
|
58830
|
+
return svg;
|
|
58831
|
+
}
|
|
58832
|
+
function getEmbedSvgViewBox(svg) {
|
|
58833
|
+
const tight = computeBBox(svg);
|
|
58834
|
+
if (!tight || tight.width <= 0 || tight.height <= 0) return null;
|
|
58835
|
+
const pad2 = 16;
|
|
58836
|
+
return {
|
|
58837
|
+
x: tight.x - pad2,
|
|
58838
|
+
y: tight.y - pad2,
|
|
58839
|
+
width: tight.width + pad2 * 2,
|
|
58840
|
+
height: tight.height + pad2 * 2
|
|
58841
|
+
};
|
|
58842
|
+
}
|
|
58843
|
+
function computeBBox(svg) {
|
|
58844
|
+
const xs = [];
|
|
58845
|
+
const ys = [];
|
|
58846
|
+
function push(x, y) {
|
|
58847
|
+
if (Number.isFinite(x) && Number.isFinite(y)) {
|
|
58848
|
+
xs.push(x);
|
|
58849
|
+
ys.push(y);
|
|
58850
|
+
}
|
|
58851
|
+
}
|
|
58852
|
+
function attr(tag, name) {
|
|
58853
|
+
const m = tag.match(new RegExp(`\\b${name}="([^"]*)"`));
|
|
58854
|
+
if (!m) return null;
|
|
58855
|
+
const n = parseFloat(m[1]);
|
|
58856
|
+
return Number.isFinite(n) ? n : null;
|
|
58857
|
+
}
|
|
58858
|
+
for (const m of svg.matchAll(/<rect\b[^>]*?\/?>/g)) {
|
|
58859
|
+
const tag = m[0];
|
|
58860
|
+
const x = attr(tag, "x");
|
|
58861
|
+
const y = attr(tag, "y");
|
|
58862
|
+
const w = attr(tag, "width");
|
|
58863
|
+
const h = attr(tag, "height");
|
|
58864
|
+
if (x !== null && y !== null && w !== null && h !== null) {
|
|
58865
|
+
push(x, y);
|
|
58866
|
+
push(x + w, y + h);
|
|
58867
|
+
}
|
|
58868
|
+
}
|
|
58869
|
+
for (const m of svg.matchAll(/<line\b[^>]*?\/?>/g)) {
|
|
58870
|
+
const tag = m[0];
|
|
58871
|
+
const x1 = attr(tag, "x1");
|
|
58872
|
+
const y1 = attr(tag, "y1");
|
|
58873
|
+
const x2 = attr(tag, "x2");
|
|
58874
|
+
const y2 = attr(tag, "y2");
|
|
58875
|
+
if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
|
|
58876
|
+
push(x1, y1);
|
|
58877
|
+
push(x2, y2);
|
|
58878
|
+
}
|
|
58879
|
+
}
|
|
58880
|
+
for (const m of svg.matchAll(/<circle\b[^>]*?\/?>/g)) {
|
|
58881
|
+
const tag = m[0];
|
|
58882
|
+
const cx = attr(tag, "cx");
|
|
58883
|
+
const cy = attr(tag, "cy");
|
|
58884
|
+
const r = attr(tag, "r");
|
|
58885
|
+
if (cx !== null && cy !== null && r !== null) {
|
|
58886
|
+
push(cx - r, cy - r);
|
|
58887
|
+
push(cx + r, cy + r);
|
|
58888
|
+
}
|
|
58889
|
+
}
|
|
58890
|
+
for (const m of svg.matchAll(/<ellipse\b[^>]*?\/?>/g)) {
|
|
58891
|
+
const tag = m[0];
|
|
58892
|
+
const cx = attr(tag, "cx");
|
|
58893
|
+
const cy = attr(tag, "cy");
|
|
58894
|
+
const rx = attr(tag, "rx");
|
|
58895
|
+
const ry = attr(tag, "ry");
|
|
58896
|
+
if (cx !== null && cy !== null && rx !== null && ry !== null) {
|
|
58897
|
+
push(cx - rx, cy - ry);
|
|
58898
|
+
push(cx + rx, cy + ry);
|
|
58899
|
+
}
|
|
58900
|
+
}
|
|
58901
|
+
for (const m of svg.matchAll(/<text\b([^>]*?)>([\s\S]*?)<\/text>/g)) {
|
|
58902
|
+
const tag = `<text${m[1]}>`;
|
|
58903
|
+
const text = m[2].replace(/<[^>]+>/g, "");
|
|
58904
|
+
const x = attr(tag, "x");
|
|
58905
|
+
const y = attr(tag, "y");
|
|
58906
|
+
if (x !== null && y !== null) {
|
|
58907
|
+
const w = text.length * 7;
|
|
58908
|
+
push(x - w / 2, y - 14);
|
|
58909
|
+
push(x + w / 2, y + 4);
|
|
58910
|
+
}
|
|
58911
|
+
}
|
|
58912
|
+
for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
|
|
58913
|
+
const d = m[1];
|
|
58914
|
+
const nums = d.match(/-?\d+(?:\.\d+)?/g);
|
|
58915
|
+
if (!nums) continue;
|
|
58916
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58917
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58918
|
+
}
|
|
58919
|
+
}
|
|
58920
|
+
for (const m of svg.matchAll(
|
|
58921
|
+
/<(?:polygon|polyline)\b[^>]*?\bpoints="([^"]+)"/g
|
|
58922
|
+
)) {
|
|
58923
|
+
const nums = m[1].match(/-?\d+(?:\.\d+)?/g);
|
|
58924
|
+
if (!nums) continue;
|
|
58925
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58926
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58927
|
+
}
|
|
58928
|
+
}
|
|
58929
|
+
if (xs.length === 0 || ys.length === 0) return null;
|
|
58930
|
+
const minX = Math.min(...xs);
|
|
58931
|
+
const maxX = Math.max(...xs);
|
|
58932
|
+
const minY = Math.min(...ys);
|
|
58933
|
+
const maxY = Math.max(...ys);
|
|
58934
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
58935
|
+
}
|
|
58936
|
+
|
|
58539
58937
|
// src/map/completion.ts
|
|
58540
58938
|
var fold2 = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
58541
58939
|
var groupThousands = (n) => String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
@@ -58659,8 +59057,10 @@ export {
|
|
|
58659
59057
|
decodeDiagramUrl2 as decodeDiagramUrl,
|
|
58660
59058
|
encodeDiagramUrl2 as encodeDiagramUrl,
|
|
58661
59059
|
formatDgmoError,
|
|
59060
|
+
getEmbedSvgViewBox,
|
|
58662
59061
|
getMinDimensions,
|
|
58663
59062
|
getPalette,
|
|
59063
|
+
normalizeSvgForEmbed,
|
|
58664
59064
|
palettes,
|
|
58665
59065
|
render2 as render,
|
|
58666
59066
|
themes,
|