@diagrammo/dgmo 0.86.0 → 0.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.ts +6 -18
- package/dist/advanced.js +40 -37
- package/dist/block.js +6 -17
- package/dist/{chunk-FAV4RDVT.js → chunk-2A4DQAXG.js} +1 -1
- package/dist/{chunk-JIPUBFAM.js → chunk-5KGM44TG.js} +2 -2
- package/dist/{chunk-VEE777MD.js → chunk-5LD7SHXO.js} +3 -3
- package/dist/{chunk-QJ2JOLFN.js → chunk-6I5UN4FD.js} +2 -2
- package/dist/{chunk-ETBXIKK6.js → chunk-ABP5BUD6.js} +9 -430
- package/dist/{chunk-PKXKWHDW.js → chunk-AUS7V54P.js} +1 -1
- package/dist/{chunk-BF7JAFJI.js → chunk-B7CU2HW5.js} +2 -2
- package/dist/{chunk-X2VEJ5NT.js → chunk-BMUWF77V.js} +2 -2
- package/dist/{chunk-BP4BT5TH.js → chunk-CLQIXD2C.js} +1 -1
- package/dist/{chunk-QJFT5MAH.js → chunk-DSG6GBUQ.js} +2 -2
- package/dist/{chunk-EWSESGC2.js → chunk-EJS3K44P.js} +117 -78
- package/dist/{chunk-5JO443MB.js → chunk-HAH5X345.js} +1 -1
- package/dist/{chunk-HBCAY3KR.js → chunk-HTNLLT34.js} +1 -1
- package/dist/{chunk-HUMQIRJK.js → chunk-HTPZDZKQ.js} +2 -2
- package/dist/{chunk-VPVWG2GH.js → chunk-J7Q4VPBJ.js} +1 -1
- package/dist/{chunk-QPE646M2.js → chunk-JLETTWUJ.js} +30 -10
- package/dist/{chunk-3CQS3CIO.js → chunk-LL6D3MES.js} +1 -1
- package/dist/{chunk-ERYHC4KJ.js → chunk-LSQGJN5H.js} +1 -1
- package/dist/{chunk-AGO3PFGS.js → chunk-MVCPO6LI.js} +15 -10
- package/dist/{chunk-E6S2K6O2.js → chunk-N7XRBWXA.js} +2 -2
- package/dist/{chunk-WMIKC5XO.js → chunk-NPWVOFB3.js} +1 -1
- package/dist/{chunk-MYHPRQHR.js → chunk-O6MMQQLF.js} +3 -3
- package/dist/{chunk-GYORDNOM.js → chunk-P5V63L35.js} +1 -1
- package/dist/{chunk-BHZE36F7.js → chunk-PUVTFUNH.js} +1 -1
- package/dist/{chunk-TW6WMZFW.js → chunk-QT3KDDXK.js} +156 -7
- package/dist/{chunk-ZGHV4QLK.js → chunk-RJNZHFNG.js} +1 -1
- package/dist/{chunk-FWNJDD4U.js → chunk-S7W75MIM.js} +3 -20
- package/dist/{chunk-4YA5XW43.js → chunk-VW52W5F6.js} +981 -107
- package/dist/chunk-WXPBP4IT.js +438 -0
- package/dist/{chunk-C6FZZFYD.js → chunk-WZ23JJ7U.js} +1 -1
- package/dist/{chunk-LIYWJ6DV.js → chunk-XIFK423U.js} +108 -13
- package/dist/{chunk-4ELXLATB.js → chunk-XUDGZJTJ.js} +2 -2
- package/dist/{chunk-H6AFNCN3.js → chunk-XVSJYAK7.js} +1 -1
- package/dist/{chunk-LHBMQJC3.js → chunk-XWYR5T52.js} +2 -2
- package/dist/{chunk-QNKHJ5CK.js → chunk-YK4N6TBN.js} +4 -2
- package/dist/{chunk-XFMQSFS4.js → chunk-YMG7JDEY.js} +16 -6
- package/dist/chunk-Z6DXWULM.js +23 -0
- package/dist/{chunk-PBEH52A2.js → chunk-ZNNVI5SR.js} +1 -1
- package/dist/{flowchart-renderer-H72L7BEC.js → flowchart-renderer-THC6Y7EH.js} +7 -6
- package/dist/index.d.ts +68 -1
- package/dist/index.js +76 -7
- package/dist/{layout-QIPCNUSB.js → layout-BOVTLAOT.js} +7 -6
- package/dist/{layout-6JARW64V.js → layout-EHTYSMV4.js} +6 -5
- package/dist/{layout-YELNBVPC.js → layout-P6DTD4RT.js} +6 -5
- package/dist/{layout-T6TAB5OI.js → layout-RANVNAKI.js} +3 -3
- package/dist/{layout-FMKSENGL.js → layout-XUW444O5.js} +5 -4
- package/dist/{layout-search-AW5VBDCV.js → layout-search-VKSBUCDM.js} +57 -28
- package/dist/{renderer-AI2MD52D.js → renderer-222OTVQV.js} +3 -2
- package/dist/{renderer-UUWR7NGF.js → renderer-2KVQGGTT.js} +4 -3
- package/dist/{renderer-E5EKGIX2.js → renderer-2OOPQ4CH.js} +4 -3
- package/dist/{renderer-CZJ4AMYV.js → renderer-3FF4QVGW.js} +3 -2
- package/dist/{renderer-R6VJDZFO.js → renderer-4BHOELCE.js} +4 -3
- package/dist/{renderer-425QUIYO.js → renderer-4BIMRO4X.js} +4 -3
- package/dist/{renderer-5JVVJBAS.js → renderer-A4LMOBZL.js} +8 -7
- package/dist/{renderer-3AOOLHJU.js → renderer-A6ACVK4X.js} +3 -2
- package/dist/{renderer-ML2CLU25.js → renderer-DCFQDBGJ.js} +4 -3
- package/dist/{renderer-RH4U3UVM.js → renderer-LODEVN3V.js} +3 -2
- package/dist/{renderer-E7WF75GY.js → renderer-NHPKNNBD.js} +5 -4
- package/dist/{renderer-JEEGPLMM.js → renderer-R34GJL7U.js} +8 -7
- package/dist/{renderer-2BWRW23Z.js → renderer-RENDISO5.js} +1 -1
- package/dist/{renderer-NX4YKWCJ.js → renderer-RNCYODNF.js} +1 -1
- package/dist/{renderer-VKAJ52UO.js → renderer-SDUSBCJI.js} +3 -2
- package/dist/{renderer-RLSR7N6I.js → renderer-TPOZOAXR.js} +5 -4
- package/dist/{renderer-RUGMKHX5.js → renderer-WH2HWE5Z.js} +3 -2
- package/dist/{renderer-V6LLASGN.js → renderer-X5A5VIRD.js} +5 -4
- package/dist/{renderer-ADX4DWRJ.js → renderer-XUPLAO4B.js} +4 -2
- package/dist/{renderer-EWJS2RAZ.js → renderer-YDAVCRTP.js} +3 -2
- package/dist/{state-renderer-DDVJ43HR.js → state-renderer-5IQ4OJUI.js} +7 -6
- package/gallery/fixtures/journey-map.dgmo +28 -0
- package/gallery/fixtures/mindmap.dgmo +31 -0
- package/gallery/fixtures/pert.dgmo +27 -0
- package/gallery/fixtures/wireframe.dgmo +30 -0
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
wrapDescriptionLines
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NPWVOFB3.js";
|
|
4
4
|
import {
|
|
5
5
|
renderInlineText
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-S7W75MIM.js";
|
|
7
7
|
import {
|
|
8
8
|
ScaleContext
|
|
9
9
|
} from "./chunk-24YPR5EH.js";
|
|
@@ -842,7 +842,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
842
842
|
}
|
|
843
843
|
msgToLastStep.set(step.messageIndex, si);
|
|
844
844
|
});
|
|
845
|
-
const
|
|
845
|
+
const closestPrecedingMsgIndex = (note) => {
|
|
846
846
|
let closestMsgIndex = -1;
|
|
847
847
|
let closestLine = -1;
|
|
848
848
|
for (let mi = 0; mi < messages.length; mi++) {
|
|
@@ -852,9 +852,15 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
852
852
|
closestMsgIndex = mi;
|
|
853
853
|
}
|
|
854
854
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
855
|
+
return closestMsgIndex;
|
|
856
|
+
};
|
|
857
|
+
const isNoteHiddenByCollapse = (note) => {
|
|
858
|
+
const closestMsgIndex = closestPrecedingMsgIndex(note);
|
|
859
|
+
return closestMsgIndex >= 0 && hiddenMsgIndices.has(closestMsgIndex);
|
|
860
|
+
};
|
|
861
|
+
const findAssociatedLastStep = (note) => {
|
|
862
|
+
if (isNoteHiddenByCollapse(note)) return -1;
|
|
863
|
+
const closestMsgIndex = closestPrecedingMsgIndex(note);
|
|
858
864
|
if (closestMsgIndex < 0) return -1;
|
|
859
865
|
return msgToLastStep.get(closestMsgIndex) ?? -1;
|
|
860
866
|
};
|
|
@@ -942,6 +948,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
942
948
|
for (let i = 0; i < els.length; i++) {
|
|
943
949
|
const el = els[i];
|
|
944
950
|
if (isSequenceNote(el)) {
|
|
951
|
+
if (isNoteHiddenByCollapse(el)) {
|
|
952
|
+
while (i + 1 < els.length && isSequenceNote(els[i + 1])) i++;
|
|
953
|
+
continue;
|
|
954
|
+
}
|
|
945
955
|
const firstOffset = noteOffsetBelow(el);
|
|
946
956
|
let totalExtent = firstOffset;
|
|
947
957
|
let j = i;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/utils/safe-href.ts
|
|
2
|
+
var ALLOWED_SCHEMES = ["http", "https", "mailto"];
|
|
3
|
+
var SCHEME_RE = /^([a-z][a-z0-9+.-]*):/i;
|
|
4
|
+
var LEADING_TRIM_RE = /^[\x00-\x20]+/;
|
|
5
|
+
var URL_STRIP_RE = /[\x09\x0A\x0D]/g;
|
|
6
|
+
function safeHref(url) {
|
|
7
|
+
if (typeof url !== "string") return null;
|
|
8
|
+
const trimmed = url.replace(URL_STRIP_RE, "").replace(LEADING_TRIM_RE, "");
|
|
9
|
+
if (trimmed.length === 0) return null;
|
|
10
|
+
const match = SCHEME_RE.exec(trimmed);
|
|
11
|
+
if (!match) {
|
|
12
|
+
return url;
|
|
13
|
+
}
|
|
14
|
+
const scheme = match[1].toLowerCase();
|
|
15
|
+
if (ALLOWED_SCHEMES.includes(scheme)) {
|
|
16
|
+
return url;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
safeHref
|
|
23
|
+
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderFlowchart,
|
|
3
3
|
renderFlowchartForExport
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XUDGZJTJ.js";
|
|
5
5
|
import "./chunk-26EVL454.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-ZNNVI5SR.js";
|
|
7
|
+
import "./chunk-HAH5X345.js";
|
|
8
8
|
import "./chunk-XBJJP2HN.js";
|
|
9
9
|
import "./chunk-6EK55ART.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-RJNZHFNG.js";
|
|
11
11
|
import "./chunk-5DH3KYFH.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-NPWVOFB3.js";
|
|
13
|
+
import "./chunk-S7W75MIM.js";
|
|
14
|
+
import "./chunk-Z6DXWULM.js";
|
|
14
15
|
import "./chunk-EPDBWATV.js";
|
|
15
16
|
import "./chunk-24YPR5EH.js";
|
|
16
17
|
import "./chunk-XCKNFFKM.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -102,6 +102,73 @@ declare function attachDataChartInteractions(svg: SVGSVGElement, opts?: DataChar
|
|
|
102
102
|
declare const D3_DATA_CHART_TYPES: Set<string>;
|
|
103
103
|
declare function supportsD3DataChart(type: string): boolean;
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* The supported sanitizing boundary for renderer output that is about to land
|
|
107
|
+
* in a live document.
|
|
108
|
+
*
|
|
109
|
+
* Renderer output is trusted only as far as the renderer that produced it, and
|
|
110
|
+
* every host — the desktop app, the web editor, Obsidian, the script-tag
|
|
111
|
+
* drop-ins, this library's own `mountD3DataChart` — puts that output into the
|
|
112
|
+
* DOM. This module is what they call first. It lives here, beside `safe-href`,
|
|
113
|
+
* rather than inside `src/auto/shared.ts` where it started: that module is the
|
|
114
|
+
* browser-embed bundle's private toolbox, reachable only from the two IIFE
|
|
115
|
+
* script-tag builds, so a host importing `@diagrammo/dgmo` could not call the
|
|
116
|
+
* sanitizer at all however much it wanted to.
|
|
117
|
+
*
|
|
118
|
+
* 🔴 **Parse into a DETACHED holder, take the `<svg>`, sanitize, insert.** All
|
|
119
|
+
* four steps, in that order:
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* const holder = document.createElement('div');
|
|
123
|
+
* holder.innerHTML = svg; // inert: nothing here is connected yet
|
|
124
|
+
* const svgEl = holder.querySelector('svg');
|
|
125
|
+
* if (svgEl) {
|
|
126
|
+
* sanitizeSvgInPlace(svgEl);
|
|
127
|
+
* container.replaceChildren(svgEl);
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* Sanitizing *after* assigning into a live container is too late: connecting
|
|
132
|
+
* the subtree is what creates a nested browsing context for an `<iframe>` and
|
|
133
|
+
* runs a custom element's `connectedCallback`, both synchronously inside the
|
|
134
|
+
* assignment. And taking only the `<svg>` is half the safety — moving every
|
|
135
|
+
* child of the holder across would connect whatever a hostile document put
|
|
136
|
+
* *beside* the diagram. `auto/index.ts` and `element/index.ts` have always done
|
|
137
|
+
* both; `mount.ts` learned them on diagrammo/diagrammo#884.
|
|
138
|
+
*
|
|
139
|
+
* 🔴 **What this does NOT do**, so a caller is not misled about the contract:
|
|
140
|
+
*
|
|
141
|
+
* - It does not parse CSS. An `@import` or a `url()` inside a `<style>`
|
|
142
|
+
* element passes through untouched.
|
|
143
|
+
* - It removes the elements listed in `REMOVED_TAGS` and nothing else. That
|
|
144
|
+
* set is the script-execution and remote-content surface as of
|
|
145
|
+
* diagrammo/diagrammo#884; an element neither it nor the attribute scrub
|
|
146
|
+
* below names survives, so a caller sanitizing *arbitrary* HTML rather than
|
|
147
|
+
* dgmo renderer output needs its own allowlist on top.
|
|
148
|
+
* - It does not stop a resource load that an attribute alone starts —
|
|
149
|
+
* `<img src>` fetches whether or not the node is connected. What protects
|
|
150
|
+
* that case is the `on*` strip, not the detached holder.
|
|
151
|
+
* - It is no substitute for escaping where a renderer interpolates author
|
|
152
|
+
* text (see `src/embed/escape.ts`).
|
|
153
|
+
*
|
|
154
|
+
* Browser-only — it needs a live DOM. There is nothing to sanitize on the
|
|
155
|
+
* rasterising path, which never builds a document.
|
|
156
|
+
*/
|
|
157
|
+
/**
|
|
158
|
+
* Strip script-execution surface from a freshly parsed SVG tree before it
|
|
159
|
+
* lands in the live DOM. This is the safety net that lets us build SVG from
|
|
160
|
+
* markup without trusting renderer output to be fully sanitized.
|
|
161
|
+
*
|
|
162
|
+
* Removes every element in `REMOVED_TAGS`, any SMIL element animating an
|
|
163
|
+
* `href`, any `on*` event-handler attribute, and any `href`/`xlink:href`
|
|
164
|
+
* failing the `safeHref` allowlist.
|
|
165
|
+
*
|
|
166
|
+
* Mutates `root` and returns nothing. Call it on a detached holder — see the
|
|
167
|
+
* module comment above for why the order matters, and for what this does not
|
|
168
|
+
* cover.
|
|
169
|
+
*/
|
|
170
|
+
declare function sanitizeSvgInPlace(root: Element): void;
|
|
171
|
+
|
|
105
172
|
/**
|
|
106
173
|
* The full diagnostic catalog, sorted by code. Every coded diagnostic
|
|
107
174
|
* dgmo can emit — its severity, owning chart type, canonical message,
|
|
@@ -206,4 +273,4 @@ interface DecodedDiagramUrl {
|
|
|
206
273
|
*/
|
|
207
274
|
declare function decodeDiagramUrl(url: string): DecodedDiagramUrl | null;
|
|
208
275
|
|
|
209
|
-
export { CompactViewState, D3_DATA_CHART_TYPES, type DataChartInteractionOpts, type DecodedDiagramUrl, DgmoError, DiagnosticSpec, type EncodeDiagramUrlOptions, MapDataSource, type MountD3Opts, type MountedD3Chart, type NormalizeSvgForEmbedOptions, PaletteConfig, type RenderOptions, type RenderResult, Theme, attachDataChartInteractions, decodeDiagramUrl, defaultEmbedBackground, encodeDiagramUrl, getDiagnosticSpec, getEmbedSvgViewBox, listDiagnosticCodes, mountD3DataChart, normalizeSvgForEmbed, render, supportsD3DataChart };
|
|
276
|
+
export { CompactViewState, D3_DATA_CHART_TYPES, type DataChartInteractionOpts, type DecodedDiagramUrl, DgmoError, DiagnosticSpec, type EncodeDiagramUrlOptions, MapDataSource, type MountD3Opts, type MountedD3Chart, type NormalizeSvgForEmbedOptions, PaletteConfig, type RenderOptions, type RenderResult, Theme, attachDataChartInteractions, decodeDiagramUrl, defaultEmbedBackground, encodeDiagramUrl, getDiagnosticSpec, getEmbedSvgViewBox, listDiagnosticCodes, mountD3DataChart, normalizeSvgForEmbed, render, sanitizeSvgInPlace, supportsD3DataChart };
|
package/dist/index.js
CHANGED
|
@@ -9,9 +9,13 @@ import {
|
|
|
9
9
|
searchMapLocations,
|
|
10
10
|
themes
|
|
11
11
|
} from "./chunk-SQAG3UXH.js";
|
|
12
|
+
import {
|
|
13
|
+
safeHref
|
|
14
|
+
} from "./chunk-Z6DXWULM.js";
|
|
12
15
|
import {
|
|
13
16
|
render
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-VW52W5F6.js";
|
|
18
|
+
import "./chunk-ABP5BUD6.js";
|
|
15
19
|
import {
|
|
16
20
|
renderErrorCard
|
|
17
21
|
} from "./chunk-D4M25W6R.js";
|
|
@@ -34,7 +38,7 @@ import "./chunk-KMU65FYM.js";
|
|
|
34
38
|
import "./chunk-EPDBWATV.js";
|
|
35
39
|
import "./chunk-7UDAIP6W.js";
|
|
36
40
|
import "./chunk-2CW5ZTNH.js";
|
|
37
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-JLETTWUJ.js";
|
|
38
42
|
import "./chunk-YRYKTYMQ.js";
|
|
39
43
|
import "./chunk-24YPR5EH.js";
|
|
40
44
|
import {
|
|
@@ -124,6 +128,50 @@ import {
|
|
|
124
128
|
} from "./chunk-BYU54C3S.js";
|
|
125
129
|
import "./chunk-5WRI5ZAA.js";
|
|
126
130
|
|
|
131
|
+
// src/utils/sanitize-svg.ts
|
|
132
|
+
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
133
|
+
var REMOVED_TAGS = "script, foreignObject, iframe, object, embed, frame, base, link, meta";
|
|
134
|
+
var ANIMATION_TAGS = new Set(
|
|
135
|
+
["animate", "set", "animateTransform", "animateMotion"].map(
|
|
136
|
+
(t) => t.toLowerCase()
|
|
137
|
+
)
|
|
138
|
+
);
|
|
139
|
+
var ANIMATED_URL_ATTRS = /* @__PURE__ */ new Set(["href", "xlink:href"]);
|
|
140
|
+
function isUrlAnimation(node) {
|
|
141
|
+
if (!ANIMATION_TAGS.has(node.localName.toLowerCase())) return false;
|
|
142
|
+
const target = (node.getAttribute("attributeName") ?? "").trim().toLowerCase();
|
|
143
|
+
return ANIMATED_URL_ATTRS.has(target);
|
|
144
|
+
}
|
|
145
|
+
function scrubElement(node) {
|
|
146
|
+
for (const attr of Array.from(node.attributes)) {
|
|
147
|
+
if (attr.name.toLowerCase().startsWith("on")) {
|
|
148
|
+
node.removeAttribute(attr.name);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (node.hasAttribute("href")) {
|
|
152
|
+
const safe = safeHref(node.getAttribute("href"));
|
|
153
|
+
if (safe === null) node.removeAttribute("href");
|
|
154
|
+
}
|
|
155
|
+
if (node.hasAttributeNS(XLINK_NS, "href")) {
|
|
156
|
+
const v = node.getAttributeNS(XLINK_NS, "href");
|
|
157
|
+
if (safeHref(v) === null) {
|
|
158
|
+
node.removeAttributeNS(XLINK_NS, "href");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function sanitizeSvgInPlace(root) {
|
|
163
|
+
const dangerous = root.querySelectorAll(REMOVED_TAGS);
|
|
164
|
+
dangerous.forEach((n) => n.remove());
|
|
165
|
+
const all = [root, ...Array.from(root.querySelectorAll("*"))];
|
|
166
|
+
for (const node of all) {
|
|
167
|
+
if (isUrlAnimation(node)) {
|
|
168
|
+
node.remove();
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
scrubElement(node);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
127
175
|
// src/charts-d3/interactions.ts
|
|
128
176
|
var NS = "http://www.w3.org/2000/svg";
|
|
129
177
|
var STYLE_ID = "dgmo-chart-interactions-style";
|
|
@@ -134,7 +182,8 @@ function ensureStyle(svg, muted) {
|
|
|
134
182
|
style.id = STYLE_ID;
|
|
135
183
|
style.textContent = `
|
|
136
184
|
.dgmo-series,.dgmo-datum,.dgmo-tick,.dgmo-ptlabel{transition:opacity .12s ease}
|
|
137
|
-
|
|
185
|
+
[data-legend-entry]{transition:opacity .12s ease}
|
|
186
|
+
.dgmo-series.dgmo-dim,.dgmo-datum.dgmo-dim,.dgmo-ptlabel.dgmo-dim,[data-legend-entry].dgmo-dim{opacity:.18}
|
|
138
187
|
.dgmo-tick.dgmo-faded{opacity:.22}
|
|
139
188
|
.dgmo-datum{cursor:pointer}
|
|
140
189
|
.dgmo-axis-label{cursor:pointer}
|
|
@@ -177,6 +226,9 @@ function attachDataChartInteractions(svg, opts = {}) {
|
|
|
177
226
|
svg.querySelectorAll(".dgmo-series")
|
|
178
227
|
);
|
|
179
228
|
const datums = Array.from(svg.querySelectorAll(".dgmo-datum"));
|
|
229
|
+
const legendEntries = Array.from(
|
|
230
|
+
svg.querySelectorAll(".chart-legend [data-legend-entry]")
|
|
231
|
+
);
|
|
180
232
|
const circles = Array.from(
|
|
181
233
|
svg.querySelectorAll(".dgmo-pt")
|
|
182
234
|
);
|
|
@@ -247,6 +299,15 @@ function attachDataChartInteractions(svg, opts = {}) {
|
|
|
247
299
|
const ptLabels = Array.from(
|
|
248
300
|
svg.querySelectorAll(".dgmo-ptlabel")
|
|
249
301
|
);
|
|
302
|
+
const dimLegendExcept = (el) => {
|
|
303
|
+
const name = el?.getAttribute("data-series-name") ?? el?.getAttribute("data-emph-key") ?? null;
|
|
304
|
+
const paired = name != null && legendEntries.some((e) => e.getAttribute("data-series-name") === name);
|
|
305
|
+
for (const e of legendEntries)
|
|
306
|
+
e.classList.toggle(
|
|
307
|
+
"dgmo-dim",
|
|
308
|
+
paired && e.getAttribute("data-series-name") !== name
|
|
309
|
+
);
|
|
310
|
+
};
|
|
250
311
|
const dimDatumsExcept = (el) => {
|
|
251
312
|
for (const d of datums) d.classList.toggle("dgmo-dim", d !== el);
|
|
252
313
|
const line = el?.getAttribute("data-line-number");
|
|
@@ -255,6 +316,7 @@ function attachDataChartInteractions(svg, opts = {}) {
|
|
|
255
316
|
"dgmo-dim",
|
|
256
317
|
line == null || l.getAttribute("data-line-number") !== line
|
|
257
318
|
);
|
|
319
|
+
dimLegendExcept(el);
|
|
258
320
|
};
|
|
259
321
|
const dimByKey = (el) => {
|
|
260
322
|
const key = el.getAttribute("data-emph-key");
|
|
@@ -263,11 +325,13 @@ function attachDataChartInteractions(svg, opts = {}) {
|
|
|
263
325
|
if (key) d.classList.toggle("dgmo-dim", dk !== key);
|
|
264
326
|
else d.classList.toggle("dgmo-dim", d !== el);
|
|
265
327
|
}
|
|
328
|
+
dimLegendExcept(el);
|
|
266
329
|
};
|
|
267
330
|
const clearDim = () => {
|
|
268
331
|
for (const d of datums) d.classList.remove("dgmo-dim");
|
|
269
332
|
for (const g of seriesGroups) g.classList.remove("dgmo-dim");
|
|
270
333
|
for (const l of ptLabels) l.classList.remove("dgmo-dim");
|
|
334
|
+
for (const e of legendEntries) e.classList.remove("dgmo-dim");
|
|
271
335
|
reapplyAxisPin();
|
|
272
336
|
};
|
|
273
337
|
let axisPin = null;
|
|
@@ -513,9 +577,6 @@ function attachDataChartInteractions(svg, opts = {}) {
|
|
|
513
577
|
svg.addEventListener("mousemove", onSvgMove);
|
|
514
578
|
svg.addEventListener("mouseleave", onLeave);
|
|
515
579
|
svg.addEventListener("click", onClick);
|
|
516
|
-
const legendEntries = Array.from(
|
|
517
|
-
svg.querySelectorAll(".chart-legend [data-legend-entry]")
|
|
518
|
-
);
|
|
519
580
|
const emphasizeSeries = (name) => {
|
|
520
581
|
for (const g of seriesGroups) {
|
|
521
582
|
const sn = g.getAttribute("data-series-name");
|
|
@@ -637,7 +698,14 @@ function mountD3DataChart(container, content, opts = {}) {
|
|
|
637
698
|
interaction.destroy();
|
|
638
699
|
interaction = null;
|
|
639
700
|
}
|
|
640
|
-
|
|
701
|
+
const holder = document.createElement("div");
|
|
702
|
+
holder.innerHTML = svg;
|
|
703
|
+
const parsed = holder.querySelector("svg");
|
|
704
|
+
container.innerHTML = "";
|
|
705
|
+
if (parsed) {
|
|
706
|
+
sanitizeSvgInPlace(parsed);
|
|
707
|
+
container.append(parsed);
|
|
708
|
+
}
|
|
641
709
|
const el = container.querySelector("svg");
|
|
642
710
|
if (el) {
|
|
643
711
|
const pal = paletteOf(current);
|
|
@@ -750,6 +818,7 @@ export {
|
|
|
750
818
|
palettes,
|
|
751
819
|
render2 as render,
|
|
752
820
|
resolvePaletteOrFallback,
|
|
821
|
+
sanitizeSvgInPlace,
|
|
753
822
|
searchMapLocations,
|
|
754
823
|
supportsD3DataChart,
|
|
755
824
|
themes,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeNodeSize,
|
|
3
3
|
layoutBoxesAndLines
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-XIFK423U.js";
|
|
5
|
+
import "./chunk-QT3KDDXK.js";
|
|
6
|
+
import "./chunk-HTNLLT34.js";
|
|
7
7
|
import "./chunk-6EK55ART.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-RJNZHFNG.js";
|
|
9
9
|
import "./chunk-5DH3KYFH.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-NPWVOFB3.js";
|
|
11
|
+
import "./chunk-S7W75MIM.js";
|
|
12
|
+
import "./chunk-Z6DXWULM.js";
|
|
12
13
|
import "./chunk-ICLB27PZ.js";
|
|
13
14
|
import "./chunk-KAO7JL4I.js";
|
|
14
15
|
import "./chunk-O753JUEZ.js";
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
layoutERDiagram
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-2A4DQAXG.js";
|
|
4
|
+
import "./chunk-HTNLLT34.js";
|
|
5
5
|
import "./chunk-6EK55ART.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-RJNZHFNG.js";
|
|
7
7
|
import "./chunk-5DH3KYFH.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-NPWVOFB3.js";
|
|
9
|
+
import "./chunk-S7W75MIM.js";
|
|
10
|
+
import "./chunk-Z6DXWULM.js";
|
|
10
11
|
import "./chunk-ICLB27PZ.js";
|
|
11
12
|
import "./chunk-KAO7JL4I.js";
|
|
12
13
|
import "./chunk-O753JUEZ.js";
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
layoutClassDiagram
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-CLQIXD2C.js";
|
|
4
|
+
import "./chunk-HTNLLT34.js";
|
|
5
5
|
import "./chunk-6EK55ART.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-RJNZHFNG.js";
|
|
7
7
|
import "./chunk-5DH3KYFH.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-NPWVOFB3.js";
|
|
9
|
+
import "./chunk-S7W75MIM.js";
|
|
10
|
+
import "./chunk-Z6DXWULM.js";
|
|
10
11
|
import "./chunk-ICLB27PZ.js";
|
|
11
12
|
import "./chunk-KAO7JL4I.js";
|
|
12
13
|
import "./chunk-O753JUEZ.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
layoutSwimlane
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-AUS7V54P.js";
|
|
4
|
+
import "./chunk-EJS3K44P.js";
|
|
5
|
+
import "./chunk-QT3KDDXK.js";
|
|
6
6
|
import "./chunk-KAO7JL4I.js";
|
|
7
7
|
import "./chunk-5WRI5ZAA.js";
|
|
8
8
|
export {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
layoutGraph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZNNVI5SR.js";
|
|
4
4
|
import "./chunk-6EK55ART.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-RJNZHFNG.js";
|
|
6
6
|
import "./chunk-5DH3KYFH.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-NPWVOFB3.js";
|
|
8
|
+
import "./chunk-S7W75MIM.js";
|
|
9
|
+
import "./chunk-Z6DXWULM.js";
|
|
9
10
|
import "./chunk-ICLB27PZ.js";
|
|
10
11
|
import "./chunk-KAO7JL4I.js";
|
|
11
12
|
import "./chunk-NXMESY4J.js";
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeNodeSize
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XIFK423U.js";
|
|
4
4
|
import {
|
|
5
5
|
clipEndpointsToNodes,
|
|
6
6
|
groupedTierCandidates
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-EJS3K44P.js";
|
|
8
8
|
import {
|
|
9
9
|
EDGE_LABEL_FONT_SIZE,
|
|
10
10
|
NODE_HEIGHT,
|
|
11
11
|
NODE_WIDTH,
|
|
12
12
|
measureEdgeLabel
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-QT3KDDXK.js";
|
|
14
|
+
import "./chunk-HTNLLT34.js";
|
|
15
15
|
import "./chunk-6EK55ART.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-RJNZHFNG.js";
|
|
17
17
|
import "./chunk-5DH3KYFH.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-NPWVOFB3.js";
|
|
19
|
+
import "./chunk-S7W75MIM.js";
|
|
20
|
+
import "./chunk-Z6DXWULM.js";
|
|
20
21
|
import "./chunk-ICLB27PZ.js";
|
|
21
22
|
import "./chunk-KAO7JL4I.js";
|
|
22
23
|
import "./chunk-O753JUEZ.js";
|
|
@@ -813,7 +814,8 @@ var ESCALATE_THRESHOLD = 4;
|
|
|
813
814
|
var ESCALATE_MAX_N = 45;
|
|
814
815
|
var ESCALATE_SEEDS = 18;
|
|
815
816
|
var ESCALATE_REFINE = 10;
|
|
816
|
-
var
|
|
817
|
+
var SEARCH_WORK_CAP = 36e3;
|
|
818
|
+
var MIN_SEARCH_CANDIDATES = 6;
|
|
817
819
|
function rng2(s) {
|
|
818
820
|
return () => {
|
|
819
821
|
s |= 0;
|
|
@@ -910,7 +912,7 @@ function countSplineCrossings(layout, floor = Infinity) {
|
|
|
910
912
|
if (g.collapsed) center.set("__group_" + g.label, { x: g.x, y: g.y });
|
|
911
913
|
const polys = flatPolys(layout);
|
|
912
914
|
const edges = layout.edges;
|
|
913
|
-
const
|
|
915
|
+
const R2 = 34 * 34;
|
|
914
916
|
let total = 0;
|
|
915
917
|
for (let a = 0; a < polys.length; a++)
|
|
916
918
|
for (let b = a + 1; b < polys.length; b++) {
|
|
@@ -928,6 +930,8 @@ function countSplineCrossings(layout, floor = Infinity) {
|
|
|
928
930
|
for (let i = 1; i < ap.length; i++) {
|
|
929
931
|
const a0 = ap[i - 1], a1 = ap[i];
|
|
930
932
|
const axMin = a0.x < a1.x ? a0.x : a1.x, axMax = a0.x > a1.x ? a0.x : a1.x, ayMin = a0.y < a1.y ? a0.y : a1.y, ayMax = a0.y > a1.y ? a0.y : a1.y;
|
|
933
|
+
if (axMax < B.x0 || axMin > B.x1 || ayMax < B.y0 || ayMin > B.y1)
|
|
934
|
+
continue;
|
|
931
935
|
for (let j = 1; j < bp.length; j++) {
|
|
932
936
|
const b0 = bp[j - 1], b1 = bp[j];
|
|
933
937
|
if (axMax < (b0.x < b1.x ? b0.x : b1.x)) continue;
|
|
@@ -936,9 +940,9 @@ function countSplineCrossings(layout, floor = Infinity) {
|
|
|
936
940
|
if ((b0.y > b1.y ? b0.y : b1.y) < ayMin) continue;
|
|
937
941
|
const p = segPoint(a0, a1, b0, b1);
|
|
938
942
|
if (!p) continue;
|
|
939
|
-
if (sh0 &&
|
|
940
|
-
if (sh1 &&
|
|
941
|
-
if (!hits.some((h) =>
|
|
943
|
+
if (sh0 && (p.x - sh0.x) ** 2 + (p.y - sh0.y) ** 2 < R2) continue;
|
|
944
|
+
if (sh1 && (p.x - sh1.x) ** 2 + (p.y - sh1.y) ** 2 < R2) continue;
|
|
945
|
+
if (!hits.some((h) => (h.x - p.x) ** 2 + (h.y - p.y) ** 2 < 36))
|
|
942
946
|
hits.push(p);
|
|
943
947
|
}
|
|
944
948
|
}
|
|
@@ -947,19 +951,25 @@ function countSplineCrossings(layout, floor = Infinity) {
|
|
|
947
951
|
}
|
|
948
952
|
return total;
|
|
949
953
|
}
|
|
950
|
-
function
|
|
954
|
+
function pointSegDist2(p, a, b) {
|
|
951
955
|
const dx = b.x - a.x, dy = b.y - a.y;
|
|
952
956
|
const len2 = dx * dx + dy * dy;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
+
let qx = p.x - a.x, qy = p.y - a.y;
|
|
958
|
+
if (len2 >= 1e-9) {
|
|
959
|
+
let t = (qx * dx + qy * dy) / len2;
|
|
960
|
+
t = t < 0 ? 0 : t > 1 ? 1 : t;
|
|
961
|
+
qx -= t * dx;
|
|
962
|
+
qy -= t * dy;
|
|
963
|
+
}
|
|
964
|
+
return qx * qx + qy * qy;
|
|
957
965
|
}
|
|
958
|
-
function
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
966
|
+
function nearPoly(p, poly, dist) {
|
|
967
|
+
if (p.x < poly.x0 - dist || p.x > poly.x1 + dist || p.y < poly.y0 - dist || p.y > poly.y1 + dist)
|
|
968
|
+
return false;
|
|
969
|
+
const d2 = dist * dist, pts = poly.pts;
|
|
970
|
+
for (let i = 1; i < pts.length; i++)
|
|
971
|
+
if (pointSegDist2(p, pts[i - 1], pts[i]) < d2) return true;
|
|
972
|
+
return false;
|
|
963
973
|
}
|
|
964
974
|
function pointRectDist(p, r) {
|
|
965
975
|
const dx = Math.max(r.x - r.w / 2 - p.x, 0, p.x - (r.x + r.w / 2));
|
|
@@ -1010,7 +1020,7 @@ function detectEdgeOverlaps(layout, opts) {
|
|
|
1010
1020
|
};
|
|
1011
1021
|
for (const p of A.pts) {
|
|
1012
1022
|
const nearShared = shr0 !== void 0 && pointRectDist(p, shr0) < nodeClear || shr1 !== void 0 && pointRectDist(p, shr1) < nodeClear;
|
|
1013
|
-
const covered = !nearShared &&
|
|
1023
|
+
const covered = !nearShared && nearPoly(p, B, dist);
|
|
1014
1024
|
if (covered) {
|
|
1015
1025
|
if (run.length)
|
|
1016
1026
|
runLen += Math.hypot(
|
|
@@ -1434,8 +1444,6 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1434
1444
|
const YIELD_EVERY_MS = 30;
|
|
1435
1445
|
const searchStart = performance.now();
|
|
1436
1446
|
let lastYield = searchStart;
|
|
1437
|
-
const budgetMs = opts?.budgetMs ?? DEFAULT_SEARCH_BUDGET_MS;
|
|
1438
|
-
const overBudget = () => budgetMs > 0 && performance.now() - searchStart > budgetMs;
|
|
1439
1447
|
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
1440
1448
|
if (collapseInfo) {
|
|
1441
1449
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -1694,10 +1702,16 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1694
1702
|
};
|
|
1695
1703
|
}
|
|
1696
1704
|
const n = parsed.nodes.length;
|
|
1697
|
-
const seedCount = opts?.seeds ?? (n <= 12 ?
|
|
1705
|
+
const seedCount = opts?.seeds ?? (n <= 12 ? 20 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
|
|
1698
1706
|
const REFINE_K = opts?.refineK ?? 6;
|
|
1699
1707
|
const lambda = opts?.lambda ?? DEFAULT_LAMBDA;
|
|
1700
1708
|
const prev = opts?.previousPositions;
|
|
1709
|
+
const searchSize = Math.max(1, n + parsed.edges.length);
|
|
1710
|
+
const maxCandidates = Math.max(
|
|
1711
|
+
MIN_SEARCH_CANDIDATES,
|
|
1712
|
+
Math.floor(SEARCH_WORK_CAP / Math.pow(searchSize, 1.5))
|
|
1713
|
+
);
|
|
1714
|
+
let attempts = 0;
|
|
1701
1715
|
const configs = [];
|
|
1702
1716
|
if (opts?.configs) {
|
|
1703
1717
|
configs.push(...opts.configs);
|
|
@@ -1737,7 +1751,15 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1737
1751
|
};
|
|
1738
1752
|
const pool = [];
|
|
1739
1753
|
const cfgOf = /* @__PURE__ */ new Map();
|
|
1754
|
+
const perfect = [];
|
|
1755
|
+
let seedsChecked = false;
|
|
1740
1756
|
for (const cfg of configs) {
|
|
1757
|
+
if (!opts?.configs && cfg.seed !== void 0 && !seedsChecked) {
|
|
1758
|
+
seedsChecked = true;
|
|
1759
|
+
for (const lay of pool) if (badness(lay, 0) === 0) perfect.push(lay);
|
|
1760
|
+
if (perfect.length) break;
|
|
1761
|
+
}
|
|
1762
|
+
attempts++;
|
|
1741
1763
|
try {
|
|
1742
1764
|
const lay = place(cfg);
|
|
1743
1765
|
pool.push(lay);
|
|
@@ -1745,7 +1767,7 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1745
1767
|
} catch {
|
|
1746
1768
|
}
|
|
1747
1769
|
await step("Optimizing layout");
|
|
1748
|
-
if (pool.length &&
|
|
1770
|
+
if (pool.length && attempts >= maxCandidates) break;
|
|
1749
1771
|
}
|
|
1750
1772
|
if (!pool.length) {
|
|
1751
1773
|
const plain = {
|
|
@@ -1813,6 +1835,12 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1813
1835
|
if (cfg) topConfigs.push(cfg);
|
|
1814
1836
|
await step("Refining layout");
|
|
1815
1837
|
}
|
|
1838
|
+
for (const lay of perfect) {
|
|
1839
|
+
if (pool.indexOf(lay) < refineK) continue;
|
|
1840
|
+
consider(lay);
|
|
1841
|
+
const cfg = cfgOf.get(lay);
|
|
1842
|
+
if (cfg) topConfigs.push(cfg);
|
|
1843
|
+
}
|
|
1816
1844
|
if (!opts?.configs && bestBad >= ESCALATE_THRESHOLD && n <= ESCALATE_MAX_N) {
|
|
1817
1845
|
const extra = [];
|
|
1818
1846
|
for (let s = seedCount; s < seedCount + ESCALATE_SEEDS; s++) {
|
|
@@ -1822,13 +1850,14 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
1822
1850
|
ranksep: 60,
|
|
1823
1851
|
seed: s
|
|
1824
1852
|
};
|
|
1853
|
+
attempts++;
|
|
1825
1854
|
try {
|
|
1826
1855
|
const lay = place(cfg);
|
|
1827
1856
|
extra.push(lay);
|
|
1828
1857
|
cfgOf.set(lay, cfg);
|
|
1829
1858
|
} catch {
|
|
1830
1859
|
}
|
|
1831
|
-
if (
|
|
1860
|
+
if (attempts >= maxCandidates) break;
|
|
1832
1861
|
}
|
|
1833
1862
|
const extraKey = /* @__PURE__ */ new Map();
|
|
1834
1863
|
for (const lay of extra)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderGoal,
|
|
3
3
|
renderGoalForExport
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XVSJYAK7.js";
|
|
5
5
|
import "./chunk-LNO3ASX5.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-S7W75MIM.js";
|
|
7
|
+
import "./chunk-Z6DXWULM.js";
|
|
7
8
|
import "./chunk-VLC6WNRD.js";
|
|
8
9
|
import "./chunk-ICLB27PZ.js";
|
|
9
10
|
import "./chunk-KAO7JL4I.js";
|