@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.cjs
CHANGED
|
@@ -895,9 +895,7 @@ var init_reserved_key_registry = __esm({
|
|
|
895
895
|
BOXES_AND_LINES_REGISTRY = staticRegistry([
|
|
896
896
|
"color",
|
|
897
897
|
"description",
|
|
898
|
-
"
|
|
899
|
-
"split",
|
|
900
|
-
"fanout"
|
|
898
|
+
"value"
|
|
901
899
|
]);
|
|
902
900
|
TIMELINE_REGISTRY = staticRegistry([
|
|
903
901
|
"color",
|
|
@@ -16899,6 +16897,21 @@ function parseBoxesAndLines(content) {
|
|
|
16899
16897
|
}
|
|
16900
16898
|
continue;
|
|
16901
16899
|
}
|
|
16900
|
+
if (!contentStarted) {
|
|
16901
|
+
const metricMatch = trimmed.match(/^box-metric\s+(.+)$/i);
|
|
16902
|
+
if (metricMatch) {
|
|
16903
|
+
const { label, colorName } = peelTrailingColorName(
|
|
16904
|
+
metricMatch[1].trim()
|
|
16905
|
+
);
|
|
16906
|
+
result.boxMetric = label;
|
|
16907
|
+
if (colorName !== void 0) result.boxMetricColor = colorName;
|
|
16908
|
+
continue;
|
|
16909
|
+
}
|
|
16910
|
+
if (/^show-values$/i.test(trimmed)) {
|
|
16911
|
+
result.showValues = true;
|
|
16912
|
+
continue;
|
|
16913
|
+
}
|
|
16914
|
+
}
|
|
16902
16915
|
if (!contentStarted) {
|
|
16903
16916
|
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
16904
16917
|
if (optMatch) {
|
|
@@ -17277,6 +17290,19 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17277
17290
|
description = [metadata["description"]];
|
|
17278
17291
|
delete metadata["description"];
|
|
17279
17292
|
}
|
|
17293
|
+
let value;
|
|
17294
|
+
if (metadata["value"] !== void 0) {
|
|
17295
|
+
const raw = metadata["value"];
|
|
17296
|
+
const num = Number(raw);
|
|
17297
|
+
if (Number.isFinite(num)) {
|
|
17298
|
+
value = num;
|
|
17299
|
+
} else {
|
|
17300
|
+
diagnostics.push(
|
|
17301
|
+
makeDgmoError(lineNum, `value must be a number (got "${raw}")`, "error")
|
|
17302
|
+
);
|
|
17303
|
+
}
|
|
17304
|
+
delete metadata["value"];
|
|
17305
|
+
}
|
|
17280
17306
|
if (split.alias) {
|
|
17281
17307
|
nameAliasMap?.set(normalizeName(split.alias), label);
|
|
17282
17308
|
}
|
|
@@ -17285,7 +17311,8 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17285
17311
|
label,
|
|
17286
17312
|
lineNumber: lineNum,
|
|
17287
17313
|
metadata,
|
|
17288
|
-
...description !== void 0 && { description }
|
|
17314
|
+
...description !== void 0 && { description },
|
|
17315
|
+
...value !== void 0 && { value }
|
|
17289
17316
|
};
|
|
17290
17317
|
}
|
|
17291
17318
|
function splitTargetAndMeta(rest, metaAliasMap) {
|
|
@@ -26405,7 +26432,18 @@ function fitLabelToHeader(label, nodeWidth, maxLines) {
|
|
|
26405
26432
|
const truncated = label.length > maxChars ? label.slice(0, maxChars - 1) + "\u2026" : label;
|
|
26406
26433
|
return { lines: [truncated], fontSize: MIN_NODE_FONT_SIZE };
|
|
26407
26434
|
}
|
|
26408
|
-
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, solid) {
|
|
26435
|
+
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, solid) {
|
|
26436
|
+
const neutralFill = mix(palette.bg, palette.text, isDark ? 90 : 95);
|
|
26437
|
+
if (value.active) {
|
|
26438
|
+
const fill3 = node.value !== void 0 ? value.fillForValue(node.value) : neutralFill;
|
|
26439
|
+
const stroke3 = value.hue;
|
|
26440
|
+
const text2 = contrastText(
|
|
26441
|
+
fill3,
|
|
26442
|
+
palette.textOnFillLight,
|
|
26443
|
+
palette.textOnFillDark
|
|
26444
|
+
);
|
|
26445
|
+
return { fill: fill3, stroke: stroke3, text: text2 };
|
|
26446
|
+
}
|
|
26409
26447
|
const tagColor = resolveTagColor(
|
|
26410
26448
|
node.metadata,
|
|
26411
26449
|
[...tagGroups],
|
|
@@ -26514,25 +26552,65 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26514
26552
|
const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
|
|
26515
26553
|
const sTitleFontSize = sctx.text(TITLE_FONT_SIZE);
|
|
26516
26554
|
const sTitleY = sctx.structural(TITLE_Y);
|
|
26555
|
+
const nodeValues = parsed.nodes.filter((n) => n.value !== void 0).map((n) => n.value);
|
|
26556
|
+
const hasRamp = nodeValues.length > 0;
|
|
26557
|
+
const allNonNegative = hasRamp && nodeValues.every((v) => v >= 0);
|
|
26558
|
+
const rampMin = allNonNegative ? 0 : Math.min(...nodeValues);
|
|
26559
|
+
const rampMax = Math.max(...nodeValues);
|
|
26560
|
+
const rampHue = resolveColor(parsed.boxMetricColor ?? "", palette) ?? palette.primary;
|
|
26561
|
+
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
26562
|
+
const fillForValue = (v) => {
|
|
26563
|
+
const t = rampMax > rampMin ? (v - rampMin) / (rampMax - rampMin) : 1;
|
|
26564
|
+
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
26565
|
+
return mix(rampHue, rampBase, pct);
|
|
26566
|
+
};
|
|
26567
|
+
const VALUE_NAME = hasRamp ? parsed.boxMetric?.trim() || "Value" : null;
|
|
26568
|
+
const matchColorGroup = (v) => {
|
|
26569
|
+
const lv = v.trim().toLowerCase();
|
|
26570
|
+
if (lv === "" || lv === "none") return null;
|
|
26571
|
+
const tg = parsed.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
26572
|
+
if (tg) return tg.name;
|
|
26573
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
26574
|
+
return v;
|
|
26575
|
+
};
|
|
26576
|
+
const override = activeTagGroup;
|
|
26577
|
+
let activeGroup;
|
|
26578
|
+
if (override !== void 0) {
|
|
26579
|
+
activeGroup = override === null ? null : matchColorGroup(override);
|
|
26580
|
+
} else if (parsed.options["active-tag"] !== void 0) {
|
|
26581
|
+
activeGroup = matchColorGroup(parsed.options["active-tag"]);
|
|
26582
|
+
} else {
|
|
26583
|
+
activeGroup = VALUE_NAME ?? (parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null);
|
|
26584
|
+
}
|
|
26585
|
+
const activeIsValue = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
26586
|
+
const valueGroup = VALUE_NAME !== null ? {
|
|
26587
|
+
name: VALUE_NAME,
|
|
26588
|
+
entries: [],
|
|
26589
|
+
gradient: {
|
|
26590
|
+
min: rampMin,
|
|
26591
|
+
max: rampMax,
|
|
26592
|
+
hue: rampHue,
|
|
26593
|
+
base: rampBase
|
|
26594
|
+
}
|
|
26595
|
+
} : null;
|
|
26596
|
+
const legendGroups = [
|
|
26597
|
+
...valueGroup ? [valueGroup] : [],
|
|
26598
|
+
...parsed.tagGroups
|
|
26599
|
+
];
|
|
26517
26600
|
const reserveHasDescriptions = parsed.nodes.some(
|
|
26518
26601
|
(n) => n.description && n.description.length > 0
|
|
26519
26602
|
);
|
|
26520
|
-
const willRenderLegend =
|
|
26603
|
+
const willRenderLegend = legendGroups.length > 0 || reserveHasDescriptions && controlsHost !== "app";
|
|
26521
26604
|
const sLegendHeight = willRenderLegend ? sctx.structural(
|
|
26522
26605
|
getMaxLegendReservedHeight(
|
|
26523
26606
|
{
|
|
26524
|
-
groups:
|
|
26607
|
+
groups: legendGroups,
|
|
26525
26608
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26526
26609
|
mode: exportMode ? "export" : "preview"
|
|
26527
26610
|
},
|
|
26528
26611
|
width
|
|
26529
26612
|
)
|
|
26530
26613
|
) : 0;
|
|
26531
|
-
const activeGroup = resolveActiveTagGroup(
|
|
26532
|
-
parsed.tagGroups,
|
|
26533
|
-
parsed.options["active-tag"],
|
|
26534
|
-
activeTagGroup
|
|
26535
|
-
);
|
|
26536
26614
|
const hidden = hiddenTagValues ?? parsed.initialHiddenTagValues;
|
|
26537
26615
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
26538
26616
|
for (const node of parsed.nodes) nodeMap.set(node.label, node);
|
|
@@ -26543,7 +26621,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26543
26621
|
const hasAnyDescriptions = parsed.nodes.some(
|
|
26544
26622
|
(n) => n.description && n.description.length > 0
|
|
26545
26623
|
);
|
|
26546
|
-
const needsLegend =
|
|
26624
|
+
const needsLegend = legendGroups.length > 0 || hasAnyDescriptions && onToggleDescriptions;
|
|
26547
26625
|
const legendH = needsLegend ? sLegendHeight + 8 : 0;
|
|
26548
26626
|
const groupLabelsSet = new Set(layout.groups.map((g) => g.label));
|
|
26549
26627
|
let labelZoneExtension = 0;
|
|
@@ -26749,12 +26827,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26749
26827
|
activeGroup,
|
|
26750
26828
|
palette,
|
|
26751
26829
|
isDark,
|
|
26830
|
+
{ active: activeIsValue, hue: rampHue, fillForValue },
|
|
26752
26831
|
parsed.options["solid-fill"] === "on"
|
|
26753
26832
|
);
|
|
26754
26833
|
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);
|
|
26755
26834
|
for (const [key, val] of Object.entries(node.metadata)) {
|
|
26756
26835
|
nodeG.attr(`data-tag-${key.toLowerCase()}`, val.toLowerCase());
|
|
26757
26836
|
}
|
|
26837
|
+
if (node.value !== void 0) {
|
|
26838
|
+
nodeG.attr("data-value", node.value);
|
|
26839
|
+
}
|
|
26758
26840
|
if (onClickItem) {
|
|
26759
26841
|
nodeG.on("click", (event) => {
|
|
26760
26842
|
const target = event.target;
|
|
@@ -26826,6 +26908,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26826
26908
|
const tooltipText = fullText.length > 200 ? fullText.slice(0, 199) + "\u2026" : fullText;
|
|
26827
26909
|
nodeG.append("title").text(tooltipText);
|
|
26828
26910
|
}
|
|
26911
|
+
} else if (parsed.showValues && node.value !== void 0) {
|
|
26912
|
+
const valueLabel = parsed.boxMetric ? `${parsed.boxMetric}: ${node.value}` : String(node.value);
|
|
26913
|
+
const headerH = ln.height / 2;
|
|
26914
|
+
const sepY = -ln.height / 2 + headerH;
|
|
26915
|
+
const fitted = fitLabelToHeader(node.label, ln.width, 2);
|
|
26916
|
+
const labelLineH = fitted.fontSize * 1.3;
|
|
26917
|
+
const labelTotalH = fitted.lines.length * labelLineH;
|
|
26918
|
+
const headerCenterY = -ln.height / 2 + headerH / 2;
|
|
26919
|
+
for (let li = 0; li < fitted.lines.length; li++) {
|
|
26920
|
+
nodeG.append("text").attr("x", 0).attr(
|
|
26921
|
+
"y",
|
|
26922
|
+
headerCenterY - labelTotalH / 2 + labelLineH / 2 + li * labelLineH
|
|
26923
|
+
).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]);
|
|
26924
|
+
}
|
|
26925
|
+
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);
|
|
26926
|
+
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);
|
|
26829
26927
|
} else {
|
|
26830
26928
|
const maxLabelLines = Math.max(
|
|
26831
26929
|
2,
|
|
@@ -26838,11 +26936,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26838
26936
|
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]);
|
|
26839
26937
|
}
|
|
26840
26938
|
}
|
|
26939
|
+
if (parsed.showValues && node.value !== void 0 && desc && desc.length > 0 && !hideDescriptions) {
|
|
26940
|
+
const valueText = String(node.value);
|
|
26941
|
+
const padX = 6;
|
|
26942
|
+
const padY = 5;
|
|
26943
|
+
const bw = valueText.length * VALUE_FONT_SIZE * CHAR_WIDTH_RATIO2 + 8;
|
|
26944
|
+
const bh = VALUE_FONT_SIZE + 4;
|
|
26945
|
+
const bx = Math.max(-ln.width / 2 + 4, ln.width / 2 - bw - 4);
|
|
26946
|
+
const by = -ln.height / 2 + 4;
|
|
26947
|
+
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);
|
|
26948
|
+
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);
|
|
26949
|
+
}
|
|
26841
26950
|
}
|
|
26842
26951
|
const hasDescriptions = parsed.nodes.some(
|
|
26843
26952
|
(n) => n.description && n.description.length > 0
|
|
26844
26953
|
);
|
|
26845
|
-
const hasLegend =
|
|
26954
|
+
const hasLegend = legendGroups.length > 0 || hasDescriptions && controlsHost !== "app";
|
|
26846
26955
|
if (hasLegend) {
|
|
26847
26956
|
let controlsGroup;
|
|
26848
26957
|
if (hasDescriptions && (onToggleDescriptions || controlsHost === "app")) {
|
|
@@ -26860,7 +26969,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26860
26969
|
};
|
|
26861
26970
|
}
|
|
26862
26971
|
const legendConfig = {
|
|
26863
|
-
groups:
|
|
26972
|
+
groups: legendGroups,
|
|
26864
26973
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26865
26974
|
mode: exportMode ? "export" : "preview",
|
|
26866
26975
|
// Keep inactive sibling tag groups visible as collapsed pills so the user
|
|
@@ -26915,7 +27024,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
26915
27024
|
}
|
|
26916
27025
|
});
|
|
26917
27026
|
}
|
|
26918
|
-
var d3Selection6, d3Shape4, 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;
|
|
27027
|
+
var d3Selection6, d3Shape4, 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;
|
|
26919
27028
|
var init_renderer6 = __esm({
|
|
26920
27029
|
"src/boxes-and-lines/renderer.ts"() {
|
|
26921
27030
|
"use strict";
|
|
@@ -26926,12 +27035,13 @@ var init_renderer6 = __esm({
|
|
|
26926
27035
|
init_legend_layout();
|
|
26927
27036
|
init_title_constants();
|
|
26928
27037
|
init_color_utils();
|
|
27038
|
+
init_colors();
|
|
26929
27039
|
init_tag_groups();
|
|
26930
27040
|
init_inline_markdown();
|
|
26931
27041
|
init_wrapped_desc();
|
|
26932
27042
|
init_scaling();
|
|
26933
27043
|
DIAGRAM_PADDING6 = 20;
|
|
26934
|
-
NODE_FONT_SIZE =
|
|
27044
|
+
NODE_FONT_SIZE = 11;
|
|
26935
27045
|
MIN_NODE_FONT_SIZE = 9;
|
|
26936
27046
|
EDGE_LABEL_FONT_SIZE4 = 11;
|
|
26937
27047
|
EDGE_STROKE_WIDTH5 = 1.5;
|
|
@@ -26948,6 +27058,8 @@ var init_renderer6 = __esm({
|
|
|
26948
27058
|
GROUP_RX = 8;
|
|
26949
27059
|
GROUP_LABEL_FONT_SIZE = 14;
|
|
26950
27060
|
GROUP_LABEL_ZONE = 32;
|
|
27061
|
+
RAMP_FLOOR = 15;
|
|
27062
|
+
VALUE_FONT_SIZE = 11;
|
|
26951
27063
|
lineGeneratorLR = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26952
27064
|
lineGeneratorTB = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26953
27065
|
}
|
|
@@ -46666,7 +46778,11 @@ function resolveMap(parsed, data) {
|
|
|
46666
46778
|
if (bb && !isWholeSphere(bb)) containerBoxes.push(bb);
|
|
46667
46779
|
}
|
|
46668
46780
|
const containerUnion = unionExtent(containerBoxes, points);
|
|
46669
|
-
if (containerUnion)
|
|
46781
|
+
if (containerUnion)
|
|
46782
|
+
extent2 = pad(
|
|
46783
|
+
clampContainerToCluster(containerUnion, points),
|
|
46784
|
+
PAD_FRACTION
|
|
46785
|
+
);
|
|
46670
46786
|
}
|
|
46671
46787
|
if (isPoiOnly) {
|
|
46672
46788
|
const cx = (extent2[0][0] + extent2[1][0]) / 2;
|
|
@@ -46747,6 +46863,22 @@ function mostCommonCountry(regions, poiCountries) {
|
|
|
46747
46863
|
}
|
|
46748
46864
|
return best;
|
|
46749
46865
|
}
|
|
46866
|
+
function clampContainerToCluster(container, points) {
|
|
46867
|
+
const poi = unionExtent([], points);
|
|
46868
|
+
if (!poi) return container;
|
|
46869
|
+
let [[west, south], [east, north]] = container;
|
|
46870
|
+
const [[pWest, pSouth], [pEast, pNorth]] = poi;
|
|
46871
|
+
south = Math.max(south, pSouth - CONTAINER_OVERSHOOT_DEG);
|
|
46872
|
+
north = Math.min(north, pNorth + CONTAINER_OVERSHOOT_DEG);
|
|
46873
|
+
if (east <= 180 && pEast <= 180) {
|
|
46874
|
+
west = Math.max(west, pWest - CONTAINER_OVERSHOOT_DEG);
|
|
46875
|
+
east = Math.min(east, pEast + CONTAINER_OVERSHOOT_DEG);
|
|
46876
|
+
}
|
|
46877
|
+
return [
|
|
46878
|
+
[west, south],
|
|
46879
|
+
[east, north]
|
|
46880
|
+
];
|
|
46881
|
+
}
|
|
46750
46882
|
function pad(e, frac) {
|
|
46751
46883
|
const dLon = (e[1][0] - e[0][0]) * frac || 1;
|
|
46752
46884
|
const dLat = (e[1][1] - e[0][1]) * frac || 1;
|
|
@@ -46759,7 +46891,7 @@ function firstError(diags) {
|
|
|
46759
46891
|
const e = diags.find((d) => d.severity === "error");
|
|
46760
46892
|
return e ? formatDgmoError(e) : null;
|
|
46761
46893
|
}
|
|
46762
|
-
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;
|
|
46894
|
+
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;
|
|
46763
46895
|
var init_resolver2 = __esm({
|
|
46764
46896
|
"src/map/resolver.ts"() {
|
|
46765
46897
|
"use strict";
|
|
@@ -46772,6 +46904,7 @@ var init_resolver2 = __esm({
|
|
|
46772
46904
|
WORLD_LAT_SOUTH = -58;
|
|
46773
46905
|
WORLD_LAT_NORTH = 78;
|
|
46774
46906
|
POI_ZOOM_FLOOR_DEG = 7;
|
|
46907
|
+
CONTAINER_OVERSHOOT_DEG = 8;
|
|
46775
46908
|
US_NATIONAL_LON_SPAN = 48;
|
|
46776
46909
|
REGION_ALIASES = {
|
|
46777
46910
|
// Common everyday names → the Natural-Earth display name actually shipped.
|
|
@@ -46850,6 +46983,55 @@ var init_resolver2 = __esm({
|
|
|
46850
46983
|
}
|
|
46851
46984
|
});
|
|
46852
46985
|
|
|
46986
|
+
// src/map/legend-band.ts
|
|
46987
|
+
function mapLegendGroups(legend) {
|
|
46988
|
+
const ramp = legend.ramp;
|
|
46989
|
+
const scoreGroup = ramp ? {
|
|
46990
|
+
name: ramp.metric?.trim() || "Value",
|
|
46991
|
+
entries: [],
|
|
46992
|
+
gradient: {
|
|
46993
|
+
min: ramp.min,
|
|
46994
|
+
max: ramp.max,
|
|
46995
|
+
hue: ramp.hue,
|
|
46996
|
+
base: ramp.base
|
|
46997
|
+
}
|
|
46998
|
+
} : null;
|
|
46999
|
+
const tagGroups = legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
47000
|
+
return [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
47001
|
+
}
|
|
47002
|
+
function mapLegendConfig(groups, mode) {
|
|
47003
|
+
return {
|
|
47004
|
+
groups,
|
|
47005
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47006
|
+
mode,
|
|
47007
|
+
showEmptyGroups: false,
|
|
47008
|
+
showInactivePills: true
|
|
47009
|
+
};
|
|
47010
|
+
}
|
|
47011
|
+
function mapLegendTop(hasTitle, hasSubtitle) {
|
|
47012
|
+
return (hasTitle ? TITLE_Y + TITLE_FONT_SIZE : 0) + (hasSubtitle ? TITLE_FONT_SIZE : 0) + LEGEND_TOP_GAP2;
|
|
47013
|
+
}
|
|
47014
|
+
function mapLegendBand(legend, opts) {
|
|
47015
|
+
if (!legend) return 0;
|
|
47016
|
+
const groups = mapLegendGroups(legend);
|
|
47017
|
+
if (groups.length === 0) return 0;
|
|
47018
|
+
const config = mapLegendConfig(groups, opts.mode);
|
|
47019
|
+
const state = { activeGroup: legend.activeGroup };
|
|
47020
|
+
const { height } = computeLegendLayout(config, state, opts.width);
|
|
47021
|
+
if (height <= 0) return 0;
|
|
47022
|
+
return mapLegendTop(opts.hasTitle, opts.hasSubtitle) + height + LEGEND_BOTTOM_GAP2;
|
|
47023
|
+
}
|
|
47024
|
+
var LEGEND_TOP_GAP2, LEGEND_BOTTOM_GAP2;
|
|
47025
|
+
var init_legend_band = __esm({
|
|
47026
|
+
"src/map/legend-band.ts"() {
|
|
47027
|
+
"use strict";
|
|
47028
|
+
init_legend_layout();
|
|
47029
|
+
init_title_constants();
|
|
47030
|
+
LEGEND_TOP_GAP2 = 8;
|
|
47031
|
+
LEGEND_BOTTOM_GAP2 = 10;
|
|
47032
|
+
}
|
|
47033
|
+
});
|
|
47034
|
+
|
|
46853
47035
|
// src/map/colorize.ts
|
|
46854
47036
|
function assignColors(isos, adjacency) {
|
|
46855
47037
|
const sorted = [...isos].sort();
|
|
@@ -47279,6 +47461,38 @@ function parsePathRings(d) {
|
|
|
47279
47461
|
if (cur.length) rings.push(cur);
|
|
47280
47462
|
return rings;
|
|
47281
47463
|
}
|
|
47464
|
+
function dropAntimeridianWrapSlivers(d, width, height) {
|
|
47465
|
+
const rings = parsePathRings(d);
|
|
47466
|
+
if (rings.length <= 1) return d;
|
|
47467
|
+
const eps = 0.75;
|
|
47468
|
+
const minArea = 3e-3 * width * height;
|
|
47469
|
+
const ringArea = (r) => {
|
|
47470
|
+
let s = 0;
|
|
47471
|
+
for (let i = 0; i < r.length; i++) {
|
|
47472
|
+
const a = r[i];
|
|
47473
|
+
const b = r[(i + 1) % r.length];
|
|
47474
|
+
s += a[0] * b[1] - b[0] * a[1];
|
|
47475
|
+
}
|
|
47476
|
+
return Math.abs(s) / 2;
|
|
47477
|
+
};
|
|
47478
|
+
const areas = rings.map(ringArea);
|
|
47479
|
+
const maxArea = Math.max(...areas);
|
|
47480
|
+
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;
|
|
47481
|
+
let dropped = false;
|
|
47482
|
+
const kept = rings.filter((r, idx) => {
|
|
47483
|
+
if (areas[idx] >= maxArea || areas[idx] >= minArea) return true;
|
|
47484
|
+
const touches = r.some((p, i) => onVEdge(p, r[(i + 1) % r.length]));
|
|
47485
|
+
if (touches) {
|
|
47486
|
+
dropped = true;
|
|
47487
|
+
return false;
|
|
47488
|
+
}
|
|
47489
|
+
return true;
|
|
47490
|
+
});
|
|
47491
|
+
if (!dropped) return d;
|
|
47492
|
+
return kept.map(
|
|
47493
|
+
(r) => r.map((p, i) => (i ? "L" : "M") + p[0] + "," + p[1]).join("") + "Z"
|
|
47494
|
+
).join("");
|
|
47495
|
+
}
|
|
47282
47496
|
function layoutMap(resolved, data, size, opts) {
|
|
47283
47497
|
const { palette, isDark } = opts;
|
|
47284
47498
|
const { width, height } = size;
|
|
@@ -47362,7 +47576,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47362
47576
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
47363
47577
|
const fillForValue = (s) => {
|
|
47364
47578
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
47365
|
-
const pct =
|
|
47579
|
+
const pct = RAMP_FLOOR2 + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR2);
|
|
47366
47580
|
return mix(rampHue, rampBase, pct);
|
|
47367
47581
|
};
|
|
47368
47582
|
const tagFill = (tags, groupName) => {
|
|
@@ -47398,12 +47612,43 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47398
47612
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
47399
47613
|
};
|
|
47400
47614
|
const regionById = new Map(resolved.regions.map((r) => [r.iso, r]));
|
|
47615
|
+
let legend = null;
|
|
47616
|
+
if (!resolved.directives.noLegend) {
|
|
47617
|
+
const legendTagGroups = resolved.tagGroups.map((g) => ({
|
|
47618
|
+
name: g.name,
|
|
47619
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
47620
|
+
}));
|
|
47621
|
+
if (legendTagGroups.length > 0 || hasRamp) {
|
|
47622
|
+
legend = {
|
|
47623
|
+
tagGroups: legendTagGroups,
|
|
47624
|
+
activeGroup,
|
|
47625
|
+
...hasRamp && {
|
|
47626
|
+
ramp: {
|
|
47627
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47628
|
+
metric: resolved.directives.regionMetric
|
|
47629
|
+
},
|
|
47630
|
+
min: rampMin,
|
|
47631
|
+
max: rampMax,
|
|
47632
|
+
hue: rampHue,
|
|
47633
|
+
base: rampBase
|
|
47634
|
+
}
|
|
47635
|
+
}
|
|
47636
|
+
};
|
|
47637
|
+
}
|
|
47638
|
+
}
|
|
47401
47639
|
const TITLE_GAP2 = 16;
|
|
47402
47640
|
let topPad = FIT_PAD;
|
|
47403
47641
|
if (resolved.title && resolved.pois.length > 0) {
|
|
47404
47642
|
const bannerBottom = (resolved.subtitle ? TITLE_Y + TITLE_FONT_SIZE : TITLE_Y) + TITLE_FONT_SIZE / 2;
|
|
47405
47643
|
topPad = Math.max(FIT_PAD, bannerBottom + TITLE_GAP2);
|
|
47406
47644
|
}
|
|
47645
|
+
const legendBand = mapLegendBand(legend, {
|
|
47646
|
+
width,
|
|
47647
|
+
mode: opts.legendMode ?? "preview",
|
|
47648
|
+
hasTitle: Boolean(resolved.title),
|
|
47649
|
+
hasSubtitle: Boolean(resolved.subtitle)
|
|
47650
|
+
});
|
|
47651
|
+
if (legendBand > topPad) topPad = legendBand;
|
|
47407
47652
|
const fitBox = [
|
|
47408
47653
|
[FIT_PAD, topPad],
|
|
47409
47654
|
[
|
|
@@ -47421,10 +47666,11 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47421
47666
|
const by0 = cb[0][1];
|
|
47422
47667
|
const cw = cb[1][0] - bx0;
|
|
47423
47668
|
const ch = cb[1][1] - by0;
|
|
47424
|
-
const
|
|
47425
|
-
const
|
|
47426
|
-
const
|
|
47427
|
-
const
|
|
47669
|
+
const topReserve = resolved.title && resolved.pois.length > 0 || legendBand > 0 ? topPad : 0;
|
|
47670
|
+
const ox = 0;
|
|
47671
|
+
const oy = topReserve;
|
|
47672
|
+
const sx = cw > 0 ? width / cw : 1;
|
|
47673
|
+
const sy = ch > 0 ? (height - topReserve) / ch : 1;
|
|
47428
47674
|
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
47429
47675
|
const stretch = (x, y) => [
|
|
47430
47676
|
ox + (x - bx0) * sx,
|
|
@@ -47697,7 +47943,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47697
47943
|
const r = regionById.get(iso);
|
|
47698
47944
|
const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
|
|
47699
47945
|
if (!viewF) continue;
|
|
47700
|
-
const
|
|
47946
|
+
const raw = path(viewF) ?? "";
|
|
47947
|
+
const d = fitIsGlobal ? dropAntimeridianWrapSlivers(raw, width, height) : raw;
|
|
47701
47948
|
if (!d) continue;
|
|
47702
47949
|
const isThisLayer = r?.layer === layerKind;
|
|
47703
47950
|
const isForeign = layerKind === "country" && usContext && iso !== "US";
|
|
@@ -47714,6 +47961,9 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47714
47961
|
} else {
|
|
47715
47962
|
label = f.properties?.name;
|
|
47716
47963
|
}
|
|
47964
|
+
const labelAnchor = WORLD_LABEL_ANCHORS[iso];
|
|
47965
|
+
const c = labelAnchor ? project(labelAnchor[0], labelAnchor[1]) : path.centroid(viewF);
|
|
47966
|
+
const hasCentroid = c != null && Number.isFinite(c[0]) && Number.isFinite(c[1]);
|
|
47717
47967
|
regions.push({
|
|
47718
47968
|
id: iso,
|
|
47719
47969
|
d,
|
|
@@ -47722,6 +47972,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47722
47972
|
lineNumber,
|
|
47723
47973
|
layer,
|
|
47724
47974
|
...label !== void 0 && { label },
|
|
47975
|
+
...hasCentroid && { labelX: c[0], labelY: c[1] },
|
|
47725
47976
|
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
47726
47977
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
47727
47978
|
});
|
|
@@ -48162,10 +48413,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48162
48413
|
lineNumber
|
|
48163
48414
|
});
|
|
48164
48415
|
};
|
|
48165
|
-
const WORLD_LABEL_ANCHORS = {
|
|
48166
|
-
US: [-98.5, 39.5]
|
|
48167
|
-
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48168
|
-
};
|
|
48169
48416
|
const REGION_LABEL_GAP = 2;
|
|
48170
48417
|
const regionLabelRect = (cx, cy, text) => {
|
|
48171
48418
|
const w = measureLegendText(text, FONT2) + 2 * REGION_LABEL_GAP;
|
|
@@ -48483,30 +48730,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48483
48730
|
});
|
|
48484
48731
|
labels.push(...contextLabels);
|
|
48485
48732
|
}
|
|
48486
|
-
let legend = null;
|
|
48487
|
-
if (!resolved.directives.noLegend) {
|
|
48488
|
-
const tagGroups = resolved.tagGroups.map((g) => ({
|
|
48489
|
-
name: g.name,
|
|
48490
|
-
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
48491
|
-
}));
|
|
48492
|
-
if (tagGroups.length > 0 || hasRamp) {
|
|
48493
|
-
legend = {
|
|
48494
|
-
tagGroups,
|
|
48495
|
-
activeGroup,
|
|
48496
|
-
...hasRamp && {
|
|
48497
|
-
ramp: {
|
|
48498
|
-
...resolved.directives.regionMetric !== void 0 && {
|
|
48499
|
-
metric: resolved.directives.regionMetric
|
|
48500
|
-
},
|
|
48501
|
-
min: rampMin,
|
|
48502
|
-
max: rampMax,
|
|
48503
|
-
hue: rampHue,
|
|
48504
|
-
base: rampBase
|
|
48505
|
-
}
|
|
48506
|
-
}
|
|
48507
|
-
};
|
|
48508
|
-
}
|
|
48509
|
-
}
|
|
48510
48733
|
return {
|
|
48511
48734
|
width,
|
|
48512
48735
|
height,
|
|
@@ -48531,7 +48754,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48531
48754
|
diagnostics: []
|
|
48532
48755
|
};
|
|
48533
48756
|
}
|
|
48534
|
-
var import_d3_geo2, import_topojson_client2, FIT_PAD,
|
|
48757
|
+
var import_d3_geo2, import_topojson_client2, 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;
|
|
48535
48758
|
var init_layout15 = __esm({
|
|
48536
48759
|
"src/map/layout.ts"() {
|
|
48537
48760
|
"use strict";
|
|
@@ -48544,15 +48767,20 @@ var init_layout15 = __esm({
|
|
|
48544
48767
|
init_label_layout();
|
|
48545
48768
|
init_legend_constants();
|
|
48546
48769
|
init_title_constants();
|
|
48770
|
+
init_legend_band();
|
|
48547
48771
|
init_context_labels();
|
|
48548
48772
|
FIT_PAD = 24;
|
|
48549
|
-
|
|
48773
|
+
RAMP_FLOOR2 = 15;
|
|
48550
48774
|
R_DEFAULT = 6;
|
|
48551
48775
|
R_MIN = 4;
|
|
48552
48776
|
R_MAX = 22;
|
|
48553
48777
|
W_MIN = 1.25;
|
|
48554
48778
|
W_MAX = 8;
|
|
48555
48779
|
FONT2 = 11;
|
|
48780
|
+
WORLD_LABEL_ANCHORS = {
|
|
48781
|
+
US: [-98.5, 39.5]
|
|
48782
|
+
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48783
|
+
};
|
|
48556
48784
|
MAX_CLUSTER_EXTENT_FACTOR = 0.18;
|
|
48557
48785
|
MAX_COLUMN_ROWS = 7;
|
|
48558
48786
|
REGION_LABEL_HALO_RATIO = 4.5;
|
|
@@ -48566,9 +48794,9 @@ var init_layout15 = __esm({
|
|
|
48566
48794
|
COMPACT_WIDTH_PX = 480;
|
|
48567
48795
|
RELIEF_MIN_AREA = 12;
|
|
48568
48796
|
RELIEF_MIN_DIM = 2;
|
|
48569
|
-
RELIEF_HATCH_SPACING =
|
|
48570
|
-
RELIEF_HATCH_WIDTH = 0.
|
|
48571
|
-
RELIEF_HATCH_STRENGTH =
|
|
48797
|
+
RELIEF_HATCH_SPACING = 1.5;
|
|
48798
|
+
RELIEF_HATCH_WIDTH = 0.2;
|
|
48799
|
+
RELIEF_HATCH_STRENGTH = 26;
|
|
48572
48800
|
COASTLINE_RING_COUNT = 5;
|
|
48573
48801
|
COASTLINE_D0 = 16e-4;
|
|
48574
48802
|
COASTLINE_STEP = 28e-4;
|
|
@@ -48646,7 +48874,47 @@ function ringToPath(ring) {
|
|
|
48646
48874
|
d += (i ? "L" : "M") + ring[i][0] + "," + ring[i][1];
|
|
48647
48875
|
return d + "Z";
|
|
48648
48876
|
}
|
|
48649
|
-
function
|
|
48877
|
+
function polylineToPath(pts) {
|
|
48878
|
+
let d = "";
|
|
48879
|
+
for (let i = 0; i < pts.length; i++)
|
|
48880
|
+
d += (i ? "L" : "M") + pts[i][0] + "," + pts[i][1];
|
|
48881
|
+
return d;
|
|
48882
|
+
}
|
|
48883
|
+
function ringToCoastPaths(ring, frame) {
|
|
48884
|
+
if (!frame) return [ringToPath(ring)];
|
|
48885
|
+
const n = ring.length;
|
|
48886
|
+
const eps = 0.75;
|
|
48887
|
+
const onL = (x) => Math.abs(x) <= eps;
|
|
48888
|
+
const onR = (x) => Math.abs(x - frame.w) <= eps;
|
|
48889
|
+
const onT = (y) => Math.abs(y) <= eps;
|
|
48890
|
+
const onB = (y) => Math.abs(y - frame.h) <= eps;
|
|
48891
|
+
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]);
|
|
48892
|
+
let firstBreak = -1;
|
|
48893
|
+
for (let i = 0; i < n; i++)
|
|
48894
|
+
if (isFrameEdge(ring[i], ring[(i + 1) % n])) {
|
|
48895
|
+
firstBreak = i;
|
|
48896
|
+
break;
|
|
48897
|
+
}
|
|
48898
|
+
if (firstBreak === -1) return [ringToPath(ring)];
|
|
48899
|
+
const paths = [];
|
|
48900
|
+
let cur = [];
|
|
48901
|
+
const start = (firstBreak + 1) % n;
|
|
48902
|
+
for (let k = 0; k < n; k++) {
|
|
48903
|
+
const i = (start + k) % n;
|
|
48904
|
+
const a = ring[i];
|
|
48905
|
+
const b = ring[(i + 1) % n];
|
|
48906
|
+
if (isFrameEdge(a, b)) {
|
|
48907
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48908
|
+
cur = [];
|
|
48909
|
+
continue;
|
|
48910
|
+
}
|
|
48911
|
+
if (cur.length === 0) cur.push(a);
|
|
48912
|
+
cur.push(b);
|
|
48913
|
+
}
|
|
48914
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48915
|
+
return paths;
|
|
48916
|
+
}
|
|
48917
|
+
function coastlineOuterRings(regions, minExtent, frame) {
|
|
48650
48918
|
const paths = [];
|
|
48651
48919
|
for (const r of regions) {
|
|
48652
48920
|
const rings = parsePathRings(r.d);
|
|
@@ -48669,7 +48937,7 @@ function coastlineOuterRings(regions, minExtent) {
|
|
|
48669
48937
|
for (let j = 0; j < rings.length; j++)
|
|
48670
48938
|
if (j !== i && pointInRing2(fx, fy, rings[j])) depth++;
|
|
48671
48939
|
if (depth % 2 === 1) continue;
|
|
48672
|
-
paths.push(
|
|
48940
|
+
paths.push(...ringToCoastPaths(ring, frame));
|
|
48673
48941
|
}
|
|
48674
48942
|
}
|
|
48675
48943
|
return paths;
|
|
@@ -48699,6 +48967,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48699
48967
|
// stretch-distorting. The in-app preview pane passes no exportDims → unset →
|
|
48700
48968
|
// keeps the global stretch-fill.
|
|
48701
48969
|
preferContain: exportDims?.preferContain ?? false,
|
|
48970
|
+
// Reserve the legend band for the mode actually drawn below (export shows
|
|
48971
|
+
// only the active group; preview keeps the inactive pills).
|
|
48972
|
+
legendMode: exportDims ? "export" : "preview",
|
|
48702
48973
|
...activeGroupOverride !== void 0 && {
|
|
48703
48974
|
activeGroup: activeGroupOverride
|
|
48704
48975
|
}
|
|
@@ -48713,6 +48984,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48713
48984
|
const drawRegion = (g, r, strokeWidth) => {
|
|
48714
48985
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
48715
48986
|
if (r.label) p.attr("data-region-name", r.label);
|
|
48987
|
+
if (r.id && r.id !== "lake") p.attr("data-iso", r.id);
|
|
48988
|
+
if (r.labelX !== void 0 && r.labelY !== void 0) {
|
|
48989
|
+
p.attr("data-label-x", r.labelX).attr("data-label-y", r.labelY);
|
|
48990
|
+
}
|
|
48716
48991
|
if (r.layer !== "base") {
|
|
48717
48992
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
48718
48993
|
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
@@ -48742,7 +49017,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48742
49017
|
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
48743
49018
|
for (const r of layout.regions)
|
|
48744
49019
|
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
48745
|
-
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");
|
|
49020
|
+
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");
|
|
48746
49021
|
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
48747
49022
|
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
48748
49023
|
}
|
|
@@ -48763,10 +49038,16 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48763
49038
|
mask.append("path").attr("d", d).attr("fill", "black").attr("stroke", "black").attr("stroke-width", 2 * reach).attr("stroke-linejoin", "round");
|
|
48764
49039
|
}
|
|
48765
49040
|
}
|
|
48766
|
-
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").attr("mask", `url(#${maskId})`);
|
|
49041
|
+
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
|
|
48767
49042
|
appendWaterLines(
|
|
48768
49043
|
gWater,
|
|
48769
|
-
|
|
49044
|
+
// Pass the canvas frame so edges collinear with it (the antimeridian on a
|
|
49045
|
+
// world map, regional clipExtent cuts) don't get ringed as fake coast —
|
|
49046
|
+
// land runs cleanly to the render-area edge.
|
|
49047
|
+
coastlineOuterRings(layout.regions, cs.minExtent, {
|
|
49048
|
+
w: width,
|
|
49049
|
+
h: height
|
|
49050
|
+
}),
|
|
48770
49051
|
cs,
|
|
48771
49052
|
layout.background
|
|
48772
49053
|
);
|
|
@@ -48780,7 +49061,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48780
49061
|
gWater.append("path").attr("d", ds.join(" ")).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-linejoin", "round");
|
|
48781
49062
|
}
|
|
48782
49063
|
if (layout.rivers.length) {
|
|
48783
|
-
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
49064
|
+
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none").style("pointer-events", "none");
|
|
48784
49065
|
for (const r of layout.rivers) {
|
|
48785
49066
|
gRivers.append("path").attr("d", r.d).attr("stroke", r.color).attr("stroke-width", r.width).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
48786
49067
|
}
|
|
@@ -48821,7 +49102,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48821
49102
|
const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
|
|
48822
49103
|
clip.append("path").attr("d", d);
|
|
48823
49104
|
}
|
|
48824
|
-
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})`);
|
|
49105
|
+
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})`);
|
|
48825
49106
|
appendWaterLines(
|
|
48826
49107
|
gInsetWater,
|
|
48827
49108
|
coastlineOuterRings(layout.insetRegions, cs.minExtent),
|
|
@@ -48980,30 +49261,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48980
49261
|
if (layout.legend) {
|
|
48981
49262
|
const legendY = (layout.title ? TITLE_Y + TITLE_FONT_SIZE : 0) + (layout.subtitle ? TITLE_FONT_SIZE : 0) + 8;
|
|
48982
49263
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
48983
|
-
const
|
|
48984
|
-
const scoreGroup = ramp ? {
|
|
48985
|
-
name: ramp.metric?.trim() || "Value",
|
|
48986
|
-
entries: [],
|
|
48987
|
-
gradient: {
|
|
48988
|
-
min: ramp.min,
|
|
48989
|
-
max: ramp.max,
|
|
48990
|
-
hue: ramp.hue,
|
|
48991
|
-
base: ramp.base
|
|
48992
|
-
}
|
|
48993
|
-
} : null;
|
|
48994
|
-
const tagGroups = layout.legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
48995
|
-
const groups = [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
49264
|
+
const groups = mapLegendGroups(layout.legend);
|
|
48996
49265
|
if (groups.length > 0) {
|
|
48997
|
-
const config =
|
|
49266
|
+
const config = mapLegendConfig(
|
|
48998
49267
|
groups,
|
|
48999
|
-
|
|
49000
|
-
|
|
49001
|
-
showEmptyGroups: false,
|
|
49002
|
-
// Keep inactive siblings visible as pills so the user can click to flip
|
|
49003
|
-
// the active colouring dimension (preview only — export shows just the
|
|
49004
|
-
// active group).
|
|
49005
|
-
showInactivePills: true
|
|
49006
|
-
};
|
|
49268
|
+
exportDims ? "export" : "preview"
|
|
49269
|
+
);
|
|
49007
49270
|
const state = { activeGroup: layout.legend.activeGroup };
|
|
49008
49271
|
renderLegendD3(legendG, config, state, palette, isDark, void 0, width);
|
|
49009
49272
|
}
|
|
@@ -49048,6 +49311,7 @@ var init_renderer16 = __esm({
|
|
|
49048
49311
|
init_title_constants();
|
|
49049
49312
|
init_color_utils();
|
|
49050
49313
|
init_legend_d3();
|
|
49314
|
+
init_legend_band();
|
|
49051
49315
|
init_layout15();
|
|
49052
49316
|
LABEL_FONT = 11;
|
|
49053
49317
|
}
|
|
@@ -49068,9 +49332,10 @@ function mapContentAspect(resolved, data, ref = REF) {
|
|
|
49068
49332
|
const aspect = w / h;
|
|
49069
49333
|
return Number.isFinite(aspect) && aspect > 0 ? aspect : FALLBACK_ASPECT;
|
|
49070
49334
|
}
|
|
49071
|
-
function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
49072
|
-
const
|
|
49073
|
-
const
|
|
49335
|
+
function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
49336
|
+
const useOverride = aspectOverride !== void 0 && Number.isFinite(aspectOverride) && aspectOverride > 0;
|
|
49337
|
+
const raw = useOverride ? aspectOverride : mapContentAspect(resolved, data);
|
|
49338
|
+
const clamped = useOverride ? raw : Math.max(ASPECT_MIN, Math.min(ASPECT_MAX, raw));
|
|
49074
49339
|
const width = baseWidth;
|
|
49075
49340
|
let height = Math.round(width / clamped);
|
|
49076
49341
|
let chromeReserve = 0;
|
|
@@ -49083,7 +49348,7 @@ function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
|
49083
49348
|
height = Math.round(chromeReserve + MIN_MAP_BAND);
|
|
49084
49349
|
floored = true;
|
|
49085
49350
|
}
|
|
49086
|
-
const preferContain = clamped !== raw || floored;
|
|
49351
|
+
const preferContain = useOverride ? floored : clamped !== raw || floored;
|
|
49087
49352
|
return { width, height, preferContain };
|
|
49088
49353
|
}
|
|
49089
49354
|
var import_d3_geo3, FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
@@ -54790,7 +55055,6 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
54790
55055
|
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
54791
55056
|
const {
|
|
54792
55057
|
width,
|
|
54793
|
-
height,
|
|
54794
55058
|
tooltip,
|
|
54795
55059
|
solid,
|
|
54796
55060
|
textColor,
|
|
@@ -54839,10 +55103,11 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
|
|
|
54839
55103
|
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
54840
55104
|
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
54841
55105
|
const innerWidth = width - margin.left - margin.right;
|
|
54842
|
-
const
|
|
54843
|
-
const
|
|
55106
|
+
const rowH = ctx.structural(28);
|
|
55107
|
+
const innerHeight = rowH * sorted.length;
|
|
55108
|
+
const usedHeight = margin.top + innerHeight + margin.bottom;
|
|
54844
55109
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
54845
|
-
const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height",
|
|
55110
|
+
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);
|
|
54846
55111
|
if (ctx.isBelowFloor) {
|
|
54847
55112
|
svg.attr("width", "100%");
|
|
54848
55113
|
}
|
|
@@ -57363,7 +57628,12 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
57363
57628
|
}
|
|
57364
57629
|
}
|
|
57365
57630
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
57366
|
-
const dims2 = mapExportDimensions2(
|
|
57631
|
+
const dims2 = mapExportDimensions2(
|
|
57632
|
+
mapResolved,
|
|
57633
|
+
mapData,
|
|
57634
|
+
EXPORT_WIDTH,
|
|
57635
|
+
options?.mapAspect
|
|
57636
|
+
);
|
|
57367
57637
|
const container2 = createExportContainer(dims2.width, dims2.height);
|
|
57368
57638
|
renderMapForExport2(
|
|
57369
57639
|
container2,
|
|
@@ -58156,8 +58426,10 @@ __export(index_exports, {
|
|
|
58156
58426
|
decodeDiagramUrl: () => decodeDiagramUrl2,
|
|
58157
58427
|
encodeDiagramUrl: () => encodeDiagramUrl2,
|
|
58158
58428
|
formatDgmoError: () => formatDgmoError,
|
|
58429
|
+
getEmbedSvgViewBox: () => getEmbedSvgViewBox,
|
|
58159
58430
|
getMinDimensions: () => getMinDimensions,
|
|
58160
58431
|
getPalette: () => getPalette,
|
|
58432
|
+
normalizeSvgForEmbed: () => normalizeSvgForEmbed,
|
|
58161
58433
|
palettes: () => palettes,
|
|
58162
58434
|
render: () => render2,
|
|
58163
58435
|
themes: () => themes,
|
|
@@ -58529,6 +58801,134 @@ function extractInfraCounts(content) {
|
|
|
58529
58801
|
return { nodes: parsed.nodes.length };
|
|
58530
58802
|
}
|
|
58531
58803
|
|
|
58804
|
+
// src/utils/svg-embed.ts
|
|
58805
|
+
function normalizeSvgForEmbed(input) {
|
|
58806
|
+
let svg = input;
|
|
58807
|
+
const rootMatch = svg.match(/<svg[^>]*>/);
|
|
58808
|
+
const rootTag = rootMatch?.[0] ?? "";
|
|
58809
|
+
if (rootTag && !rootTag.includes("viewBox")) {
|
|
58810
|
+
const wh = rootTag.match(/width="(\d+)"[^>]*height="(\d+)"/);
|
|
58811
|
+
if (wh) {
|
|
58812
|
+
svg = svg.replace(/<svg/, `<svg viewBox="0 0 ${wh[1]} ${wh[2]}"`);
|
|
58813
|
+
}
|
|
58814
|
+
}
|
|
58815
|
+
const tight = computeBBox(svg);
|
|
58816
|
+
if (tight && tight.width > 0 && tight.height > 0) {
|
|
58817
|
+
const pad2 = 16;
|
|
58818
|
+
const vb = `${tight.x - pad2} ${tight.y - pad2} ${tight.width + pad2 * 2} ${tight.height + pad2 * 2}`;
|
|
58819
|
+
svg = svg.replace(/(<svg[^>]*?)viewBox="[^"]*"/, `$1viewBox="${vb}"`);
|
|
58820
|
+
}
|
|
58821
|
+
svg = svg.replace(/(<svg[^>]*?) width="[^"]*"/g, "$1");
|
|
58822
|
+
svg = svg.replace(/(<svg[^>]*?) height="[^"]*"/g, "$1");
|
|
58823
|
+
svg = svg.replace(/(<svg[^>]*?style="[^"]*?)background:[^;"]*;?\s*/g, "$1");
|
|
58824
|
+
svg = svg.replace(/<svg\s{2,}/g, "<svg ");
|
|
58825
|
+
return svg;
|
|
58826
|
+
}
|
|
58827
|
+
function getEmbedSvgViewBox(svg) {
|
|
58828
|
+
const tight = computeBBox(svg);
|
|
58829
|
+
if (!tight || tight.width <= 0 || tight.height <= 0) return null;
|
|
58830
|
+
const pad2 = 16;
|
|
58831
|
+
return {
|
|
58832
|
+
x: tight.x - pad2,
|
|
58833
|
+
y: tight.y - pad2,
|
|
58834
|
+
width: tight.width + pad2 * 2,
|
|
58835
|
+
height: tight.height + pad2 * 2
|
|
58836
|
+
};
|
|
58837
|
+
}
|
|
58838
|
+
function computeBBox(svg) {
|
|
58839
|
+
const xs = [];
|
|
58840
|
+
const ys = [];
|
|
58841
|
+
function push(x, y) {
|
|
58842
|
+
if (Number.isFinite(x) && Number.isFinite(y)) {
|
|
58843
|
+
xs.push(x);
|
|
58844
|
+
ys.push(y);
|
|
58845
|
+
}
|
|
58846
|
+
}
|
|
58847
|
+
function attr(tag, name) {
|
|
58848
|
+
const m = tag.match(new RegExp(`\\b${name}="([^"]*)"`));
|
|
58849
|
+
if (!m) return null;
|
|
58850
|
+
const n = parseFloat(m[1]);
|
|
58851
|
+
return Number.isFinite(n) ? n : null;
|
|
58852
|
+
}
|
|
58853
|
+
for (const m of svg.matchAll(/<rect\b[^>]*?\/?>/g)) {
|
|
58854
|
+
const tag = m[0];
|
|
58855
|
+
const x = attr(tag, "x");
|
|
58856
|
+
const y = attr(tag, "y");
|
|
58857
|
+
const w = attr(tag, "width");
|
|
58858
|
+
const h = attr(tag, "height");
|
|
58859
|
+
if (x !== null && y !== null && w !== null && h !== null) {
|
|
58860
|
+
push(x, y);
|
|
58861
|
+
push(x + w, y + h);
|
|
58862
|
+
}
|
|
58863
|
+
}
|
|
58864
|
+
for (const m of svg.matchAll(/<line\b[^>]*?\/?>/g)) {
|
|
58865
|
+
const tag = m[0];
|
|
58866
|
+
const x1 = attr(tag, "x1");
|
|
58867
|
+
const y1 = attr(tag, "y1");
|
|
58868
|
+
const x2 = attr(tag, "x2");
|
|
58869
|
+
const y2 = attr(tag, "y2");
|
|
58870
|
+
if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
|
|
58871
|
+
push(x1, y1);
|
|
58872
|
+
push(x2, y2);
|
|
58873
|
+
}
|
|
58874
|
+
}
|
|
58875
|
+
for (const m of svg.matchAll(/<circle\b[^>]*?\/?>/g)) {
|
|
58876
|
+
const tag = m[0];
|
|
58877
|
+
const cx = attr(tag, "cx");
|
|
58878
|
+
const cy = attr(tag, "cy");
|
|
58879
|
+
const r = attr(tag, "r");
|
|
58880
|
+
if (cx !== null && cy !== null && r !== null) {
|
|
58881
|
+
push(cx - r, cy - r);
|
|
58882
|
+
push(cx + r, cy + r);
|
|
58883
|
+
}
|
|
58884
|
+
}
|
|
58885
|
+
for (const m of svg.matchAll(/<ellipse\b[^>]*?\/?>/g)) {
|
|
58886
|
+
const tag = m[0];
|
|
58887
|
+
const cx = attr(tag, "cx");
|
|
58888
|
+
const cy = attr(tag, "cy");
|
|
58889
|
+
const rx = attr(tag, "rx");
|
|
58890
|
+
const ry = attr(tag, "ry");
|
|
58891
|
+
if (cx !== null && cy !== null && rx !== null && ry !== null) {
|
|
58892
|
+
push(cx - rx, cy - ry);
|
|
58893
|
+
push(cx + rx, cy + ry);
|
|
58894
|
+
}
|
|
58895
|
+
}
|
|
58896
|
+
for (const m of svg.matchAll(/<text\b([^>]*?)>([\s\S]*?)<\/text>/g)) {
|
|
58897
|
+
const tag = `<text${m[1]}>`;
|
|
58898
|
+
const text = m[2].replace(/<[^>]+>/g, "");
|
|
58899
|
+
const x = attr(tag, "x");
|
|
58900
|
+
const y = attr(tag, "y");
|
|
58901
|
+
if (x !== null && y !== null) {
|
|
58902
|
+
const w = text.length * 7;
|
|
58903
|
+
push(x - w / 2, y - 14);
|
|
58904
|
+
push(x + w / 2, y + 4);
|
|
58905
|
+
}
|
|
58906
|
+
}
|
|
58907
|
+
for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
|
|
58908
|
+
const d = m[1];
|
|
58909
|
+
const nums = d.match(/-?\d+(?:\.\d+)?/g);
|
|
58910
|
+
if (!nums) continue;
|
|
58911
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58912
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58913
|
+
}
|
|
58914
|
+
}
|
|
58915
|
+
for (const m of svg.matchAll(
|
|
58916
|
+
/<(?:polygon|polyline)\b[^>]*?\bpoints="([^"]+)"/g
|
|
58917
|
+
)) {
|
|
58918
|
+
const nums = m[1].match(/-?\d+(?:\.\d+)?/g);
|
|
58919
|
+
if (!nums) continue;
|
|
58920
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58921
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58922
|
+
}
|
|
58923
|
+
}
|
|
58924
|
+
if (xs.length === 0 || ys.length === 0) return null;
|
|
58925
|
+
const minX = Math.min(...xs);
|
|
58926
|
+
const maxX = Math.max(...xs);
|
|
58927
|
+
const minY = Math.min(...ys);
|
|
58928
|
+
const maxY = Math.max(...ys);
|
|
58929
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
58930
|
+
}
|
|
58931
|
+
|
|
58532
58932
|
// src/map/completion.ts
|
|
58533
58933
|
var fold2 = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
58534
58934
|
var groupThousands = (n) => String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
@@ -58653,8 +59053,10 @@ function decodeDiagramUrl2(url) {
|
|
|
58653
59053
|
decodeDiagramUrl,
|
|
58654
59054
|
encodeDiagramUrl,
|
|
58655
59055
|
formatDgmoError,
|
|
59056
|
+
getEmbedSvgViewBox,
|
|
58656
59057
|
getMinDimensions,
|
|
58657
59058
|
getPalette,
|
|
59059
|
+
normalizeSvgForEmbed,
|
|
58658
59060
|
palettes,
|
|
58659
59061
|
render,
|
|
58660
59062
|
themes,
|