@diagrammo/dgmo 0.32.1 → 0.34.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/.cursorrules +7 -2
- package/.github/copilot-instructions.md +7 -2
- package/.windsurfrules +7 -2
- package/SKILL.md +7 -2
- package/dist/advanced.cjs +1434 -443
- package/dist/advanced.d.cts +41 -1
- package/dist/advanced.d.ts +41 -1
- package/dist/advanced.js +1433 -443
- package/dist/auto.cjs +1242 -318
- package/dist/auto.js +91 -91
- package/dist/auto.mjs +1242 -318
- package/dist/cli.cjs +138 -136
- package/dist/index.cjs +1308 -317
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +1307 -317
- package/docs/ai-integration.md +7 -2
- package/docs/language-reference.md +39 -8
- package/package.json +2 -2
- package/src/advanced.ts +6 -1
- package/src/boxes-and-lines/label-placement.ts +339 -0
- package/src/boxes-and-lines/layout-grouped.ts +909 -0
- package/src/boxes-and-lines/layout-search.ts +34 -3
- package/src/boxes-and-lines/layout.ts +32 -7
- package/src/boxes-and-lines/parser.ts +3 -2
- package/src/boxes-and-lines/renderer.ts +67 -139
- package/src/c4/layout.ts +2 -1
- package/src/c4/parser.ts +3 -2
- package/src/c4/renderer.ts +3 -2
- package/src/cli.ts +68 -0
- package/src/er/parser.ts +2 -1
- package/src/er/renderer.ts +2 -1
- package/src/gantt/parser.ts +3 -5
- package/src/gantt/renderer.ts +7 -6
- package/src/index.ts +6 -1
- package/src/infra/parser.ts +2 -1
- package/src/infra/renderer.ts +4 -3
- package/src/journey-map/parser.ts +27 -8
- package/src/journey-map/renderer.ts +26 -9
- package/src/kanban/parser.ts +4 -3
- package/src/kanban/renderer.ts +6 -5
- package/src/map/completion.ts +116 -0
- package/src/map/layout.ts +4 -3
- package/src/map/parser.ts +3 -2
- package/src/mindmap/parser.ts +4 -3
- package/src/mindmap/renderer.ts +2 -1
- package/src/org/layout.ts +3 -2
- package/src/org/parser.ts +3 -2
- package/src/org/renderer.ts +5 -4
- package/src/pert/parser.ts +3 -2
- package/src/sequence/renderer.ts +10 -12
- package/src/sequence/tag-resolution.ts +2 -1
- package/src/sitemap/layout.ts +3 -2
- package/src/sitemap/parser.ts +36 -2
- package/src/sitemap/renderer.ts +12 -6
- package/src/timeline/renderer.ts +4 -3
- package/src/utils/legend-d3.ts +4 -3
- package/src/utils/legend-svg.ts +3 -2
- package/src/utils/tag-groups.ts +28 -7
- package/src/visualizations/parse.ts +2 -1
package/dist/advanced.cjs
CHANGED
|
@@ -1255,6 +1255,9 @@ var init_parsing = __esm({
|
|
|
1255
1255
|
});
|
|
1256
1256
|
|
|
1257
1257
|
// src/utils/tag-groups.ts
|
|
1258
|
+
function tagAttrKey(name) {
|
|
1259
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1260
|
+
}
|
|
1258
1261
|
function stripDefaultModifier(text) {
|
|
1259
1262
|
if (/\bdefault\s*$/.test(text)) {
|
|
1260
1263
|
return { text: text.replace(/\s+default\s*$/, "").trim(), isDefault: true };
|
|
@@ -1400,17 +1403,17 @@ function parseTagDeclaration(line11) {
|
|
|
1400
1403
|
function resolveTagColor(metadata, tagGroups, activeGroupName, isContainer) {
|
|
1401
1404
|
if (!activeGroupName) return void 0;
|
|
1402
1405
|
const group = tagGroups.find(
|
|
1403
|
-
(g) => g.name
|
|
1406
|
+
(g) => tagAttrKey(g.name) === tagAttrKey(activeGroupName)
|
|
1404
1407
|
);
|
|
1405
1408
|
if (!group) return void 0;
|
|
1406
|
-
const metaValue = metadata[group.name
|
|
1409
|
+
const metaValue = metadata[tagAttrKey(group.name)] ?? (isContainer ? void 0 : group.defaultValue);
|
|
1407
1410
|
if (!metaValue) return "#999999";
|
|
1408
1411
|
return group.entries.find((e) => e.value.toLowerCase() === metaValue.toLowerCase())?.color ?? "#999999";
|
|
1409
1412
|
}
|
|
1410
1413
|
function validateTagValues(entities, tagGroups, pushWarning, suggestFn) {
|
|
1411
1414
|
if (tagGroups.length === 0) return;
|
|
1412
1415
|
const groupMap = /* @__PURE__ */ new Map();
|
|
1413
|
-
for (const g of tagGroups) groupMap.set(g.name
|
|
1416
|
+
for (const g of tagGroups) groupMap.set(tagAttrKey(g.name), g);
|
|
1414
1417
|
for (const entity of entities) {
|
|
1415
1418
|
for (const [key, value] of Object.entries(entity.metadata)) {
|
|
1416
1419
|
const group = groupMap.get(key);
|
|
@@ -1447,10 +1450,10 @@ function validateTagGroupNames(tagGroups, pushWarning, pushError) {
|
|
|
1447
1450
|
`'none' is a reserved keyword and cannot be used as a tag group name`
|
|
1448
1451
|
);
|
|
1449
1452
|
}
|
|
1450
|
-
if (!VALID_TAG_IDENT_RE.test(group.name)) {
|
|
1453
|
+
if (!VALID_TAG_IDENT_RE.test(tagAttrKey(group.name))) {
|
|
1451
1454
|
report(
|
|
1452
1455
|
group.lineNumber,
|
|
1453
|
-
`Tag group name "${group.name}"
|
|
1456
|
+
`Tag group name "${group.name}" can't form a valid key \u2014 use letters, digits, underscore, or hyphen, and quote a multi-word name (e.g. tag "Trust Zone" as tz)`
|
|
1454
1457
|
);
|
|
1455
1458
|
}
|
|
1456
1459
|
if (group.alias != null && !VALID_TAG_IDENT_RE.test(group.alias)) {
|
|
@@ -1462,7 +1465,7 @@ function validateTagGroupNames(tagGroups, pushWarning, pushError) {
|
|
|
1462
1465
|
}
|
|
1463
1466
|
}
|
|
1464
1467
|
function cascadeTagMetadata(roots, tagGroups) {
|
|
1465
|
-
const keys = tagGroups.map((g) => g.name
|
|
1468
|
+
const keys = tagGroups.map((g) => tagAttrKey(g.name));
|
|
1466
1469
|
if (keys.length === 0) return;
|
|
1467
1470
|
const walk = (node, inherited) => {
|
|
1468
1471
|
const childInherited = { ...inherited };
|
|
@@ -1483,7 +1486,7 @@ function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
|
1483
1486
|
for (const group of tagGroups) {
|
|
1484
1487
|
if (group.defaultValue) {
|
|
1485
1488
|
defaults.push({
|
|
1486
|
-
key: group.name
|
|
1489
|
+
key: tagAttrKey(group.name),
|
|
1487
1490
|
value: group.defaultValue
|
|
1488
1491
|
});
|
|
1489
1492
|
}
|
|
@@ -2874,7 +2877,7 @@ function parseVisualizationFull(content, palette) {
|
|
|
2874
2877
|
);
|
|
2875
2878
|
for (const group of result.timelineTagGroups) {
|
|
2876
2879
|
if (!group.defaultValue) continue;
|
|
2877
|
-
const key = group.name
|
|
2880
|
+
const key = tagAttrKey(group.name);
|
|
2878
2881
|
for (const event of result.timelineEvents) {
|
|
2879
2882
|
if (!event.metadata[key]) {
|
|
2880
2883
|
event.metadata[key] = group.defaultValue;
|
|
@@ -5270,7 +5273,7 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
5270
5273
|
};
|
|
5271
5274
|
}
|
|
5272
5275
|
function renderCapsule(parent, capsule, palette, groupBg, pillBorder, isDark, callbacks) {
|
|
5273
|
-
const g = parent.append("g").attr("transform", `translate(${capsule.x},${capsule.y})`).attr("data-legend-group", capsule.groupName
|
|
5276
|
+
const g = parent.append("g").attr("transform", `translate(${capsule.x},${capsule.y})`).attr("data-legend-group", tagAttrKey(capsule.groupName)).style("cursor", "pointer");
|
|
5274
5277
|
g.append("rect").attr("width", capsule.width).attr("height", capsule.height).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
5275
5278
|
const pill = capsule.pill;
|
|
5276
5279
|
g.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", palette.bg);
|
|
@@ -5278,7 +5281,7 @@ function renderCapsule(parent, capsule, palette, groupBg, pillBorder, isDark, ca
|
|
|
5278
5281
|
g.append("text").attr("x", pill.x + pill.width / 2).attr("y", LEGEND_HEIGHT / 2).attr("text-anchor", "middle").call(centerText).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", palette.text).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(capsule.groupName);
|
|
5279
5282
|
if (capsule.gradient) {
|
|
5280
5283
|
const gr = capsule.gradient;
|
|
5281
|
-
const gradId = `dgmo-legend-ramp-${capsule.groupName
|
|
5284
|
+
const gradId = `dgmo-legend-ramp-${tagAttrKey(capsule.groupName).replace(/[^a-z0-9]+/g, "-")}`;
|
|
5282
5285
|
const def = g.append("defs").append("linearGradient").attr("id", gradId);
|
|
5283
5286
|
for (const stop of valueRampStops(gr.low, gr.high, { isDark })) {
|
|
5284
5287
|
def.append("stop").attr("offset", `${stop.offset * 100}%`).attr("stop-color", stop.color);
|
|
@@ -5308,7 +5311,7 @@ function renderCapsule(parent, capsule, palette, groupBg, pillBorder, isDark, ca
|
|
|
5308
5311
|
}
|
|
5309
5312
|
}
|
|
5310
5313
|
function renderPill(parent, pill, palette, groupBg, callbacks) {
|
|
5311
|
-
const g = parent.append("g").attr("transform", `translate(${pill.x},${pill.y})`).attr("data-legend-group", pill.groupName
|
|
5314
|
+
const g = parent.append("g").attr("transform", `translate(${pill.x},${pill.y})`).attr("data-legend-group", tagAttrKey(pill.groupName)).style("cursor", "pointer");
|
|
5312
5315
|
g.append("rect").attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", groupBg);
|
|
5313
5316
|
g.append("text").attr("x", pill.width / 2).attr("y", pill.height / 2).attr("text-anchor", "middle").call(centerText).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", palette.textMuted).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(pill.groupName);
|
|
5314
5317
|
if (callbacks?.onGroupToggle) {
|
|
@@ -5414,6 +5417,7 @@ var LEGEND_TEXT_DY;
|
|
|
5414
5417
|
var init_legend_d3 = __esm({
|
|
5415
5418
|
"src/utils/legend-d3.ts"() {
|
|
5416
5419
|
"use strict";
|
|
5420
|
+
init_tag_groups();
|
|
5417
5421
|
init_legend_constants();
|
|
5418
5422
|
init_legend_layout();
|
|
5419
5423
|
init_color_utils();
|
|
@@ -9335,7 +9339,7 @@ function parseERDiagram(content, palette) {
|
|
|
9335
9339
|
);
|
|
9336
9340
|
for (const group of result.tagGroups) {
|
|
9337
9341
|
if (!group.defaultValue) continue;
|
|
9338
|
-
const key = group.name
|
|
9342
|
+
const key = tagAttrKey(group.name);
|
|
9339
9343
|
for (const table of result.tables) {
|
|
9340
9344
|
if (!table.metadata[key]) {
|
|
9341
9345
|
const mutableMeta = tableMetadataMap.get(table.id);
|
|
@@ -9565,12 +9569,12 @@ function parseOrg(content, palette) {
|
|
|
9565
9569
|
if (tagBlockMatch.alias) {
|
|
9566
9570
|
metaAliasMap.set(
|
|
9567
9571
|
normalizeName(tagBlockMatch.alias),
|
|
9568
|
-
tagBlockMatch.name
|
|
9572
|
+
tagAttrKey(tagBlockMatch.name)
|
|
9569
9573
|
);
|
|
9570
9574
|
}
|
|
9571
9575
|
metaAliasMap.set(
|
|
9572
9576
|
normalizeName(tagBlockMatch.name),
|
|
9573
|
-
tagBlockMatch.name
|
|
9577
|
+
tagAttrKey(tagBlockMatch.name)
|
|
9574
9578
|
);
|
|
9575
9579
|
result.tagGroups.push(currentTagGroup);
|
|
9576
9580
|
continue;
|
|
@@ -9956,12 +9960,12 @@ function parseSitemap(content, palette) {
|
|
|
9956
9960
|
if (tagBlockMatch.alias) {
|
|
9957
9961
|
metaAliasMap.set(
|
|
9958
9962
|
normalizeName(tagBlockMatch.alias),
|
|
9959
|
-
tagBlockMatch.name
|
|
9963
|
+
tagAttrKey(tagBlockMatch.name)
|
|
9960
9964
|
);
|
|
9961
9965
|
}
|
|
9962
9966
|
metaAliasMap.set(
|
|
9963
9967
|
normalizeName(tagBlockMatch.name),
|
|
9964
|
-
tagBlockMatch.name
|
|
9968
|
+
tagAttrKey(tagBlockMatch.name)
|
|
9965
9969
|
);
|
|
9966
9970
|
result.tagGroups.push(newTagGroup);
|
|
9967
9971
|
continue;
|
|
@@ -10131,6 +10135,14 @@ function parseSitemap(content, palette) {
|
|
|
10131
10135
|
continue;
|
|
10132
10136
|
}
|
|
10133
10137
|
}
|
|
10138
|
+
const enclosingContainer = nestedPageInsideContainer(indent, indentStack);
|
|
10139
|
+
if (enclosingContainer) {
|
|
10140
|
+
pushError(
|
|
10141
|
+
lineNumber,
|
|
10142
|
+
`Pages inside container '[${enclosingContainer}]' cannot have indented sub-pages. Containers hold a flat list of pages.`
|
|
10143
|
+
);
|
|
10144
|
+
continue;
|
|
10145
|
+
}
|
|
10134
10146
|
const node = parseNodeLabel2(
|
|
10135
10147
|
trimmed,
|
|
10136
10148
|
lineNumber,
|
|
@@ -10278,6 +10290,16 @@ function attachNode2(node, indent, indentStack, result) {
|
|
|
10278
10290
|
}
|
|
10279
10291
|
indentStack.push({ node, indent });
|
|
10280
10292
|
}
|
|
10293
|
+
function nestedPageInsideContainer(indent, indentStack) {
|
|
10294
|
+
let idx = indentStack.length - 1;
|
|
10295
|
+
while (idx >= 0 && indentStack[idx].indent >= indent) idx--;
|
|
10296
|
+
if (idx < 0) return null;
|
|
10297
|
+
if (indentStack[idx].node.isContainer) return null;
|
|
10298
|
+
for (let k = idx - 1; k >= 0; k--) {
|
|
10299
|
+
if (indentStack[k].node.isContainer) return indentStack[k].node.label;
|
|
10300
|
+
}
|
|
10301
|
+
return null;
|
|
10302
|
+
}
|
|
10281
10303
|
function findParentNode(indent, indentStack) {
|
|
10282
10304
|
for (let i = indentStack.length - 1; i >= 0; i--) {
|
|
10283
10305
|
if (indentStack[i].indent < indent) {
|
|
@@ -10861,12 +10883,12 @@ function parsePert(content, parseOpts = {}) {
|
|
|
10861
10883
|
if (tagBlockMatch.alias) {
|
|
10862
10884
|
metaAliasMap.set(
|
|
10863
10885
|
tagBlockMatch.alias.toLowerCase(),
|
|
10864
|
-
tagBlockMatch.name
|
|
10886
|
+
tagAttrKey(tagBlockMatch.name)
|
|
10865
10887
|
);
|
|
10866
10888
|
}
|
|
10867
10889
|
metaAliasMap.set(
|
|
10868
10890
|
normalizeName(tagBlockMatch.name),
|
|
10869
|
-
tagBlockMatch.name
|
|
10891
|
+
tagAttrKey(tagBlockMatch.name)
|
|
10870
10892
|
);
|
|
10871
10893
|
tagGroups.push(currentTagGroup);
|
|
10872
10894
|
if (tagBlockMatch.inlineValues) {
|
|
@@ -12331,10 +12353,10 @@ function emitCapsule(capsule, palette, groupBg, pillBorder) {
|
|
|
12331
12353
|
`<g data-legend-entry="${esc(entry.value.toLowerCase())}" data-series-name="${esc(entry.value)}" style="cursor:pointer"><circle cx="${entry.dotCx}" cy="${entry.dotCy}" r="${LEGEND_DOT_R}" fill="${esc(entry.color)}"/><text x="${entry.textX}" y="${entry.dotCy + LEGEND_ENTRY_FONT_SIZE / 2 - 1}" font-size="${LEGEND_ENTRY_FONT_SIZE}" fill="${esc(palette.textMuted)}" font-family="${esc(FONT_FAMILY)}">${esc(label)}</text></g>`
|
|
12332
12354
|
);
|
|
12333
12355
|
}
|
|
12334
|
-
return `<g transform="translate(${capsule.x},${capsule.y})" data-legend-group="${esc(capsule.groupName
|
|
12356
|
+
return `<g transform="translate(${capsule.x},${capsule.y})" data-legend-group="${esc(tagAttrKey(capsule.groupName))}" style="cursor:pointer">${inner.join("")}</g>`;
|
|
12335
12357
|
}
|
|
12336
12358
|
function emitPill(pill, palette, groupBg) {
|
|
12337
|
-
return `<g transform="translate(${pill.x},${pill.y})" data-legend-group="${esc(pill.groupName
|
|
12359
|
+
return `<g transform="translate(${pill.x},${pill.y})" data-legend-group="${esc(tagAttrKey(pill.groupName))}" style="cursor:pointer"><rect width="${pill.width}" height="${pill.height}" rx="${pill.height / 2}" fill="${esc(groupBg)}"/><text x="${pill.width / 2}" y="${pill.height / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2}" font-size="${LEGEND_PILL_FONT_SIZE}" font-weight="500" fill="${esc(palette.textMuted)}" text-anchor="middle" font-family="${esc(FONT_FAMILY)}">${esc(pill.groupName)}</text></g>`;
|
|
12338
12360
|
}
|
|
12339
12361
|
function renderLegendSvg(groups, options) {
|
|
12340
12362
|
if (groups.length === 0) return { svg: "", height: 0, width: 0 };
|
|
@@ -12395,6 +12417,7 @@ function renderLegendSvgFromConfig(config, state, palette, containerWidth) {
|
|
|
12395
12417
|
var init_legend_svg = __esm({
|
|
12396
12418
|
"src/utils/legend-svg.ts"() {
|
|
12397
12419
|
"use strict";
|
|
12420
|
+
init_tag_groups();
|
|
12398
12421
|
init_legend_constants();
|
|
12399
12422
|
init_legend_layout();
|
|
12400
12423
|
init_color_utils();
|
|
@@ -15085,12 +15108,12 @@ function parseKanban(content, palette) {
|
|
|
15085
15108
|
if (tagBlockMatch.alias) {
|
|
15086
15109
|
metaAliasMap.set(
|
|
15087
15110
|
normalizeName(tagBlockMatch.alias),
|
|
15088
|
-
tagBlockMatch.name
|
|
15111
|
+
tagAttrKey(tagBlockMatch.name)
|
|
15089
15112
|
);
|
|
15090
15113
|
}
|
|
15091
15114
|
metaAliasMap.set(
|
|
15092
15115
|
normalizeName(tagBlockMatch.name),
|
|
15093
|
-
tagBlockMatch.name
|
|
15116
|
+
tagAttrKey(tagBlockMatch.name)
|
|
15094
15117
|
);
|
|
15095
15118
|
result.tagGroups.push(currentTagGroup);
|
|
15096
15119
|
continue;
|
|
@@ -15279,7 +15302,7 @@ function parseKanban(content, palette) {
|
|
|
15279
15302
|
}
|
|
15280
15303
|
for (const group of result.tagGroups) {
|
|
15281
15304
|
const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
|
|
15282
|
-
tagValueSets.set(group.name
|
|
15305
|
+
tagValueSets.set(tagAttrKey(group.name), values);
|
|
15283
15306
|
}
|
|
15284
15307
|
for (const col of result.columns) {
|
|
15285
15308
|
if (col.wipLimit != null && col.cards.length > col.wipLimit) {
|
|
@@ -15541,12 +15564,12 @@ function parseC4(content, palette) {
|
|
|
15541
15564
|
if (tagBlockMatch.alias) {
|
|
15542
15565
|
metaAliasMap.set(
|
|
15543
15566
|
normalizeName(tagBlockMatch.alias),
|
|
15544
|
-
tagBlockMatch.name
|
|
15567
|
+
tagAttrKey(tagBlockMatch.name)
|
|
15545
15568
|
);
|
|
15546
15569
|
}
|
|
15547
15570
|
metaAliasMap.set(
|
|
15548
15571
|
normalizeName(tagBlockMatch.name),
|
|
15549
|
-
tagBlockMatch.name
|
|
15572
|
+
tagAttrKey(tagBlockMatch.name)
|
|
15550
15573
|
);
|
|
15551
15574
|
result.tagGroups.push(currentTagGroup);
|
|
15552
15575
|
continue;
|
|
@@ -17229,7 +17252,7 @@ function parseInfra(content) {
|
|
|
17229
17252
|
}
|
|
17230
17253
|
for (const tg of result.tagGroups) {
|
|
17231
17254
|
if (!tg.defaultValue) continue;
|
|
17232
|
-
const key = (tg.alias ?? tg.name)
|
|
17255
|
+
const key = tagAttrKey(tg.alias ?? tg.name);
|
|
17233
17256
|
for (const node of result.nodes) {
|
|
17234
17257
|
if (node.isEdge) continue;
|
|
17235
17258
|
if (!(key in node.tags)) {
|
|
@@ -17366,6 +17389,7 @@ var CONNECTION_RE, SIMPLE_CONNECTION_RE, ASYNC_CONNECTION_RE, ASYNC_SIMPLE_CONNE
|
|
|
17366
17389
|
var init_parser15 = __esm({
|
|
17367
17390
|
"src/infra/parser.ts"() {
|
|
17368
17391
|
"use strict";
|
|
17392
|
+
init_tag_groups();
|
|
17369
17393
|
init_diagnostics();
|
|
17370
17394
|
init_description_helpers();
|
|
17371
17395
|
init_arrows();
|
|
@@ -17911,13 +17935,10 @@ function parseGantt(content, palette) {
|
|
|
17911
17935
|
if (tagMatch.alias) {
|
|
17912
17936
|
metaAliasMap.set(
|
|
17913
17937
|
normalizeName(tagMatch.alias),
|
|
17914
|
-
tagMatch.name
|
|
17938
|
+
tagAttrKey(tagMatch.name)
|
|
17915
17939
|
);
|
|
17916
17940
|
}
|
|
17917
|
-
metaAliasMap.set(
|
|
17918
|
-
normalizeName(tagMatch.name),
|
|
17919
|
-
tagMatch.name.toLowerCase()
|
|
17920
|
-
);
|
|
17941
|
+
metaAliasMap.set(normalizeName(tagMatch.name), tagAttrKey(tagMatch.name));
|
|
17921
17942
|
continue;
|
|
17922
17943
|
}
|
|
17923
17944
|
const topWorkweekMatch = line11.match(WORKWEEK_RE);
|
|
@@ -18843,7 +18864,7 @@ function parseMap(content, palette) {
|
|
|
18843
18864
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
18844
18865
|
const open = { tag: null, route: null, poi: null };
|
|
18845
18866
|
const registry = () => withTagAliases(MAP_REGISTRY, new Set(aliasMap.keys()));
|
|
18846
|
-
const tagGroupNames = () => new Set(tagGroups.map((g) => g.name
|
|
18867
|
+
const tagGroupNames = () => new Set(tagGroups.map((g) => tagAttrKey(g.name)));
|
|
18847
18868
|
const closeBlocks = () => {
|
|
18848
18869
|
open.tag = null;
|
|
18849
18870
|
open.route = null;
|
|
@@ -19027,7 +19048,7 @@ function parseMap(content, palette) {
|
|
|
19027
19048
|
entries: [],
|
|
19028
19049
|
lineNumber: line11
|
|
19029
19050
|
};
|
|
19030
|
-
if (m.alias) aliasMap.set(m.alias.toLowerCase(), m.name
|
|
19051
|
+
if (m.alias) aliasMap.set(m.alias.toLowerCase(), tagAttrKey(m.name));
|
|
19031
19052
|
tagGroups.push(group);
|
|
19032
19053
|
open.tag = group;
|
|
19033
19054
|
if (m.inlineValues?.length) {
|
|
@@ -19560,12 +19581,12 @@ function parseBoxesAndLines(content, palette) {
|
|
|
19560
19581
|
if (tagBlockMatch.alias) {
|
|
19561
19582
|
metaAliasMap.set(
|
|
19562
19583
|
normalizeName(tagBlockMatch.alias),
|
|
19563
|
-
tagBlockMatch.name
|
|
19584
|
+
tagAttrKey(tagBlockMatch.name)
|
|
19564
19585
|
);
|
|
19565
19586
|
}
|
|
19566
19587
|
metaAliasMap.set(
|
|
19567
19588
|
normalizeName(tagBlockMatch.name),
|
|
19568
|
-
tagBlockMatch.name
|
|
19589
|
+
tagAttrKey(tagBlockMatch.name)
|
|
19569
19590
|
);
|
|
19570
19591
|
if (tagBlockMatch.inlineValues) {
|
|
19571
19592
|
for (const rawVal of tagBlockMatch.inlineValues) {
|
|
@@ -20306,12 +20327,12 @@ function parseMindmap(content, palette) {
|
|
|
20306
20327
|
if (tagBlockMatch.alias) {
|
|
20307
20328
|
aliasMap.set(
|
|
20308
20329
|
tagBlockMatch.alias.toLowerCase(),
|
|
20309
|
-
tagBlockMatch.name
|
|
20330
|
+
tagAttrKey(tagBlockMatch.name)
|
|
20310
20331
|
);
|
|
20311
20332
|
}
|
|
20312
20333
|
aliasMap.set(
|
|
20313
|
-
tagBlockMatch.name
|
|
20314
|
-
tagBlockMatch.name
|
|
20334
|
+
tagAttrKey(tagBlockMatch.name),
|
|
20335
|
+
tagAttrKey(tagBlockMatch.name)
|
|
20315
20336
|
);
|
|
20316
20337
|
result.tagGroups.push(currentTagGroup);
|
|
20317
20338
|
continue;
|
|
@@ -22020,7 +22041,18 @@ function parseJourneyMap(content, palette) {
|
|
|
22020
22041
|
palette
|
|
22021
22042
|
) ?? void 0;
|
|
22022
22043
|
} else {
|
|
22023
|
-
|
|
22044
|
+
const { label, colorName } = peelTrailingColorName(afterKeyword);
|
|
22045
|
+
if (colorName) {
|
|
22046
|
+
personaName = label;
|
|
22047
|
+
personaColor = resolveColorWithDiagnostic(
|
|
22048
|
+
colorName,
|
|
22049
|
+
lineNumber,
|
|
22050
|
+
result.diagnostics,
|
|
22051
|
+
palette
|
|
22052
|
+
) ?? void 0;
|
|
22053
|
+
} else {
|
|
22054
|
+
personaName = afterKeyword;
|
|
22055
|
+
}
|
|
22024
22056
|
}
|
|
22025
22057
|
}
|
|
22026
22058
|
if (!personaName) {
|
|
@@ -22063,12 +22095,12 @@ function parseJourneyMap(content, palette) {
|
|
|
22063
22095
|
if (tagBlockMatch.alias) {
|
|
22064
22096
|
aliasMap.set(
|
|
22065
22097
|
tagBlockMatch.alias.toLowerCase(),
|
|
22066
|
-
tagBlockMatch.name
|
|
22098
|
+
tagAttrKey(tagBlockMatch.name)
|
|
22067
22099
|
);
|
|
22068
22100
|
}
|
|
22069
22101
|
aliasMap.set(
|
|
22070
|
-
tagBlockMatch.name
|
|
22071
|
-
tagBlockMatch.name
|
|
22102
|
+
tagAttrKey(tagBlockMatch.name),
|
|
22103
|
+
tagAttrKey(tagBlockMatch.name)
|
|
22072
22104
|
);
|
|
22073
22105
|
result.tagGroups.push(currentTagGroup);
|
|
22074
22106
|
continue;
|
|
@@ -22212,7 +22244,7 @@ function parseJourneyMap(content, palette) {
|
|
|
22212
22244
|
}
|
|
22213
22245
|
for (const group of result.tagGroups) {
|
|
22214
22246
|
const values = new Set(group.entries.map((e) => e.value.toLowerCase()));
|
|
22215
|
-
tagValueSets.set(group.name
|
|
22247
|
+
tagValueSets.set(tagAttrKey(group.name), values);
|
|
22216
22248
|
}
|
|
22217
22249
|
const allSteps = hasPhases ? result.phases.flatMap((p) => p.steps) : result.steps;
|
|
22218
22250
|
for (const step of allSteps) {
|
|
@@ -24198,7 +24230,7 @@ function computeLegendGroups(tagGroups, showEyeIcons, usedValuesByGroup) {
|
|
|
24198
24230
|
const groups = [];
|
|
24199
24231
|
for (const group of tagGroups) {
|
|
24200
24232
|
if (group.entries.length === 0) continue;
|
|
24201
|
-
const usedValues = usedValuesByGroup?.get(group.name
|
|
24233
|
+
const usedValues = usedValuesByGroup?.get(tagAttrKey(group.name));
|
|
24202
24234
|
const visibleEntries = usedValues ? group.entries.filter((e) => usedValues.has(e.value.toLowerCase())) : group.entries;
|
|
24203
24235
|
if (visibleEntries.length === 0) continue;
|
|
24204
24236
|
const pillWidth2 = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
@@ -24811,7 +24843,7 @@ function layoutOrg(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, expan
|
|
|
24811
24843
|
const totalHeight = finalMaxY - minY + MARGIN * 2;
|
|
24812
24844
|
const usedValuesByGroup = /* @__PURE__ */ new Map();
|
|
24813
24845
|
for (const group of parsed.tagGroups) {
|
|
24814
|
-
const key = group.name
|
|
24846
|
+
const key = tagAttrKey(group.name);
|
|
24815
24847
|
const used = /* @__PURE__ */ new Set();
|
|
24816
24848
|
const walk = (node) => {
|
|
24817
24849
|
if (!node.isContainer && node.metadata[key]) {
|
|
@@ -24869,6 +24901,7 @@ var import_d3_hierarchy, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT, HEAD
|
|
|
24869
24901
|
var init_layout = __esm({
|
|
24870
24902
|
"src/org/layout.ts"() {
|
|
24871
24903
|
"use strict";
|
|
24904
|
+
init_tag_groups();
|
|
24872
24905
|
import_d3_hierarchy = require("d3-hierarchy");
|
|
24873
24906
|
init_tag_groups();
|
|
24874
24907
|
init_legend_constants();
|
|
@@ -25230,14 +25263,14 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
25230
25263
|
const contentG = mainG.append("g").attr("transform", `translate(0, ${contentYShift})`);
|
|
25231
25264
|
const displayNames = /* @__PURE__ */ new Map();
|
|
25232
25265
|
for (const group of parsed.tagGroups) {
|
|
25233
|
-
displayNames.set(group.name
|
|
25266
|
+
displayNames.set(tagAttrKey(group.name), group.name);
|
|
25234
25267
|
}
|
|
25235
25268
|
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
25236
25269
|
const colorOff = parsed.options?.["color"] === "off";
|
|
25237
25270
|
for (const c of layout.containers) {
|
|
25238
25271
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
25239
25272
|
if (activeTagGroup) {
|
|
25240
|
-
const tagKey = activeTagGroup
|
|
25273
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
25241
25274
|
const metaValue = c.tagMetadata[tagKey];
|
|
25242
25275
|
if (metaValue) {
|
|
25243
25276
|
cG.attr(`data-tag-${tagKey}`, metaValue.toLowerCase());
|
|
@@ -25319,7 +25352,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
25319
25352
|
if (containerNodeIds.has(node.id)) continue;
|
|
25320
25353
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x - node.width / 2}, ${node.y})`).attr("class", "org-node").attr("data-line-number", String(node.lineNumber));
|
|
25321
25354
|
if (activeTagGroup) {
|
|
25322
|
-
const tagKey = activeTagGroup
|
|
25355
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
25323
25356
|
const metaValue = node.tagMetadata[tagKey];
|
|
25324
25357
|
if (metaValue) {
|
|
25325
25358
|
nodeG.attr(`data-tag-${tagKey}`, metaValue.toLowerCase());
|
|
@@ -25492,7 +25525,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
25492
25525
|
const computedLayout = legendHandle.getLayout();
|
|
25493
25526
|
if (computedLayout.activeCapsule?.addonX != null) {
|
|
25494
25527
|
const capsule = computedLayout.activeCapsule;
|
|
25495
|
-
const groupKey2 = capsule.groupName
|
|
25528
|
+
const groupKey2 = tagAttrKey(capsule.groupName);
|
|
25496
25529
|
const isHidden = hiddenAttributes?.has(groupKey2) ?? false;
|
|
25497
25530
|
const activeGroupEl = legendParentBase.select(
|
|
25498
25531
|
`[data-legend-group="${groupKey2}"]`
|
|
@@ -25531,6 +25564,7 @@ var d3Selection6, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, ANCESTOR_DOT_R, ANCE
|
|
|
25531
25564
|
var init_renderer = __esm({
|
|
25532
25565
|
"src/org/renderer.ts"() {
|
|
25533
25566
|
"use strict";
|
|
25567
|
+
init_tag_groups();
|
|
25534
25568
|
d3Selection6 = __toESM(require("d3-selection"), 1);
|
|
25535
25569
|
init_fonts();
|
|
25536
25570
|
init_export_container();
|
|
@@ -25616,7 +25650,7 @@ function computeLegendGroups2(tagGroups, usedValuesByGroup) {
|
|
|
25616
25650
|
const groups = [];
|
|
25617
25651
|
for (const group of tagGroups) {
|
|
25618
25652
|
if (group.entries.length === 0) continue;
|
|
25619
|
-
const usedValues = usedValuesByGroup?.get(group.name
|
|
25653
|
+
const usedValues = usedValuesByGroup?.get(tagAttrKey(group.name));
|
|
25620
25654
|
const visibleEntries = usedValues ? group.entries.filter((e) => usedValues.has(e.value.toLowerCase())) : group.entries;
|
|
25621
25655
|
if (visibleEntries.length === 0) continue;
|
|
25622
25656
|
const pillWidth2 = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
@@ -26096,7 +26130,7 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
26096
26130
|
totalHeight += MARGIN2;
|
|
26097
26131
|
const usedValuesByGroup = /* @__PURE__ */ new Map();
|
|
26098
26132
|
for (const group of parsed.tagGroups) {
|
|
26099
|
-
const key = group.name
|
|
26133
|
+
const key = tagAttrKey(group.name);
|
|
26100
26134
|
const used = /* @__PURE__ */ new Set();
|
|
26101
26135
|
const walk = (node) => {
|
|
26102
26136
|
if (!node.isContainer && node.metadata[key]) {
|
|
@@ -26140,6 +26174,7 @@ var import_dagre, LABEL_FONT_SIZE3, META_FONT_SIZE3, CONTAINER_LABEL_FONT_SIZE2,
|
|
|
26140
26174
|
var init_layout2 = __esm({
|
|
26141
26175
|
"src/sitemap/layout.ts"() {
|
|
26142
26176
|
"use strict";
|
|
26177
|
+
init_tag_groups();
|
|
26143
26178
|
import_dagre = __toESM(require("@dagrejs/dagre"), 1);
|
|
26144
26179
|
init_tag_groups();
|
|
26145
26180
|
init_legend_constants();
|
|
@@ -26409,10 +26444,10 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
26409
26444
|
const displayNames = /* @__PURE__ */ new Map();
|
|
26410
26445
|
const tagColors = /* @__PURE__ */ new Map();
|
|
26411
26446
|
for (const group of parsed.tagGroups) {
|
|
26412
|
-
displayNames.set(group.name
|
|
26447
|
+
displayNames.set(tagAttrKey(group.name), group.name);
|
|
26413
26448
|
for (const entry of group.entries) {
|
|
26414
26449
|
tagColors.set(
|
|
26415
|
-
`${group.name
|
|
26450
|
+
`${tagAttrKey(group.name)}:${entry.value.toLowerCase()}`,
|
|
26416
26451
|
entry.color
|
|
26417
26452
|
);
|
|
26418
26453
|
}
|
|
@@ -26429,7 +26464,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
26429
26464
|
);
|
|
26430
26465
|
}
|
|
26431
26466
|
if (activeTagGroup) {
|
|
26432
|
-
const tagKey = activeTagGroup
|
|
26467
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
26433
26468
|
const tagVal = c.tagMetadata[tagKey];
|
|
26434
26469
|
if (tagVal) cG.attr(`data-tag-${tagKey}`, tagVal.toLowerCase());
|
|
26435
26470
|
}
|
|
@@ -26492,7 +26527,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
26492
26527
|
nodeG.style("cursor", "pointer").on("click", () => onClickItem(node.lineNumber));
|
|
26493
26528
|
}
|
|
26494
26529
|
if (activeTagGroup) {
|
|
26495
|
-
const tagKey = activeTagGroup
|
|
26530
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
26496
26531
|
const tagVal = node.tagMetadata[tagKey];
|
|
26497
26532
|
if (tagVal) nodeG.attr(`data-tag-${tagKey}`, tagVal.toLowerCase());
|
|
26498
26533
|
}
|
|
@@ -26619,7 +26654,7 @@ function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fix
|
|
|
26619
26654
|
const computedLayout = legendHandle.getLayout();
|
|
26620
26655
|
if (computedLayout.activeCapsule?.addonX != null) {
|
|
26621
26656
|
const capsule = computedLayout.activeCapsule;
|
|
26622
|
-
const groupKey2 = capsule.groupName
|
|
26657
|
+
const groupKey2 = tagAttrKey(capsule.groupName);
|
|
26623
26658
|
const isHidden = hiddenAttributes?.has(groupKey2) ?? false;
|
|
26624
26659
|
const activeGroupEl = parent.select(`[data-legend-group="${groupKey2}"]`);
|
|
26625
26660
|
if (!activeGroupEl.empty()) {
|
|
@@ -26684,6 +26719,7 @@ var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHE
|
|
|
26684
26719
|
var init_renderer2 = __esm({
|
|
26685
26720
|
"src/sitemap/renderer.ts"() {
|
|
26686
26721
|
"use strict";
|
|
26722
|
+
init_tag_groups();
|
|
26687
26723
|
d3Selection7 = __toESM(require("d3-selection"), 1);
|
|
26688
26724
|
d3Shape2 = __toESM(require("d3-shape"), 1);
|
|
26689
26725
|
init_fonts();
|
|
@@ -26822,7 +26858,7 @@ function resolveCardTagMeta(card, tagGroups, hiddenMetaGroups) {
|
|
|
26822
26858
|
const meta = [];
|
|
26823
26859
|
for (const group of tagGroups) {
|
|
26824
26860
|
if (hiddenMetaGroups?.includes(group.name.toLowerCase())) continue;
|
|
26825
|
-
const tagValue = card.tags[group.name
|
|
26861
|
+
const tagValue = card.tags[tagAttrKey(group.name)];
|
|
26826
26862
|
const value = tagValue ?? group.defaultValue;
|
|
26827
26863
|
if (!value) continue;
|
|
26828
26864
|
const entry = group.entries.find(
|
|
@@ -26842,7 +26878,7 @@ function resolveCardTagColor(card, tagGroups, activeTagGroup) {
|
|
|
26842
26878
|
(g) => g.name.toLowerCase() === activeTagGroup.toLowerCase()
|
|
26843
26879
|
);
|
|
26844
26880
|
if (!group) return card.color;
|
|
26845
|
-
const tagValue = card.tags[group.name
|
|
26881
|
+
const tagValue = card.tags[tagAttrKey(group.name)];
|
|
26846
26882
|
const value = tagValue ?? group.defaultValue;
|
|
26847
26883
|
if (!value) return void 0;
|
|
26848
26884
|
const entry = group.entries.find(
|
|
@@ -27152,7 +27188,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
|
|
|
27152
27188
|
);
|
|
27153
27189
|
const cg = g.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
|
|
27154
27190
|
if (activeTagGroup) {
|
|
27155
|
-
const tagKey = activeTagGroup
|
|
27191
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
27156
27192
|
const tagValue = card.tags[tagKey];
|
|
27157
27193
|
const group = parsed.tagGroups.find(
|
|
27158
27194
|
(tg) => tg.name.toLowerCase() === tagKey
|
|
@@ -27213,7 +27249,7 @@ function drawSwimlaneIcon(parent, x, y, isActive, palette) {
|
|
|
27213
27249
|
return iconG;
|
|
27214
27250
|
}
|
|
27215
27251
|
function bucketCardsBySwimlane(columns, swimlaneGroup) {
|
|
27216
|
-
const tagKey = swimlaneGroup.name
|
|
27252
|
+
const tagKey = tagAttrKey(swimlaneGroup.name);
|
|
27217
27253
|
const buckets = /* @__PURE__ */ new Map();
|
|
27218
27254
|
for (const entry of swimlaneGroup.entries) {
|
|
27219
27255
|
buckets.set(entry.value.toLowerCase(), {
|
|
@@ -27501,7 +27537,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
|
|
|
27501
27537
|
);
|
|
27502
27538
|
const cg = parent.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
|
|
27503
27539
|
if (activeTagGroup) {
|
|
27504
|
-
const tagKey = activeTagGroup
|
|
27540
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
27505
27541
|
const group = tagGroups.find((tg) => tg.name.toLowerCase() === tagKey);
|
|
27506
27542
|
const value = card.tags[tagKey] ?? group?.defaultValue;
|
|
27507
27543
|
if (value) {
|
|
@@ -27534,6 +27570,7 @@ var d3Selection8, DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PAD
|
|
|
27534
27570
|
var init_renderer3 = __esm({
|
|
27535
27571
|
"src/kanban/renderer.ts"() {
|
|
27536
27572
|
"use strict";
|
|
27573
|
+
init_tag_groups();
|
|
27537
27574
|
d3Selection8 = __toESM(require("d3-selection"), 1);
|
|
27538
27575
|
init_fonts();
|
|
27539
27576
|
init_color_utils();
|
|
@@ -28516,7 +28553,7 @@ function classifyEREntities(tables, relationships) {
|
|
|
28516
28553
|
const variance = indegreeValues.reduce((a, b) => a + (b - mean) ** 2, 0) / indegreeValues.length;
|
|
28517
28554
|
const stddev = Math.sqrt(variance);
|
|
28518
28555
|
const sorted = [...indegreeValues].sort((a, b) => a - b);
|
|
28519
|
-
const
|
|
28556
|
+
const median2 = sorted.length % 2 === 0 ? (sorted[sorted.length / 2 - 1] + sorted[sorted.length / 2]) / 2 : sorted[Math.floor(sorted.length / 2)];
|
|
28520
28557
|
for (const table of tables) {
|
|
28521
28558
|
const id = table.id;
|
|
28522
28559
|
const cols = table.columns;
|
|
@@ -28557,7 +28594,7 @@ function classifyEREntities(tables, relationships) {
|
|
|
28557
28594
|
const nameMatchesLookup = LOOKUP_NAME_SUFFIXES.some(
|
|
28558
28595
|
(s) => nameLower.endsWith(s)
|
|
28559
28596
|
);
|
|
28560
|
-
if (nameMatchesLookup && cols.length <= 6 && fkCount <= 1 && indegree >
|
|
28597
|
+
if (nameMatchesLookup && cols.length <= 6 && fkCount <= 1 && indegree > median2) {
|
|
28561
28598
|
result.set(id, "lookup");
|
|
28562
28599
|
continue;
|
|
28563
28600
|
}
|
|
@@ -28796,7 +28833,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
28796
28833
|
seriesColors2[ni % seriesColors2.length];
|
|
28797
28834
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "er-table").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
28798
28835
|
if (activeTagGroup) {
|
|
28799
|
-
const tagKey = activeTagGroup
|
|
28836
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
28800
28837
|
const tagValue = node.metadata[tagKey];
|
|
28801
28838
|
if (tagValue) {
|
|
28802
28839
|
nodeG.attr(`data-tag-${tagKey}`, tagValue.toLowerCase());
|
|
@@ -28975,6 +29012,7 @@ var d3Selection10, d3Shape4, DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COL
|
|
|
28975
29012
|
var init_renderer5 = __esm({
|
|
28976
29013
|
"src/er/renderer.ts"() {
|
|
28977
29014
|
"use strict";
|
|
29015
|
+
init_tag_groups();
|
|
28978
29016
|
d3Selection10 = __toESM(require("d3-selection"), 1);
|
|
28979
29017
|
d3Shape4 = __toESM(require("d3-shape"), 1);
|
|
28980
29018
|
init_fonts();
|
|
@@ -29145,63 +29183,6 @@ function ensureArrowMarkers(defs, colors) {
|
|
|
29145
29183
|
).attr("fill", color);
|
|
29146
29184
|
}
|
|
29147
29185
|
}
|
|
29148
|
-
function edgePolylineMidpoint(points) {
|
|
29149
|
-
if (points.length === 0) return { x: 0, y: 0 };
|
|
29150
|
-
if (points.length === 1) return { x: points[0].x, y: points[0].y };
|
|
29151
|
-
let total = 0;
|
|
29152
|
-
const segLen = [];
|
|
29153
|
-
for (let k = 1; k < points.length; k++) {
|
|
29154
|
-
const len = Math.hypot(
|
|
29155
|
-
points[k].x - points[k - 1].x,
|
|
29156
|
-
points[k].y - points[k - 1].y
|
|
29157
|
-
);
|
|
29158
|
-
segLen.push(len);
|
|
29159
|
-
total += len;
|
|
29160
|
-
}
|
|
29161
|
-
let half = total / 2;
|
|
29162
|
-
for (let k = 1; k < points.length; k++) {
|
|
29163
|
-
const len = segLen[k - 1];
|
|
29164
|
-
if (half <= len || k === points.length - 1) {
|
|
29165
|
-
const t = len === 0 ? 0 : Math.min(1, half / len);
|
|
29166
|
-
return {
|
|
29167
|
-
x: points[k - 1].x + (points[k].x - points[k - 1].x) * t,
|
|
29168
|
-
y: points[k - 1].y + (points[k].y - points[k - 1].y) * t
|
|
29169
|
-
};
|
|
29170
|
-
}
|
|
29171
|
-
half -= len;
|
|
29172
|
-
}
|
|
29173
|
-
const last = points[points.length - 1];
|
|
29174
|
-
return { x: last.x, y: last.y };
|
|
29175
|
-
}
|
|
29176
|
-
function resolveEdgeLabelOverlaps(labels) {
|
|
29177
|
-
const MAX_PASSES = 8;
|
|
29178
|
-
const PAD = 4;
|
|
29179
|
-
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
29180
|
-
let moved = false;
|
|
29181
|
-
for (let i = 0; i < labels.length; i++) {
|
|
29182
|
-
for (let j = i + 1; j < labels.length; j++) {
|
|
29183
|
-
const a = labels[i];
|
|
29184
|
-
const b = labels[j];
|
|
29185
|
-
const dx = Math.abs(a.x - b.x);
|
|
29186
|
-
const dy = Math.abs(a.y - b.y);
|
|
29187
|
-
const overlapX = (a.width + b.width) / 2 + PAD - dx;
|
|
29188
|
-
const overlapY = (a.height + b.height) / 2 + PAD - dy;
|
|
29189
|
-
if (overlapX > 0 && overlapY > 0) {
|
|
29190
|
-
const shift = overlapY / 2 + 1;
|
|
29191
|
-
if (a.y < b.y) {
|
|
29192
|
-
a.y -= shift;
|
|
29193
|
-
b.y += shift;
|
|
29194
|
-
} else {
|
|
29195
|
-
a.y += shift;
|
|
29196
|
-
b.y -= shift;
|
|
29197
|
-
}
|
|
29198
|
-
moved = true;
|
|
29199
|
-
}
|
|
29200
|
-
}
|
|
29201
|
-
}
|
|
29202
|
-
if (!moved) break;
|
|
29203
|
-
}
|
|
29204
|
-
}
|
|
29205
29186
|
function renderBoxesAndLines(container, parsed, layout, palette, isDark, options) {
|
|
29206
29187
|
const {
|
|
29207
29188
|
onClickItem,
|
|
@@ -29408,8 +29389,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29408
29389
|
groupG.append("text").attr("class", "bl-group-label").attr("x", gx + group.width / 2).attr("y", gy + 18).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sGroupLabelFontSize).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
|
|
29409
29390
|
}
|
|
29410
29391
|
}
|
|
29411
|
-
const labelPositions = [];
|
|
29412
|
-
const edgeGroups = /* @__PURE__ */ new Map();
|
|
29413
29392
|
for (let i = 0; i < layout.edges.length; i++) {
|
|
29414
29393
|
const le = layout.edges[i];
|
|
29415
29394
|
const color = edgeColorMap.get(i) ?? palette.textMuted;
|
|
@@ -29428,7 +29407,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29428
29407
|
const nodeLayout = layoutNodeMap.get(le.source);
|
|
29429
29408
|
if (nodeLayout) {
|
|
29430
29409
|
const edgeG2 = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
|
|
29431
|
-
edgeGroups.set(i, edgeG2);
|
|
29432
29410
|
const markerId2 = `bl-arrow-${color.replace("#", "")}`;
|
|
29433
29411
|
const cx = nodeLayout.x;
|
|
29434
29412
|
const cy = nodeLayout.y;
|
|
@@ -29477,7 +29455,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29477
29455
|
}
|
|
29478
29456
|
if (points.length < 2) continue;
|
|
29479
29457
|
const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
|
|
29480
|
-
edgeGroups.set(i, edgeG);
|
|
29481
29458
|
const markerId = `bl-arrow-${color.replace("#", "")}`;
|
|
29482
29459
|
const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
|
|
29483
29460
|
const path = edgeG.append("path").attr("class", "bl-edge").attr("d", gen(points) ?? "").attr("fill", "none").attr("stroke", color).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`);
|
|
@@ -29485,31 +29462,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29485
29462
|
const revId = `bl-arrow-rev-${color.replace("#", "")}`;
|
|
29486
29463
|
path.attr("marker-start", `url(#${revId})`);
|
|
29487
29464
|
}
|
|
29488
|
-
if (le.label && le.points.length > 0) {
|
|
29489
|
-
const lw = measureText(le.label, sEdgeLabelFontSize);
|
|
29490
|
-
const labelH = sEdgeLabelFontSize + 6;
|
|
29491
|
-
const mid = edgePolylineMidpoint(le.points);
|
|
29492
|
-
let ly = mid.y;
|
|
29493
|
-
if (le.parallelCount > 1 && le.yOffset !== 0) {
|
|
29494
|
-
ly += (le.yOffset < 0 ? -labelH : labelH) * 0.5;
|
|
29495
|
-
}
|
|
29496
|
-
labelPositions.push({
|
|
29497
|
-
x: mid.x,
|
|
29498
|
-
y: ly,
|
|
29499
|
-
width: lw + 8,
|
|
29500
|
-
height: labelH,
|
|
29501
|
-
idx: i
|
|
29502
|
-
});
|
|
29503
|
-
}
|
|
29504
|
-
}
|
|
29505
|
-
resolveEdgeLabelOverlaps(labelPositions);
|
|
29506
|
-
for (const lp of labelPositions) {
|
|
29507
|
-
const le = layout.edges[lp.idx];
|
|
29508
|
-
if (!le.label) continue;
|
|
29509
|
-
const edgeG = edgeGroups.get(lp.idx);
|
|
29510
|
-
const target = edgeG ?? diagramG;
|
|
29511
|
-
target.append("rect").attr("x", lp.x - lp.width / 2).attr("y", lp.y - lp.height / 2).attr("width", lp.width).attr("height", lp.height).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85);
|
|
29512
|
-
target.append("text").attr("x", lp.x).attr("y", lp.y + sEdgeLabelFontSize / 3).attr("text-anchor", "middle").attr("font-size", sEdgeLabelFontSize).attr("fill", palette.textMuted).text(le.label);
|
|
29513
29465
|
}
|
|
29514
29466
|
for (const ln of layout.nodes) {
|
|
29515
29467
|
const node = nodeMap.get(ln.label);
|
|
@@ -29560,8 +29512,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29560
29512
|
nodeG.append("rect").attr("x", x).attr("y", y).attr("width", ln.width).attr("height", ln.height).attr("rx", NODE_RX).attr("ry", NODE_RX).attr("fill", colors.fill).attr("stroke", colors.stroke).attr("stroke-width", sNodeStrokeWidth);
|
|
29561
29513
|
const desc = node.description;
|
|
29562
29514
|
if (desc && desc.length > 0 && !hideDescriptions) {
|
|
29563
|
-
const
|
|
29564
|
-
const fitted = fitLabelToHeader(node.label, ln.width,
|
|
29515
|
+
const MAX_LABEL_LINES4 = 3;
|
|
29516
|
+
const fitted = fitLabelToHeader(node.label, ln.width, MAX_LABEL_LINES4);
|
|
29565
29517
|
const labelLines = fitted.lines;
|
|
29566
29518
|
const labelLineH = fitted.fontSize * 1.3;
|
|
29567
29519
|
const labelTotalH = labelLines.length * labelLineH;
|
|
@@ -29695,6 +29647,35 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
29695
29647
|
}
|
|
29696
29648
|
}
|
|
29697
29649
|
}
|
|
29650
|
+
const labelLayer = diagramG.append("g").attr("class", "bl-edge-labels");
|
|
29651
|
+
const labelLineHeight = sEdgeLabelFontSize * 1.3;
|
|
29652
|
+
for (const le of layout.edges) {
|
|
29653
|
+
if (!le.labelLines || le.labelLines.length === 0) continue;
|
|
29654
|
+
if (le.labelX === void 0 || le.labelY === void 0) continue;
|
|
29655
|
+
const lx = le.labelX;
|
|
29656
|
+
const ly = le.labelY;
|
|
29657
|
+
if (hidden.size > 0) {
|
|
29658
|
+
let isHidden = false;
|
|
29659
|
+
for (const [groupKey2, hiddenVals] of hidden) {
|
|
29660
|
+
const val = le.metadata[groupKey2];
|
|
29661
|
+
if (val && hiddenVals.has(val.toLowerCase())) {
|
|
29662
|
+
isHidden = true;
|
|
29663
|
+
break;
|
|
29664
|
+
}
|
|
29665
|
+
}
|
|
29666
|
+
if (isHidden) continue;
|
|
29667
|
+
}
|
|
29668
|
+
const lw = le.labelWidth ?? 0;
|
|
29669
|
+
const lh = le.labelHeight ?? sEdgeLabelFontSize + 6;
|
|
29670
|
+
const lines = le.labelLines;
|
|
29671
|
+
const labelG = labelLayer.append("g").attr("class", "bl-edge-label").attr("data-line-number", String(le.lineNumber));
|
|
29672
|
+
labelG.append("rect").attr("x", lx - lw / 2).attr("y", ly - lh / 2).attr("width", lw).attr("height", lh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.72);
|
|
29673
|
+
const text = labelG.append("text").attr("x", lx).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sEdgeLabelFontSize).attr("fill", palette.textMuted);
|
|
29674
|
+
const firstY = ly - (lines.length - 1) / 2 * labelLineHeight + sEdgeLabelFontSize / 3;
|
|
29675
|
+
lines.forEach((line11, k) => {
|
|
29676
|
+
text.append("tspan").attr("x", lx).attr("y", firstY + k * labelLineHeight).text(line11);
|
|
29677
|
+
});
|
|
29678
|
+
}
|
|
29698
29679
|
const hasDescriptions = parsed.nodes.some(
|
|
29699
29680
|
(n) => n.description && n.description.length > 0
|
|
29700
29681
|
);
|
|
@@ -29811,6 +29792,222 @@ var init_renderer6 = __esm({
|
|
|
29811
29792
|
}
|
|
29812
29793
|
});
|
|
29813
29794
|
|
|
29795
|
+
// src/boxes-and-lines/label-placement.ts
|
|
29796
|
+
function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE6, maxWidth = LABEL_MAX_WIDTH) {
|
|
29797
|
+
let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
|
|
29798
|
+
if (lines.length > MAX_LABEL_LINES) {
|
|
29799
|
+
const kept = lines.slice(0, MAX_LABEL_LINES - 1);
|
|
29800
|
+
const rest = lines.slice(MAX_LABEL_LINES - 1).join(" ");
|
|
29801
|
+
kept.push(truncateText(rest, fontSize, maxWidth));
|
|
29802
|
+
lines = kept;
|
|
29803
|
+
}
|
|
29804
|
+
let textW = 0;
|
|
29805
|
+
for (const ln of lines) {
|
|
29806
|
+
const w = measureText(ln, fontSize);
|
|
29807
|
+
if (w > textW) textW = w;
|
|
29808
|
+
}
|
|
29809
|
+
return {
|
|
29810
|
+
lines,
|
|
29811
|
+
width: textW + 2 * H_PAD,
|
|
29812
|
+
height: lines.length * fontSize * LABEL_LINE_HEIGHT + 2 * V_PAD
|
|
29813
|
+
};
|
|
29814
|
+
}
|
|
29815
|
+
function edgePolylineMidpoint(points) {
|
|
29816
|
+
return pointAtArcFraction(points, 0.5).p;
|
|
29817
|
+
}
|
|
29818
|
+
function pointAtArcFraction(points, t) {
|
|
29819
|
+
if (points.length === 0) return { p: { x: 0, y: 0 }, nx: 0, ny: 1 };
|
|
29820
|
+
if (points.length === 1)
|
|
29821
|
+
return { p: { x: points[0].x, y: points[0].y }, nx: 0, ny: 1 };
|
|
29822
|
+
const segLen = [];
|
|
29823
|
+
let total = 0;
|
|
29824
|
+
for (let k = 1; k < points.length; k++) {
|
|
29825
|
+
const len = Math.hypot(
|
|
29826
|
+
points[k].x - points[k - 1].x,
|
|
29827
|
+
points[k].y - points[k - 1].y
|
|
29828
|
+
);
|
|
29829
|
+
segLen.push(len);
|
|
29830
|
+
total += len;
|
|
29831
|
+
}
|
|
29832
|
+
let want = total * Math.max(0, Math.min(1, t));
|
|
29833
|
+
for (let k = 1; k < points.length; k++) {
|
|
29834
|
+
const len = segLen[k - 1];
|
|
29835
|
+
if (want <= len || k === points.length - 1) {
|
|
29836
|
+
const f = len === 0 ? 0 : Math.min(1, want / len);
|
|
29837
|
+
const ax = points[k - 1].x;
|
|
29838
|
+
const ay = points[k - 1].y;
|
|
29839
|
+
const bx = points[k].x;
|
|
29840
|
+
const by = points[k].y;
|
|
29841
|
+
const dx = bx - ax;
|
|
29842
|
+
const dy = by - ay;
|
|
29843
|
+
const dlen = Math.hypot(dx, dy) || 1;
|
|
29844
|
+
return {
|
|
29845
|
+
p: { x: ax + dx * f, y: ay + dy * f },
|
|
29846
|
+
nx: -dy / dlen,
|
|
29847
|
+
ny: dx / dlen
|
|
29848
|
+
};
|
|
29849
|
+
}
|
|
29850
|
+
want -= len;
|
|
29851
|
+
}
|
|
29852
|
+
const last = points[points.length - 1];
|
|
29853
|
+
return { p: { x: last.x, y: last.y }, nx: 0, ny: 1 };
|
|
29854
|
+
}
|
|
29855
|
+
function rectFromCenter(cx, cy, w, h) {
|
|
29856
|
+
return {
|
|
29857
|
+
minX: cx - w / 2,
|
|
29858
|
+
minY: cy - h / 2,
|
|
29859
|
+
maxX: cx + w / 2,
|
|
29860
|
+
maxY: cy + h / 2
|
|
29861
|
+
};
|
|
29862
|
+
}
|
|
29863
|
+
function overlapsAny(cx, cy, w, h, obstacles, pad2) {
|
|
29864
|
+
const minX = cx - w / 2 - pad2;
|
|
29865
|
+
const minY = cy - h / 2 - pad2;
|
|
29866
|
+
const maxX = cx + w / 2 + pad2;
|
|
29867
|
+
const maxY = cy + h / 2 + pad2;
|
|
29868
|
+
for (const o of obstacles) {
|
|
29869
|
+
if (minX < o.maxX && maxX > o.minX && minY < o.maxY && maxY > o.minY)
|
|
29870
|
+
return true;
|
|
29871
|
+
}
|
|
29872
|
+
return false;
|
|
29873
|
+
}
|
|
29874
|
+
function slideFractions() {
|
|
29875
|
+
const out = [0.5];
|
|
29876
|
+
for (let k = 1; k <= SLIDE_SAMPLES; k++) {
|
|
29877
|
+
const off = k * 0.08;
|
|
29878
|
+
if (0.5 - off >= 0.12) out.push(0.5 - off);
|
|
29879
|
+
if (0.5 + off <= 0.88) out.push(0.5 + off);
|
|
29880
|
+
}
|
|
29881
|
+
return out;
|
|
29882
|
+
}
|
|
29883
|
+
function findClearPosition(w, h, points, obstacles) {
|
|
29884
|
+
const ts = slideFractions();
|
|
29885
|
+
for (const t of ts) {
|
|
29886
|
+
const { p } = pointAtArcFraction(points, t);
|
|
29887
|
+
if (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
|
|
29888
|
+
}
|
|
29889
|
+
for (let mag = PERP_STEP; mag <= PERP_MAX; mag += PERP_STEP) {
|
|
29890
|
+
for (const t of ts) {
|
|
29891
|
+
const { p, nx, ny } = pointAtArcFraction(points, t);
|
|
29892
|
+
for (const sign of [-1, 1]) {
|
|
29893
|
+
const x = p.x + nx * mag * sign;
|
|
29894
|
+
const y = p.y + ny * mag * sign;
|
|
29895
|
+
if (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
|
|
29896
|
+
}
|
|
29897
|
+
}
|
|
29898
|
+
}
|
|
29899
|
+
return null;
|
|
29900
|
+
}
|
|
29901
|
+
function resolveLabelOverlaps(boxes) {
|
|
29902
|
+
const MAX_PASSES = 8;
|
|
29903
|
+
const PAD = 4;
|
|
29904
|
+
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
29905
|
+
let moved = false;
|
|
29906
|
+
for (let i = 0; i < boxes.length; i++) {
|
|
29907
|
+
for (let j = i + 1; j < boxes.length; j++) {
|
|
29908
|
+
const a = boxes[i];
|
|
29909
|
+
const b = boxes[j];
|
|
29910
|
+
const dx = Math.abs(a.cx - b.cx);
|
|
29911
|
+
const dy = Math.abs(a.cy - b.cy);
|
|
29912
|
+
const overlapX = (a.w + b.w) / 2 + PAD - dx;
|
|
29913
|
+
const overlapY = (a.h + b.h) / 2 + PAD - dy;
|
|
29914
|
+
if (overlapX > 0 && overlapY > 0) {
|
|
29915
|
+
const shift = overlapY / 2 + 1;
|
|
29916
|
+
if (a.cy < b.cy) {
|
|
29917
|
+
a.cy -= shift;
|
|
29918
|
+
b.cy += shift;
|
|
29919
|
+
} else {
|
|
29920
|
+
a.cy += shift;
|
|
29921
|
+
b.cy -= shift;
|
|
29922
|
+
}
|
|
29923
|
+
moved = true;
|
|
29924
|
+
}
|
|
29925
|
+
}
|
|
29926
|
+
}
|
|
29927
|
+
if (!moved) break;
|
|
29928
|
+
}
|
|
29929
|
+
}
|
|
29930
|
+
function placeEdgeLabels(layout, opts) {
|
|
29931
|
+
const fontSize = opts?.fontSize ?? EDGE_LABEL_FONT_SIZE6;
|
|
29932
|
+
const maxWidth = opts?.maxWidth ?? LABEL_MAX_WIDTH;
|
|
29933
|
+
const obstacles = [];
|
|
29934
|
+
for (const n of layout.nodes)
|
|
29935
|
+
obstacles.push(rectFromCenter(n.x, n.y, n.width, n.height));
|
|
29936
|
+
for (const g of layout.groups)
|
|
29937
|
+
if (g.collapsed)
|
|
29938
|
+
obstacles.push(rectFromCenter(g.x, g.y, g.width, g.height));
|
|
29939
|
+
const boxes = [];
|
|
29940
|
+
layout.edges.forEach((e, idx) => {
|
|
29941
|
+
if (!e.label || e.points.length < 2) return;
|
|
29942
|
+
const m = measureEdgeLabel(e.label, fontSize, maxWidth);
|
|
29943
|
+
const mid = edgePolylineMidpoint(e.points);
|
|
29944
|
+
let cy = mid.y;
|
|
29945
|
+
if (e.parallelCount > 1 && e.yOffset !== 0)
|
|
29946
|
+
cy += (e.yOffset < 0 ? -1 : 1) * (m.height / 2);
|
|
29947
|
+
boxes.push({
|
|
29948
|
+
edgeIdx: idx,
|
|
29949
|
+
cx: mid.x,
|
|
29950
|
+
cy,
|
|
29951
|
+
w: m.width,
|
|
29952
|
+
h: m.height,
|
|
29953
|
+
lines: m.lines,
|
|
29954
|
+
resolved: true
|
|
29955
|
+
});
|
|
29956
|
+
});
|
|
29957
|
+
for (const box of boxes) {
|
|
29958
|
+
if (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
|
|
29959
|
+
continue;
|
|
29960
|
+
const e = layout.edges[box.edgeIdx];
|
|
29961
|
+
const clear = findClearPosition(box.w, box.h, e.points, obstacles);
|
|
29962
|
+
if (clear) {
|
|
29963
|
+
box.cx = clear.x;
|
|
29964
|
+
box.cy = clear.y;
|
|
29965
|
+
} else {
|
|
29966
|
+
box.resolved = false;
|
|
29967
|
+
}
|
|
29968
|
+
}
|
|
29969
|
+
resolveLabelOverlaps(boxes);
|
|
29970
|
+
for (const box of boxes) {
|
|
29971
|
+
if (overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
|
|
29972
|
+
box.resolved = false;
|
|
29973
|
+
}
|
|
29974
|
+
const boxByIdx = /* @__PURE__ */ new Map();
|
|
29975
|
+
for (const b of boxes) boxByIdx.set(b.edgeIdx, b);
|
|
29976
|
+
const edges = layout.edges.map((e, idx) => {
|
|
29977
|
+
const b = boxByIdx.get(idx);
|
|
29978
|
+
if (!b) return e;
|
|
29979
|
+
return {
|
|
29980
|
+
...e,
|
|
29981
|
+
labelX: b.cx,
|
|
29982
|
+
labelY: b.cy,
|
|
29983
|
+
labelWidth: b.w,
|
|
29984
|
+
labelHeight: b.h,
|
|
29985
|
+
labelLines: b.lines
|
|
29986
|
+
};
|
|
29987
|
+
});
|
|
29988
|
+
return {
|
|
29989
|
+
layout: { ...layout, edges },
|
|
29990
|
+
unresolved: boxes.filter((b) => !b.resolved).map((b) => b.edgeIdx)
|
|
29991
|
+
};
|
|
29992
|
+
}
|
|
29993
|
+
var EDGE_LABEL_FONT_SIZE6, LABEL_MAX_WIDTH, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, H_PAD, V_PAD, BOX_CLEAR_PAD, PERP_STEP, PERP_MAX, SLIDE_SAMPLES;
|
|
29994
|
+
var init_label_placement = __esm({
|
|
29995
|
+
"src/boxes-and-lines/label-placement.ts"() {
|
|
29996
|
+
"use strict";
|
|
29997
|
+
init_text_measure();
|
|
29998
|
+
EDGE_LABEL_FONT_SIZE6 = 11;
|
|
29999
|
+
LABEL_MAX_WIDTH = 160;
|
|
30000
|
+
MAX_LABEL_LINES = 3;
|
|
30001
|
+
LABEL_LINE_HEIGHT = 1.3;
|
|
30002
|
+
H_PAD = 6;
|
|
30003
|
+
V_PAD = 3;
|
|
30004
|
+
BOX_CLEAR_PAD = 4;
|
|
30005
|
+
PERP_STEP = 8;
|
|
30006
|
+
PERP_MAX = 40;
|
|
30007
|
+
SLIDE_SAMPLES = 9;
|
|
30008
|
+
}
|
|
30009
|
+
});
|
|
30010
|
+
|
|
29814
30011
|
// src/boxes-and-lines/layout-layered.ts
|
|
29815
30012
|
function rng(s) {
|
|
29816
30013
|
return () => {
|
|
@@ -29970,7 +30167,7 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
29970
30167
|
for (let r = 0; r < maxRank; r++) c += gapCrossings(r);
|
|
29971
30168
|
return c;
|
|
29972
30169
|
};
|
|
29973
|
-
const
|
|
30170
|
+
const median2 = (vals) => {
|
|
29974
30171
|
if (vals.length === 0) return -1;
|
|
29975
30172
|
vals.sort((x, y) => x - y);
|
|
29976
30173
|
const m = Math.floor(vals.length / 2);
|
|
@@ -29980,6 +30177,623 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
29980
30177
|
const right = vals[vals.length - 1] - vals[m];
|
|
29981
30178
|
return left + right === 0 ? (vals[m - 1] + vals[m]) / 2 : (vals[m - 1] * right + vals[m] * left) / (left + right);
|
|
29982
30179
|
};
|
|
30180
|
+
const wmedianRank = (r, useUp) => {
|
|
30181
|
+
const ids = ranks[r];
|
|
30182
|
+
const neigh = useUp ? up : down;
|
|
30183
|
+
const med = /* @__PURE__ */ new Map();
|
|
30184
|
+
for (const id of ids)
|
|
30185
|
+
med.set(id, median2(neigh.get(id).map((x) => orderOf.get(x))));
|
|
30186
|
+
const movable = ids.filter((id) => med.get(id) >= 0).sort((a, b) => med.get(a) - med.get(b));
|
|
30187
|
+
const out = new Array(ids.length).fill(null);
|
|
30188
|
+
for (const id of ids) if (med.get(id) < 0) out[orderOf.get(id)] = id;
|
|
30189
|
+
let mi = 0;
|
|
30190
|
+
for (let slot = 0; slot < out.length; slot++)
|
|
30191
|
+
if (out[slot] === null) out[slot] = movable[mi++];
|
|
30192
|
+
const final = out;
|
|
30193
|
+
final.forEach((id, i) => orderOf.set(id, i));
|
|
30194
|
+
ranks[r] = final;
|
|
30195
|
+
};
|
|
30196
|
+
const transpose = () => {
|
|
30197
|
+
let improved = true;
|
|
30198
|
+
let guard = 0;
|
|
30199
|
+
while (improved && guard++ < 12) {
|
|
30200
|
+
improved = false;
|
|
30201
|
+
for (let r = 0; r <= maxRank; r++) {
|
|
30202
|
+
const ids = ranks[r];
|
|
30203
|
+
for (let i = 0; i < ids.length - 1; i++) {
|
|
30204
|
+
const before = (r > 0 ? gapCrossings(r - 1) : 0) + (r < maxRank ? gapCrossings(r) : 0);
|
|
30205
|
+
const a = ids[i], b = ids[i + 1];
|
|
30206
|
+
ids[i] = b;
|
|
30207
|
+
ids[i + 1] = a;
|
|
30208
|
+
orderOf.set(b, i);
|
|
30209
|
+
orderOf.set(a, i + 1);
|
|
30210
|
+
const after = (r > 0 ? gapCrossings(r - 1) : 0) + (r < maxRank ? gapCrossings(r) : 0);
|
|
30211
|
+
if (after < before) {
|
|
30212
|
+
improved = true;
|
|
30213
|
+
} else {
|
|
30214
|
+
ids[i] = a;
|
|
30215
|
+
ids[i + 1] = b;
|
|
30216
|
+
orderOf.set(a, i);
|
|
30217
|
+
orderOf.set(b, i + 1);
|
|
30218
|
+
}
|
|
30219
|
+
}
|
|
30220
|
+
}
|
|
30221
|
+
}
|
|
30222
|
+
};
|
|
30223
|
+
const initOrder = (seed) => {
|
|
30224
|
+
const r = seed === 0 ? null : rng(seed);
|
|
30225
|
+
for (let rr = 0; rr <= maxRank; rr++) {
|
|
30226
|
+
const ids = ranks[rr].slice();
|
|
30227
|
+
if (r) {
|
|
30228
|
+
for (let i = ids.length - 1; i > 0; i--) {
|
|
30229
|
+
const j = Math.floor(r() * (i + 1));
|
|
30230
|
+
[ids[i], ids[j]] = [ids[j], ids[i]];
|
|
30231
|
+
}
|
|
30232
|
+
}
|
|
30233
|
+
ranks[rr] = ids;
|
|
30234
|
+
ids.forEach((id, i) => orderOf.set(id, i));
|
|
30235
|
+
}
|
|
30236
|
+
};
|
|
30237
|
+
const found = [];
|
|
30238
|
+
for (let s = 0; s < restarts; s++) {
|
|
30239
|
+
initOrder(s);
|
|
30240
|
+
let best = totalCrossings();
|
|
30241
|
+
let bestSnap = new Map(orderOf);
|
|
30242
|
+
for (let iter = 0; iter < 8; iter++) {
|
|
30243
|
+
const down1 = iter % 2 === 0;
|
|
30244
|
+
if (down1) for (let r = 1; r <= maxRank; r++) wmedianRank(r, true);
|
|
30245
|
+
else for (let r = maxRank - 1; r >= 0; r--) wmedianRank(r, false);
|
|
30246
|
+
transpose();
|
|
30247
|
+
const c = totalCrossings();
|
|
30248
|
+
if (c < best) {
|
|
30249
|
+
best = c;
|
|
30250
|
+
bestSnap = new Map(orderOf);
|
|
30251
|
+
}
|
|
30252
|
+
if (c === 0) break;
|
|
30253
|
+
}
|
|
30254
|
+
applyOrder(bestSnap);
|
|
30255
|
+
for (let r = 0; r <= maxRank; r++)
|
|
30256
|
+
ranks[r].sort((a, b) => orderOf.get(a) - orderOf.get(b));
|
|
30257
|
+
const sig = ranks.map((r) => r.join(",")).join("|");
|
|
30258
|
+
if (!found.some((f) => f.sig === sig))
|
|
30259
|
+
found.push({ sig, cross: best, order: new Map(bestSnap) });
|
|
30260
|
+
}
|
|
30261
|
+
found.sort((a, b) => a.cross - b.cross);
|
|
30262
|
+
const keep = found.slice(0, keepK);
|
|
30263
|
+
if (keep.length === 0) return [];
|
|
30264
|
+
const results = [];
|
|
30265
|
+
for (const cand of keep) {
|
|
30266
|
+
applyOrder(cand.order);
|
|
30267
|
+
const rk = Array.from({ length: maxRank + 1 }, () => []);
|
|
30268
|
+
for (const n of node.values()) rk[n.rank].push(n.id);
|
|
30269
|
+
for (let r = 0; r <= maxRank; r++)
|
|
30270
|
+
rk[r].sort((a, b) => cand.order.get(a) - cand.order.get(b));
|
|
30271
|
+
results.push(realize(rk));
|
|
30272
|
+
}
|
|
30273
|
+
return results;
|
|
30274
|
+
function realize(rk) {
|
|
30275
|
+
const bandDepth = rk.map(
|
|
30276
|
+
(ids) => Math.max(0, ...ids.map((id) => node.get(id).depth))
|
|
30277
|
+
);
|
|
30278
|
+
const bandCenter = [];
|
|
30279
|
+
let acc = MARGIN3;
|
|
30280
|
+
for (let r = 0; r <= maxRank; r++) {
|
|
30281
|
+
bandCenter[r] = acc + bandDepth[r] / 2;
|
|
30282
|
+
acc += bandDepth[r] + ranksep;
|
|
30283
|
+
}
|
|
30284
|
+
for (let r = 0; r <= maxRank; r++) {
|
|
30285
|
+
let x = MARGIN3;
|
|
30286
|
+
for (const id of rk[r]) {
|
|
30287
|
+
const n = node.get(id);
|
|
30288
|
+
n.cross = x + n.thick / 2;
|
|
30289
|
+
x += n.thick + nodesep;
|
|
30290
|
+
}
|
|
30291
|
+
}
|
|
30292
|
+
const ITER = 18;
|
|
30293
|
+
for (let it = 0; it < ITER; it++) {
|
|
30294
|
+
const downPass = it % 2 === 0;
|
|
30295
|
+
const order = downPass ? Array.from({ length: maxRank + 1 }, (_, i) => i) : Array.from({ length: maxRank + 1 }, (_, i) => maxRank - i);
|
|
30296
|
+
for (const r of order) {
|
|
30297
|
+
const ids = rk[r];
|
|
30298
|
+
const desired = ids.map((id) => {
|
|
30299
|
+
const n = node.get(id);
|
|
30300
|
+
let sw = 0, sx2 = 0;
|
|
30301
|
+
for (const nb of up.get(id)) {
|
|
30302
|
+
const w = weight(n, node.get(nb));
|
|
30303
|
+
sw += w;
|
|
30304
|
+
sx2 += w * node.get(nb).cross;
|
|
30305
|
+
}
|
|
30306
|
+
for (const nb of down.get(id)) {
|
|
30307
|
+
const w = weight(n, node.get(nb));
|
|
30308
|
+
sw += w;
|
|
30309
|
+
sx2 += w * node.get(nb).cross;
|
|
30310
|
+
}
|
|
30311
|
+
return sw > 0 ? sx2 / sw : n.cross;
|
|
30312
|
+
});
|
|
30313
|
+
placeWithSeparation(ids, desired);
|
|
30314
|
+
}
|
|
30315
|
+
}
|
|
30316
|
+
let minC = Infinity;
|
|
30317
|
+
for (const n of node.values()) minC = Math.min(minC, n.cross - n.thick / 2);
|
|
30318
|
+
const shift = MARGIN3 - minC;
|
|
30319
|
+
for (const n of node.values()) n.cross += shift;
|
|
30320
|
+
const coord = (n) => isTB ? { x: n.cross, y: bandCenter[n.rank] } : { x: bandCenter[n.rank], y: n.cross };
|
|
30321
|
+
const layoutNodes = parsed.nodes.map((pn) => {
|
|
30322
|
+
const n = node.get(pn.label);
|
|
30323
|
+
const c = coord(n);
|
|
30324
|
+
return {
|
|
30325
|
+
label: pn.label,
|
|
30326
|
+
x: c.x,
|
|
30327
|
+
y: c.y,
|
|
30328
|
+
width: n.realW,
|
|
30329
|
+
height: n.realH
|
|
30330
|
+
};
|
|
30331
|
+
});
|
|
30332
|
+
const chainById = /* @__PURE__ */ new Map();
|
|
30333
|
+
for (const ch of chains) chainById.set(ch.edgeIdx, ch.chain);
|
|
30334
|
+
let minCross = Infinity, maxCross = -Infinity;
|
|
30335
|
+
for (const n of node.values()) {
|
|
30336
|
+
if (n.dummy) continue;
|
|
30337
|
+
minCross = Math.min(minCross, n.cross - n.thick / 2);
|
|
30338
|
+
maxCross = Math.max(maxCross, n.cross + n.thick / 2);
|
|
30339
|
+
}
|
|
30340
|
+
const GAP = 34;
|
|
30341
|
+
const LANE = 28;
|
|
30342
|
+
const sideOf = (b) => {
|
|
30343
|
+
if (backEdgeSide === "left") return -1;
|
|
30344
|
+
if (backEdgeSide === "right") return 1;
|
|
30345
|
+
const d = node.get(b.src).cross - node.get(b.tgt).cross;
|
|
30346
|
+
return d >= 0 ? 1 : -1;
|
|
30347
|
+
};
|
|
30348
|
+
const backSorted = backEdges.map((b) => ({
|
|
30349
|
+
...b,
|
|
30350
|
+
side: sideOf(b),
|
|
30351
|
+
span: Math.abs(node.get(b.src).rank - node.get(b.tgt).rank)
|
|
30352
|
+
})).sort((a, b) => a.side - b.side || a.span - b.span);
|
|
30353
|
+
const sideCounts = /* @__PURE__ */ new Map();
|
|
30354
|
+
for (const b of backSorted)
|
|
30355
|
+
sideCounts.set(b.side, (sideCounts.get(b.side) ?? 0) + 1);
|
|
30356
|
+
const laneCounter = /* @__PURE__ */ new Map();
|
|
30357
|
+
const backPoints = /* @__PURE__ */ new Map();
|
|
30358
|
+
const faceLim = (depth) => Math.max(0, depth / 2 - 6);
|
|
30359
|
+
const hubIndex = /* @__PURE__ */ new Map();
|
|
30360
|
+
const hubSize = /* @__PURE__ */ new Map();
|
|
30361
|
+
{
|
|
30362
|
+
const counter = /* @__PURE__ */ new Map();
|
|
30363
|
+
for (const b of backSorted) {
|
|
30364
|
+
const key = `${b.side}|${b.tgt}`;
|
|
30365
|
+
const idx = counter.get(key) ?? 0;
|
|
30366
|
+
counter.set(key, idx + 1);
|
|
30367
|
+
hubIndex.set(b.edgeIdx, idx);
|
|
30368
|
+
}
|
|
30369
|
+
for (const [key, v] of counter) hubSize.set(key, v);
|
|
30370
|
+
}
|
|
30371
|
+
for (const b of backSorted) {
|
|
30372
|
+
const s = b.side;
|
|
30373
|
+
const k = laneCounter.get(s) ?? 0;
|
|
30374
|
+
laneCounter.set(s, k + 1);
|
|
30375
|
+
const K = sideCounts.get(s);
|
|
30376
|
+
const src = node.get(b.src);
|
|
30377
|
+
const tgt = node.get(b.tgt);
|
|
30378
|
+
const laneC = s > 0 ? maxCross + GAP + k * LANE : minCross - GAP - k * LANE;
|
|
30379
|
+
const srcCtr = bandCenter[src.rank];
|
|
30380
|
+
const tgtCtr = bandCenter[tgt.rank];
|
|
30381
|
+
const frac = K > 1 ? (k + 1) / (K + 1) : 0;
|
|
30382
|
+
const srcR = srcCtr + frac * faceLim(src.depth);
|
|
30383
|
+
const tgtR = tgtCtr - frac * faceLim(tgt.depth);
|
|
30384
|
+
const m = (c, r) => isTB ? { x: c, y: r } : { x: r, y: c };
|
|
30385
|
+
const off = 10;
|
|
30386
|
+
const srcEdgeC = src.cross + s * (src.thick / 2 + off);
|
|
30387
|
+
const tgtEdgeC = tgt.cross + s * (tgt.thick / 2 + off);
|
|
30388
|
+
const hubK = hubIndex.get(b.edgeIdx);
|
|
30389
|
+
const hubN = hubSize.get(`${s}|${b.tgt}`);
|
|
30390
|
+
if (hubN > 1 && hubK > 0) {
|
|
30391
|
+
const tgtTop = tgtCtr - (tgt.depth / 2 + GAP + (hubK - 1) * LANE);
|
|
30392
|
+
const entryCross = tgt.cross + s * faceLim(tgt.thick) * (hubK / hubN);
|
|
30393
|
+
backPoints.set(b.edgeIdx, [
|
|
30394
|
+
m(src.cross, srcCtr),
|
|
30395
|
+
m(srcEdgeC, srcR),
|
|
30396
|
+
m(laneC, srcR),
|
|
30397
|
+
m(laneC, tgtTop),
|
|
30398
|
+
m(entryCross, tgtTop),
|
|
30399
|
+
m(tgt.cross, tgtCtr)
|
|
30400
|
+
]);
|
|
30401
|
+
} else {
|
|
30402
|
+
backPoints.set(b.edgeIdx, [
|
|
30403
|
+
m(src.cross, srcCtr),
|
|
30404
|
+
m(srcEdgeC, srcR),
|
|
30405
|
+
m(laneC, srcR),
|
|
30406
|
+
m(laneC, tgtR),
|
|
30407
|
+
m(tgtEdgeC, tgtR),
|
|
30408
|
+
m(tgt.cross, tgtCtr)
|
|
30409
|
+
]);
|
|
30410
|
+
}
|
|
30411
|
+
}
|
|
30412
|
+
const layoutEdges = [];
|
|
30413
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
30414
|
+
const e = parsed.edges[i];
|
|
30415
|
+
if (!labelSet.has(e.source) || !labelSet.has(e.target)) continue;
|
|
30416
|
+
let points;
|
|
30417
|
+
if (e.source === e.target) {
|
|
30418
|
+
const c = coord(node.get(e.source));
|
|
30419
|
+
points = [c, c];
|
|
30420
|
+
} else if (backPoints.has(i)) {
|
|
30421
|
+
points = backPoints.get(i);
|
|
30422
|
+
} else {
|
|
30423
|
+
const chain = chainById.get(i);
|
|
30424
|
+
if (!chain) continue;
|
|
30425
|
+
points = chain.map((id) => coord(node.get(id)));
|
|
30426
|
+
}
|
|
30427
|
+
layoutEdges.push({
|
|
30428
|
+
source: e.source,
|
|
30429
|
+
target: e.target,
|
|
30430
|
+
...e.label !== void 0 && { label: e.label },
|
|
30431
|
+
bidirectional: e.bidirectional,
|
|
30432
|
+
lineNumber: e.lineNumber,
|
|
30433
|
+
points,
|
|
30434
|
+
yOffset: 0,
|
|
30435
|
+
parallelCount: 1,
|
|
30436
|
+
metadata: e.metadata
|
|
30437
|
+
});
|
|
30438
|
+
}
|
|
30439
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
30440
|
+
for (const n of layoutNodes) {
|
|
30441
|
+
minX = Math.min(minX, n.x - n.width / 2);
|
|
30442
|
+
minY = Math.min(minY, n.y - n.height / 2);
|
|
30443
|
+
maxX = Math.max(maxX, n.x + n.width / 2);
|
|
30444
|
+
maxY = Math.max(maxY, n.y + n.height / 2);
|
|
30445
|
+
}
|
|
30446
|
+
for (const e of layoutEdges)
|
|
30447
|
+
for (const p of e.points) {
|
|
30448
|
+
minX = Math.min(minX, p.x);
|
|
30449
|
+
minY = Math.min(minY, p.y);
|
|
30450
|
+
maxX = Math.max(maxX, p.x);
|
|
30451
|
+
maxY = Math.max(maxY, p.y);
|
|
30452
|
+
}
|
|
30453
|
+
const sx = MARGIN3 - minX;
|
|
30454
|
+
const sy = MARGIN3 - minY;
|
|
30455
|
+
const shifted = sx !== 0 || sy !== 0 ? {
|
|
30456
|
+
nodes: layoutNodes.map((n) => ({ ...n, x: n.x + sx, y: n.y + sy })),
|
|
30457
|
+
edges: layoutEdges.map((e) => ({
|
|
30458
|
+
...e,
|
|
30459
|
+
points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
|
|
30460
|
+
}))
|
|
30461
|
+
} : { nodes: layoutNodes, edges: layoutEdges };
|
|
30462
|
+
return {
|
|
30463
|
+
nodes: shifted.nodes,
|
|
30464
|
+
edges: shifted.edges,
|
|
30465
|
+
groups: [],
|
|
30466
|
+
width: maxX + sx + MARGIN3,
|
|
30467
|
+
height: maxY + sy + MARGIN3
|
|
30468
|
+
};
|
|
30469
|
+
}
|
|
30470
|
+
function weight(a, b) {
|
|
30471
|
+
if (a.dummy && b.dummy) return W_DUMMY_DUMMY;
|
|
30472
|
+
if (a.dummy || b.dummy) return W_REAL_DUMMY;
|
|
30473
|
+
return W_REAL_REAL;
|
|
30474
|
+
}
|
|
30475
|
+
function placeWithSeparation(ids, desired) {
|
|
30476
|
+
const n = ids.length;
|
|
30477
|
+
if (n === 0) return;
|
|
30478
|
+
const half = ids.map((id) => node.get(id).thick / 2);
|
|
30479
|
+
const off = [0];
|
|
30480
|
+
for (let i = 1; i < n; i++)
|
|
30481
|
+
off[i] = off[i - 1] + half[i - 1] + nodesep + half[i];
|
|
30482
|
+
const d = desired.map((v, i) => v - off[i]);
|
|
30483
|
+
const blocks = [];
|
|
30484
|
+
for (let i = 0; i < n; i++) {
|
|
30485
|
+
let b = { pos: d[i], count: 1, sumOffset: d[i], first: i };
|
|
30486
|
+
while (blocks.length && blocks[blocks.length - 1].pos >= b.pos) {
|
|
30487
|
+
const prev = blocks.pop();
|
|
30488
|
+
const count = prev.count + b.count;
|
|
30489
|
+
const sumOffset = prev.sumOffset + b.sumOffset;
|
|
30490
|
+
b = { pos: sumOffset / count, count, sumOffset, first: prev.first };
|
|
30491
|
+
}
|
|
30492
|
+
blocks.push(b);
|
|
30493
|
+
}
|
|
30494
|
+
const xs = new Array(n);
|
|
30495
|
+
for (const b of blocks)
|
|
30496
|
+
for (let k = 0; k < b.count; k++) xs[b.first + k] = b.pos;
|
|
30497
|
+
for (let i = 0; i < n; i++) node.get(ids[i]).cross = xs[i] + off[i];
|
|
30498
|
+
}
|
|
30499
|
+
}
|
|
30500
|
+
var NODESEP, RANKSEP, DUMMY_THICK, MARGIN3, W_REAL_REAL, W_REAL_DUMMY, W_DUMMY_DUMMY;
|
|
30501
|
+
var init_layout_layered = __esm({
|
|
30502
|
+
"src/boxes-and-lines/layout-layered.ts"() {
|
|
30503
|
+
"use strict";
|
|
30504
|
+
init_layout5();
|
|
30505
|
+
NODESEP = 50;
|
|
30506
|
+
RANKSEP = 60;
|
|
30507
|
+
DUMMY_THICK = 10;
|
|
30508
|
+
MARGIN3 = 40;
|
|
30509
|
+
W_REAL_REAL = 1;
|
|
30510
|
+
W_REAL_DUMMY = 2;
|
|
30511
|
+
W_DUMMY_DUMMY = 8;
|
|
30512
|
+
}
|
|
30513
|
+
});
|
|
30514
|
+
|
|
30515
|
+
// src/boxes-and-lines/layout-grouped.ts
|
|
30516
|
+
function rng2(s) {
|
|
30517
|
+
return () => {
|
|
30518
|
+
s |= 0;
|
|
30519
|
+
s = s + 1831565813 | 0;
|
|
30520
|
+
let t = Math.imul(s ^ s >>> 15, 1 | s);
|
|
30521
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
30522
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
30523
|
+
};
|
|
30524
|
+
}
|
|
30525
|
+
function median(vals) {
|
|
30526
|
+
if (vals.length === 0) return -1;
|
|
30527
|
+
vals.sort((x, y) => x - y);
|
|
30528
|
+
const m = Math.floor(vals.length / 2);
|
|
30529
|
+
if (vals.length % 2 === 1) return vals[m];
|
|
30530
|
+
if (vals.length === 2) return (vals[0] + vals[1]) / 2;
|
|
30531
|
+
const left = vals[m - 1] - vals[0];
|
|
30532
|
+
const right = vals[vals.length - 1] - vals[m];
|
|
30533
|
+
return left + right === 0 ? (vals[m - 1] + vals[m]) / 2 : (vals[m - 1] * right + vals[m] * left) / (left + right);
|
|
30534
|
+
}
|
|
30535
|
+
function acyclicOrient(ids, edges) {
|
|
30536
|
+
const adj = /* @__PURE__ */ new Map();
|
|
30537
|
+
for (const l of ids) adj.set(l, []);
|
|
30538
|
+
for (const e of edges) adj.get(e.from)?.push({ to: e.to, idx: e.idx });
|
|
30539
|
+
const reversed = /* @__PURE__ */ new Set();
|
|
30540
|
+
const state = /* @__PURE__ */ new Map();
|
|
30541
|
+
for (const l of ids) state.set(l, 0);
|
|
30542
|
+
const stack = [];
|
|
30543
|
+
const visit = (root) => {
|
|
30544
|
+
stack.push(root);
|
|
30545
|
+
const it = /* @__PURE__ */ new Map();
|
|
30546
|
+
while (stack.length) {
|
|
30547
|
+
const u = stack[stack.length - 1];
|
|
30548
|
+
if (state.get(u) === 0) state.set(u, 1);
|
|
30549
|
+
const list = adj.get(u);
|
|
30550
|
+
let i = it.get(u) ?? 0;
|
|
30551
|
+
let descended = false;
|
|
30552
|
+
for (; i < list.length; i++) {
|
|
30553
|
+
const { to, idx } = list[i];
|
|
30554
|
+
const st = state.get(to);
|
|
30555
|
+
if (st === 1) reversed.add(idx);
|
|
30556
|
+
else if (st === 0) {
|
|
30557
|
+
it.set(u, i + 1);
|
|
30558
|
+
stack.push(to);
|
|
30559
|
+
descended = true;
|
|
30560
|
+
break;
|
|
30561
|
+
}
|
|
30562
|
+
}
|
|
30563
|
+
if (!descended) {
|
|
30564
|
+
it.set(u, list.length);
|
|
30565
|
+
state.set(u, 2);
|
|
30566
|
+
stack.pop();
|
|
30567
|
+
}
|
|
30568
|
+
}
|
|
30569
|
+
};
|
|
30570
|
+
for (const l of ids) if (state.get(l) === 0) visit(l);
|
|
30571
|
+
const dag = edges.map(
|
|
30572
|
+
(e) => reversed.has(e.idx) ? { from: e.to, to: e.from, idx: e.idx, rev: true } : { from: e.from, to: e.to, idx: e.idx, rev: false }
|
|
30573
|
+
);
|
|
30574
|
+
return { dag };
|
|
30575
|
+
}
|
|
30576
|
+
function longestPath(ids, dag) {
|
|
30577
|
+
const out = /* @__PURE__ */ new Map();
|
|
30578
|
+
const inDeg = /* @__PURE__ */ new Map();
|
|
30579
|
+
for (const l of ids) {
|
|
30580
|
+
out.set(l, []);
|
|
30581
|
+
inDeg.set(l, 0);
|
|
30582
|
+
}
|
|
30583
|
+
for (const d of dag) {
|
|
30584
|
+
out.get(d.from).push(d.to);
|
|
30585
|
+
inDeg.set(d.to, (inDeg.get(d.to) ?? 0) + 1);
|
|
30586
|
+
}
|
|
30587
|
+
const rank = /* @__PURE__ */ new Map();
|
|
30588
|
+
for (const l of ids) rank.set(l, 0);
|
|
30589
|
+
const queue = ids.filter((l) => (inDeg.get(l) ?? 0) === 0);
|
|
30590
|
+
const indeg2 = new Map(inDeg);
|
|
30591
|
+
let seen = 0;
|
|
30592
|
+
while (queue.length) {
|
|
30593
|
+
const u = queue.shift();
|
|
30594
|
+
seen++;
|
|
30595
|
+
for (const v of out.get(u)) {
|
|
30596
|
+
rank.set(v, Math.max(rank.get(v), rank.get(u) + 1));
|
|
30597
|
+
indeg2.set(v, indeg2.get(v) - 1);
|
|
30598
|
+
if (indeg2.get(v) === 0) queue.push(v);
|
|
30599
|
+
}
|
|
30600
|
+
}
|
|
30601
|
+
return seen === ids.length ? rank : null;
|
|
30602
|
+
}
|
|
30603
|
+
function groupedTierCandidates(parsed, sizes, opts) {
|
|
30604
|
+
if (parsed.groups.length === 0) return [];
|
|
30605
|
+
const nCount = parsed.nodes.length;
|
|
30606
|
+
if (nCount < 3 || nCount > 60) return [];
|
|
30607
|
+
const isTB = parsed.direction === "TB";
|
|
30608
|
+
const labels = parsed.nodes.map((n) => n.label);
|
|
30609
|
+
const labelSet = new Set(labels);
|
|
30610
|
+
for (const e of parsed.edges)
|
|
30611
|
+
if (e.source.startsWith("__group_") || e.target.startsWith("__group_"))
|
|
30612
|
+
return [];
|
|
30613
|
+
const groupByLabel = new Map(parsed.groups.map((g) => [g.label, g]));
|
|
30614
|
+
const directGroupOf = /* @__PURE__ */ new Map();
|
|
30615
|
+
for (const grp of parsed.groups)
|
|
30616
|
+
for (const c of grp.children)
|
|
30617
|
+
if (labelSet.has(c)) directGroupOf.set(c, grp.label);
|
|
30618
|
+
const topGroupOf = (groupLabel) => {
|
|
30619
|
+
let cur = groupLabel;
|
|
30620
|
+
const guard = /* @__PURE__ */ new Set();
|
|
30621
|
+
while (true) {
|
|
30622
|
+
const g = groupByLabel.get(cur);
|
|
30623
|
+
if (!g?.parentGroup || guard.has(cur)) return cur;
|
|
30624
|
+
guard.add(cur);
|
|
30625
|
+
cur = g.parentGroup;
|
|
30626
|
+
}
|
|
30627
|
+
};
|
|
30628
|
+
const pathOf = (label) => {
|
|
30629
|
+
const direct = directGroupOf.get(label);
|
|
30630
|
+
if (!direct) return [];
|
|
30631
|
+
const chain = [direct];
|
|
30632
|
+
let cur = direct;
|
|
30633
|
+
const guard = /* @__PURE__ */ new Set([direct]);
|
|
30634
|
+
while (true) {
|
|
30635
|
+
const g = groupByLabel.get(cur);
|
|
30636
|
+
if (!g?.parentGroup || guard.has(g.parentGroup)) break;
|
|
30637
|
+
chain.push(g.parentGroup);
|
|
30638
|
+
guard.add(g.parentGroup);
|
|
30639
|
+
cur = g.parentGroup;
|
|
30640
|
+
}
|
|
30641
|
+
return chain.reverse();
|
|
30642
|
+
};
|
|
30643
|
+
const SINGLE = "\0node\0";
|
|
30644
|
+
const unitOf = (label) => {
|
|
30645
|
+
const direct = directGroupOf.get(label);
|
|
30646
|
+
return direct ? topGroupOf(direct) : SINGLE + label;
|
|
30647
|
+
};
|
|
30648
|
+
const edges = parsed.edges.map((e, i) => ({ e, i })).filter(
|
|
30649
|
+
({ e }) => labelSet.has(e.source) && labelSet.has(e.target) && e.source !== e.target
|
|
30650
|
+
);
|
|
30651
|
+
if (edges.length === 0) return [];
|
|
30652
|
+
const unitOfNode = /* @__PURE__ */ new Map();
|
|
30653
|
+
for (const l of labels) unitOfNode.set(l, unitOf(l));
|
|
30654
|
+
const units = Array.from(new Set(labels.map((l) => unitOfNode.get(l))));
|
|
30655
|
+
const interUnit = edges.filter(({ e }) => unitOfNode.get(e.source) !== unitOfNode.get(e.target)).map(({ e, i }) => ({
|
|
30656
|
+
from: unitOfNode.get(e.source),
|
|
30657
|
+
to: unitOfNode.get(e.target),
|
|
30658
|
+
idx: i
|
|
30659
|
+
}));
|
|
30660
|
+
const { dag: unitDag } = acyclicOrient(units, interUnit);
|
|
30661
|
+
const tier = longestPath(
|
|
30662
|
+
units,
|
|
30663
|
+
unitDag.map((d) => ({ from: d.from, to: d.to }))
|
|
30664
|
+
);
|
|
30665
|
+
if (!tier) return [];
|
|
30666
|
+
const localRank = /* @__PURE__ */ new Map();
|
|
30667
|
+
const unitMembers = /* @__PURE__ */ new Map();
|
|
30668
|
+
for (const l of labels) {
|
|
30669
|
+
const u = unitOfNode.get(l);
|
|
30670
|
+
(unitMembers.get(u) ?? unitMembers.set(u, []).get(u)).push(l);
|
|
30671
|
+
}
|
|
30672
|
+
for (const [u, members] of unitMembers) {
|
|
30673
|
+
const memberSet = new Set(members);
|
|
30674
|
+
const intra = edges.filter(
|
|
30675
|
+
({ e }) => unitOfNode.get(e.source) === u && unitOfNode.get(e.target) === u && memberSet.has(e.source) && memberSet.has(e.target)
|
|
30676
|
+
).map(({ e, i }) => ({ from: e.source, to: e.target, idx: i }));
|
|
30677
|
+
const { dag } = acyclicOrient(members, intra);
|
|
30678
|
+
const lr = longestPath(
|
|
30679
|
+
members,
|
|
30680
|
+
dag.map((d) => ({ from: d.from, to: d.to }))
|
|
30681
|
+
);
|
|
30682
|
+
if (!lr) return [];
|
|
30683
|
+
for (const m of members) localRank.set(m, lr.get(m));
|
|
30684
|
+
}
|
|
30685
|
+
const maxTier = Math.max(...units.map((u) => tier.get(u)));
|
|
30686
|
+
const bandHeight = Array.from({ length: maxTier + 1 }, () => 1);
|
|
30687
|
+
for (const u of units) {
|
|
30688
|
+
const h = Math.max(
|
|
30689
|
+
...unitMembers.get(u).map((m) => localRank.get(m) + 1)
|
|
30690
|
+
);
|
|
30691
|
+
const t = tier.get(u);
|
|
30692
|
+
bandHeight[t] = Math.max(bandHeight[t], h);
|
|
30693
|
+
}
|
|
30694
|
+
const tierBase = [];
|
|
30695
|
+
let accBase = 0;
|
|
30696
|
+
for (let t = 0; t <= maxTier; t++) {
|
|
30697
|
+
tierBase[t] = accBase;
|
|
30698
|
+
accBase += bandHeight[t];
|
|
30699
|
+
}
|
|
30700
|
+
const tierStartRanks = new Set(tierBase.slice(1));
|
|
30701
|
+
const globalRank = /* @__PURE__ */ new Map();
|
|
30702
|
+
for (const l of labels)
|
|
30703
|
+
globalRank.set(
|
|
30704
|
+
l,
|
|
30705
|
+
tierBase[tier.get(unitOfNode.get(l))] + localRank.get(l)
|
|
30706
|
+
);
|
|
30707
|
+
const maxRank = Math.max(...labels.map((l) => globalRank.get(l)));
|
|
30708
|
+
const node = /* @__PURE__ */ new Map();
|
|
30709
|
+
for (const n of parsed.nodes) {
|
|
30710
|
+
const s = sizes.get(n.label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
30711
|
+
node.set(n.label, {
|
|
30712
|
+
id: n.label,
|
|
30713
|
+
dummy: false,
|
|
30714
|
+
rank: globalRank.get(n.label),
|
|
30715
|
+
cross: 0,
|
|
30716
|
+
thick: isTB ? s.width : s.height,
|
|
30717
|
+
depth: isTB ? s.height : s.width,
|
|
30718
|
+
realW: s.width,
|
|
30719
|
+
realH: s.height,
|
|
30720
|
+
unit: unitOfNode.get(n.label),
|
|
30721
|
+
path: pathOf(n.label)
|
|
30722
|
+
});
|
|
30723
|
+
}
|
|
30724
|
+
const chains = [];
|
|
30725
|
+
const segs = [];
|
|
30726
|
+
const backEdges = [];
|
|
30727
|
+
const flatEdges = [];
|
|
30728
|
+
for (const { e, i } of edges) {
|
|
30729
|
+
const rs = globalRank.get(e.source);
|
|
30730
|
+
const rt = globalRank.get(e.target);
|
|
30731
|
+
if (rs === rt) {
|
|
30732
|
+
flatEdges.push({ edgeIdx: i, a: e.source, b: e.target });
|
|
30733
|
+
continue;
|
|
30734
|
+
}
|
|
30735
|
+
if (rt < rs) {
|
|
30736
|
+
backEdges.push({ edgeIdx: i, src: e.source, tgt: e.target });
|
|
30737
|
+
continue;
|
|
30738
|
+
}
|
|
30739
|
+
const chain = [e.source];
|
|
30740
|
+
let prev = e.source;
|
|
30741
|
+
for (let r = rs + 1; r < rt; r++) {
|
|
30742
|
+
const id = `__d${i}_${r}`;
|
|
30743
|
+
node.set(id, {
|
|
30744
|
+
id,
|
|
30745
|
+
dummy: true,
|
|
30746
|
+
rank: r,
|
|
30747
|
+
cross: 0,
|
|
30748
|
+
thick: DUMMY_THICK2,
|
|
30749
|
+
depth: 0,
|
|
30750
|
+
realW: 0,
|
|
30751
|
+
realH: 0,
|
|
30752
|
+
unit: SINGLE + id,
|
|
30753
|
+
path: []
|
|
30754
|
+
});
|
|
30755
|
+
segs.push({ a: prev, b: id });
|
|
30756
|
+
chain.push(id);
|
|
30757
|
+
prev = id;
|
|
30758
|
+
}
|
|
30759
|
+
segs.push({ a: prev, b: e.target });
|
|
30760
|
+
chain.push(e.target);
|
|
30761
|
+
chains.push({ edgeIdx: i, chain });
|
|
30762
|
+
}
|
|
30763
|
+
const ranks = Array.from({ length: maxRank + 1 }, () => []);
|
|
30764
|
+
for (const n of node.values()) ranks[n.rank].push(n.id);
|
|
30765
|
+
const up = /* @__PURE__ */ new Map();
|
|
30766
|
+
const down = /* @__PURE__ */ new Map();
|
|
30767
|
+
for (const id of node.keys()) {
|
|
30768
|
+
up.set(id, []);
|
|
30769
|
+
down.set(id, []);
|
|
30770
|
+
}
|
|
30771
|
+
for (const s of segs) {
|
|
30772
|
+
down.get(s.a).push(s.b);
|
|
30773
|
+
up.get(s.b).push(s.a);
|
|
30774
|
+
}
|
|
30775
|
+
const orderOf = /* @__PURE__ */ new Map();
|
|
30776
|
+
const gapCrossings = (r) => {
|
|
30777
|
+
const lower = ranks[r + 1];
|
|
30778
|
+
if (!lower) return 0;
|
|
30779
|
+
const es = [];
|
|
30780
|
+
for (const a of ranks[r]) {
|
|
30781
|
+
const pa = orderOf.get(a);
|
|
30782
|
+
for (const b of down.get(a)) es.push({ p: pa, q: orderOf.get(b) });
|
|
30783
|
+
}
|
|
30784
|
+
let c = 0;
|
|
30785
|
+
for (let i = 0; i < es.length; i++)
|
|
30786
|
+
for (let j = i + 1; j < es.length; j++) {
|
|
30787
|
+
const A = es[i], B = es[j];
|
|
30788
|
+
if ((A.p - B.p) * (A.q - B.q) < 0) c++;
|
|
30789
|
+
}
|
|
30790
|
+
return c;
|
|
30791
|
+
};
|
|
30792
|
+
const totalCrossings = () => {
|
|
30793
|
+
let c = 0;
|
|
30794
|
+
for (let r = 0; r < maxRank; r++) c += gapCrossings(r);
|
|
30795
|
+
return c;
|
|
30796
|
+
};
|
|
29983
30797
|
const wmedianRank = (r, useUp) => {
|
|
29984
30798
|
const ids = ranks[r];
|
|
29985
30799
|
const neigh = useUp ? up : down;
|
|
@@ -30011,9 +30825,8 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30011
30825
|
orderOf.set(b, i);
|
|
30012
30826
|
orderOf.set(a, i + 1);
|
|
30013
30827
|
const after = (r > 0 ? gapCrossings(r - 1) : 0) + (r < maxRank ? gapCrossings(r) : 0);
|
|
30014
|
-
if (after < before)
|
|
30015
|
-
|
|
30016
|
-
} else {
|
|
30828
|
+
if (after < before) improved = true;
|
|
30829
|
+
else {
|
|
30017
30830
|
ids[i] = a;
|
|
30018
30831
|
ids[i + 1] = b;
|
|
30019
30832
|
orderOf.set(a, i);
|
|
@@ -30024,27 +30837,28 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30024
30837
|
}
|
|
30025
30838
|
};
|
|
30026
30839
|
const initOrder = (seed) => {
|
|
30027
|
-
const r = seed === 0 ? null :
|
|
30840
|
+
const r = seed === 0 ? null : rng2(seed);
|
|
30028
30841
|
for (let rr = 0; rr <= maxRank; rr++) {
|
|
30029
30842
|
const ids = ranks[rr].slice();
|
|
30030
|
-
if (r)
|
|
30843
|
+
if (r)
|
|
30031
30844
|
for (let i = ids.length - 1; i > 0; i--) {
|
|
30032
30845
|
const j = Math.floor(r() * (i + 1));
|
|
30033
30846
|
[ids[i], ids[j]] = [ids[j], ids[i]];
|
|
30034
30847
|
}
|
|
30035
|
-
}
|
|
30036
30848
|
ranks[rr] = ids;
|
|
30037
30849
|
ids.forEach((id, i) => orderOf.set(id, i));
|
|
30038
30850
|
}
|
|
30039
30851
|
};
|
|
30852
|
+
const restarts = opts?.restarts ?? (nCount <= 16 ? 20 : nCount <= 30 ? 12 : 6);
|
|
30853
|
+
const keepK = opts?.keepK ?? 3;
|
|
30040
30854
|
const found = [];
|
|
30041
30855
|
for (let s = 0; s < restarts; s++) {
|
|
30042
30856
|
initOrder(s);
|
|
30043
30857
|
let best = totalCrossings();
|
|
30044
30858
|
let bestSnap = new Map(orderOf);
|
|
30045
30859
|
for (let iter = 0; iter < 8; iter++) {
|
|
30046
|
-
|
|
30047
|
-
|
|
30860
|
+
if (iter % 2 === 0)
|
|
30861
|
+
for (let r = 1; r <= maxRank; r++) wmedianRank(r, true);
|
|
30048
30862
|
else for (let r = maxRank - 1; r >= 0; r--) wmedianRank(r, false);
|
|
30049
30863
|
transpose();
|
|
30050
30864
|
const c = totalCrossings();
|
|
@@ -30054,7 +30868,7 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30054
30868
|
}
|
|
30055
30869
|
if (c === 0) break;
|
|
30056
30870
|
}
|
|
30057
|
-
|
|
30871
|
+
for (const [k, v] of bestSnap) orderOf.set(k, v);
|
|
30058
30872
|
for (let r = 0; r <= maxRank; r++)
|
|
30059
30873
|
ranks[r].sort((a, b) => orderOf.get(a) - orderOf.get(b));
|
|
30060
30874
|
const sig = ranks.map((r) => r.join(",")).join("|");
|
|
@@ -30066,7 +30880,7 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30066
30880
|
if (keep.length === 0) return [];
|
|
30067
30881
|
const results = [];
|
|
30068
30882
|
for (const cand of keep) {
|
|
30069
|
-
|
|
30883
|
+
for (const [k, v] of cand.order) orderOf.set(k, v);
|
|
30070
30884
|
const rk = Array.from({ length: maxRank + 1 }, () => []);
|
|
30071
30885
|
for (const n of node.values()) rk[n.rank].push(n.id);
|
|
30072
30886
|
for (let r = 0; r <= maxRank; r++)
|
|
@@ -30074,22 +30888,64 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30074
30888
|
results.push(realize(rk));
|
|
30075
30889
|
}
|
|
30076
30890
|
return results;
|
|
30891
|
+
function weight(a, b) {
|
|
30892
|
+
if (a.dummy && b.dummy) return W_DUMMY_DUMMY2;
|
|
30893
|
+
if (a.dummy || b.dummy) return W_REAL_DUMMY2;
|
|
30894
|
+
return W_REAL_REAL2;
|
|
30895
|
+
}
|
|
30896
|
+
function placeWithSeparation(ids, desired, gap) {
|
|
30897
|
+
const n = ids.length;
|
|
30898
|
+
if (n === 0) return;
|
|
30899
|
+
const off = [0];
|
|
30900
|
+
for (let i = 1; i < n; i++) off[i] = off[i - 1] + gap[i];
|
|
30901
|
+
const d = desired.map((v, i) => v - off[i]);
|
|
30902
|
+
const blocks = [];
|
|
30903
|
+
for (let i = 0; i < n; i++) {
|
|
30904
|
+
let b = { pos: d[i], count: 1, sumOffset: d[i], first: i };
|
|
30905
|
+
while (blocks.length && blocks[blocks.length - 1].pos >= b.pos) {
|
|
30906
|
+
const prev = blocks.pop();
|
|
30907
|
+
const count = prev.count + b.count;
|
|
30908
|
+
const sumOffset = prev.sumOffset + b.sumOffset;
|
|
30909
|
+
b = { pos: sumOffset / count, count, sumOffset, first: prev.first };
|
|
30910
|
+
}
|
|
30911
|
+
blocks.push(b);
|
|
30912
|
+
}
|
|
30913
|
+
const xs = new Array(n);
|
|
30914
|
+
for (const b of blocks)
|
|
30915
|
+
for (let k = 0; k < b.count; k++) xs[b.first + k] = b.pos;
|
|
30916
|
+
for (let i = 0; i < n; i++) node.get(ids[i]).cross = xs[i] + off[i];
|
|
30917
|
+
}
|
|
30918
|
+
function gapBetween(a, b) {
|
|
30919
|
+
const base = a.thick / 2 + b.thick / 2 + NODESEP2;
|
|
30920
|
+
if (a.dummy || b.dummy) return base;
|
|
30921
|
+
if (a.unit !== b.unit) return base + 2 * GROUP_PAD + GROUP_GAP;
|
|
30922
|
+
const da = a.path[a.path.length - 1];
|
|
30923
|
+
const db = b.path[b.path.length - 1];
|
|
30924
|
+
if (da !== db && (da || db)) return base + 2 * GROUP_PAD;
|
|
30925
|
+
return base;
|
|
30926
|
+
}
|
|
30077
30927
|
function realize(rk) {
|
|
30078
30928
|
const bandDepth = rk.map(
|
|
30079
30929
|
(ids) => Math.max(0, ...ids.map((id) => node.get(id).depth))
|
|
30080
30930
|
);
|
|
30081
30931
|
const bandCenter = [];
|
|
30082
|
-
let acc =
|
|
30932
|
+
let acc = MARGIN4;
|
|
30083
30933
|
for (let r = 0; r <= maxRank; r++) {
|
|
30934
|
+
if (r > 0) acc += RANKSEP2 + (tierStartRanks.has(r) ? TIER_GAP : 0);
|
|
30084
30935
|
bandCenter[r] = acc + bandDepth[r] / 2;
|
|
30085
|
-
acc += bandDepth[r]
|
|
30936
|
+
acc += bandDepth[r];
|
|
30086
30937
|
}
|
|
30938
|
+
const gapsFor = (ids) => ids.map(
|
|
30939
|
+
(id, i) => i === 0 ? 0 : gapBetween(node.get(ids[i - 1]), node.get(id))
|
|
30940
|
+
);
|
|
30087
30941
|
for (let r = 0; r <= maxRank; r++) {
|
|
30088
|
-
|
|
30089
|
-
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
30942
|
+
const ids = rk[r];
|
|
30943
|
+
const gap = gapsFor(ids);
|
|
30944
|
+
let x = MARGIN4;
|
|
30945
|
+
for (let i = 0; i < ids.length; i++) {
|
|
30946
|
+
const n = node.get(ids[i]);
|
|
30947
|
+
x += gap[i];
|
|
30948
|
+
n.cross = i === 0 ? MARGIN4 + n.thick / 2 : x;
|
|
30093
30949
|
}
|
|
30094
30950
|
}
|
|
30095
30951
|
const ITER = 18;
|
|
@@ -30113,13 +30969,13 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30113
30969
|
}
|
|
30114
30970
|
return sw > 0 ? sx2 / sw : n.cross;
|
|
30115
30971
|
});
|
|
30116
|
-
placeWithSeparation(ids, desired);
|
|
30972
|
+
placeWithSeparation(ids, desired, gapsFor(ids));
|
|
30117
30973
|
}
|
|
30118
30974
|
}
|
|
30119
30975
|
let minC = Infinity;
|
|
30120
30976
|
for (const n of node.values()) minC = Math.min(minC, n.cross - n.thick / 2);
|
|
30121
|
-
const
|
|
30122
|
-
for (const n of node.values()) n.cross +=
|
|
30977
|
+
const shiftC = MARGIN4 - minC;
|
|
30978
|
+
for (const n of node.values()) n.cross += shiftC;
|
|
30123
30979
|
const coord = (n) => isTB ? { x: n.cross, y: bandCenter[n.rank] } : { x: bandCenter[n.rank], y: n.cross };
|
|
30124
30980
|
const layoutNodes = parsed.nodes.map((pn) => {
|
|
30125
30981
|
const n = node.get(pn.label);
|
|
@@ -30142,9 +30998,8 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30142
30998
|
}
|
|
30143
30999
|
const GAP = 34;
|
|
30144
31000
|
const LANE = 28;
|
|
31001
|
+
const faceLim = (depth) => Math.max(0, depth / 2 - 6);
|
|
30145
31002
|
const sideOf = (b) => {
|
|
30146
|
-
if (backEdgeSide === "left") return -1;
|
|
30147
|
-
if (backEdgeSide === "right") return 1;
|
|
30148
31003
|
const d = node.get(b.src).cross - node.get(b.tgt).cross;
|
|
30149
31004
|
return d >= 0 ? 1 : -1;
|
|
30150
31005
|
};
|
|
@@ -30158,19 +31013,6 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30158
31013
|
sideCounts.set(b.side, (sideCounts.get(b.side) ?? 0) + 1);
|
|
30159
31014
|
const laneCounter = /* @__PURE__ */ new Map();
|
|
30160
31015
|
const backPoints = /* @__PURE__ */ new Map();
|
|
30161
|
-
const faceLim = (depth) => Math.max(0, depth / 2 - 6);
|
|
30162
|
-
const hubIndex = /* @__PURE__ */ new Map();
|
|
30163
|
-
const hubSize = /* @__PURE__ */ new Map();
|
|
30164
|
-
{
|
|
30165
|
-
const counter = /* @__PURE__ */ new Map();
|
|
30166
|
-
for (const b of backSorted) {
|
|
30167
|
-
const key = `${b.side}|${b.tgt}`;
|
|
30168
|
-
const idx = counter.get(key) ?? 0;
|
|
30169
|
-
counter.set(key, idx + 1);
|
|
30170
|
-
hubIndex.set(b.edgeIdx, idx);
|
|
30171
|
-
}
|
|
30172
|
-
for (const [key, v] of counter) hubSize.set(key, v);
|
|
30173
|
-
}
|
|
30174
31016
|
for (const b of backSorted) {
|
|
30175
31017
|
const s = b.side;
|
|
30176
31018
|
const k = laneCounter.get(s) ?? 0;
|
|
@@ -30182,35 +31024,34 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30182
31024
|
const srcCtr = bandCenter[src.rank];
|
|
30183
31025
|
const tgtCtr = bandCenter[tgt.rank];
|
|
30184
31026
|
const frac = K > 1 ? (k + 1) / (K + 1) : 0;
|
|
30185
|
-
const srcR = srcCtr
|
|
30186
|
-
const tgtR = tgtCtr
|
|
30187
|
-
const m = (c,
|
|
31027
|
+
const srcR = srcCtr - frac * faceLim(src.depth);
|
|
31028
|
+
const tgtR = tgtCtr + frac * faceLim(tgt.depth);
|
|
31029
|
+
const m = (c, rr) => isTB ? { x: c, y: rr } : { x: rr, y: c };
|
|
30188
31030
|
const off = 10;
|
|
30189
31031
|
const srcEdgeC = src.cross + s * (src.thick / 2 + off);
|
|
30190
31032
|
const tgtEdgeC = tgt.cross + s * (tgt.thick / 2 + off);
|
|
30191
|
-
|
|
30192
|
-
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30199
|
-
|
|
30200
|
-
|
|
30201
|
-
|
|
30202
|
-
|
|
30203
|
-
|
|
30204
|
-
|
|
30205
|
-
|
|
30206
|
-
|
|
30207
|
-
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
}
|
|
31033
|
+
backPoints.set(b.edgeIdx, [
|
|
31034
|
+
m(src.cross, srcCtr),
|
|
31035
|
+
m(srcEdgeC, srcR),
|
|
31036
|
+
m(laneC, srcR),
|
|
31037
|
+
m(laneC, tgtR),
|
|
31038
|
+
m(tgtEdgeC, tgtR),
|
|
31039
|
+
m(tgt.cross, tgtCtr)
|
|
31040
|
+
]);
|
|
31041
|
+
}
|
|
31042
|
+
const flatPoints = /* @__PURE__ */ new Map();
|
|
31043
|
+
for (const f of flatEdges) {
|
|
31044
|
+
const a = node.get(f.a);
|
|
31045
|
+
const b = node.get(f.b);
|
|
31046
|
+
const ctr = bandCenter[a.rank];
|
|
31047
|
+
const bow = ctr - (a.depth / 2 + 26);
|
|
31048
|
+
const m = (c, rr) => isTB ? { x: c, y: rr } : { x: rr, y: c };
|
|
31049
|
+
flatPoints.set(f.edgeIdx, [
|
|
31050
|
+
m(a.cross, ctr),
|
|
31051
|
+
m(a.cross, bow),
|
|
31052
|
+
m(b.cross, bow),
|
|
31053
|
+
m(b.cross, ctr)
|
|
31054
|
+
]);
|
|
30214
31055
|
}
|
|
30215
31056
|
const layoutEdges = [];
|
|
30216
31057
|
for (let i = 0; i < parsed.edges.length; i++) {
|
|
@@ -30220,9 +31061,9 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30220
31061
|
if (e.source === e.target) {
|
|
30221
31062
|
const c = coord(node.get(e.source));
|
|
30222
31063
|
points = [c, c];
|
|
30223
|
-
} else if (backPoints.has(i))
|
|
30224
|
-
|
|
30225
|
-
|
|
31064
|
+
} else if (backPoints.has(i)) points = backPoints.get(i);
|
|
31065
|
+
else if (flatPoints.has(i)) points = flatPoints.get(i);
|
|
31066
|
+
else {
|
|
30226
31067
|
const chain = chainById.get(i);
|
|
30227
31068
|
if (!chain) continue;
|
|
30228
31069
|
points = chain.map((id) => coord(node.get(id)));
|
|
@@ -30239,79 +31080,124 @@ function layeredCandidates(parsed, sizes, opts) {
|
|
|
30239
31080
|
metadata: e.metadata
|
|
30240
31081
|
});
|
|
30241
31082
|
}
|
|
30242
|
-
|
|
30243
|
-
|
|
30244
|
-
|
|
30245
|
-
|
|
30246
|
-
|
|
30247
|
-
|
|
31083
|
+
const nodeBox = new Map(
|
|
31084
|
+
layoutNodes.map((n) => [
|
|
31085
|
+
n.label,
|
|
31086
|
+
{
|
|
31087
|
+
l: n.x - n.width / 2,
|
|
31088
|
+
r: n.x + n.width / 2,
|
|
31089
|
+
t: n.y - n.height / 2,
|
|
31090
|
+
b: n.y + n.height / 2
|
|
31091
|
+
}
|
|
31092
|
+
])
|
|
31093
|
+
);
|
|
31094
|
+
const depthOf = (label) => {
|
|
31095
|
+
let d = 0;
|
|
31096
|
+
let cur = label;
|
|
31097
|
+
const guard = /* @__PURE__ */ new Set();
|
|
31098
|
+
while (cur && !guard.has(cur)) {
|
|
31099
|
+
guard.add(cur);
|
|
31100
|
+
cur = groupByLabel.get(cur)?.parentGroup;
|
|
31101
|
+
if (cur) d++;
|
|
31102
|
+
}
|
|
31103
|
+
return d;
|
|
31104
|
+
};
|
|
31105
|
+
const childGroups = /* @__PURE__ */ new Map();
|
|
31106
|
+
for (const g of parsed.groups)
|
|
31107
|
+
if (g.parentGroup)
|
|
31108
|
+
(childGroups.get(g.parentGroup) ?? childGroups.set(g.parentGroup, []).get(g.parentGroup)).push(g.label);
|
|
31109
|
+
const rectByGroup = /* @__PURE__ */ new Map();
|
|
31110
|
+
const ordered = [...parsed.groups].sort(
|
|
31111
|
+
(a, b) => depthOf(b.label) - depthOf(a.label)
|
|
31112
|
+
);
|
|
31113
|
+
const layoutGroups = [];
|
|
31114
|
+
for (const grp of ordered) {
|
|
31115
|
+
let l = Infinity, r = -Infinity, t = Infinity, bm = -Infinity;
|
|
31116
|
+
const acc2 = (box) => {
|
|
31117
|
+
l = Math.min(l, box.l);
|
|
31118
|
+
r = Math.max(r, box.r);
|
|
31119
|
+
t = Math.min(t, box.t);
|
|
31120
|
+
bm = Math.max(bm, box.b);
|
|
31121
|
+
};
|
|
31122
|
+
for (const c of grp.children) {
|
|
31123
|
+
const nb = nodeBox.get(c);
|
|
31124
|
+
if (nb) acc2(nb);
|
|
31125
|
+
}
|
|
31126
|
+
for (const sub of childGroups.get(grp.label) ?? []) {
|
|
31127
|
+
const sr = rectByGroup.get(sub);
|
|
31128
|
+
if (sr) acc2(sr);
|
|
31129
|
+
}
|
|
31130
|
+
if (!Number.isFinite(l)) continue;
|
|
31131
|
+
const x0 = l - GROUP_PAD;
|
|
31132
|
+
const x1 = r + GROUP_PAD;
|
|
31133
|
+
const y0 = t - GROUP_LABEL_ZONE2;
|
|
31134
|
+
const y1 = bm + GROUP_PAD;
|
|
31135
|
+
rectByGroup.set(grp.label, { l: x0, r: x1, t: y0, b: y1 });
|
|
31136
|
+
layoutGroups.push({
|
|
31137
|
+
label: grp.label,
|
|
31138
|
+
lineNumber: grp.lineNumber,
|
|
31139
|
+
x: (x0 + x1) / 2,
|
|
31140
|
+
y: (y0 + y1) / 2,
|
|
31141
|
+
width: x1 - x0,
|
|
31142
|
+
height: y1 - y0,
|
|
31143
|
+
collapsed: false,
|
|
31144
|
+
childCount: grp.children.length
|
|
31145
|
+
});
|
|
30248
31146
|
}
|
|
31147
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
31148
|
+
const ext = (x0, y0, x1, y1) => {
|
|
31149
|
+
minX = Math.min(minX, x0);
|
|
31150
|
+
minY = Math.min(minY, y0);
|
|
31151
|
+
maxX = Math.max(maxX, x1);
|
|
31152
|
+
maxY = Math.max(maxY, y1);
|
|
31153
|
+
};
|
|
31154
|
+
for (const n of layoutNodes)
|
|
31155
|
+
ext(
|
|
31156
|
+
n.x - n.width / 2,
|
|
31157
|
+
n.y - n.height / 2,
|
|
31158
|
+
n.x + n.width / 2,
|
|
31159
|
+
n.y + n.height / 2
|
|
31160
|
+
);
|
|
30249
31161
|
for (const e of layoutEdges)
|
|
30250
|
-
for (const p of e.points)
|
|
30251
|
-
|
|
30252
|
-
|
|
30253
|
-
|
|
30254
|
-
|
|
30255
|
-
|
|
30256
|
-
|
|
30257
|
-
|
|
30258
|
-
const
|
|
30259
|
-
|
|
30260
|
-
|
|
31162
|
+
for (const p of e.points) ext(p.x, p.y, p.x, p.y);
|
|
31163
|
+
for (const g of layoutGroups)
|
|
31164
|
+
ext(
|
|
31165
|
+
g.x - g.width / 2,
|
|
31166
|
+
g.y - g.height / 2,
|
|
31167
|
+
g.x + g.width / 2,
|
|
31168
|
+
g.y + g.height / 2
|
|
31169
|
+
);
|
|
31170
|
+
const sx = MARGIN4 - minX;
|
|
31171
|
+
const sy = MARGIN4 - minY;
|
|
31172
|
+
const shift = sx !== 0 || sy !== 0;
|
|
31173
|
+
return {
|
|
31174
|
+
nodes: shift ? layoutNodes.map((n) => ({ ...n, x: n.x + sx, y: n.y + sy })) : layoutNodes,
|
|
31175
|
+
edges: shift ? layoutEdges.map((e) => ({
|
|
30261
31176
|
...e,
|
|
30262
31177
|
points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
|
|
30263
|
-
}))
|
|
30264
|
-
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
edges: shifted.edges,
|
|
30268
|
-
groups: [],
|
|
30269
|
-
width: maxX + sx + MARGIN3,
|
|
30270
|
-
height: maxY + sy + MARGIN3
|
|
31178
|
+
})) : layoutEdges,
|
|
31179
|
+
groups: shift ? layoutGroups.map((g) => ({ ...g, x: g.x + sx, y: g.y + sy })) : layoutGroups,
|
|
31180
|
+
width: maxX + sx + MARGIN4,
|
|
31181
|
+
height: maxY + sy + MARGIN4
|
|
30271
31182
|
};
|
|
30272
31183
|
}
|
|
30273
|
-
function weight(a, b) {
|
|
30274
|
-
if (a.dummy && b.dummy) return W_DUMMY_DUMMY;
|
|
30275
|
-
if (a.dummy || b.dummy) return W_REAL_DUMMY;
|
|
30276
|
-
return W_REAL_REAL;
|
|
30277
|
-
}
|
|
30278
|
-
function placeWithSeparation(ids, desired) {
|
|
30279
|
-
const n = ids.length;
|
|
30280
|
-
if (n === 0) return;
|
|
30281
|
-
const half = ids.map((id) => node.get(id).thick / 2);
|
|
30282
|
-
const off = [0];
|
|
30283
|
-
for (let i = 1; i < n; i++)
|
|
30284
|
-
off[i] = off[i - 1] + half[i - 1] + nodesep + half[i];
|
|
30285
|
-
const d = desired.map((v, i) => v - off[i]);
|
|
30286
|
-
const blocks = [];
|
|
30287
|
-
for (let i = 0; i < n; i++) {
|
|
30288
|
-
let b = { pos: d[i], count: 1, sumOffset: d[i], first: i };
|
|
30289
|
-
while (blocks.length && blocks[blocks.length - 1].pos >= b.pos) {
|
|
30290
|
-
const prev = blocks.pop();
|
|
30291
|
-
const count = prev.count + b.count;
|
|
30292
|
-
const sumOffset = prev.sumOffset + b.sumOffset;
|
|
30293
|
-
b = { pos: sumOffset / count, count, sumOffset, first: prev.first };
|
|
30294
|
-
}
|
|
30295
|
-
blocks.push(b);
|
|
30296
|
-
}
|
|
30297
|
-
const xs = new Array(n);
|
|
30298
|
-
for (const b of blocks)
|
|
30299
|
-
for (let k = 0; k < b.count; k++) xs[b.first + k] = b.pos;
|
|
30300
|
-
for (let i = 0; i < n; i++) node.get(ids[i]).cross = xs[i] + off[i];
|
|
30301
|
-
}
|
|
30302
31184
|
}
|
|
30303
|
-
var
|
|
30304
|
-
var
|
|
30305
|
-
"src/boxes-and-lines/layout-
|
|
31185
|
+
var NODESEP2, RANKSEP2, DUMMY_THICK2, MARGIN4, GROUP_PAD, GROUP_LABEL_ZONE2, GROUP_GAP, TIER_GAP, W_REAL_REAL2, W_REAL_DUMMY2, W_DUMMY_DUMMY2;
|
|
31186
|
+
var init_layout_grouped = __esm({
|
|
31187
|
+
"src/boxes-and-lines/layout-grouped.ts"() {
|
|
30306
31188
|
"use strict";
|
|
30307
31189
|
init_layout5();
|
|
30308
|
-
|
|
30309
|
-
|
|
30310
|
-
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
|
|
30314
|
-
|
|
31190
|
+
NODESEP2 = 50;
|
|
31191
|
+
RANKSEP2 = 60;
|
|
31192
|
+
DUMMY_THICK2 = 10;
|
|
31193
|
+
MARGIN4 = 40;
|
|
31194
|
+
GROUP_PAD = 16;
|
|
31195
|
+
GROUP_LABEL_ZONE2 = 32;
|
|
31196
|
+
GROUP_GAP = 24;
|
|
31197
|
+
TIER_GAP = GROUP_LABEL_ZONE2 + 2 * GROUP_PAD;
|
|
31198
|
+
W_REAL_REAL2 = 1;
|
|
31199
|
+
W_REAL_DUMMY2 = 2;
|
|
31200
|
+
W_DUMMY_DUMMY2 = 8;
|
|
30315
31201
|
}
|
|
30316
31202
|
});
|
|
30317
31203
|
|
|
@@ -30330,7 +31216,7 @@ __export(layout_search_exports, {
|
|
|
30330
31216
|
layoutBoxesAndLinesSearch: () => layoutBoxesAndLinesSearch,
|
|
30331
31217
|
separateGroupBands: () => separateGroupBands
|
|
30332
31218
|
});
|
|
30333
|
-
function
|
|
31219
|
+
function rng3(s) {
|
|
30334
31220
|
return () => {
|
|
30335
31221
|
s |= 0;
|
|
30336
31222
|
s = s + 1831565813 | 0;
|
|
@@ -30685,7 +31571,7 @@ function detectGroupOverlaps(layout, opts) {
|
|
|
30685
31571
|
const contains = (outer, inner) => outer.l <= inner.l + margin && outer.r >= inner.r - margin && outer.t <= inner.t + margin && outer.b >= inner.b - margin;
|
|
30686
31572
|
const rend = raw.map((a, i) => {
|
|
30687
31573
|
const parent = raw.some((b, j) => j !== i && contains(a, b));
|
|
30688
|
-
return parent ? { ...a, t: a.t -
|
|
31574
|
+
return parent ? { ...a, t: a.t - GROUP_LABEL_ZONE3 } : a;
|
|
30689
31575
|
});
|
|
30690
31576
|
const hit = /* @__PURE__ */ new Set();
|
|
30691
31577
|
for (let i = 0; i < raw.length; i++)
|
|
@@ -30712,7 +31598,7 @@ function countGroupOverlaps(layout, opts) {
|
|
|
30712
31598
|
const contains = (outer, inner) => outer.l <= inner.l + margin && outer.r >= inner.r - margin && outer.t <= inner.t + margin && outer.b >= inner.b - margin;
|
|
30713
31599
|
const rend = raw.map((a, i) => {
|
|
30714
31600
|
const parent = raw.some((b, j) => j !== i && contains(a, b));
|
|
30715
|
-
return parent ? { ...a, t: a.t -
|
|
31601
|
+
return parent ? { ...a, t: a.t - GROUP_LABEL_ZONE3 } : a;
|
|
30716
31602
|
});
|
|
30717
31603
|
let count = 0;
|
|
30718
31604
|
for (let i = 0; i < raw.length; i++)
|
|
@@ -30755,7 +31641,7 @@ function separateGroupBands(layout, parsed) {
|
|
|
30755
31641
|
let lo = (axis === "y" ? g.y : g.x) - half2;
|
|
30756
31642
|
const hi = (axis === "y" ? g.y : g.x) + half2;
|
|
30757
31643
|
const isParent = parsed.groups.some((c) => c.parentGroup === label);
|
|
30758
|
-
if (axis === "y" && isParent) lo -=
|
|
31644
|
+
if (axis === "y" && isParent) lo -= GROUP_LABEL_ZONE3;
|
|
30759
31645
|
return { label, lo, hi, c: (lo + hi) / 2 };
|
|
30760
31646
|
});
|
|
30761
31647
|
bands.sort((a, b) => a.c - b.c);
|
|
@@ -30826,7 +31712,7 @@ function separateGroupBands(layout, parsed) {
|
|
|
30826
31712
|
acc(n.x + n.width / 2, n.y + n.height / 2);
|
|
30827
31713
|
}
|
|
30828
31714
|
for (const g of groups) {
|
|
30829
|
-
acc(g.x - g.width / 2, g.y - g.height / 2 -
|
|
31715
|
+
acc(g.x - g.width / 2, g.y - g.height / 2 - GROUP_LABEL_ZONE3);
|
|
30830
31716
|
acc(g.x + g.width / 2, g.y + g.height / 2);
|
|
30831
31717
|
}
|
|
30832
31718
|
for (const e of edges) for (const p of e.points) acc(p.x, p.y);
|
|
@@ -30909,6 +31795,7 @@ function edgeLength(layout) {
|
|
|
30909
31795
|
}
|
|
30910
31796
|
async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
30911
31797
|
const hideDescriptions = opts?.hideDescriptions ?? false;
|
|
31798
|
+
const reserveEdgeLabels = opts?.reserveEdgeLabels ?? false;
|
|
30912
31799
|
const onProgress = opts?.onProgress;
|
|
30913
31800
|
const tick = onProgress ? () => new Promise((r) => setTimeout(r)) : () => void 0;
|
|
30914
31801
|
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
@@ -31090,7 +31977,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31090
31977
|
}
|
|
31091
31978
|
];
|
|
31092
31979
|
});
|
|
31093
|
-
const
|
|
31980
|
+
const GROUP_PAD2 = 16;
|
|
31094
31981
|
const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
|
|
31095
31982
|
const groups = [];
|
|
31096
31983
|
for (const grp of parsed.groups) {
|
|
@@ -31104,10 +31991,10 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31104
31991
|
gy1 = Math.max(gy1, n2.y + n2.height / 2);
|
|
31105
31992
|
}
|
|
31106
31993
|
if (!Number.isFinite(gx0)) continue;
|
|
31107
|
-
const x0 = gx0 -
|
|
31108
|
-
const x1 = gx1 +
|
|
31109
|
-
const y0 = gy0 -
|
|
31110
|
-
const y1 = gy1 +
|
|
31994
|
+
const x0 = gx0 - GROUP_PAD2;
|
|
31995
|
+
const x1 = gx1 + GROUP_PAD2;
|
|
31996
|
+
const y0 = gy0 - GROUP_LABEL_ZONE3;
|
|
31997
|
+
const y1 = gy1 + GROUP_PAD2;
|
|
31111
31998
|
groups.push({
|
|
31112
31999
|
label: grp.label,
|
|
31113
32000
|
lineNumber: grp.lineNumber,
|
|
@@ -31164,7 +32051,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31164
32051
|
};
|
|
31165
32052
|
}
|
|
31166
32053
|
function place(cfg) {
|
|
31167
|
-
const r = cfg.seed === void 0 ? null :
|
|
32054
|
+
const r = cfg.seed === void 0 ? null : rng3(cfg.seed + 1);
|
|
31168
32055
|
const ord = (a) => r ? shuffle(a, r) : a.slice();
|
|
31169
32056
|
const g = new import_dagre4.default.graphlib.Graph({ compound: true, multigraph: true });
|
|
31170
32057
|
g.setGraph({
|
|
@@ -31201,8 +32088,14 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31201
32088
|
for (const e of ord(parsed.edges)) {
|
|
31202
32089
|
const s = srcRep(e.source);
|
|
31203
32090
|
const t = tgtRep(e.target);
|
|
31204
|
-
if (s !== t && g.hasNode(s) && g.hasNode(t))
|
|
31205
|
-
|
|
32091
|
+
if (s !== t && g.hasNode(s) && g.hasNode(t)) {
|
|
32092
|
+
let edgeLabel = {};
|
|
32093
|
+
if (reserveEdgeLabels && e.label) {
|
|
32094
|
+
const m = measureEdgeLabel(e.label, EDGE_LABEL_FONT_SIZE6);
|
|
32095
|
+
edgeLabel = { width: m.width, height: m.height, labelpos: "c" };
|
|
32096
|
+
}
|
|
32097
|
+
g.setEdge(s, t, edgeLabel, edgeKey(e));
|
|
32098
|
+
}
|
|
31206
32099
|
}
|
|
31207
32100
|
import_dagre4.default.layout(g);
|
|
31208
32101
|
const nodes = parsed.nodes.map((n2) => {
|
|
@@ -31351,8 +32244,15 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31351
32244
|
layered = layeredCandidates(parsed, sizes);
|
|
31352
32245
|
} catch {
|
|
31353
32246
|
}
|
|
32247
|
+
if (parsed.groups.length > 0 && collapsedGroupLabels.size === 0) {
|
|
32248
|
+
try {
|
|
32249
|
+
layered = layered.concat(groupedTierCandidates(parsed, sizes));
|
|
32250
|
+
} catch {
|
|
32251
|
+
}
|
|
32252
|
+
}
|
|
31354
32253
|
const fastKey = /* @__PURE__ */ new Map();
|
|
31355
|
-
for (const lay of pool)
|
|
32254
|
+
for (const lay of pool)
|
|
32255
|
+
fastKey.set(lay, objective(lay, countCrossingsFast(lay)));
|
|
31356
32256
|
pool.sort((a, b) => fastKey.get(a) - fastKey.get(b));
|
|
31357
32257
|
const refineK = Math.min(REFINE_K, pool.length);
|
|
31358
32258
|
let best = pool[0];
|
|
@@ -31417,7 +32317,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31417
32317
|
}
|
|
31418
32318
|
return best;
|
|
31419
32319
|
}
|
|
31420
|
-
var import_dagre4, import_d3_shape, DEFAULT_LAMBDA, ESCALATE_THRESHOLD, ESCALATE_MAX_N, ESCALATE_SEEDS, ESCALATE_REFINE, splineGen, PATH_TOKEN_RE, FLAT_CACHE,
|
|
32320
|
+
var import_dagre4, import_d3_shape, DEFAULT_LAMBDA, ESCALATE_THRESHOLD, ESCALATE_MAX_N, ESCALATE_SEEDS, ESCALATE_REFINE, splineGen, PATH_TOKEN_RE, FLAT_CACHE, GROUP_LABEL_ZONE3;
|
|
31421
32321
|
var init_layout_search = __esm({
|
|
31422
32322
|
"src/boxes-and-lines/layout-search.ts"() {
|
|
31423
32323
|
"use strict";
|
|
@@ -31425,6 +32325,8 @@ var init_layout_search = __esm({
|
|
|
31425
32325
|
import_d3_shape = require("d3-shape");
|
|
31426
32326
|
init_layout5();
|
|
31427
32327
|
init_layout_layered();
|
|
32328
|
+
init_layout_grouped();
|
|
32329
|
+
init_label_placement();
|
|
31428
32330
|
DEFAULT_LAMBDA = 4;
|
|
31429
32331
|
ESCALATE_THRESHOLD = 4;
|
|
31430
32332
|
ESCALATE_MAX_N = 45;
|
|
@@ -31433,7 +32335,7 @@ var init_layout_search = __esm({
|
|
|
31433
32335
|
splineGen = (0, import_d3_shape.line)().x((d) => d.x).y((d) => d.y).curve(import_d3_shape.curveBasis);
|
|
31434
32336
|
PATH_TOKEN_RE = /[MLQC]|-?\d*\.?\d+(?:e-?\d+)?/gi;
|
|
31435
32337
|
FLAT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
31436
|
-
|
|
32338
|
+
GROUP_LABEL_ZONE3 = 32;
|
|
31437
32339
|
}
|
|
31438
32340
|
});
|
|
31439
32341
|
|
|
@@ -31483,9 +32385,9 @@ function estimateLabelLines(label, nodeWidth = NODE_WIDTH) {
|
|
|
31483
32385
|
current = word;
|
|
31484
32386
|
}
|
|
31485
32387
|
}
|
|
31486
|
-
if (lines <=
|
|
32388
|
+
if (lines <= MAX_LABEL_LINES2) return Math.min(lines, MAX_LABEL_LINES2);
|
|
31487
32389
|
}
|
|
31488
|
-
return
|
|
32390
|
+
return MAX_LABEL_LINES2;
|
|
31489
32391
|
}
|
|
31490
32392
|
function computeNodeSize(node, reserveValueRow) {
|
|
31491
32393
|
if (!node.description || node.description.length === 0) {
|
|
@@ -31493,7 +32395,7 @@ function computeNodeSize(node, reserveValueRow) {
|
|
|
31493
32395
|
}
|
|
31494
32396
|
const w = DESC_NODE_WIDTH;
|
|
31495
32397
|
const labelLines = estimateLabelLines(node.label, w);
|
|
31496
|
-
const labelHeight = labelLines * 13 *
|
|
32398
|
+
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT2 + LABEL_PAD;
|
|
31497
32399
|
const maxTextWidth = w - 24;
|
|
31498
32400
|
let totalRenderedLines = 0;
|
|
31499
32401
|
for (const line11 of node.description) {
|
|
@@ -31517,7 +32419,7 @@ function computeNodeSize(node, reserveValueRow) {
|
|
|
31517
32419
|
}
|
|
31518
32420
|
async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
31519
32421
|
const { layoutBoxesAndLinesSearch: layoutBoxesAndLinesSearch2 } = await Promise.resolve().then(() => (init_layout_search(), layout_search_exports));
|
|
31520
|
-
const
|
|
32422
|
+
const searchOpts = {
|
|
31521
32423
|
...layoutOptions?.hideDescriptions !== void 0 && {
|
|
31522
32424
|
hideDescriptions: layoutOptions.hideDescriptions
|
|
31523
32425
|
},
|
|
@@ -31527,12 +32429,23 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
|
31527
32429
|
...layoutOptions?.onProgress !== void 0 && {
|
|
31528
32430
|
onProgress: layoutOptions.onProgress
|
|
31529
32431
|
}
|
|
31530
|
-
}
|
|
31531
|
-
|
|
31532
|
-
applyParallelEdgeOffsets(searched),
|
|
32432
|
+
};
|
|
32433
|
+
const searched = await layoutBoxesAndLinesSearch2(
|
|
31533
32434
|
parsed,
|
|
31534
|
-
|
|
32435
|
+
collapseInfo,
|
|
32436
|
+
searchOpts
|
|
31535
32437
|
);
|
|
32438
|
+
let placed = placeEdgeLabels(applyParallelEdgeOffsets(searched));
|
|
32439
|
+
if (placed.unresolved.length > 0) {
|
|
32440
|
+
const relaid = await layoutBoxesAndLinesSearch2(parsed, collapseInfo, {
|
|
32441
|
+
...searchOpts,
|
|
32442
|
+
reserveEdgeLabels: true
|
|
32443
|
+
});
|
|
32444
|
+
const relaidPlaced = placeEdgeLabels(applyParallelEdgeOffsets(relaid));
|
|
32445
|
+
if (relaidPlaced.unresolved.length < placed.unresolved.length)
|
|
32446
|
+
placed = relaidPlaced;
|
|
32447
|
+
}
|
|
32448
|
+
return attachNotes(placed.layout, parsed, layoutOptions?.collapsedNotes);
|
|
31536
32449
|
}
|
|
31537
32450
|
function attachNotes(layout, parsed, collapsedNotes) {
|
|
31538
32451
|
const notesSuppressed = parsed.options?.["no-notes"] === "on";
|
|
@@ -31600,6 +32513,7 @@ function attachNotes(layout, parsed, collapsedNotes) {
|
|
|
31600
32513
|
points: e.points.map((pt) => ({ x: pt.x + shiftX, y: pt.y + shiftY })),
|
|
31601
32514
|
...e.labelX !== void 0 && { labelX: e.labelX + shiftX },
|
|
31602
32515
|
...e.labelY !== void 0 && { labelY: e.labelY + shiftY }
|
|
32516
|
+
// labelWidth/labelHeight/labelLines are shift-invariant — carried via spread.
|
|
31603
32517
|
})) : layout.edges;
|
|
31604
32518
|
const finalGroups = shifted ? layout.groups.map((grp) => ({
|
|
31605
32519
|
...grp,
|
|
@@ -31610,8 +32524,8 @@ function attachNotes(layout, parsed, collapsedNotes) {
|
|
|
31610
32524
|
nodes: finalNodes,
|
|
31611
32525
|
edges: finalEdges,
|
|
31612
32526
|
groups: finalGroups,
|
|
31613
|
-
width: bbMaxX + shiftX +
|
|
31614
|
-
height: bbMaxY + shiftY +
|
|
32527
|
+
width: bbMaxX + shiftX + MARGIN5,
|
|
32528
|
+
height: bbMaxY + shiftY + MARGIN5
|
|
31615
32529
|
};
|
|
31616
32530
|
}
|
|
31617
32531
|
function applyParallelEdgeOffsets(layout) {
|
|
@@ -31644,13 +32558,14 @@ function applyParallelEdgeOffsets(layout) {
|
|
|
31644
32558
|
}))
|
|
31645
32559
|
};
|
|
31646
32560
|
}
|
|
31647
|
-
var
|
|
32561
|
+
var MARGIN5, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP4, MAX_DESC_LINES2, MAX_LABEL_LINES2, LABEL_LINE_HEIGHT2, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
|
|
31648
32562
|
var init_layout5 = __esm({
|
|
31649
32563
|
"src/boxes-and-lines/layout.ts"() {
|
|
31650
32564
|
"use strict";
|
|
31651
32565
|
init_text_measure();
|
|
32566
|
+
init_label_placement();
|
|
31652
32567
|
init_notes();
|
|
31653
|
-
|
|
32568
|
+
MARGIN5 = 40;
|
|
31654
32569
|
MAX_PARALLEL_EDGES = 5;
|
|
31655
32570
|
PARALLEL_SPACING = 22;
|
|
31656
32571
|
PHI = 1.618;
|
|
@@ -31662,8 +32577,8 @@ var init_layout5 = __esm({
|
|
|
31662
32577
|
DESC_PADDING = 8;
|
|
31663
32578
|
SEPARATOR_GAP4 = 4;
|
|
31664
32579
|
MAX_DESC_LINES2 = 6;
|
|
31665
|
-
|
|
31666
|
-
|
|
32580
|
+
MAX_LABEL_LINES2 = 3;
|
|
32581
|
+
LABEL_LINE_HEIGHT2 = 1.3;
|
|
31667
32582
|
LABEL_PAD = 12;
|
|
31668
32583
|
VALUE_ROW_FONT = 11;
|
|
31669
32584
|
VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
|
|
@@ -31682,7 +32597,7 @@ function tokenize(text) {
|
|
|
31682
32597
|
return tokens;
|
|
31683
32598
|
}
|
|
31684
32599
|
function tryWrap(tokens, maxWidth, fontSize, maxLines) {
|
|
31685
|
-
const availWidth = maxWidth -
|
|
32600
|
+
const availWidth = maxWidth - H_PAD2;
|
|
31686
32601
|
const lines = [];
|
|
31687
32602
|
let currentLine = "";
|
|
31688
32603
|
for (const token of tokens) {
|
|
@@ -31707,7 +32622,7 @@ function tryWrap(tokens, maxWidth, fontSize, maxLines) {
|
|
|
31707
32622
|
return lines;
|
|
31708
32623
|
}
|
|
31709
32624
|
function truncateLastLine(lines, maxWidth, fontSize) {
|
|
31710
|
-
const availWidth = maxWidth -
|
|
32625
|
+
const availWidth = maxWidth - H_PAD2;
|
|
31711
32626
|
const result = [...lines];
|
|
31712
32627
|
const last = result[result.length - 1];
|
|
31713
32628
|
if (measureText(last, fontSize) > availWidth) {
|
|
@@ -31715,7 +32630,7 @@ function truncateLastLine(lines, maxWidth, fontSize) {
|
|
|
31715
32630
|
}
|
|
31716
32631
|
return result;
|
|
31717
32632
|
}
|
|
31718
|
-
function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines =
|
|
32633
|
+
function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABEL_LINES3) {
|
|
31719
32634
|
if (!text) return { lines: [""], fontSize: baseFontSize };
|
|
31720
32635
|
const tokens = tokenize(text);
|
|
31721
32636
|
for (let fs = baseFontSize; fs >= minFontSize; fs--) {
|
|
@@ -31730,7 +32645,7 @@ function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABE
|
|
|
31730
32645
|
if (allLines.length > maxLines) {
|
|
31731
32646
|
const last = truncated[truncated.length - 1];
|
|
31732
32647
|
if (!last.endsWith("\u2026")) {
|
|
31733
|
-
const availWidth = maxWidth -
|
|
32648
|
+
const availWidth = maxWidth - H_PAD2;
|
|
31734
32649
|
if (measureText(last + "\u2026", minFontSize) > availWidth) {
|
|
31735
32650
|
truncated[truncated.length - 1] = truncateText(
|
|
31736
32651
|
last,
|
|
@@ -31757,7 +32672,7 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
|
|
|
31757
32672
|
nodeWidth,
|
|
31758
32673
|
baseFontSize,
|
|
31759
32674
|
MIN_FONT_SIZE,
|
|
31760
|
-
|
|
32675
|
+
MAX_LABEL_LINES3
|
|
31761
32676
|
);
|
|
31762
32677
|
const descLines = [];
|
|
31763
32678
|
let descFontSize = DESC_FONT_SIZE3;
|
|
@@ -31785,14 +32700,14 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
|
|
|
31785
32700
|
descFontSize
|
|
31786
32701
|
};
|
|
31787
32702
|
}
|
|
31788
|
-
var
|
|
32703
|
+
var H_PAD2, MAX_LABEL_LINES3, MAX_DESC_LINES3, ROOT_FONT_SIZE, MIN_FONT_SIZE, FONT_STEP, DESC_FONT_SIZE3;
|
|
31789
32704
|
var init_text_wrap = __esm({
|
|
31790
32705
|
"src/mindmap/text-wrap.ts"() {
|
|
31791
32706
|
"use strict";
|
|
31792
32707
|
init_description_helpers();
|
|
31793
32708
|
init_text_measure();
|
|
31794
|
-
|
|
31795
|
-
|
|
32709
|
+
H_PAD2 = 16;
|
|
32710
|
+
MAX_LABEL_LINES3 = 3;
|
|
31796
32711
|
MAX_DESC_LINES3 = 2;
|
|
31797
32712
|
ROOT_FONT_SIZE = 17;
|
|
31798
32713
|
MIN_FONT_SIZE = 9;
|
|
@@ -31821,7 +32736,7 @@ function layoutMindmap(parsed, _palette, options) {
|
|
|
31821
32736
|
leafWidth: ctx.structural(LEAF_WIDTH),
|
|
31822
32737
|
hGap: ctx.aesthetic(H_GAP2),
|
|
31823
32738
|
vGap: ctx.aesthetic(V_GAP2),
|
|
31824
|
-
margin: ctx.aesthetic(
|
|
32739
|
+
margin: ctx.aesthetic(MARGIN6),
|
|
31825
32740
|
multiRootGap: ctx.aesthetic(MULTI_ROOT_GAP)
|
|
31826
32741
|
};
|
|
31827
32742
|
populateDepthCache(roots);
|
|
@@ -32179,7 +33094,7 @@ function nodeHeightS(node, hideDescriptions, sc) {
|
|
|
32179
33094
|
hideDescriptions
|
|
32180
33095
|
);
|
|
32181
33096
|
const labelLineCount = text.labelLines.length;
|
|
32182
|
-
const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT :
|
|
33097
|
+
const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT : LABEL_LINE_HEIGHT3 * labelLineCount;
|
|
32183
33098
|
let h = labelH + NODE_V_PAD;
|
|
32184
33099
|
if (text.descLines.length > 0) {
|
|
32185
33100
|
h += DESC_LINE_HEIGHT3 * text.descLines.length + 4;
|
|
@@ -32199,7 +33114,7 @@ function populateDepthCache(roots) {
|
|
|
32199
33114
|
};
|
|
32200
33115
|
walk(roots, 0);
|
|
32201
33116
|
}
|
|
32202
|
-
var ROOT_WIDTH, DEPTH1_WIDTH, LEAF_WIDTH, SINGLE_LABEL_HEIGHT,
|
|
33117
|
+
var ROOT_WIDTH, DEPTH1_WIDTH, LEAF_WIDTH, SINGLE_LABEL_HEIGHT, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT3, NODE_V_PAD, H_GAP2, V_GAP2, MARGIN6, MULTI_ROOT_GAP, nodeDepthCache;
|
|
32203
33118
|
var init_layout6 = __esm({
|
|
32204
33119
|
"src/mindmap/layout.ts"() {
|
|
32205
33120
|
"use strict";
|
|
@@ -32210,12 +33125,12 @@ var init_layout6 = __esm({
|
|
|
32210
33125
|
DEPTH1_WIDTH = 150;
|
|
32211
33126
|
LEAF_WIDTH = 120;
|
|
32212
33127
|
SINGLE_LABEL_HEIGHT = 28;
|
|
32213
|
-
|
|
33128
|
+
LABEL_LINE_HEIGHT3 = 18;
|
|
32214
33129
|
DESC_LINE_HEIGHT3 = 14;
|
|
32215
33130
|
NODE_V_PAD = 10;
|
|
32216
33131
|
H_GAP2 = 40;
|
|
32217
33132
|
V_GAP2 = 12;
|
|
32218
|
-
|
|
33133
|
+
MARGIN6 = 40;
|
|
32219
33134
|
MULTI_ROOT_GAP = 60;
|
|
32220
33135
|
nodeDepthCache = /* @__PURE__ */ new Map();
|
|
32221
33136
|
}
|
|
@@ -32472,7 +33387,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
32472
33387
|
);
|
|
32473
33388
|
const nodeG = mainG.append("g").attr("class", "mindmap-node").attr("data-line-number", node.lineNumber);
|
|
32474
33389
|
if (activeTagGroup) {
|
|
32475
|
-
const tagKey = activeTagGroup
|
|
33390
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
32476
33391
|
const metaValue = node.metadata[tagKey];
|
|
32477
33392
|
if (metaValue) {
|
|
32478
33393
|
nodeG.attr(`data-tag-${tagKey}`, metaValue.toLowerCase());
|
|
@@ -32501,18 +33416,18 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
32501
33416
|
descFontSize
|
|
32502
33417
|
} = textLayout;
|
|
32503
33418
|
const labelLineCount = labelLines.length;
|
|
32504
|
-
const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 :
|
|
33419
|
+
const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 : LABEL_LINE_HEIGHT4 * labelLineCount;
|
|
32505
33420
|
const labelZoneHeight = showDesc ? labelZoneH : node.height;
|
|
32506
33421
|
const centerX = node.x + node.width / 2;
|
|
32507
33422
|
if (labelLineCount <= 1) {
|
|
32508
33423
|
const labelY = node.y + labelZoneHeight / 2 + fontSize * 0.35;
|
|
32509
33424
|
nodeG.append("text").attr("x", centerX).attr("y", labelY).attr("text-anchor", "middle").attr("font-size", fontSize).attr("font-weight", isRoot ? "bold" : "normal").attr("fill", onFillText).text(labelLines[0]);
|
|
32510
33425
|
} else {
|
|
32511
|
-
const blockH =
|
|
33426
|
+
const blockH = LABEL_LINE_HEIGHT4 * (labelLineCount - 1);
|
|
32512
33427
|
const firstBaselineY = node.y + labelZoneHeight / 2 - blockH / 2 + fontSize * 0.35;
|
|
32513
33428
|
const textEl = nodeG.append("text").attr("x", centerX).attr("text-anchor", "middle").attr("font-size", fontSize).attr("font-weight", isRoot ? "bold" : "normal").attr("fill", onFillText);
|
|
32514
33429
|
for (let i = 0; i < labelLines.length; i++) {
|
|
32515
|
-
textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i *
|
|
33430
|
+
textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i * LABEL_LINE_HEIGHT4).text(labelLines[i]);
|
|
32516
33431
|
}
|
|
32517
33432
|
}
|
|
32518
33433
|
if (labelLines.length > 1 || labelLines[0] !== node.label) {
|
|
@@ -32587,10 +33502,11 @@ function renderMindmapForExport(content, theme, palette) {
|
|
|
32587
33502
|
return extractExportSvg(container, theme);
|
|
32588
33503
|
});
|
|
32589
33504
|
}
|
|
32590
|
-
var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2,
|
|
33505
|
+
var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT4, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
|
|
32591
33506
|
var init_renderer7 = __esm({
|
|
32592
33507
|
"src/mindmap/renderer.ts"() {
|
|
32593
33508
|
"use strict";
|
|
33509
|
+
init_tag_groups();
|
|
32594
33510
|
d3Selection12 = __toESM(require("d3-selection"), 1);
|
|
32595
33511
|
init_fonts();
|
|
32596
33512
|
init_export_container();
|
|
@@ -32609,7 +33525,7 @@ var init_renderer7 = __esm({
|
|
|
32609
33525
|
DIAGRAM_PADDING7 = 20;
|
|
32610
33526
|
TITLE_HEIGHT4 = 30;
|
|
32611
33527
|
SINGLE_LABEL_HEIGHT2 = 28;
|
|
32612
|
-
|
|
33528
|
+
LABEL_LINE_HEIGHT4 = 18;
|
|
32613
33529
|
DESC_LINE_HEIGHT4 = 14;
|
|
32614
33530
|
NODE_RADIUS = 6;
|
|
32615
33531
|
ROOT_STROKE_WIDTH = 2.5;
|
|
@@ -33801,7 +34717,7 @@ function resolveNodeColor4(el, tagGroups, activeGroupName, ancestors) {
|
|
|
33801
34717
|
(g) => g.name.toLowerCase() === activeGroupName.toLowerCase()
|
|
33802
34718
|
);
|
|
33803
34719
|
if (!group) return void 0;
|
|
33804
|
-
const key = group.name
|
|
34720
|
+
const key = tagAttrKey(group.name);
|
|
33805
34721
|
let metaValue = el.metadata[key];
|
|
33806
34722
|
if (!metaValue && ancestors) {
|
|
33807
34723
|
for (const ancestor of ancestors) {
|
|
@@ -34003,8 +34919,8 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
34003
34919
|
}
|
|
34004
34920
|
}
|
|
34005
34921
|
if (nodes.length > 0) {
|
|
34006
|
-
const shiftX =
|
|
34007
|
-
const shiftY =
|
|
34922
|
+
const shiftX = MARGIN7 - minX;
|
|
34923
|
+
const shiftY = MARGIN7 - minY;
|
|
34008
34924
|
for (const node of nodes) {
|
|
34009
34925
|
node.x += shiftX;
|
|
34010
34926
|
node.y += shiftY;
|
|
@@ -34016,12 +34932,12 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
34016
34932
|
}
|
|
34017
34933
|
}
|
|
34018
34934
|
}
|
|
34019
|
-
let totalWidth = nodes.length > 0 ? maxX - minX +
|
|
34020
|
-
let totalHeight = nodes.length > 0 ? maxY - minY +
|
|
34935
|
+
let totalWidth = nodes.length > 0 ? maxX - minX + MARGIN7 * 2 : 0;
|
|
34936
|
+
let totalHeight = nodes.length > 0 ? maxY - minY + MARGIN7 * 2 : 0;
|
|
34021
34937
|
const legendGroups = computeLegendGroups3(parsed.tagGroups);
|
|
34022
34938
|
if (legendGroups.length > 0) {
|
|
34023
|
-
const legendY = totalHeight +
|
|
34024
|
-
let legendX =
|
|
34939
|
+
const legendY = totalHeight + MARGIN7;
|
|
34940
|
+
let legendX = MARGIN7;
|
|
34025
34941
|
for (const lg of legendGroups) {
|
|
34026
34942
|
lg.x = legendX;
|
|
34027
34943
|
lg.y = legendY;
|
|
@@ -34353,8 +35269,8 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
34353
35269
|
if (pt.y > maxY) maxY = pt.y;
|
|
34354
35270
|
}
|
|
34355
35271
|
}
|
|
34356
|
-
const shiftX =
|
|
34357
|
-
const shiftY =
|
|
35272
|
+
const shiftX = MARGIN7 - minX;
|
|
35273
|
+
const shiftY = MARGIN7 - minY;
|
|
34358
35274
|
for (const node of nodes) {
|
|
34359
35275
|
node.x += shiftX;
|
|
34360
35276
|
node.y += shiftY;
|
|
@@ -34371,12 +35287,12 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
34371
35287
|
pt.y += shiftY;
|
|
34372
35288
|
}
|
|
34373
35289
|
}
|
|
34374
|
-
let totalWidth = maxX - minX +
|
|
34375
|
-
let totalHeight = maxY - minY +
|
|
35290
|
+
let totalWidth = maxX - minX + MARGIN7 * 2;
|
|
35291
|
+
let totalHeight = maxY - minY + MARGIN7 * 2;
|
|
34376
35292
|
const legendGroups = computeLegendGroups3(parsed.tagGroups);
|
|
34377
35293
|
if (legendGroups.length > 0) {
|
|
34378
|
-
const legendY = totalHeight +
|
|
34379
|
-
let legendX =
|
|
35294
|
+
const legendY = totalHeight + MARGIN7;
|
|
35295
|
+
let legendX = MARGIN7;
|
|
34380
35296
|
for (const lg of legendGroups) {
|
|
34381
35297
|
lg.x = legendX;
|
|
34382
35298
|
lg.y = legendY;
|
|
@@ -34768,8 +35684,8 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
34768
35684
|
if (pt.y > maxY) maxY = pt.y;
|
|
34769
35685
|
}
|
|
34770
35686
|
}
|
|
34771
|
-
const shiftX =
|
|
34772
|
-
const shiftY =
|
|
35687
|
+
const shiftX = MARGIN7 - minX;
|
|
35688
|
+
const shiftY = MARGIN7 - minY;
|
|
34773
35689
|
for (const node of nodes) {
|
|
34774
35690
|
node.x += shiftX;
|
|
34775
35691
|
node.y += shiftY;
|
|
@@ -34786,12 +35702,12 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
34786
35702
|
pt.y += shiftY;
|
|
34787
35703
|
}
|
|
34788
35704
|
}
|
|
34789
|
-
let totalWidth = maxX - minX +
|
|
34790
|
-
let totalHeight = maxY - minY +
|
|
35705
|
+
let totalWidth = maxX - minX + MARGIN7 * 2;
|
|
35706
|
+
let totalHeight = maxY - minY + MARGIN7 * 2;
|
|
34791
35707
|
const legendGroups = computeLegendGroups3(parsed.tagGroups);
|
|
34792
35708
|
if (legendGroups.length > 0) {
|
|
34793
|
-
const legendY = totalHeight +
|
|
34794
|
-
let legendX =
|
|
35709
|
+
const legendY = totalHeight + MARGIN7;
|
|
35710
|
+
let legendX = MARGIN7;
|
|
34795
35711
|
for (const lg of legendGroups) {
|
|
34796
35712
|
lg.x = legendX;
|
|
34797
35713
|
lg.y = legendY;
|
|
@@ -35079,8 +35995,8 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
35079
35995
|
if (pt.y > maxY) maxY = pt.y;
|
|
35080
35996
|
}
|
|
35081
35997
|
}
|
|
35082
|
-
const shiftX =
|
|
35083
|
-
const shiftY =
|
|
35998
|
+
const shiftX = MARGIN7 - minX;
|
|
35999
|
+
const shiftY = MARGIN7 - minY;
|
|
35084
36000
|
for (const node of nodes) {
|
|
35085
36001
|
node.x += shiftX;
|
|
35086
36002
|
node.y += shiftY;
|
|
@@ -35095,12 +36011,12 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
35095
36011
|
pt.y += shiftY;
|
|
35096
36012
|
}
|
|
35097
36013
|
}
|
|
35098
|
-
let totalWidth = maxX - minX +
|
|
35099
|
-
let totalHeight = maxY - minY +
|
|
36014
|
+
let totalWidth = maxX - minX + MARGIN7 * 2;
|
|
36015
|
+
let totalHeight = maxY - minY + MARGIN7 * 2;
|
|
35100
36016
|
const legendGroups = computeLegendGroups3(parsed.tagGroups);
|
|
35101
36017
|
if (legendGroups.length > 0) {
|
|
35102
|
-
const legendY = totalHeight +
|
|
35103
|
-
let legendX =
|
|
36018
|
+
const legendY = totalHeight + MARGIN7;
|
|
36019
|
+
let legendX = MARGIN7;
|
|
35104
36020
|
for (const lg of legendGroups) {
|
|
35105
36021
|
lg.x = legendX;
|
|
35106
36022
|
lg.y = legendY;
|
|
@@ -35120,10 +36036,11 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
35120
36036
|
height: totalHeight
|
|
35121
36037
|
};
|
|
35122
36038
|
}
|
|
35123
|
-
var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT4, META_FONT_SIZE4,
|
|
36039
|
+
var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT4, META_FONT_SIZE4, MARGIN7, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
|
|
35124
36040
|
var init_layout8 = __esm({
|
|
35125
36041
|
"src/c4/layout.ts"() {
|
|
35126
36042
|
"use strict";
|
|
36043
|
+
init_tag_groups();
|
|
35127
36044
|
import_dagre5 = __toESM(require("@dagrejs/dagre"), 1);
|
|
35128
36045
|
init_legend_constants();
|
|
35129
36046
|
init_text_measure();
|
|
@@ -35141,7 +36058,7 @@ var init_layout8 = __esm({
|
|
|
35141
36058
|
CARD_H_PAD3 = 20;
|
|
35142
36059
|
META_LINE_HEIGHT4 = 16;
|
|
35143
36060
|
META_FONT_SIZE4 = 11;
|
|
35144
|
-
|
|
36061
|
+
MARGIN7 = 40;
|
|
35145
36062
|
BOUNDARY_PAD = 40;
|
|
35146
36063
|
GROUP_BOUNDARY_PAD = 24;
|
|
35147
36064
|
EDGE_NODE_COLLISION_WEIGHT = 5e3;
|
|
@@ -35275,7 +36192,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
35275
36192
|
const labelText = edge.label ?? "";
|
|
35276
36193
|
const techText = edge.technology ? `[${edge.technology}]` : "";
|
|
35277
36194
|
const textW = Math.max(
|
|
35278
|
-
measureText(labelText,
|
|
36195
|
+
measureText(labelText, EDGE_LABEL_FONT_SIZE7),
|
|
35279
36196
|
measureText(techText, TECH_FONT_SIZE)
|
|
35280
36197
|
);
|
|
35281
36198
|
const bgW = textW + 12;
|
|
@@ -35286,7 +36203,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
35286
36203
|
textY = midPt.y - 4;
|
|
35287
36204
|
}
|
|
35288
36205
|
if (labelText) {
|
|
35289
|
-
edgeG.append("text").attr("x", midPt.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size",
|
|
36206
|
+
edgeG.append("text").attr("x", midPt.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size", EDGE_LABEL_FONT_SIZE7).attr("class", "c4-edge-label").text(labelText);
|
|
35290
36207
|
}
|
|
35291
36208
|
if (techText) {
|
|
35292
36209
|
edgeG.append("text").attr("x", midPt.x).attr("y", labelText ? textY + 18 : textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size", TECH_FONT_SIZE).attr("font-style", "italic").attr("class", "c4-edge-tech").text(techText);
|
|
@@ -35296,7 +36213,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
35296
36213
|
for (const node of layout.nodes) {
|
|
35297
36214
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "c4-card").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
35298
36215
|
if (activeTagGroup) {
|
|
35299
|
-
const tagKey = activeTagGroup
|
|
36216
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
35300
36217
|
const tagValue = node.metadata[tagKey];
|
|
35301
36218
|
if (tagValue) {
|
|
35302
36219
|
nodeG.attr(`data-tag-${tagKey}`, tagValue.toLowerCase());
|
|
@@ -35470,7 +36387,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
|
|
|
35470
36387
|
const labelText = edge.label ?? "";
|
|
35471
36388
|
const techText = edge.technology ? `[${edge.technology}]` : "";
|
|
35472
36389
|
const textW = Math.max(
|
|
35473
|
-
measureText(labelText,
|
|
36390
|
+
measureText(labelText, EDGE_LABEL_FONT_SIZE7),
|
|
35474
36391
|
measureText(techText, TECH_FONT_SIZE)
|
|
35475
36392
|
);
|
|
35476
36393
|
const bgW = textW + 12;
|
|
@@ -35488,7 +36405,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
|
|
|
35488
36405
|
});
|
|
35489
36406
|
}
|
|
35490
36407
|
}
|
|
35491
|
-
|
|
36408
|
+
placeEdgeLabels2(pendingLabels, edges, obstacleRects);
|
|
35492
36409
|
for (const lbl of pendingLabels) {
|
|
35493
36410
|
lbl.edgeG.append("rect").attr("x", lbl.x - lbl.bgW / 2).attr("y", lbl.y - lbl.bgH / 2).attr("width", lbl.bgW).attr("height", lbl.bgH).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.9).attr("class", "c4-edge-label-bg");
|
|
35494
36411
|
let textY = lbl.y;
|
|
@@ -35496,7 +36413,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
|
|
|
35496
36413
|
textY = lbl.y - 4;
|
|
35497
36414
|
}
|
|
35498
36415
|
if (lbl.labelText) {
|
|
35499
|
-
lbl.edgeG.append("text").attr("x", lbl.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size",
|
|
36416
|
+
lbl.edgeG.append("text").attr("x", lbl.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size", EDGE_LABEL_FONT_SIZE7).attr("class", "c4-edge-label").text(lbl.labelText);
|
|
35500
36417
|
}
|
|
35501
36418
|
if (lbl.techText) {
|
|
35502
36419
|
lbl.edgeG.append("text").attr("x", lbl.x).attr("y", lbl.labelText ? textY + 18 : textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size", TECH_FONT_SIZE).attr("font-style", "italic").attr("class", "c4-edge-tech").text(lbl.techText);
|
|
@@ -35577,7 +36494,7 @@ function tangentAt(points, t) {
|
|
|
35577
36494
|
}
|
|
35578
36495
|
return { x: 0, y: 1 };
|
|
35579
36496
|
}
|
|
35580
|
-
function
|
|
36497
|
+
function placeEdgeLabels2(labels, edges, obstacleRects) {
|
|
35581
36498
|
if (labels.length === 0) return;
|
|
35582
36499
|
const allPaths = edges.map((e) => e.points);
|
|
35583
36500
|
const placedRects = [];
|
|
@@ -35855,7 +36772,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
|
|
|
35855
36772
|
for (const node of layout.nodes) {
|
|
35856
36773
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "c4-card").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
35857
36774
|
if (activeTagGroup) {
|
|
35858
|
-
const tagKey = activeTagGroup
|
|
36775
|
+
const tagKey = tagAttrKey(activeTagGroup);
|
|
35859
36776
|
const tagValue = node.metadata[tagKey];
|
|
35860
36777
|
if (tagValue) {
|
|
35861
36778
|
nodeG.attr(`data-tag-${tagKey}`, tagValue.toLowerCase());
|
|
@@ -36115,10 +37032,11 @@ function renderC4DeploymentForExport(content, theme, palette) {
|
|
|
36115
37032
|
document.body.removeChild(el);
|
|
36116
37033
|
}
|
|
36117
37034
|
}
|
|
36118
|
-
var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6,
|
|
37035
|
+
var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE7, TECH_FONT_SIZE, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
|
|
36119
37036
|
var init_renderer9 = __esm({
|
|
36120
37037
|
"src/c4/renderer.ts"() {
|
|
36121
37038
|
"use strict";
|
|
37039
|
+
init_tag_groups();
|
|
36122
37040
|
d3Selection14 = __toESM(require("d3-selection"), 1);
|
|
36123
37041
|
d3Shape6 = __toESM(require("d3-shape"), 1);
|
|
36124
37042
|
init_fonts();
|
|
@@ -36139,7 +37057,7 @@ var init_renderer9 = __esm({
|
|
|
36139
37057
|
NAME_FONT_SIZE2 = 14;
|
|
36140
37058
|
DESC_FONT_SIZE5 = 11;
|
|
36141
37059
|
DESC_LINE_HEIGHT6 = 16;
|
|
36142
|
-
|
|
37060
|
+
EDGE_LABEL_FONT_SIZE7 = 11;
|
|
36143
37061
|
TECH_FONT_SIZE = 10;
|
|
36144
37062
|
CARD_H_PAD4 = 20;
|
|
36145
37063
|
CARD_V_PAD4 = 14;
|
|
@@ -36763,7 +37681,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
36763
37681
|
const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
|
|
36764
37682
|
const sTitleY = ctx.structural(TITLE_Y);
|
|
36765
37683
|
const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
|
|
36766
|
-
const sEdgeLabelFontSize = ctx.text(
|
|
37684
|
+
const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE8);
|
|
36767
37685
|
const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
|
|
36768
37686
|
const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
|
|
36769
37687
|
const sArrowheadW = ctx.structural(ARROWHEAD_W3);
|
|
@@ -36989,7 +37907,7 @@ function renderFlowchartForExport(content, theme, palette) {
|
|
|
36989
37907
|
document.body.removeChild(container);
|
|
36990
37908
|
}
|
|
36991
37909
|
}
|
|
36992
|
-
var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2,
|
|
37910
|
+
var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
|
|
36993
37911
|
var init_flowchart_renderer = __esm({
|
|
36994
37912
|
"src/graph/flowchart-renderer.ts"() {
|
|
36995
37913
|
"use strict";
|
|
@@ -37009,7 +37927,7 @@ var init_flowchart_renderer = __esm({
|
|
|
37009
37927
|
DIAGRAM_PADDING9 = 20;
|
|
37010
37928
|
MAX_SCALE6 = 3;
|
|
37011
37929
|
NODE_FONT_SIZE2 = 13;
|
|
37012
|
-
|
|
37930
|
+
EDGE_LABEL_FONT_SIZE8 = 11;
|
|
37013
37931
|
ARROWHEAD_W3 = 10;
|
|
37014
37932
|
ARROWHEAD_H3 = 7;
|
|
37015
37933
|
IO_SKEW = 15;
|
|
@@ -38183,7 +39101,7 @@ function separateGroups(groups, nodes, isLR, maxIterations = 20) {
|
|
|
38183
39101
|
const crossOverlap = isLR ? Math.min(ga.x + ga.width, gb.x + gb.width) - Math.max(ga.x, gb.x) : Math.min(ga.y + ga.height, gb.y + gb.height) - Math.max(ga.y, gb.y);
|
|
38184
39102
|
if (crossOverlap <= 0) continue;
|
|
38185
39103
|
anyOverlap = true;
|
|
38186
|
-
const shift = primaryOverlap +
|
|
39104
|
+
const shift = primaryOverlap + GROUP_GAP2;
|
|
38187
39105
|
const aCenter = isLR ? ga.y + ga.height / 2 : ga.x + ga.width / 2;
|
|
38188
39106
|
const bCenter = isLR ? gb.y + gb.height / 2 : gb.x + gb.width / 2;
|
|
38189
39107
|
const groupToShift = aCenter <= bCenter ? gb : ga;
|
|
@@ -38443,7 +39361,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
38443
39361
|
const midIdx = Math.floor(edge.points.length / 2);
|
|
38444
39362
|
const midPt = edge.points[midIdx];
|
|
38445
39363
|
if (midPt) {
|
|
38446
|
-
const halfWidth = (measureText(edge.label,
|
|
39364
|
+
const halfWidth = (measureText(edge.label, EDGE_LABEL_FONT_SIZE9) + 8) / 2;
|
|
38447
39365
|
if (midPt.x - halfWidth < minX) minX = midPt.x - halfWidth;
|
|
38448
39366
|
if (midPt.x + halfWidth > maxX) maxX = midPt.x + halfWidth;
|
|
38449
39367
|
}
|
|
@@ -38477,7 +39395,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
38477
39395
|
height: totalHeight
|
|
38478
39396
|
};
|
|
38479
39397
|
}
|
|
38480
|
-
var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5,
|
|
39398
|
+
var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5, EDGE_LABEL_FONT_SIZE9, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP2;
|
|
38481
39399
|
var init_layout10 = __esm({
|
|
38482
39400
|
"src/infra/layout.ts"() {
|
|
38483
39401
|
"use strict";
|
|
@@ -38492,7 +39410,7 @@ var init_layout10 = __esm({
|
|
|
38492
39410
|
COLLAPSE_BAR_HEIGHT3 = 6;
|
|
38493
39411
|
NODE_FONT_SIZE3 = 13;
|
|
38494
39412
|
META_FONT_SIZE5 = 10;
|
|
38495
|
-
|
|
39413
|
+
EDGE_LABEL_FONT_SIZE9 = 11;
|
|
38496
39414
|
PADDING_X3 = 24;
|
|
38497
39415
|
GROUP_PADDING2 = 20;
|
|
38498
39416
|
GROUP_HEADER_HEIGHT = 24;
|
|
@@ -38533,7 +39451,7 @@ var init_layout10 = __esm({
|
|
|
38533
39451
|
"retention-hours": "retention",
|
|
38534
39452
|
partitions: "partitions"
|
|
38535
39453
|
};
|
|
38536
|
-
|
|
39454
|
+
GROUP_GAP2 = GROUP_PADDING2 * 2 + GROUP_HEADER_HEIGHT;
|
|
38537
39455
|
}
|
|
38538
39456
|
});
|
|
38539
39457
|
|
|
@@ -38597,7 +39515,7 @@ function buildScaledConstants(ctx) {
|
|
|
38597
39515
|
sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
|
|
38598
39516
|
sMetaFontSize: ctx.text(META_FONT_SIZE6),
|
|
38599
39517
|
sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
|
|
38600
|
-
sEdgeLabelFontSize: ctx.text(
|
|
39518
|
+
sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE10),
|
|
38601
39519
|
sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
|
|
38602
39520
|
sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
|
|
38603
39521
|
sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
|
|
@@ -39326,7 +40244,7 @@ function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate,
|
|
|
39326
40244
|
if (!midPt) continue;
|
|
39327
40245
|
const labelText = edge.label;
|
|
39328
40246
|
const g = svg.append("g").attr("class", animate ? "infra-edge-label" : "");
|
|
39329
|
-
const textWidth = measureText(labelText,
|
|
40247
|
+
const textWidth = measureText(labelText, EDGE_LABEL_FONT_SIZE10) + 8;
|
|
39330
40248
|
g.append("rect").attr("x", midPt.x - textWidth / 2).attr("y", midPt.y - 8).attr("width", textWidth).attr("height", 16).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.9);
|
|
39331
40249
|
g.append("text").attr("x", midPt.x).attr("y", midPt.y + 4).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sEdgeLabelFontSize).attr("fill", palette.textMuted).text(labelText);
|
|
39332
40250
|
if (animate) {
|
|
@@ -39340,7 +40258,7 @@ function resolveActiveTagStroke(node, activeGroup, tagGroups, palette) {
|
|
|
39340
40258
|
(t) => t.name.toLowerCase() === activeGroup.toLowerCase()
|
|
39341
40259
|
);
|
|
39342
40260
|
if (!tg) return null;
|
|
39343
|
-
const tagKey = (tg.alias ?? tg.name)
|
|
40261
|
+
const tagKey = tagAttrKey(tg.alias ?? tg.name);
|
|
39344
40262
|
const tagVal = node.tags[tagKey];
|
|
39345
40263
|
if (!tagVal) return null;
|
|
39346
40264
|
const tv = tg.values.find(
|
|
@@ -39669,7 +40587,7 @@ function computeInfraLegendGroups(nodes, tagGroups, palette, edges) {
|
|
|
39669
40587
|
groups.push({
|
|
39670
40588
|
name: tg.name,
|
|
39671
40589
|
type: "tag",
|
|
39672
|
-
tagKey: (tg.alias ?? tg.name)
|
|
40590
|
+
tagKey: tagAttrKey(tg.alias ?? tg.name),
|
|
39673
40591
|
entries,
|
|
39674
40592
|
width: LEGEND_CAPSULE_PAD * 2 + pillWidth2 + 4 + entriesWidth2,
|
|
39675
40593
|
minifiedWidth: pillWidth2
|
|
@@ -39717,7 +40635,7 @@ function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDa
|
|
|
39717
40635
|
});
|
|
39718
40636
|
legendG.selectAll("[data-legend-group]").classed("infra-legend-group", true);
|
|
39719
40637
|
for (const group of legendGroups) {
|
|
39720
|
-
const groupKey2 = group.name
|
|
40638
|
+
const groupKey2 = tagAttrKey(group.name);
|
|
39721
40639
|
for (const entry of group.entries) {
|
|
39722
40640
|
const entryEl = legendG.select(
|
|
39723
40641
|
`[data-legend-group="${groupKey2}"] [data-legend-entry="${entry.value.toLowerCase()}"]`
|
|
@@ -39936,10 +40854,11 @@ function parseAndLayoutInfra(content) {
|
|
|
39936
40854
|
const layout = layoutInfra(computed);
|
|
39937
40855
|
return { parsed, computed, layout };
|
|
39938
40856
|
}
|
|
39939
|
-
var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6,
|
|
40857
|
+
var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
|
|
39940
40858
|
var init_renderer10 = __esm({
|
|
39941
40859
|
"src/infra/renderer.ts"() {
|
|
39942
40860
|
"use strict";
|
|
40861
|
+
init_tag_groups();
|
|
39943
40862
|
d3Selection16 = __toESM(require("d3-selection"), 1);
|
|
39944
40863
|
d3Shape8 = __toESM(require("d3-shape"), 1);
|
|
39945
40864
|
init_fonts();
|
|
@@ -39961,7 +40880,7 @@ var init_renderer10 = __esm({
|
|
|
39961
40880
|
NODE_FONT_SIZE4 = 13;
|
|
39962
40881
|
META_FONT_SIZE6 = 10;
|
|
39963
40882
|
META_LINE_HEIGHT6 = 14;
|
|
39964
|
-
|
|
40883
|
+
EDGE_LABEL_FONT_SIZE10 = 11;
|
|
39965
40884
|
GROUP_LABEL_FONT_SIZE2 = 14;
|
|
39966
40885
|
NODE_BORDER_RADIUS = 8;
|
|
39967
40886
|
OVERLOAD_STROKE_WIDTH = 3;
|
|
@@ -40038,17 +40957,17 @@ function mulberry32(seed) {
|
|
|
40038
40957
|
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
40039
40958
|
};
|
|
40040
40959
|
}
|
|
40041
|
-
function standardNormal(
|
|
40960
|
+
function standardNormal(rng4) {
|
|
40042
40961
|
let u = 0;
|
|
40043
40962
|
let v = 0;
|
|
40044
|
-
while (u === 0) u =
|
|
40045
|
-
while (v === 0) v =
|
|
40963
|
+
while (u === 0) u = rng4();
|
|
40964
|
+
while (v === 0) v = rng4();
|
|
40046
40965
|
return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
|
|
40047
40966
|
}
|
|
40048
|
-
function gamma(shape,
|
|
40967
|
+
function gamma(shape, rng4) {
|
|
40049
40968
|
if (shape < 1) {
|
|
40050
|
-
const u =
|
|
40051
|
-
return gamma(shape + 1,
|
|
40969
|
+
const u = rng4();
|
|
40970
|
+
return gamma(shape + 1, rng4) * Math.pow(u, 1 / shape);
|
|
40052
40971
|
}
|
|
40053
40972
|
const d = shape - 1 / 3;
|
|
40054
40973
|
const c = 1 / Math.sqrt(9 * d);
|
|
@@ -40056,29 +40975,29 @@ function gamma(shape, rng3) {
|
|
|
40056
40975
|
let x;
|
|
40057
40976
|
let v;
|
|
40058
40977
|
do {
|
|
40059
|
-
x = standardNormal(
|
|
40978
|
+
x = standardNormal(rng4);
|
|
40060
40979
|
v = 1 + c * x;
|
|
40061
40980
|
} while (v <= 0);
|
|
40062
40981
|
v = v * v * v;
|
|
40063
|
-
const u =
|
|
40982
|
+
const u = rng4();
|
|
40064
40983
|
if (u < 1 - 0.0331 * x * x * x * x) return d * v;
|
|
40065
40984
|
if (Math.log(u) < x * x / 2 + d * (1 - v + Math.log(v))) return d * v;
|
|
40066
40985
|
}
|
|
40067
40986
|
}
|
|
40068
|
-
function sampleBeta(alpha, beta,
|
|
40069
|
-
const x = gamma(alpha,
|
|
40070
|
-
const y = gamma(beta,
|
|
40987
|
+
function sampleBeta(alpha, beta, rng4) {
|
|
40988
|
+
const x = gamma(alpha, rng4);
|
|
40989
|
+
const y = gamma(beta, rng4);
|
|
40071
40990
|
return x / (x + y);
|
|
40072
40991
|
}
|
|
40073
|
-
function sampleBetaPert(o, m, p,
|
|
40992
|
+
function sampleBetaPert(o, m, p, rng4) {
|
|
40074
40993
|
if (o === p) return m;
|
|
40075
40994
|
const range = p - o;
|
|
40076
40995
|
const alpha = 1 + 4 * (m - o) / range;
|
|
40077
40996
|
const beta = 1 + 4 * (p - m) / range;
|
|
40078
|
-
return o + sampleBeta(alpha, beta,
|
|
40997
|
+
return o + sampleBeta(alpha, beta, rng4) * range;
|
|
40079
40998
|
}
|
|
40080
40999
|
function simulate(resolved, expanded, _predecessors, _successors, topo, terminals, poisoned, opts) {
|
|
40081
|
-
const
|
|
41000
|
+
const rng4 = mulberry32(opts.seed);
|
|
40082
41001
|
const expById = /* @__PURE__ */ new Map();
|
|
40083
41002
|
for (const e of expanded) expById.set(e.id, e);
|
|
40084
41003
|
const completionTimes = new Array(opts.trials);
|
|
@@ -40101,7 +41020,7 @@ function simulate(resolved, expanded, _predecessors, _successors, topo, terminal
|
|
|
40101
41020
|
} else if (exp.o === exp.p) {
|
|
40102
41021
|
duration = exp.m;
|
|
40103
41022
|
} else {
|
|
40104
|
-
duration = sampleBetaPert(exp.o, exp.m, exp.p,
|
|
41023
|
+
duration = sampleBetaPert(exp.o, exp.m, exp.p, rng4);
|
|
40105
41024
|
}
|
|
40106
41025
|
let esLower = 0;
|
|
40107
41026
|
let efLower = -Infinity;
|
|
@@ -44389,7 +45308,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
44389
45308
|
const ctx = exportDims ? ScaleContext.identity() : ScaleContext.from(containerWidth, idealWidth);
|
|
44390
45309
|
const sBarH = ctx.structural(BAR_H);
|
|
44391
45310
|
const sRowGap = ctx.structural(ROW_GAP);
|
|
44392
|
-
const sGroupGap = ctx.structural(
|
|
45311
|
+
const sGroupGap = ctx.structural(GROUP_GAP3);
|
|
44393
45312
|
const sMilestoneSize = ctx.structural(MILESTONE_SIZE);
|
|
44394
45313
|
const sBottomMargin = ctx.aesthetic(BOTTOM_MARGIN);
|
|
44395
45314
|
const sRightMargin = ctx.aesthetic(RIGHT_MARGIN);
|
|
@@ -44561,7 +45480,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
44561
45480
|
(tg) => tg.name.toLowerCase() === currentSwimlaneGroup.toLowerCase()
|
|
44562
45481
|
);
|
|
44563
45482
|
if (tagGroup) {
|
|
44564
|
-
const tagKey = tagGroup.name
|
|
45483
|
+
const tagKey = tagAttrKey(tagGroup.name);
|
|
44565
45484
|
for (const rt of resolved.tasks) {
|
|
44566
45485
|
let value = rt.effectiveMetadata[tagKey];
|
|
44567
45486
|
if (!value && tagGroup.defaultValue) value = tagGroup.defaultValue;
|
|
@@ -45302,7 +46221,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
45302
46221
|
const usedValues = /* @__PURE__ */ new Map();
|
|
45303
46222
|
if (resolvedTasks) {
|
|
45304
46223
|
for (const group of visibleGroups) {
|
|
45305
|
-
const key = group.name
|
|
46224
|
+
const key = tagAttrKey(group.name);
|
|
45306
46225
|
const used = /* @__PURE__ */ new Set();
|
|
45307
46226
|
for (const rt of resolvedTasks) {
|
|
45308
46227
|
const val = rt.effectiveMetadata[key];
|
|
@@ -45313,7 +46232,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
45313
46232
|
}
|
|
45314
46233
|
const filteredEntries = /* @__PURE__ */ new Map();
|
|
45315
46234
|
for (const group of visibleGroups) {
|
|
45316
|
-
const key = group.name
|
|
46235
|
+
const key = tagAttrKey(group.name);
|
|
45317
46236
|
const used = usedValues.get(key);
|
|
45318
46237
|
if (used && used.size > 0) {
|
|
45319
46238
|
filteredEntries.set(
|
|
@@ -45334,7 +46253,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
45334
46253
|
const pillW = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD + iconReserve;
|
|
45335
46254
|
let groupW = pillW;
|
|
45336
46255
|
if (isActive) {
|
|
45337
|
-
const entries = filteredEntries.get(group.name
|
|
46256
|
+
const entries = filteredEntries.get(tagAttrKey(group.name)) ?? group.entries;
|
|
45338
46257
|
let entriesW = 0;
|
|
45339
46258
|
for (const entry of entries) {
|
|
45340
46259
|
entriesW += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
@@ -45391,7 +46310,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
45391
46310
|
},
|
|
45392
46311
|
...onControlsToggle !== void 0 && { onControlsToggle },
|
|
45393
46312
|
onEntryHover: (groupName, entryValue) => {
|
|
45394
|
-
const tagKey = groupName
|
|
46313
|
+
const tagKey = tagAttrKey(groupName);
|
|
45395
46314
|
if (entryValue) {
|
|
45396
46315
|
const ev = entryValue.toLowerCase();
|
|
45397
46316
|
chartG.selectAll(".gantt-task").each(function() {
|
|
@@ -46081,7 +47000,7 @@ function buildTagLaneRowList(resolved, swimlaneGroup, collapsedLanes) {
|
|
|
46081
47000
|
(g) => g.name.toLowerCase() === swimlaneGroup.toLowerCase()
|
|
46082
47001
|
);
|
|
46083
47002
|
if (!tagGroup) return null;
|
|
46084
|
-
const tagKey = tagGroup.name
|
|
47003
|
+
const tagKey = tagAttrKey(tagGroup.name);
|
|
46085
47004
|
const rows = [];
|
|
46086
47005
|
const buckets = /* @__PURE__ */ new Map();
|
|
46087
47006
|
const unbucketed = [];
|
|
@@ -46265,10 +47184,11 @@ function renderTimeScaleHorizontal(g, scale, _innerWidth, innerHeight, textColor
|
|
|
46265
47184
|
g.append("text").attr("class", "gantt-scale-tick").attr("x", tick.pos).attr("y", innerHeight + tickLen + 12).attr("text-anchor", "middle").attr("font-size", "10px").attr("fill", textColor).attr("opacity", opacity).text(tick.label);
|
|
46266
47185
|
}
|
|
46267
47186
|
}
|
|
46268
|
-
var d3Scale5, d3Selection18, BAR_H, ROW_GAP,
|
|
47187
|
+
var d3Scale5, d3Selection18, BAR_H, ROW_GAP, GROUP_GAP3, MILESTONE_SIZE, MIN_LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, LABEL_PAD2, LABEL_GAP, BAND_ACCENT_W, BAND_RADIUS, bandClipCounter, JS_DAY_TO_WEEKDAY2, ERA_COLORS, SPRINT_BAND_OPACITY, SPRINT_HOVER_OPACITY, SPRINT_BOUNDARY_OPACITY, FADE_OPACITY;
|
|
46269
47188
|
var init_renderer12 = __esm({
|
|
46270
47189
|
"src/gantt/renderer.ts"() {
|
|
46271
47190
|
"use strict";
|
|
47191
|
+
init_tag_groups();
|
|
46272
47192
|
d3Scale5 = __toESM(require("d3-scale"), 1);
|
|
46273
47193
|
d3Selection18 = __toESM(require("d3-selection"), 1);
|
|
46274
47194
|
init_fonts();
|
|
@@ -46285,7 +47205,7 @@ var init_renderer12 = __esm({
|
|
|
46285
47205
|
init_title_constants();
|
|
46286
47206
|
BAR_H = 22;
|
|
46287
47207
|
ROW_GAP = 6;
|
|
46288
|
-
|
|
47208
|
+
GROUP_GAP3 = 14;
|
|
46289
47209
|
MILESTONE_SIZE = 10;
|
|
46290
47210
|
MIN_LEFT_MARGIN = 120;
|
|
46291
47211
|
BOTTOM_MARGIN = 40;
|
|
@@ -46351,7 +47271,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
46351
47271
|
const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
|
|
46352
47272
|
const sTitleY = ctx.structural(TITLE_Y);
|
|
46353
47273
|
const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
|
|
46354
|
-
const sEdgeLabelFontSize = ctx.text(
|
|
47274
|
+
const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE11);
|
|
46355
47275
|
const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
|
|
46356
47276
|
const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
|
|
46357
47277
|
const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
|
|
@@ -46631,7 +47551,7 @@ function renderStateForExport(content, theme, palette) {
|
|
|
46631
47551
|
document.body.removeChild(container);
|
|
46632
47552
|
}
|
|
46633
47553
|
}
|
|
46634
|
-
var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6,
|
|
47554
|
+
var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE11, GROUP_LABEL_FONT_SIZE3, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
|
|
46635
47555
|
var init_state_renderer = __esm({
|
|
46636
47556
|
"src/graph/state-renderer.ts"() {
|
|
46637
47557
|
"use strict";
|
|
@@ -46651,7 +47571,7 @@ var init_state_renderer = __esm({
|
|
|
46651
47571
|
DIAGRAM_PADDING12 = 20;
|
|
46652
47572
|
MAX_SCALE7 = 3;
|
|
46653
47573
|
NODE_FONT_SIZE6 = 13;
|
|
46654
|
-
|
|
47574
|
+
EDGE_LABEL_FONT_SIZE11 = 11;
|
|
46655
47575
|
GROUP_LABEL_FONT_SIZE3 = 11;
|
|
46656
47576
|
ARROWHEAD_W5 = 10;
|
|
46657
47577
|
ARROWHEAD_H5 = 7;
|
|
@@ -48578,7 +49498,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
48578
49498
|
const panelWidth = 280;
|
|
48579
49499
|
const textAreaWidth = panelWidth - silhouetteZone - CARD_PADDING_X3;
|
|
48580
49500
|
const descLineH = 14;
|
|
48581
|
-
const descLines = parsed.persona.description ?
|
|
49501
|
+
const descLines = parsed.persona.description ? wrapNoteBody(parsed.persona.description, textAreaWidth, FONT_SIZE_META) : [];
|
|
48582
49502
|
const descRowH = descLines.length > 0 ? descLines.length * descLineH + 8 : 0;
|
|
48583
49503
|
const panelHeight = titleRowH + descRowH;
|
|
48584
49504
|
const panelX = layout.totalWidth - PADDING2 - panelWidth;
|
|
@@ -48603,8 +49523,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
48603
49523
|
personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
|
|
48604
49524
|
personaG.append("text").attr("x", textX).attr("y", panelY + CARD_PADDING_Y3 + FONT_SIZE_STEP).attr("font-size", FONT_SIZE_STEP).attr("font-weight", "500").attr("fill", onPersonaText).text(parsed.persona.name);
|
|
48605
49525
|
for (let li = 0; li < descLines.length; li++) {
|
|
48606
|
-
const
|
|
48607
|
-
|
|
49526
|
+
const line11 = descLines[li];
|
|
49527
|
+
const indent = line11.kind === "plain" ? 0 : NOTE_BULLET_INDENT;
|
|
49528
|
+
const lineY = panelY + titleRowH + descLineH * (li + 1);
|
|
49529
|
+
if (line11.kind === "bullet-first") {
|
|
49530
|
+
personaG.append("text").attr("x", textX).attr("y", lineY).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText).text("\u2022");
|
|
49531
|
+
}
|
|
49532
|
+
const lineEl = personaG.append("text").attr("x", textX + indent).attr("y", lineY).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
|
|
49533
|
+
renderInlineText(lineEl, line11.text, palette, FONT_SIZE_META);
|
|
48608
49534
|
}
|
|
48609
49535
|
if (onNavigateToLine) {
|
|
48610
49536
|
personaG.style("cursor", "pointer").on("click", () => {
|
|
@@ -48643,7 +49569,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
48643
49569
|
return;
|
|
48644
49570
|
}
|
|
48645
49571
|
const isScore = groupName === "Score";
|
|
48646
|
-
const attrName = isScore ? "data-score" : `data-tag-${groupName
|
|
49572
|
+
const attrName = isScore ? "data-score" : `data-tag-${tagAttrKey(groupName)}`;
|
|
48647
49573
|
const matches = (el) => el.getAttribute(attrName) === entryValue;
|
|
48648
49574
|
svg.selectAll(".journey-step").each(function() {
|
|
48649
49575
|
const hit = matches(this);
|
|
@@ -49124,7 +50050,7 @@ function resolveStepColor(step, scoreColor, activeGroup, tagGroups, _palette) {
|
|
|
49124
50050
|
(g) => g.name.toLowerCase() === activeGroup.toLowerCase()
|
|
49125
50051
|
);
|
|
49126
50052
|
if (!group) return void 0;
|
|
49127
|
-
const tagValue = step.tags[group.name
|
|
50053
|
+
const tagValue = step.tags[tagAttrKey(group.name)];
|
|
49128
50054
|
if (!tagValue) return void 0;
|
|
49129
50055
|
const entry = group.entries.find(
|
|
49130
50056
|
(e) => e.value.toLowerCase() === tagValue.toLowerCase()
|
|
@@ -49339,6 +50265,7 @@ var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3
|
|
|
49339
50265
|
var init_renderer14 = __esm({
|
|
49340
50266
|
"src/journey-map/renderer.ts"() {
|
|
49341
50267
|
"use strict";
|
|
50268
|
+
init_tag_groups();
|
|
49342
50269
|
d3 = __toESM(require("d3-selection"), 1);
|
|
49343
50270
|
d3Shape10 = __toESM(require("d3-shape"), 1);
|
|
49344
50271
|
init_color_utils();
|
|
@@ -49346,6 +50273,7 @@ var init_renderer14 = __esm({
|
|
|
49346
50273
|
init_parser23();
|
|
49347
50274
|
init_layout13();
|
|
49348
50275
|
init_inline_markdown();
|
|
50276
|
+
init_note_box();
|
|
49349
50277
|
init_legend_integration();
|
|
49350
50278
|
init_tag_groups();
|
|
49351
50279
|
init_scaling();
|
|
@@ -49685,10 +50613,10 @@ function renderedDescNodeHeight(numLines, scale) {
|
|
|
49685
50613
|
return headerH + textBlockH + bottomPad;
|
|
49686
50614
|
}
|
|
49687
50615
|
function wrapEdgeLabelText(label, description, maxWidth = EDGE_LABEL_MAX_WIDTH) {
|
|
49688
|
-
const labelLines = label ? wrapTextToWidth(label,
|
|
50616
|
+
const labelLines = label ? wrapTextToWidth(label, EDGE_LABEL_FONT_SIZE12, maxWidth) : [];
|
|
49689
50617
|
const descLines = [];
|
|
49690
50618
|
for (const d of description) {
|
|
49691
|
-
descLines.push(...wrapTextToWidth(d,
|
|
50619
|
+
descLines.push(...wrapTextToWidth(d, EDGE_LABEL_FONT_SIZE12, maxWidth));
|
|
49692
50620
|
}
|
|
49693
50621
|
return { labelLines, descLines };
|
|
49694
50622
|
}
|
|
@@ -49826,9 +50754,9 @@ function computeEdgePaths(layoutNodes, parsed, cx, cy, radius, isClockwise) {
|
|
|
49826
50754
|
const lineCount = labelLines.length + descLines.length;
|
|
49827
50755
|
let labelPxW = 0;
|
|
49828
50756
|
for (const l of labelLines)
|
|
49829
|
-
labelPxW = Math.max(labelPxW, measureText(l,
|
|
50757
|
+
labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
|
|
49830
50758
|
for (const l of descLines)
|
|
49831
|
-
labelPxW = Math.max(labelPxW, measureText(l,
|
|
50759
|
+
labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
|
|
49832
50760
|
const { labelX, labelY, labelAngle } = computeEdgeLabelPosition(
|
|
49833
50761
|
midAngle,
|
|
49834
50762
|
radius,
|
|
@@ -49930,9 +50858,9 @@ function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isC
|
|
|
49930
50858
|
);
|
|
49931
50859
|
let textWidth = 0;
|
|
49932
50860
|
for (const l of labelLines)
|
|
49933
|
-
textWidth = Math.max(textWidth, measureText(l,
|
|
50861
|
+
textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
|
|
49934
50862
|
for (const l of descLines)
|
|
49935
|
-
textWidth = Math.max(textWidth, measureText(l,
|
|
50863
|
+
textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
|
|
49936
50864
|
if (textWidth === 0) continue;
|
|
49937
50865
|
const normAngle = (le.labelAngle % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
|
|
49938
50866
|
const isRight = normAngle < Math.PI * 0.4 || normAngle > Math.PI * 1.6;
|
|
@@ -50006,7 +50934,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
|
|
|
50006
50934
|
const midAngle = srcExitAngle + dir * visibleSweep / 2;
|
|
50007
50935
|
return { path, midAngle };
|
|
50008
50936
|
}
|
|
50009
|
-
var MIN_ARC_ANGLE, LABEL_FONT_SIZE4, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6,
|
|
50937
|
+
var MIN_ARC_ANGLE, LABEL_FONT_SIZE4, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6, EDGE_LABEL_FONT_SIZE12, MIN_NODE_WIDTH4, MAX_NODE_WIDTH3, DESC_MIN_WIDTH, DESC_WIDTH_STEP, DESC_TARGET_RATIO, PLAIN_NODE_HEIGHT, HEADER_HEIGHT4, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, RENDERER_DESC_FONT, RENDERER_DESC_FONT_MIN, RENDERER_DESC_LINE_H, RENDERER_DESC_LINE_H_MIN, EDGE_LABEL_MAX_WIDTH;
|
|
50010
50938
|
var init_layout14 = __esm({
|
|
50011
50939
|
"src/cycle/layout.ts"() {
|
|
50012
50940
|
"use strict";
|
|
@@ -50017,7 +50945,7 @@ var init_layout14 = __esm({
|
|
|
50017
50945
|
LABEL_FONT_SIZE4 = 13;
|
|
50018
50946
|
CIRCLE_LABEL_FONT_SIZE = 16;
|
|
50019
50947
|
DESC_FONT_SIZE6 = 11;
|
|
50020
|
-
|
|
50948
|
+
EDGE_LABEL_FONT_SIZE12 = 11;
|
|
50021
50949
|
MIN_NODE_WIDTH4 = 70;
|
|
50022
50950
|
MAX_NODE_WIDTH3 = 260;
|
|
50023
50951
|
DESC_MIN_WIDTH = 140;
|
|
@@ -50162,7 +51090,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
|
|
|
50162
51090
|
const scaledNodeFont = Math.max(6, Math.round(NODE_FONT_SIZE7 * layout.scale));
|
|
50163
51091
|
const scaledEdgeLabelFont = Math.max(
|
|
50164
51092
|
6,
|
|
50165
|
-
Math.round(
|
|
51093
|
+
Math.round(EDGE_LABEL_FONT_SIZE13 * layout.scale)
|
|
50166
51094
|
);
|
|
50167
51095
|
const CIRCLE_LABEL_FONT_SIZE2 = 16;
|
|
50168
51096
|
const scaledCircleLabelFont = Math.max(
|
|
@@ -50325,7 +51253,7 @@ function ensureArrowMarker(defs, color, strokeWidth) {
|
|
|
50325
51253
|
const mh = Math.max(1.5, mw * 0.5);
|
|
50326
51254
|
defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${mw} ${mh}`).attr("refX", mw * 0.1).attr("refY", mh / 2).attr("markerWidth", mw).attr("markerHeight", mh).attr("orient", "auto").append("polygon").attr("points", `0,0 ${mw},${mh / 2} 0,${mh}`).attr("fill", color);
|
|
50327
51255
|
}
|
|
50328
|
-
var d3Selection22, NODE_FONT_SIZE7, DESC_FONT_SIZE7,
|
|
51256
|
+
var d3Selection22, NODE_FONT_SIZE7, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE13, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
|
|
50329
51257
|
var init_renderer15 = __esm({
|
|
50330
51258
|
"src/cycle/renderer.ts"() {
|
|
50331
51259
|
"use strict";
|
|
@@ -50343,7 +51271,7 @@ var init_renderer15 = __esm({
|
|
|
50343
51271
|
init_text_measure();
|
|
50344
51272
|
NODE_FONT_SIZE7 = 13;
|
|
50345
51273
|
DESC_FONT_SIZE7 = 11;
|
|
50346
|
-
|
|
51274
|
+
EDGE_LABEL_FONT_SIZE13 = 11;
|
|
50347
51275
|
DESC_LINE_HEIGHT8 = 15;
|
|
50348
51276
|
TITLE_AREA_HEIGHT = 50;
|
|
50349
51277
|
}
|
|
@@ -52169,7 +53097,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
52169
53097
|
(g) => g.name.toLowerCase() === groupName.toLowerCase()
|
|
52170
53098
|
);
|
|
52171
53099
|
if (!group) return null;
|
|
52172
|
-
const val = tags[group.name
|
|
53100
|
+
const val = tags[tagAttrKey(group.name)] ?? group.defaultValue;
|
|
52173
53101
|
if (!val) return null;
|
|
52174
53102
|
const entry = group.entries.find(
|
|
52175
53103
|
(e) => e.value.toLowerCase() === val.toLowerCase()
|
|
@@ -52783,7 +53711,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
52783
53711
|
if (directHex)
|
|
52784
53712
|
return { fill: directHex, stroke: mix(directHex, palette.text, 18) };
|
|
52785
53713
|
for (const group of resolved.tagGroups) {
|
|
52786
|
-
const val = p.tags[group.name
|
|
53714
|
+
const val = p.tags[tagAttrKey(group.name)];
|
|
52787
53715
|
if (!val) continue;
|
|
52788
53716
|
const entry = group.entries.find(
|
|
52789
53717
|
(e) => e.value.toLowerCase() === val.toLowerCase()
|
|
@@ -52798,7 +53726,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
52798
53726
|
};
|
|
52799
53727
|
const lineColor = (tags) => {
|
|
52800
53728
|
for (const group of resolved.tagGroups) {
|
|
52801
|
-
const val = tags[group.name
|
|
53729
|
+
const val = tags[tagAttrKey(group.name)];
|
|
52802
53730
|
if (!val) continue;
|
|
52803
53731
|
const entry = group.entries.find(
|
|
52804
53732
|
(e) => e.value.toLowerCase() === val.toLowerCase()
|
|
@@ -54064,6 +54992,7 @@ var import_d3_geo2, import_topojson_client2, FIT_PAD, PATH_DIGITS, THIN_TOL, ALB
|
|
|
54064
54992
|
var init_layout15 = __esm({
|
|
54065
54993
|
"src/map/layout.ts"() {
|
|
54066
54994
|
"use strict";
|
|
54995
|
+
init_tag_groups();
|
|
54067
54996
|
import_d3_geo2 = require("d3-geo");
|
|
54068
54997
|
import_topojson_client2 = require("topojson-client");
|
|
54069
54998
|
init_color_utils();
|
|
@@ -56480,7 +57409,7 @@ function resolveSequenceTags(parsed, activeTagGroup) {
|
|
|
56480
57409
|
}
|
|
56481
57410
|
return result;
|
|
56482
57411
|
}
|
|
56483
|
-
const groupKey2 = group.name
|
|
57412
|
+
const groupKey2 = tagAttrKey(group.name);
|
|
56484
57413
|
const participantMeta = /* @__PURE__ */ new Map();
|
|
56485
57414
|
for (const p of parsed.participants) {
|
|
56486
57415
|
participantMeta.set(p.id, { ...p.metadata || {} });
|
|
@@ -56516,6 +57445,7 @@ function resolveSequenceTags(parsed, activeTagGroup) {
|
|
|
56516
57445
|
var init_tag_resolution = __esm({
|
|
56517
57446
|
"src/sequence/tag-resolution.ts"() {
|
|
56518
57447
|
"use strict";
|
|
57448
|
+
init_tag_groups();
|
|
56519
57449
|
}
|
|
56520
57450
|
});
|
|
56521
57451
|
|
|
@@ -56990,7 +57920,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
56990
57920
|
}
|
|
56991
57921
|
}
|
|
56992
57922
|
const getTagColor = (value) => value ? tagValueToColor.get(value.toLowerCase()) : void 0;
|
|
56993
|
-
const tagKey = activeTagGroup
|
|
57923
|
+
const tagKey = activeTagGroup ? tagAttrKey(activeTagGroup) : void 0;
|
|
56994
57924
|
const hiddenMsgIndices = /* @__PURE__ */ new Set();
|
|
56995
57925
|
if (collapsedSections && collapsedSections.size > 0) {
|
|
56996
57926
|
const sectionGroups = groupMessagesBySection(elements, messages);
|
|
@@ -57582,11 +58512,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
57582
58512
|
const boxH = sBoxH + GROUP_PADDING_TOP2 + GROUP_PADDING_BOTTOM2;
|
|
57583
58513
|
const groupTagValue = tagKey && group.metadata?.[tagKey];
|
|
57584
58514
|
const groupTagColor = getTagColor(groupTagValue || void 0);
|
|
57585
|
-
const fillColor = groupTagColor ? mix(
|
|
57586
|
-
groupTagColor,
|
|
57587
|
-
themeBaseBg(palette, isDark),
|
|
57588
|
-
isDark ? 15 : 20
|
|
57589
|
-
) : isDark ? palette.surface : palette.bg;
|
|
58515
|
+
const fillColor = groupTagColor ? mix(groupTagColor, themeBaseBg(palette, isDark), isDark ? 15 : 20) : isDark ? palette.surface : palette.bg;
|
|
57590
58516
|
const strokeColor = groupTagColor || palette.textMuted;
|
|
57591
58517
|
const groupG = svg.append("g").attr("class", "group-box-wrapper").attr("data-group-toggle", "").attr("data-group-line", String(group.lineNumber)).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", "true").attr("cursor", "pointer");
|
|
57592
58518
|
groupG.append("title").text("Click to collapse");
|
|
@@ -57636,11 +58562,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
57636
58562
|
);
|
|
57637
58563
|
participantG.attr("data-group-toggle", "").attr("data-group-line", String(meta.lineNumber)).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", "false").attr("cursor", "pointer");
|
|
57638
58564
|
participantG.append("title").text("Click to expand");
|
|
57639
|
-
const pFill = effectiveTagColor ? mix(
|
|
57640
|
-
effectiveTagColor,
|
|
57641
|
-
themeBaseBg(palette, isDark),
|
|
57642
|
-
isDark ? 30 : 40
|
|
57643
|
-
) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
|
|
58565
|
+
const pFill = effectiveTagColor ? mix(effectiveTagColor, themeBaseBg(palette, isDark), isDark ? 30 : 40) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
|
|
57644
58566
|
const pStroke = effectiveTagColor || palette.border;
|
|
57645
58567
|
participantG.append("rect").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP2).attr("width", boxW).attr("height", fullH).attr("rx", 6).attr("fill", pFill).attr("stroke", pStroke).attr("stroke-width", 1.5);
|
|
57646
58568
|
participantG.append("text").attr("x", 0).attr("y", -GROUP_PADDING_TOP2 + fullH / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", ctx.text(13)).attr("font-weight", 500).text(participant.label);
|
|
@@ -58136,6 +59058,7 @@ var d3Selection27, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGH
|
|
|
58136
59058
|
var init_renderer20 = __esm({
|
|
58137
59059
|
"src/sequence/renderer.ts"() {
|
|
58138
59060
|
"use strict";
|
|
59061
|
+
init_tag_groups();
|
|
58139
59062
|
d3Selection27 = __toESM(require("d3-selection"), 1);
|
|
58140
59063
|
init_color_utils();
|
|
58141
59064
|
init_inline_markdown();
|
|
@@ -58889,6 +59812,7 @@ __export(advanced_exports, {
|
|
|
58889
59812
|
resolveTaskName: () => resolveTaskName,
|
|
58890
59813
|
rollUpContextRelationships: () => rollUpContextRelationships,
|
|
58891
59814
|
sampleBetaPert: () => sampleBetaPert,
|
|
59815
|
+
searchMapLocations: () => searchMapLocations,
|
|
58892
59816
|
seriesColors: () => seriesColors,
|
|
58893
59817
|
shade: () => shade,
|
|
58894
59818
|
shapeFill: () => shapeFill,
|
|
@@ -59562,6 +60486,7 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
|
|
|
59562
60486
|
init_parser3();
|
|
59563
60487
|
|
|
59564
60488
|
// src/timeline/renderer.ts
|
|
60489
|
+
init_tag_groups();
|
|
59565
60490
|
var d3Scale3 = __toESM(require("d3-scale"), 1);
|
|
59566
60491
|
var d3Selection3 = __toESM(require("d3-selection"), 1);
|
|
59567
60492
|
init_fonts();
|
|
@@ -59826,7 +60751,7 @@ function setupTimeline(container, parsed, palette, isDark, exportDims, activeTag
|
|
|
59826
60751
|
});
|
|
59827
60752
|
let tagLanes = null;
|
|
59828
60753
|
if (resolvedSwimlaneTG) {
|
|
59829
|
-
const tagKey = resolvedSwimlaneTG
|
|
60754
|
+
const tagKey = tagAttrKey(resolvedSwimlaneTG);
|
|
59830
60755
|
const tagGroup = parsed.timelineTagGroups.find(
|
|
59831
60756
|
(g) => g.name.toLowerCase() === tagKey
|
|
59832
60757
|
);
|
|
@@ -60132,7 +61057,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
60132
61057
|
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
60133
61058
|
},
|
|
60134
61059
|
onEntryHover: (groupName, entryValue) => {
|
|
60135
|
-
const tagKey = groupName
|
|
61060
|
+
const tagKey = tagAttrKey(groupName);
|
|
60136
61061
|
if (entryValue) {
|
|
60137
61062
|
const tagVal = entryValue.toLowerCase();
|
|
60138
61063
|
fadeToTagValue(mainG, tagKey, tagVal);
|
|
@@ -60151,7 +61076,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
60151
61076
|
}
|
|
60152
61077
|
},
|
|
60153
61078
|
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
60154
|
-
const groupKey2 = groupName
|
|
61079
|
+
const groupKey2 = tagAttrKey(groupName);
|
|
60155
61080
|
groupEl.attr("data-tag-group", groupKey2);
|
|
60156
61081
|
if (isActive && !viewMode) {
|
|
60157
61082
|
const isSwimActive = currentSwimlaneGroup?.toLowerCase() === groupKey2;
|
|
@@ -64016,6 +64941,71 @@ function completeMapPlaces(query, gazetteer, opts) {
|
|
|
64016
64941
|
});
|
|
64017
64942
|
return [...cityItems, ...airportItems].slice(0, limit);
|
|
64018
64943
|
}
|
|
64944
|
+
function searchMapLocations(query, gazetteer, opts) {
|
|
64945
|
+
const q = fold2(query);
|
|
64946
|
+
if (!q) return [];
|
|
64947
|
+
const limit = opts?.limit ?? 20;
|
|
64948
|
+
const rankOf = (hay) => hay === q ? 0 : hay.startsWith(q) ? 1 : hay.includes(q) ? 2 : -1;
|
|
64949
|
+
const cityRank = /* @__PURE__ */ new Map();
|
|
64950
|
+
const consider = (idx, rank) => {
|
|
64951
|
+
if (rank < 0) return;
|
|
64952
|
+
const prev = cityRank.get(idx);
|
|
64953
|
+
if (prev === void 0 || rank < prev) cityRank.set(idx, rank);
|
|
64954
|
+
};
|
|
64955
|
+
for (const [key, list] of Object.entries(gazetteer.byName)) {
|
|
64956
|
+
const r = rankOf(key);
|
|
64957
|
+
if (r >= 0) for (const i of list) consider(i, r);
|
|
64958
|
+
}
|
|
64959
|
+
for (const [key, idx] of Object.entries(gazetteer.alt)) {
|
|
64960
|
+
consider(idx, rankOf(key));
|
|
64961
|
+
}
|
|
64962
|
+
const cityItems = [...cityRank].filter(([i]) => gazetteer.cities[i] !== void 0).map(([i, rank]) => {
|
|
64963
|
+
const c = gazetteer.cities[i];
|
|
64964
|
+
const [, , iso, pop, name, sub] = c;
|
|
64965
|
+
const ambiguous = (gazetteer.byName[fold2(name)]?.length ?? 0) > 1;
|
|
64966
|
+
const qualifier = sub ?? iso;
|
|
64967
|
+
return {
|
|
64968
|
+
name,
|
|
64969
|
+
token: ambiguous ? `${name} ${qualifier}` : name,
|
|
64970
|
+
kind: "city",
|
|
64971
|
+
iso,
|
|
64972
|
+
...sub !== void 0 && { sub },
|
|
64973
|
+
pop,
|
|
64974
|
+
detail: `${qualifier} \xB7 ${groupThousands(pop)}`,
|
|
64975
|
+
_rank: rank
|
|
64976
|
+
};
|
|
64977
|
+
});
|
|
64978
|
+
const airports = opts?.airports;
|
|
64979
|
+
const airportItems = [];
|
|
64980
|
+
if (airports?.airportIata) {
|
|
64981
|
+
for (const [code, idx] of Object.entries(airports.airportIata)) {
|
|
64982
|
+
const a = airports.airports[idx];
|
|
64983
|
+
if (!a) continue;
|
|
64984
|
+
const codeRank = rankOf(code);
|
|
64985
|
+
const nameRank = rankOf(fold2(a[4]));
|
|
64986
|
+
const rank = Math.min(
|
|
64987
|
+
codeRank < 0 ? 99 : codeRank,
|
|
64988
|
+
nameRank < 0 ? 99 : nameRank
|
|
64989
|
+
);
|
|
64990
|
+
if (rank > 2) continue;
|
|
64991
|
+
airportItems.push({
|
|
64992
|
+
name: a[4],
|
|
64993
|
+
token: code.toUpperCase(),
|
|
64994
|
+
kind: "airport",
|
|
64995
|
+
iso: a[2],
|
|
64996
|
+
pop: 0,
|
|
64997
|
+
detail: `Airport \xB7 ${a[4]}`,
|
|
64998
|
+
_rank: rank
|
|
64999
|
+
});
|
|
65000
|
+
}
|
|
65001
|
+
}
|
|
65002
|
+
return [...cityItems, ...airportItems].sort(
|
|
65003
|
+
(x, y) => x._rank - y._rank || // best match tier first
|
|
65004
|
+
(x.kind === y.kind ? 0 : x.kind === "city" ? -1 : 1) || // city before airport
|
|
65005
|
+
y.pop - x.pop || // populous city first
|
|
65006
|
+
(x.token < y.token ? -1 : x.token > y.token ? 1 : 0)
|
|
65007
|
+
).slice(0, limit).map(({ _rank, ...rest }) => rest);
|
|
65008
|
+
}
|
|
64019
65009
|
function completeMapRegions(query, regions, opts) {
|
|
64020
65010
|
const q = fold2(query);
|
|
64021
65011
|
if (!q) return [];
|
|
@@ -65234,6 +66224,7 @@ function formatLineDiff(path, original, migrated) {
|
|
|
65234
66224
|
resolveTaskName,
|
|
65235
66225
|
rollUpContextRelationships,
|
|
65236
66226
|
sampleBetaPert,
|
|
66227
|
+
searchMapLocations,
|
|
65237
66228
|
seriesColors,
|
|
65238
66229
|
shade,
|
|
65239
66230
|
shapeFill,
|