import { D as DEFAULT_DIAGRAM_DIRECTION, a as DEFAULT_STATE_TYPE, b as DIVIDER_TYPE, S as STMT_RELATION, c as STMT_STATE, e as DEFAULT_NESTED_DOC_DIR, p as parser, d as db, s as styles } from "./styles-47a825a5.js"; import * as graphlib from "dagre-d3-es/src/graphlib/index.js"; import { select } from "d3"; import { l as log, g as getConfig, e as common } from "./commonDb-573409be.js"; import { r as render } from "./index-5219d011.js"; import { u as utils, k as configureSvgSize } from "./utils-d622194a.js"; import "./mermaidAPI-3ae0f2f0.js"; import "stylis"; import "dompurify"; import "lodash-es/isEmpty.js"; import "dayjs"; import "khroma"; import "dagre-d3-es/src/dagre/index.js"; import "dagre-d3-es/src/graphlib/json.js"; import "./edges-2e77835f.js"; import "./createText-1f5f8f92.js"; import "@khanacademy/simple-markdown"; import "./svgDraw-2526cba0.js"; import "@braintree/sanitize-url"; import "lodash-es/memoize.js"; const SHAPE_STATE = "rect"; const SHAPE_STATE_WITH_DESC = "rectWithTitle"; const SHAPE_START = "start"; const SHAPE_END = "end"; const SHAPE_DIVIDER = "divider"; const SHAPE_GROUP = "roundedWithTitle"; const SHAPE_NOTE = "note"; const SHAPE_NOTEGROUP = "noteGroup"; const CSS_DIAGRAM = "statediagram"; const CSS_STATE = "state"; const CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`; const CSS_EDGE = "transition"; const CSS_NOTE = "note"; const CSS_NOTE_EDGE = "note-edge"; const CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`; const CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`; const CSS_CLUSTER = "cluster"; const CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`; const CSS_CLUSTER_ALT = "cluster-alt"; const CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`; const PARENT = "parent"; const NOTE = "note"; const DOMID_STATE = "state"; const DOMID_TYPE_SPACER = "----"; const NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`; const PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`; const G_EDGE_STYLE = "fill:none"; const G_EDGE_ARROWHEADSTYLE = "fill: #333"; const G_EDGE_LABELPOS = "c"; const G_EDGE_LABELTYPE = "text"; const G_EDGE_THICKNESS = "normal"; let nodeDb = {}; let graphItemCount = 0; const setConf = function(cnf) { const keys = Object.keys(cnf); for (const key of keys) { cnf[key]; } }; const getClasses = function(text, diagramObj) { log.trace("Extracting classes"); diagramObj.db.clear(); try { diagramObj.parser.parse(text); diagramObj.db.extract(diagramObj.db.getRootDocV2()); return diagramObj.db.getClasses(); } catch (e) { return e; } }; function getClassesFromDbInfo(dbInfoItem) { if (dbInfoItem === void 0 || dbInfoItem === null) { return ""; } else { if (dbInfoItem.classes) { return dbInfoItem.classes.join(" "); } else { return ""; } } } function stateDomId(itemId = "", counter = 0, type = "", typeSpacer = DOMID_TYPE_SPACER) { const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : ""; return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`; } const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { const itemId = parsedItem.id; const classStr = getClassesFromDbInfo(diagramStates[itemId]); if (itemId !== "root") { let shape = SHAPE_STATE; if (parsedItem.start === true) { shape = SHAPE_START; } if (parsedItem.start === false) { shape = SHAPE_END; } if (parsedItem.type !== DEFAULT_STATE_TYPE) { shape = parsedItem.type; } if (!nodeDb[itemId]) { nodeDb[itemId] = { id: itemId, shape, description: common.sanitizeText(itemId, getConfig()), classes: `${classStr} ${CSS_DIAGRAM_STATE}` }; } const newNode = nodeDb[itemId]; if (parsedItem.description) { if (Array.isArray(newNode.description)) { newNode.shape = SHAPE_STATE_WITH_DESC; newNode.description.push(parsedItem.description); } else { if (newNode.description.length > 0) { newNode.shape = SHAPE_STATE_WITH_DESC; if (newNode.description === itemId) { newNode.description = [parsedItem.description]; } else { newNode.description = [newNode.description, parsedItem.description]; } } else { newNode.shape = SHAPE_STATE; newNode.description = parsedItem.description; } } newNode.description = common.sanitizeTextOrArray(newNode.description, getConfig()); } if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) { newNode.shape = SHAPE_STATE; } if (!newNode.type && parsedItem.doc) { log.info("Setting cluster for ", itemId, getDir(parsedItem)); newNode.type = "group"; newNode.dir = getDir(parsedItem); newNode.shape = parsedItem.type === DIVIDER_TYPE ? SHAPE_DIVIDER : SHAPE_GROUP; newNode.classes = newNode.classes + " " + CSS_DIAGRAM_CLUSTER + " " + (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : ""); } const nodeData = { labelStyle: "", shape: newNode.shape, labelText: newNode.description, // typeof newNode.description === 'object' // ? newNode.description[0] // : newNode.description, classes: newNode.classes, style: "", //styles.style, id: itemId, dir: newNode.dir, domId: stateDomId(itemId, graphItemCount), type: newNode.type, padding: 15 //getConfig().flowchart.padding }; nodeData.centerLabel = true; if (parsedItem.note) { const noteData = { labelStyle: "", shape: SHAPE_NOTE, labelText: parsedItem.note.text, classes: CSS_DIAGRAM_NOTE, // useHtmlLabels: false, style: "", // styles.style, id: itemId + NOTE_ID + "-" + graphItemCount, domId: stateDomId(itemId, graphItemCount, NOTE), type: newNode.type, padding: 15 //getConfig().flowchart.padding }; const groupData = { labelStyle: "", shape: SHAPE_NOTEGROUP, labelText: parsedItem.note.text, classes: newNode.classes, style: "", // styles.style, id: itemId + PARENT_ID, domId: stateDomId(itemId, graphItemCount, PARENT), type: "group", padding: 0 //getConfig().flowchart.padding }; graphItemCount++; const parentNodeId = itemId + PARENT_ID; g.setNode(parentNodeId, groupData); g.setNode(noteData.id, noteData); g.setNode(itemId, nodeData); g.setParent(itemId, parentNodeId); g.setParent(noteData.id, parentNodeId); let from = itemId; let to = noteData.id; if (parsedItem.note.position === "left of") { from = noteData.id; to = itemId; } g.setEdge(from, to, { arrowhead: "none", arrowType: "", style: G_EDGE_STYLE, labelStyle: "", classes: CSS_EDGE_NOTE_EDGE, arrowheadStyle: G_EDGE_ARROWHEADSTYLE, labelpos: G_EDGE_LABELPOS, labelType: G_EDGE_LABELTYPE, thickness: G_EDGE_THICKNESS }); } else { g.setNode(itemId, nodeData); } } if (parent && parent.id !== "root") { log.trace("Setting node ", itemId, " to be child of its parent ", parent.id); g.setParent(itemId, parent.id); } if (parsedItem.doc) { log.trace("Adding nodes children "); setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); } }; const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { log.trace("items", doc); doc.forEach((item) => { switch (item.stmt) { case STMT_STATE: setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case DEFAULT_STATE_TYPE: setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case STMT_RELATION: { setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); const edgeData = { id: "edge" + graphItemCount, arrowhead: "normal", arrowTypeEnd: "arrow_barb", style: G_EDGE_STYLE, labelStyle: "", label: common.sanitizeText(item.description, getConfig()), arrowheadStyle: G_EDGE_ARROWHEADSTYLE, labelpos: G_EDGE_LABELPOS, labelType: G_EDGE_LABELTYPE, thickness: G_EDGE_THICKNESS, classes: CSS_EDGE }; g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount); graphItemCount++; } break; } }); }; const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => { let dir = defaultDir; if (parsedItem.doc) { for (let i = 0; i < parsedItem.doc.length; i++) { const parsedItemDoc = parsedItem.doc[i]; if (parsedItemDoc.stmt === "dir") { dir = parsedItemDoc.value; } } } return dir; }; const draw = function(text, id, _version, diag) { log.info("Drawing state diagram (v2)", id); nodeDb = {}; let dir = diag.db.getDirection(); if (dir === void 0) { dir = DEFAULT_DIAGRAM_DIRECTION; } const { securityLevel, state: conf } = getConfig(); const nodeSpacing = conf.nodeSpacing || 50; const rankSpacing = conf.rankSpacing || 50; log.info(diag.db.getRootDocV2()); diag.db.extract(diag.db.getRootDocV2()); log.info(diag.db.getRootDocV2()); const diagramStates = diag.db.getStates(); const g = new graphlib.Graph({ multigraph: true, compound: true }).setGraph({ rankdir: getDir(diag.db.getRootDocV2()), nodesep: nodeSpacing, ranksep: rankSpacing, marginx: 8, marginy: 8 }).setDefaultEdgeLabel(function() { return {}; }); setupNode(g, void 0, diag.db.getRootDocV2(), diagramStates, diag.db, true); let sandboxElement; if (securityLevel === "sandbox") { sandboxElement = select("#i" + id); } const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body"); const svg = root.select(`[id="${id}"]`); const element = root.select("#" + id + " g"); render(element, g, ["barb"], CSS_DIAGRAM, id); const padding = 8; utils.insertTitle(svg, "statediagramTitleText", conf.titleTopMargin, diag.db.getDiagramTitle()); const bounds = svg.node().getBBox(); const width = bounds.width + padding * 2; const height = bounds.height + padding * 2; svg.attr("class", CSS_DIAGRAM); const svgBounds = svg.node().getBBox(); configureSvgSize(svg, height, width, conf.useMaxWidth); const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; log.debug(`viewBox ${vBox}`); svg.attr("viewBox", vBox); const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); for (const label of labels) { const dim = label.getBBox(); const rect = document.createElementNS("http://www.w3.org/2000/svg", SHAPE_STATE); rect.setAttribute("rx", 0); rect.setAttribute("ry", 0); rect.setAttribute("width", dim.width); rect.setAttribute("height", dim.height); label.insertBefore(rect, label.firstChild); } }; const renderer = { setConf, getClasses, draw }; const diagram = { parser, db, renderer, styles, init: (cnf) => { if (!cnf.state) { cnf.state = {}; } cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; db.clear(); } }; export { diagram }; //# sourceMappingURL=stateDiagram-v2-9765461d.js.map