UNPKG

20.2 kBJavaScriptView Raw
1import { p as parser, f as flowDb } from "./flowDb-a707052f.js";
2import * as graphlib from "dagre-d3-es/src/graphlib/index.js";
3import { select, curveLinear, selectAll } from "d3";
4import { k as getStylesFromArray, n as evaluate, c as getConfig, e as common, l as log, o as interpolateToCurve, p as setupGraphViewbox } from "./mermaid-a953d906.js";
5import { render } from "dagre-d3-es";
6import { applyStyle } from "dagre-d3-es/src/dagre-js/util.js";
7import { addHtmlLabel } from "dagre-d3-es/src/dagre-js/label/add-html-label.js";
8import { intersectPolygon } from "dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js";
9import { intersectRect } from "dagre-d3-es/src/dagre-js/intersect/intersect-rect.js";
10import { f as flowRendererV2, a as flowStyles } from "./styles-40ddcbf3.js";
11import "ts-dedent";
12import "dayjs/esm/index.js";
13import "@braintree/sanitize-url";
14import "dompurify";
15import "khroma";
16import "lodash-es/memoize.js";
17import "stylis";
18import "lodash-es/isEmpty.js";
19import "./index-05087a90.js";
20import "dagre-d3-es/src/dagre/index.js";
21import "dagre-d3-es/src/graphlib/json.js";
22import "./edges-97052da4.js";
23import "./createText-2f679d62.js";
24import "mdast-util-from-markdown";
25import "./svgDraw-6750006d.js";
26function question(parent, bbox, node) {
27 const w = bbox.width;
28 const h = bbox.height;
29 const s = (w + h) * 0.9;
30 const points = [
31 { x: s / 2, y: 0 },
32 { x: s, y: -s / 2 },
33 { x: s / 2, y: -s },
34 { x: 0, y: -s / 2 }
35 ];
36 const shapeSvg = insertPolygonShape(parent, s, s, points);
37 node.intersect = function(point) {
38 return intersectPolygon(node, points, point);
39 };
40 return shapeSvg;
41}
42function hexagon(parent, bbox, node) {
43 const f = 4;
44 const h = bbox.height;
45 const m = h / f;
46 const w = bbox.width + 2 * m;
47 const points = [
48 { x: m, y: 0 },
49 { x: w - m, y: 0 },
50 { x: w, y: -h / 2 },
51 { x: w - m, y: -h },
52 { x: m, y: -h },
53 { x: 0, y: -h / 2 }
54 ];
55 const shapeSvg = insertPolygonShape(parent, w, h, points);
56 node.intersect = function(point) {
57 return intersectPolygon(node, points, point);
58 };
59 return shapeSvg;
60}
61function rect_left_inv_arrow(parent, bbox, node) {
62 const w = bbox.width;
63 const h = bbox.height;
64 const points = [
65 { x: -h / 2, y: 0 },
66 { x: w, y: 0 },
67 { x: w, y: -h },
68 { x: -h / 2, y: -h },
69 { x: 0, y: -h / 2 }
70 ];
71 const shapeSvg = insertPolygonShape(parent, w, h, points);
72 node.intersect = function(point) {
73 return intersectPolygon(node, points, point);
74 };
75 return shapeSvg;
76}
77function lean_right(parent, bbox, node) {
78 const w = bbox.width;
79 const h = bbox.height;
80 const points = [
81 { x: -2 * h / 6, y: 0 },
82 { x: w - h / 6, y: 0 },
83 { x: w + 2 * h / 6, y: -h },
84 { x: h / 6, y: -h }
85 ];
86 const shapeSvg = insertPolygonShape(parent, w, h, points);
87 node.intersect = function(point) {
88 return intersectPolygon(node, points, point);
89 };
90 return shapeSvg;
91}
92function lean_left(parent, bbox, node) {
93 const w = bbox.width;
94 const h = bbox.height;
95 const points = [
96 { x: 2 * h / 6, y: 0 },
97 { x: w + h / 6, y: 0 },
98 { x: w - 2 * h / 6, y: -h },
99 { x: -h / 6, y: -h }
100 ];
101 const shapeSvg = insertPolygonShape(parent, w, h, points);
102 node.intersect = function(point) {
103 return intersectPolygon(node, points, point);
104 };
105 return shapeSvg;
106}
107function trapezoid(parent, bbox, node) {
108 const w = bbox.width;
109 const h = bbox.height;
110 const points = [
111 { x: -2 * h / 6, y: 0 },
112 { x: w + 2 * h / 6, y: 0 },
113 { x: w - h / 6, y: -h },
114 { x: h / 6, y: -h }
115 ];
116 const shapeSvg = insertPolygonShape(parent, w, h, points);
117 node.intersect = function(point) {
118 return intersectPolygon(node, points, point);
119 };
120 return shapeSvg;
121}
122function inv_trapezoid(parent, bbox, node) {
123 const w = bbox.width;
124 const h = bbox.height;
125 const points = [
126 { x: h / 6, y: 0 },
127 { x: w - h / 6, y: 0 },
128 { x: w + 2 * h / 6, y: -h },
129 { x: -2 * h / 6, y: -h }
130 ];
131 const shapeSvg = insertPolygonShape(parent, w, h, points);
132 node.intersect = function(point) {
133 return intersectPolygon(node, points, point);
134 };
135 return shapeSvg;
136}
137function rect_right_inv_arrow(parent, bbox, node) {
138 const w = bbox.width;
139 const h = bbox.height;
140 const points = [
141 { x: 0, y: 0 },
142 { x: w + h / 2, y: 0 },
143 { x: w, y: -h / 2 },
144 { x: w + h / 2, y: -h },
145 { x: 0, y: -h }
146 ];
147 const shapeSvg = insertPolygonShape(parent, w, h, points);
148 node.intersect = function(point) {
149 return intersectPolygon(node, points, point);
150 };
151 return shapeSvg;
152}
153function stadium(parent, bbox, node) {
154 const h = bbox.height;
155 const w = bbox.width + h / 4;
156 const shapeSvg = parent.insert("rect", ":first-child").attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h);
157 node.intersect = function(point) {
158 return intersectRect(node, point);
159 };
160 return shapeSvg;
161}
162function subroutine(parent, bbox, node) {
163 const w = bbox.width;
164 const h = bbox.height;
165 const points = [
166 { x: 0, y: 0 },
167 { x: w, y: 0 },
168 { x: w, y: -h },
169 { x: 0, y: -h },
170 { x: 0, y: 0 },
171 { x: -8, y: 0 },
172 { x: w + 8, y: 0 },
173 { x: w + 8, y: -h },
174 { x: -8, y: -h },
175 { x: -8, y: 0 }
176 ];
177 const shapeSvg = insertPolygonShape(parent, w, h, points);
178 node.intersect = function(point) {
179 return intersectPolygon(node, points, point);
180 };
181 return shapeSvg;
182}
183function cylinder(parent, bbox, node) {
184 const w = bbox.width;
185 const rx = w / 2;
186 const ry = rx / (2.5 + w / 50);
187 const h = bbox.height + ry;
188 const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h;
189 const shapeSvg = parent.attr("label-offset-y", ry).insert("path", ":first-child").attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")");
190 node.intersect = function(point) {
191 const pos = intersectRect(node, point);
192 const x = pos.x - node.x;
193 if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) {
194 let y = ry * ry * (1 - x * x / (rx * rx));
195 if (y != 0) {
196 y = Math.sqrt(y);
197 }
198 y = ry - y;
199 if (point.y - node.y > 0) {
200 y = -y;
201 }
202 pos.y += y;
203 }
204 return pos;
205 };
206 return shapeSvg;
207}
208function addToRender(render2) {
209 render2.shapes().question = question;
210 render2.shapes().hexagon = hexagon;
211 render2.shapes().stadium = stadium;
212 render2.shapes().subroutine = subroutine;
213 render2.shapes().cylinder = cylinder;
214 render2.shapes().rect_left_inv_arrow = rect_left_inv_arrow;
215 render2.shapes().lean_right = lean_right;
216 render2.shapes().lean_left = lean_left;
217 render2.shapes().trapezoid = trapezoid;
218 render2.shapes().inv_trapezoid = inv_trapezoid;
219 render2.shapes().rect_right_inv_arrow = rect_right_inv_arrow;
220}
221function addToRenderV2(addShape) {
222 addShape({ question });
223 addShape({ hexagon });
224 addShape({ stadium });
225 addShape({ subroutine });
226 addShape({ cylinder });
227 addShape({ rect_left_inv_arrow });
228 addShape({ lean_right });
229 addShape({ lean_left });
230 addShape({ trapezoid });
231 addShape({ inv_trapezoid });
232 addShape({ rect_right_inv_arrow });
233}
234function insertPolygonShape(parent, w, h, points) {
235 return parent.insert("polygon", ":first-child").attr(
236 "points",
237 points.map(function(d) {
238 return d.x + "," + d.y;
239 }).join(" ")
240 ).attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")");
241}
242const flowChartShapes = {
243 addToRender,
244 addToRenderV2
245};
246const conf = {};
247const setConf = function(cnf) {
248 const keys = Object.keys(cnf);
249 for (const key of keys) {
250 conf[key] = cnf[key];
251 }
252};
253const addVertices = function(vert, g, svgId, root, _doc, diagObj) {
254 const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`);
255 const doc = !_doc ? document : _doc;
256 const keys = Object.keys(vert);
257 keys.forEach(function(id) {
258 const vertex = vert[id];
259 let classStr = "default";
260 if (vertex.classes.length > 0) {
261 classStr = vertex.classes.join(" ");
262 }
263 const styles = getStylesFromArray(vertex.styles);
264 let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id;
265 let vertexNode;
266 if (evaluate(getConfig().flowchart.htmlLabels)) {
267 const node = {
268 label: vertexText.replace(
269 /fa[blrs]?:fa-[\w-]+/g,
270 (s) => `<i class='${s.replace(":", " ")}'></i>`
271 )
272 };
273 vertexNode = addHtmlLabel(svg, node).node();
274 vertexNode.parentNode.removeChild(vertexNode);
275 } else {
276 const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text");
277 svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:"));
278 const rows = vertexText.split(common.lineBreakRegex);
279 for (const row of rows) {
280 const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan");
281 tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve");
282 tspan.setAttribute("dy", "1em");
283 tspan.setAttribute("x", "1");
284 tspan.textContent = row;
285 svgLabel.appendChild(tspan);
286 }
287 vertexNode = svgLabel;
288 }
289 let radious = 0;
290 let _shape = "";
291 switch (vertex.type) {
292 case "round":
293 radious = 5;
294 _shape = "rect";
295 break;
296 case "square":
297 _shape = "rect";
298 break;
299 case "diamond":
300 _shape = "question";
301 break;
302 case "hexagon":
303 _shape = "hexagon";
304 break;
305 case "odd":
306 _shape = "rect_left_inv_arrow";
307 break;
308 case "lean_right":
309 _shape = "lean_right";
310 break;
311 case "lean_left":
312 _shape = "lean_left";
313 break;
314 case "trapezoid":
315 _shape = "trapezoid";
316 break;
317 case "inv_trapezoid":
318 _shape = "inv_trapezoid";
319 break;
320 case "odd_right":
321 _shape = "rect_left_inv_arrow";
322 break;
323 case "circle":
324 _shape = "circle";
325 break;
326 case "ellipse":
327 _shape = "ellipse";
328 break;
329 case "stadium":
330 _shape = "stadium";
331 break;
332 case "subroutine":
333 _shape = "subroutine";
334 break;
335 case "cylinder":
336 _shape = "cylinder";
337 break;
338 case "group":
339 _shape = "rect";
340 break;
341 default:
342 _shape = "rect";
343 }
344 log.warn("Adding node", vertex.id, vertex.domId);
345 g.setNode(diagObj.db.lookUpDomId(vertex.id), {
346 labelType: "svg",
347 labelStyle: styles.labelStyle,
348 shape: _shape,
349 label: vertexNode,
350 rx: radious,
351 ry: radious,
352 class: classStr,
353 style: styles.style,
354 id: diagObj.db.lookUpDomId(vertex.id)
355 });
356 });
357};
358const addEdges = function(edges, g, diagObj) {
359 let cnt = 0;
360 let defaultStyle;
361 let defaultLabelStyle;
362 if (edges.defaultStyle !== void 0) {
363 const defaultStyles = getStylesFromArray(edges.defaultStyle);
364 defaultStyle = defaultStyles.style;
365 defaultLabelStyle = defaultStyles.labelStyle;
366 }
367 edges.forEach(function(edge) {
368 cnt++;
369 const linkId = "L-" + edge.start + "-" + edge.end;
370 const linkNameStart = "LS-" + edge.start;
371 const linkNameEnd = "LE-" + edge.end;
372 const edgeData = {};
373 if (edge.type === "arrow_open") {
374 edgeData.arrowhead = "none";
375 } else {
376 edgeData.arrowhead = "normal";
377 }
378 let style = "";
379 let labelStyle = "";
380 if (edge.style !== void 0) {
381 const styles = getStylesFromArray(edge.style);
382 style = styles.style;
383 labelStyle = styles.labelStyle;
384 } else {
385 switch (edge.stroke) {
386 case "normal":
387 style = "fill:none";
388 if (defaultStyle !== void 0) {
389 style = defaultStyle;
390 }
391 if (defaultLabelStyle !== void 0) {
392 labelStyle = defaultLabelStyle;
393 }
394 break;
395 case "dotted":
396 style = "fill:none;stroke-width:2px;stroke-dasharray:3;";
397 break;
398 case "thick":
399 style = " stroke-width: 3.5px;fill:none";
400 break;
401 }
402 }
403 edgeData.style = style;
404 edgeData.labelStyle = labelStyle;
405 if (edge.interpolate !== void 0) {
406 edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear);
407 } else if (edges.defaultInterpolate !== void 0) {
408 edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear);
409 } else {
410 edgeData.curve = interpolateToCurve(conf.curve, curveLinear);
411 }
412 if (edge.text === void 0) {
413 if (edge.style !== void 0) {
414 edgeData.arrowheadStyle = "fill: #333";
415 }
416 } else {
417 edgeData.arrowheadStyle = "fill: #333";
418 edgeData.labelpos = "c";
419 if (evaluate(getConfig().flowchart.htmlLabels)) {
420 edgeData.labelType = "html";
421 edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}" style="${edgeData.labelStyle}">${edge.text.replace(
422 /fa[blrs]?:fa-[\w-]+/g,
423 (s) => `<i class='${s.replace(":", " ")}'></i>`
424 )}</span>`;
425 } else {
426 edgeData.labelType = "text";
427 edgeData.label = edge.text.replace(common.lineBreakRegex, "\n");
428 if (edge.style === void 0) {
429 edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none";
430 }
431 edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:");
432 }
433 }
434 edgeData.id = linkId;
435 edgeData.class = linkNameStart + " " + linkNameEnd;
436 edgeData.minlen = edge.length || 1;
437 g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt);
438 });
439};
440const getClasses = function(text, diagObj) {
441 log.info("Extracting classes");
442 diagObj.db.clear();
443 try {
444 diagObj.parse(text);
445 return diagObj.db.getClasses();
446 } catch (e) {
447 log.error(e);
448 return {};
449 }
450};
451const draw = function(text, id, _version, diagObj) {
452 log.info("Drawing flowchart");
453 diagObj.db.clear();
454 const { securityLevel, flowchart: conf2 } = getConfig();
455 let sandboxElement;
456 if (securityLevel === "sandbox") {
457 sandboxElement = select("#i" + id);
458 }
459 const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body");
460 const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document;
461 try {
462 diagObj.parser.parse(text);
463 } catch (err) {
464 log.debug("Parsing failed");
465 }
466 let dir = diagObj.db.getDirection();
467 if (dir === void 0) {
468 dir = "TD";
469 }
470 const nodeSpacing = conf2.nodeSpacing || 50;
471 const rankSpacing = conf2.rankSpacing || 50;
472 const g = new graphlib.Graph({
473 multigraph: true,
474 compound: true
475 }).setGraph({
476 rankdir: dir,
477 nodesep: nodeSpacing,
478 ranksep: rankSpacing,
479 marginx: 8,
480 marginy: 8
481 }).setDefaultEdgeLabel(function() {
482 return {};
483 });
484 let subG;
485 const subGraphs = diagObj.db.getSubGraphs();
486 for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) {
487 subG = subGraphs[i2];
488 diagObj.db.addVertex(subG.id, subG.title, "group", void 0, subG.classes);
489 }
490 const vert = diagObj.db.getVertices();
491 log.warn("Get vertices", vert);
492 const edges = diagObj.db.getEdges();
493 let i = 0;
494 for (i = subGraphs.length - 1; i >= 0; i--) {
495 subG = subGraphs[i];
496 selectAll("cluster").append("text");
497 for (let j = 0; j < subG.nodes.length; j++) {
498 log.warn(
499 "Setting subgraph",
500 subG.nodes[j],
501 diagObj.db.lookUpDomId(subG.nodes[j]),
502 diagObj.db.lookUpDomId(subG.id)
503 );
504 g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id));
505 }
506 }
507 addVertices(vert, g, id, root, doc, diagObj);
508 addEdges(edges, g, diagObj);
509 const render$1 = new render();
510 flowChartShapes.addToRender(render$1);
511 render$1.arrows().none = function normal(parent, id2, edge, type) {
512 const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto");
513 const path = marker.append("path").attr("d", "M 0 0 L 0 0 L 0 0 z");
514 applyStyle(path, edge[type + "Style"]);
515 };
516 render$1.arrows().normal = function normal(parent, id2) {
517 const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto");
518 marker.append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowheadPath").style("stroke-width", 1).style("stroke-dasharray", "1,0");
519 };
520 const svg = root.select(`[id="${id}"]`);
521 const element = root.select("#" + id + " g");
522 render$1(element, g);
523 element.selectAll("g.node").attr("title", function() {
524 return diagObj.db.getTooltip(this.id);
525 });
526 diagObj.db.indexNodes("subGraph" + i);
527 for (i = 0; i < subGraphs.length; i++) {
528 subG = subGraphs[i];
529 if (subG.title !== "undefined") {
530 const clusterRects = doc.querySelectorAll(
531 "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect'
532 );
533 const clusterEl = doc.querySelectorAll(
534 "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]'
535 );
536 const xPos = clusterRects[0].x.baseVal.value;
537 const yPos = clusterRects[0].y.baseVal.value;
538 const _width = clusterRects[0].width.baseVal.value;
539 const cluster = select(clusterEl[0]);
540 const te = cluster.select(".label");
541 te.attr("transform", `translate(${xPos + _width / 2}, ${yPos + 14})`);
542 te.attr("id", id + "Text");
543 for (let j = 0; j < subG.classes.length; j++) {
544 clusterEl[0].classList.add(subG.classes[j]);
545 }
546 }
547 }
548 if (!conf2.htmlLabels) {
549 const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
550 for (const label of labels) {
551 const dim = label.getBBox();
552 const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect");
553 rect.setAttribute("rx", 0);
554 rect.setAttribute("ry", 0);
555 rect.setAttribute("width", dim.width);
556 rect.setAttribute("height", dim.height);
557 label.insertBefore(rect, label.firstChild);
558 }
559 }
560 setupGraphViewbox(g, svg, conf2.diagramPadding, conf2.useMaxWidth);
561 const keys = Object.keys(vert);
562 keys.forEach(function(key) {
563 const vertex = vert[key];
564 if (vertex.link) {
565 const node = root.select("#" + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]');
566 if (node) {
567 const link = doc.createElementNS("http://www.w3.org/2000/svg", "a");
568 link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" "));
569 link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link);
570 link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener");
571 if (securityLevel === "sandbox") {
572 link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top");
573 } else if (vertex.linkTarget) {
574 link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget);
575 }
576 const linkNode = node.insert(function() {
577 return link;
578 }, ":first-child");
579 const shape = node.select(".label-container");
580 if (shape) {
581 linkNode.append(function() {
582 return shape.node();
583 });
584 }
585 const label = node.select(".label");
586 if (label) {
587 linkNode.append(function() {
588 return label.node();
589 });
590 }
591 }
592 }
593 });
594};
595const flowRenderer = {
596 setConf,
597 addVertices,
598 addEdges,
599 getClasses,
600 draw
601};
602const diagram = {
603 parser,
604 db: flowDb,
605 renderer: flowRendererV2,
606 styles: flowStyles,
607 init: (cnf) => {
608 if (!cnf.flowchart) {
609 cnf.flowchart = {};
610 }
611 cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
612 flowRenderer.setConf(cnf.flowchart);
613 flowDb.clear();
614 flowDb.setGen("gen-1");
615 }
616};
617export {
618 diagram
619};