UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.

8 lines (7 loc) 40.2 kB
{ "version": 3, "sources": ["../../../src/rendering-util/rendering-elements/clusters/swimlane.js", "../../../src/rendering-util/rendering-elements/clusters.js"], "sourcesContent": ["import { getConfig } from '../../../diagram-api/diagramAPI.js';\nimport { evaluate } from '../../../config.js';\nimport { log } from '../../../logger.js';\nimport { select } from 'd3';\nimport rough from 'roughjs';\nimport { createText } from '../../createText.ts';\nimport intersectRect from '../intersect/intersect-rect.js';\nimport { styles2String, userNodeOverrides } from '../shapes/handDrawnShapeStyles.js';\n\n/**\n * Swimlane cluster shape (lane). Extracted from the shared clusters.js so the\n * swimlane-specific rendering lives on its own; registered in the clusters.js\n * shape dispatch table. Supports LR/TB and the handdrawn (rough) look.\n */\nexport const swimlane = async (parent, node) => {\n const siteConfig = getConfig();\n const { themeVariables, handDrawnSeed } = siteConfig;\n const { clusterBkg, clusterBorder } = themeVariables;\n const laneStroke = clusterBorder;\n\n const { labelStyles, nodeStyles, borderStyles, backgroundStyles } = styles2String(node);\n\n // Add outer g element\n const shapeSvg = parent\n .insert('g')\n .attr('class', 'cluster swimlane ' + (node.cssClasses || ''))\n .attr('id', node.id)\n .attr('data-id', node.id)\n .attr('data-et', 'cluster')\n .attr('data-look', node.look);\n\n const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);\n\n // Determine if this is a left-to-right layout (title on left, rotated)\n const isLR = node.direction === 'LR';\n\n // Create the label and insert it after the rects\n const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label swimlane-label');\n\n const text = await createText(labelEl, node.label, {\n style: node.labelStyle,\n useHtmlLabels,\n isNode: true,\n width: node.width,\n });\n\n // Get the size of the label\n let bbox = text.getBBox();\n\n if (useHtmlLabels) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr('width', bbox.width);\n dv.attr('height', bbox.height);\n }\n\n const padding = node.padding ?? 0;\n const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;\n if (node.width <= bbox.width + padding) {\n node.diff = (width - node.width) / 2 - padding;\n } else {\n node.diff = -padding;\n }\n\n const height = node.height;\n const laneTop = node.y - height / 2;\n const laneBottom = node.y + height / 2;\n const laneLeft = node.x - width / 2;\n\n // Top of the content area across all lanes, computed in the swimlanes\n // layout write-back. This is the Y of the highest node in the pool.\n const contentTop =\n node.swimlaneContentTop !== undefined ? node.swimlaneContentTop : laneTop + height / 3;\n\n // Title band sizing - for LR, the title is on the left; for TB, on top.\n //\n // NOTE: For TB we intentionally use a smaller internal padding so that\n // the visible gap between the title band and the first row of nodes is\n // larger. In LR, the original padding works well visually and is kept.\n const titlePaddingY = isLR ? 4 : 0;\n const desiredTitleSize = bbox.height + 2 * titlePaddingY;\n\n let titleRect;\n let bodyRect;\n\n if (isLR) {\n // LR layout: title band is a vertical strip on the left\n // For rotated text, title width is based on label height (rotated)\n const titleWidth = Math.max(desiredTitleSize, bbox.height + 2 * titlePaddingY);\n const bodyX = laneLeft + titleWidth;\n const bodyWidth = Math.max(0, width - titleWidth);\n\n if (node.look === 'handDrawn') {\n // @ts-ignore TODO: Fix rough typings\n const rc = rough.svg(shapeSvg);\n const titleOptions = userNodeOverrides(node, {\n roughness: 0.7,\n fill: clusterBkg,\n stroke: laneStroke,\n fillWeight: 3,\n seed: handDrawnSeed,\n });\n const bodyOptions = userNodeOverrides(node, {\n roughness: 0.7,\n fill: 'none',\n stroke: laneStroke,\n seed: handDrawnSeed,\n });\n\n const roughTitle = rc.rectangle(laneLeft, laneTop, titleWidth, height, titleOptions);\n titleRect = shapeSvg.insert(() => roughTitle, ':first-child');\n const roughBody = rc.rectangle(bodyX, laneTop, bodyWidth, height, bodyOptions);\n bodyRect = shapeSvg.insert(() => roughBody, ':first-child');\n\n titleRect.select('path:nth-child(2)').attr('style', borderStyles.join(';'));\n titleRect.select('path').attr('style', backgroundStyles.join(';').replace('fill', 'stroke'));\n } else {\n titleRect = shapeSvg.insert('rect', ':first-child');\n bodyRect = shapeSvg.insert('rect', ':first-child');\n\n titleRect\n .attr('class', 'swimlane-title')\n .attr('style', nodeStyles)\n .attr('x', laneLeft)\n .attr('y', laneTop)\n .attr('width', titleWidth)\n .attr('height', height)\n .attr('fill', clusterBkg)\n .attr('stroke', laneStroke);\n\n bodyRect\n .attr('class', 'swimlane-body')\n .attr('style', nodeStyles)\n .attr('x', bodyX)\n .attr('y', laneTop)\n .attr('width', bodyWidth)\n .attr('height', height)\n .attr('fill', 'none')\n .attr('stroke', laneStroke);\n }\n\n // Position the label: center it within the title band and rotate -90 degrees\n // After rotation, the label reads bottom-to-top\n const labelCenterX = laneLeft + titleWidth / 2;\n const labelCenterY = node.y;\n labelEl.attr(\n 'transform',\n `translate(${labelCenterX}, ${labelCenterY}) rotate(-90) translate(${-bbox.width / 2}, ${-bbox.height / 2})`\n );\n } else {\n // TB layout (default): title band is a horizontal strip on top\n const headerMaxHeight = Math.max(0, contentTop - laneTop);\n const titleHeight = Math.min(desiredTitleSize, headerMaxHeight);\n\n // The lane body should visually start exactly where the title band ends\n // so that their borders touch. The vertical gap between the title text\n // and the first row of nodes is then controlled purely by the\n // headerMaxHeight/titleHeight relationship (and thus by titlePaddingY).\n const bodyY = laneTop + titleHeight;\n const contentHeight = Math.max(0, laneBottom - bodyY);\n\n const x = node.x - width / 2;\n\n if (node.look === 'handDrawn') {\n // @ts-ignore TODO: Fix rough typings\n const rc = rough.svg(shapeSvg);\n const titleOptions = userNodeOverrides(node, {\n roughness: 0.7,\n fill: clusterBkg,\n stroke: laneStroke,\n fillWeight: 3,\n seed: handDrawnSeed,\n });\n const bodyOptions = userNodeOverrides(node, {\n roughness: 0.7,\n fill: 'none',\n stroke: laneStroke,\n seed: handDrawnSeed,\n });\n\n const roughTitle = rc.rectangle(x, laneTop, width, titleHeight, titleOptions);\n titleRect = shapeSvg.insert(() => roughTitle, ':first-child');\n const roughBody = rc.rectangle(x, bodyY, width, contentHeight, bodyOptions);\n bodyRect = shapeSvg.insert(() => roughBody, ':first-child');\n\n titleRect.select('path:nth-child(2)').attr('style', borderStyles.join(';'));\n titleRect.select('path').attr('style', backgroundStyles.join(';').replace('fill', 'stroke'));\n } else {\n titleRect = shapeSvg.insert('rect', ':first-child');\n bodyRect = shapeSvg.insert('rect', ':first-child');\n\n titleRect\n .attr('class', 'swimlane-title')\n .attr('style', nodeStyles)\n .attr('x', x)\n .attr('y', laneTop)\n .attr('width', width)\n .attr('height', titleHeight)\n .attr('fill', clusterBkg)\n .attr('stroke', laneStroke);\n\n bodyRect\n .attr('class', 'swimlane-body')\n .attr('style', nodeStyles)\n .attr('x', x)\n .attr('y', bodyY)\n .attr('width', width)\n .attr('height', contentHeight)\n .attr('fill', 'none')\n .attr('stroke', laneStroke);\n }\n\n // Place the label centered within the title band\n const labelX = node.x - bbox.width / 2;\n const labelY = laneTop + (titleHeight - bbox.height) / 2;\n labelEl.attr('transform', `translate(${labelX}, ${labelY})`);\n }\n\n log.trace('Swimlane data ', node, JSON.stringify(node));\n\n if (labelStyles) {\n const span = labelEl.select('span');\n if (span) {\n span.attr('style', labelStyles);\n }\n }\n\n node.offsetX = 0;\n node.width = width;\n node.height = height;\n // Used by layout engine to position subgraph in parent\n node.offsetY = bbox.height - padding / 2;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: bbox };\n};\n", "import { getConfig } from '../../diagram-api/diagramAPI.js';\nimport { getEffectiveHtmlLabels } from '../../config.js';\nimport { log } from '../../logger.js';\nimport { getSubGraphTitleMargins } from '../../utils/subGraphTitleMargins.js';\nimport { select } from 'd3';\nimport rough from 'roughjs';\nimport { createText } from '../createText.ts';\nimport intersectRect from '../rendering-elements/intersect/intersect-rect.js';\nimport createLabel from './createLabel.js';\nimport { createRoundedRectPathD } from './shapes/roundedRectPath.ts';\nimport { styles2String, userNodeOverrides } from './shapes/handDrawnShapeStyles.js';\nimport { swimlane } from './clusters/swimlane.js';\n\nconst rect = async (parent, node) => {\n log.info('Creating subgraph rect for ', node.id, node);\n const siteConfig = getConfig();\n const { themeVariables, handDrawnSeed } = siteConfig;\n const { clusterBkg, clusterBorder } = themeVariables;\n\n const { labelStyles, nodeStyles, borderStyles, backgroundStyles } = styles2String(node);\n\n // Add outer g element\n const shapeSvg = parent\n .insert('g')\n .attr('class', 'cluster ' + node.cssClasses)\n .attr('id', node.domId)\n .attr('data-look', node.look);\n\n const useHtmlLabels = getEffectiveHtmlLabels(siteConfig);\n\n // Create the label and insert it after the rect\n const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');\n\n let text;\n if (node.labelType === 'markdown') {\n text = await createText(labelEl, node.label, {\n style: node.labelStyle,\n useHtmlLabels,\n isNode: true,\n width: node.width,\n });\n } else {\n text = await createLabel(labelEl, node.label, node.labelStyle || '', false, true);\n }\n\n // Get the size of the label\n let bbox = text.getBBox();\n\n if (getEffectiveHtmlLabels(siteConfig)) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr('width', bbox.width);\n dv.attr('height', bbox.height);\n }\n\n const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;\n if (node.width <= bbox.width + node.padding) {\n node.diff = (width - node.width) / 2 - node.padding;\n } else {\n node.diff = -node.padding;\n }\n\n const height = node.height;\n const x = node.x - width / 2;\n const y = node.y - height / 2;\n\n log.trace('Data ', node, JSON.stringify(node));\n let rect;\n if (node.look === 'handDrawn') {\n // @ts-ignore TODO: Fix rough typings\n const rc = rough.svg(shapeSvg);\n const options = userNodeOverrides(node, {\n roughness: 0.7,\n fill: clusterBkg,\n // fill: 'red',\n stroke: clusterBorder,\n fillWeight: 3,\n seed: handDrawnSeed,\n });\n const roughNode = rc.path(createRoundedRectPathD(x, y, width, height, 0), options);\n rect = shapeSvg.insert(() => {\n log.debug('Rough node insert CXC', roughNode);\n return roughNode;\n }, ':first-child');\n // Should we affect the options instead of doing this?\n rect.select('path:nth-child(2)').attr('style', borderStyles.join(';'));\n rect.select('path').attr('style', backgroundStyles.join(';').replace('fill', 'stroke'));\n } else {\n // add the rect\n rect = shapeSvg.insert('rect', ':first-child');\n // center the rect around its coordinate\n rect\n .attr('style', nodeStyles)\n .attr('rx', node.rx)\n .attr('ry', node.ry)\n .attr('x', x)\n .attr('y', y)\n .attr('width', width)\n .attr('height', height);\n }\n const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);\n labelEl.attr(\n 'transform',\n // This puts the label on top of the box instead of inside it\n `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`\n );\n\n if (labelStyles) {\n const span = labelEl.select('span');\n if (span) {\n span.attr('style', labelStyles);\n }\n }\n // Center the label\n\n const rectBox = rect.node().getBBox();\n node.offsetX = 0;\n node.width = rectBox.width;\n node.height = rectBox.height;\n // Used by layout engine to position subgraph in parent\n node.offsetY = bbox.height - node.padding / 2;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: bbox };\n};\n\n/**\n * Non visible cluster where the note is group with its\n *\n * @param {any} parent\n * @param {any} node\n * @returns {any} ShapeSvg\n */\nconst noteGroup = (parent, node) => {\n // Add outer g element\n const shapeSvg = parent.insert('g').attr('class', 'note-cluster').attr('id', node.domId);\n\n // add the rect\n const rect = shapeSvg.insert('rect', ':first-child');\n\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n\n // center the rect around its coordinate\n rect\n .attr('rx', node.rx)\n .attr('ry', node.ry)\n .attr('x', node.x - node.width / 2 - halfPadding)\n .attr('y', node.y - node.height / 2 - halfPadding)\n .attr('width', node.width + padding)\n .attr('height', node.height + padding)\n .attr('fill', 'none');\n\n const rectBox = rect.node().getBBox();\n node.width = rectBox.width;\n node.height = rectBox.height;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: { width: 0, height: 0 } };\n};\n\nconst roundedWithTitle = async (parent, node) => {\n const siteConfig = getConfig();\n\n const { themeVariables, handDrawnSeed } = siteConfig;\n const { altBackground, compositeBackground, compositeTitleBackground, nodeBorder } =\n themeVariables;\n\n // Add outer g element\n const shapeSvg = parent\n .insert('g')\n .attr('class', node.cssClasses)\n .attr('id', node.domId)\n .attr('data-id', node.id)\n .attr('data-look', node.look);\n\n // add the rect\n const outerRectG = shapeSvg.insert('g', ':first-child');\n\n // Create the label and insert it after the rect\n const label = shapeSvg.insert('g').attr('class', 'cluster-label');\n let innerRect = shapeSvg.append('rect');\n\n const text = await createLabel(label, node.label, node.labelStyle, undefined, true);\n\n // Get the size of the label\n let bbox = text.getBBox();\n\n if (getEffectiveHtmlLabels(siteConfig)) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr('width', bbox.width);\n dv.attr('height', bbox.height);\n }\n\n // Rounded With Title\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n\n const width =\n (node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width) + padding;\n if (node.width <= bbox.width + node.padding) {\n node.diff = (width - node.width) / 2 - node.padding;\n } else {\n node.diff = -node.padding;\n }\n\n const height = node.height + padding;\n // const height = node.height + padding;\n const innerHeight = node.height + padding - bbox.height - 6;\n const x = node.x - width / 2;\n const y = node.y - height / 2;\n node.width = width;\n const innerY = node.y - node.height / 2 - halfPadding + bbox.height + 2;\n\n // add the rect\n let rect;\n if (node.look === 'handDrawn') {\n const isAlt = node.cssClasses.includes('statediagram-cluster-alt');\n const rc = rough.svg(shapeSvg);\n const roughOuterNode =\n node.rx || node.ry\n ? rc.path(createRoundedRectPathD(x, y, width, height, 10), {\n roughness: 0.7,\n fill: compositeTitleBackground,\n fillStyle: 'solid',\n stroke: nodeBorder,\n seed: handDrawnSeed,\n })\n : rc.rectangle(x, y, width, height, { seed: handDrawnSeed });\n\n rect = shapeSvg.insert(() => roughOuterNode, ':first-child');\n const roughInnerNode = rc.rectangle(x, innerY, width, innerHeight, {\n fill: isAlt ? altBackground : compositeBackground,\n fillStyle: isAlt ? 'hachure' : 'solid',\n stroke: nodeBorder,\n seed: handDrawnSeed,\n });\n\n rect = shapeSvg.insert(() => roughOuterNode, ':first-child');\n innerRect = shapeSvg.insert(() => roughInnerNode);\n } else {\n rect = outerRectG.insert('rect', ':first-child');\n const outerRectClass = 'outer';\n\n // center the rect around its coordinate\n rect\n .attr('class', outerRectClass)\n .attr('x', x)\n .attr('y', y)\n .attr('width', width)\n .attr('height', height)\n .attr('data-look', node.look);\n innerRect\n .attr('class', 'inner')\n .attr('x', x)\n .attr('y', innerY)\n .attr('width', width)\n .attr('height', innerHeight);\n }\n\n label.attr(\n 'transform',\n `translate(${node.x - bbox.width / 2}, ${y + 1 - (getEffectiveHtmlLabels(siteConfig) ? 0 : 3)})`\n );\n\n const rectBox = rect.node().getBBox();\n node.height = rectBox.height;\n node.offsetX = 0;\n // Used by layout engine to position subgraph in parent\n node.offsetY = bbox.height - node.padding / 2;\n node.labelBBox = bbox;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: bbox };\n};\nconst kanbanSection = async (parent, node) => {\n log.info('Creating subgraph rect for ', node.id, node);\n const siteConfig = getConfig();\n const { themeVariables, handDrawnSeed } = siteConfig;\n const { clusterBkg, clusterBorder } = themeVariables;\n\n const { labelStyles, nodeStyles, borderStyles, backgroundStyles } = styles2String(node);\n\n // Add outer g element\n const shapeSvg = parent\n .insert('g')\n .attr('class', 'cluster ' + node.cssClasses)\n .attr('id', node.domId)\n .attr('data-look', node.look);\n\n const useHtmlLabels = getEffectiveHtmlLabels(siteConfig);\n\n // Create the label and insert it after the rect\n const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');\n\n const text = await createText(labelEl, node.label, {\n style: node.labelStyle,\n useHtmlLabels,\n isNode: true,\n width: node.width,\n });\n\n // Get the size of the label\n let bbox = text.getBBox();\n\n if (getEffectiveHtmlLabels(siteConfig)) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr('width', bbox.width);\n dv.attr('height', bbox.height);\n }\n\n const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;\n if (node.width <= bbox.width + node.padding) {\n node.diff = (width - node.width) / 2 - node.padding;\n } else {\n node.diff = -node.padding;\n }\n\n const height = node.height;\n const x = node.x - width / 2;\n const y = node.y - height / 2;\n\n log.trace('Data ', node, JSON.stringify(node));\n let rect;\n if (node.look === 'handDrawn') {\n // @ts-ignore TODO: Fix rough typings\n const rc = rough.svg(shapeSvg);\n const options = userNodeOverrides(node, {\n roughness: 0.7,\n fill: clusterBkg,\n // fill: 'red',\n stroke: clusterBorder,\n fillWeight: 4,\n seed: handDrawnSeed,\n });\n const roughNode = rc.path(createRoundedRectPathD(x, y, width, height, node.rx), options);\n rect = shapeSvg.insert(() => {\n log.debug('Rough node insert CXC', roughNode);\n return roughNode;\n }, ':first-child');\n // Should we affect the options instead of doing this?\n rect.select('path:nth-child(2)').attr('style', borderStyles.join(';'));\n rect.select('path').attr('style', backgroundStyles.join(';').replace('fill', 'stroke'));\n } else {\n // add the rect\n rect = shapeSvg.insert('rect', ':first-child');\n // center the rect around its coordinate\n rect\n .attr('style', nodeStyles)\n .attr('rx', node.rx)\n .attr('ry', node.ry)\n .attr('x', x)\n .attr('y', y)\n .attr('width', width)\n .attr('height', height);\n }\n const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);\n labelEl.attr(\n 'transform',\n // This puts the label on top of the box instead of inside it\n `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`\n );\n\n if (labelStyles) {\n const span = labelEl.select('span');\n if (span) {\n span.attr('style', labelStyles);\n }\n }\n // Center the label\n\n const rectBox = rect.node().getBBox();\n node.offsetX = 0;\n node.width = rectBox.width;\n node.height = rectBox.height;\n // Used by layout engine to position subgraph in parent\n node.offsetY = bbox.height - node.padding / 2;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: bbox };\n};\nconst divider = (parent, node) => {\n const siteConfig = getConfig();\n\n const { themeVariables, handDrawnSeed } = siteConfig;\n const { nodeBorder } = themeVariables;\n\n // Add outer g element\n const shapeSvg = parent\n .insert('g')\n .attr('class', node.cssClasses)\n .attr('id', node.domId)\n .attr('data-look', node.look);\n\n // add the rect\n const outerRectG = shapeSvg.insert('g', ':first-child');\n\n const padding = 0 * node.padding;\n\n const width = node.width + padding;\n\n node.diff = -node.padding;\n\n const height = node.height + padding;\n // const height = node.height + padding;\n const x = node.x - width / 2;\n const y = node.y - height / 2;\n node.width = width;\n\n // add the rect\n let rect;\n if (node.look === 'handDrawn') {\n const rc = rough.svg(shapeSvg);\n const roughOuterNode = rc.rectangle(x, y, width, height, {\n fill: 'lightgrey',\n roughness: 0.5,\n strokeLineDash: [5],\n stroke: nodeBorder,\n seed: handDrawnSeed,\n });\n\n rect = shapeSvg.insert(() => roughOuterNode, ':first-child');\n } else {\n rect = outerRectG.insert('rect', ':first-child');\n let outerRectClass = 'outer';\n if (node.look === 'neo') {\n outerRectClass = 'divider';\n } else {\n outerRectClass = 'divider';\n }\n\n // center the rect around its coordinate\n rect\n .attr('class', outerRectClass)\n .attr('x', x)\n .attr('y', y)\n .attr('width', width)\n .attr('height', height)\n .attr('data-look', node.look);\n }\n\n const rectBox = rect.node().getBBox();\n node.height = rectBox.height;\n node.offsetX = 0;\n // Used by layout engine to position subgraph in parent\n node.offsetY = 0;\n\n node.intersect = function (point) {\n return intersectRect(node, point);\n };\n\n return { cluster: shapeSvg, labelBBox: {} };\n};\n\nconst squareRect = rect;\nconst shapes = {\n rect,\n squareRect,\n roundedWithTitle,\n noteGroup,\n divider,\n kanbanSection,\n swimlane,\n};\n\nlet clusterElems = new Map();\n\n/**\n * @typedef {keyof typeof shapes} ClusterShapeID\n */\n\n/**\n * @param {import('../types.js').ClusterNode} node - Shape defaults to 'rect'\n */\nexport const insertCluster = async (elem, node) => {\n const shape = node.shape || 'rect';\n const cluster = await shapes[shape](elem, node);\n clusterElems.set(node.id, cluster);\n return cluster;\n};\n\nexport const getClusterTitleWidth = (elem, node) => {\n // TODO: Doesn't this need an `await`?\n const label = createLabel(elem, node.label, node.labelStyle, undefined, true);\n const width = label.getBBox().width;\n elem.node().removeChild(label);\n return width;\n};\n\nexport const clear = () => {\n clusterElems = new Map();\n};\n\nexport const positionCluster = (node) => {\n log.info(\n 'Position cluster (' +\n node.id +\n ', ' +\n node.x +\n ', ' +\n node.y +\n ') (' +\n node?.width +\n ', ' +\n node?.height +\n ')',\n clusterElems.get(node.id)\n );\n const el = clusterElems.get(node.id);\n el.cluster.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');\n};\n"], "mappings": "kXAcO,IAAMA,EAAWC,EAAA,MAAOC,EAAQC,IAAS,CAC9C,IAAMC,EAAaC,EAAU,EACvB,CAAE,eAAAC,EAAgB,cAAAC,CAAc,EAAIH,EACpC,CAAE,WAAAI,EAAY,cAAAC,CAAc,EAAIH,EAChCI,EAAaD,EAEb,CAAE,YAAAE,EAAa,WAAAC,EAAY,aAAAC,EAAc,iBAAAC,CAAiB,EAAIC,EAAcZ,CAAI,EAGhFa,EAAWd,EACd,OAAO,GAAG,EACV,KAAK,QAAS,qBAAuBC,EAAK,YAAc,GAAG,EAC3D,KAAK,KAAMA,EAAK,EAAE,EAClB,KAAK,UAAWA,EAAK,EAAE,EACvB,KAAK,UAAW,SAAS,EACzB,KAAK,YAAaA,EAAK,IAAI,EAExBc,EAAgBC,EAASd,EAAW,UAAU,UAAU,EAGxDe,EAAOhB,EAAK,YAAc,KAG1BiB,EAAUJ,EAAS,OAAO,GAAG,EAAE,KAAK,QAAS,8BAA8B,EAE3EK,EAAO,MAAMC,EAAWF,EAASjB,EAAK,MAAO,CACjD,MAAOA,EAAK,WACZ,cAAAc,EACA,OAAQ,GACR,MAAOd,EAAK,KACd,CAAC,EAGGoB,EAAOF,EAAK,QAAQ,EAExB,GAAIJ,EAAe,CACjB,IAAMO,EAAMH,EAAK,SAAS,CAAC,EACrBI,EAAKC,EAAOL,CAAI,EACtBE,EAAOC,EAAI,sBAAsB,EACjCC,EAAG,KAAK,QAASF,EAAK,KAAK,EAC3BE,EAAG,KAAK,SAAUF,EAAK,MAAM,CAC/B,CAEA,IAAMI,EAAUxB,EAAK,SAAW,EAC1ByB,EAAQzB,EAAK,OAASoB,EAAK,MAAQI,EAAUJ,EAAK,MAAQI,EAAUxB,EAAK,MAC3EA,EAAK,OAASoB,EAAK,MAAQI,EAC7BxB,EAAK,MAAQyB,EAAQzB,EAAK,OAAS,EAAIwB,EAEvCxB,EAAK,KAAO,CAACwB,EAGf,IAAME,EAAS1B,EAAK,OACd2B,EAAU3B,EAAK,EAAI0B,EAAS,EAC5BE,EAAa5B,EAAK,EAAI0B,EAAS,EAC/BG,EAAW7B,EAAK,EAAIyB,EAAQ,EAI5BK,EACJ9B,EAAK,qBAAuB,OAAYA,EAAK,mBAAqB2B,EAAUD,EAAS,EAOjFK,EAAgBf,EAAO,EAAI,EAC3BgB,EAAmBZ,EAAK,OAAS,EAAIW,EAEvCE,EACAC,EAEJ,GAAIlB,EAAM,CAGR,IAAMmB,EAAa,KAAK,IAAIH,EAAkBZ,EAAK,OAAS,EAAIW,CAAa,EACvEK,EAAQP,EAAWM,EACnBE,EAAY,KAAK,IAAI,EAAGZ,EAAQU,CAAU,EAEhD,GAAInC,EAAK,OAAS,YAAa,CAE7B,IAAMsC,EAAKC,EAAM,IAAI1B,CAAQ,EACvB2B,EAAeC,EAAkBzC,EAAM,CAC3C,UAAW,GACX,KAAMK,EACN,OAAQE,EACR,WAAY,EACZ,KAAMH,CACR,CAAC,EACKsC,EAAcD,EAAkBzC,EAAM,CAC1C,UAAW,GACX,KAAM,OACN,OAAQO,EACR,KAAMH,CACR,CAAC,EAEKuC,EAAaL,EAAG,UAAUT,EAAUF,EAASQ,EAAYT,EAAQc,CAAY,EACnFP,EAAYpB,EAAS,OAAO,IAAM8B,EAAY,cAAc,EAC5D,IAAMC,EAAYN,EAAG,UAAUF,EAAOT,EAASU,EAAWX,EAAQgB,CAAW,EAC7ER,EAAWrB,EAAS,OAAO,IAAM+B,EAAW,cAAc,EAE1DX,EAAU,OAAO,mBAAmB,EAAE,KAAK,QAASvB,EAAa,KAAK,GAAG,CAAC,EAC1EuB,EAAU,OAAO,MAAM,EAAE,KAAK,QAAStB,EAAiB,KAAK,GAAG,EAAE,QAAQ,OAAQ,QAAQ,CAAC,CAC7F,MACEsB,EAAYpB,EAAS,OAAO,OAAQ,cAAc,EAClDqB,EAAWrB,EAAS,OAAO,OAAQ,cAAc,EAEjDoB,EACG,KAAK,QAAS,gBAAgB,EAC9B,KAAK,QAASxB,CAAU,EACxB,KAAK,IAAKoB,CAAQ,EAClB,KAAK,IAAKF,CAAO,EACjB,KAAK,QAASQ,CAAU,EACxB,KAAK,SAAUT,CAAM,EACrB,KAAK,OAAQrB,CAAU,EACvB,KAAK,SAAUE,CAAU,EAE5B2B,EACG,KAAK,QAAS,eAAe,EAC7B,KAAK,QAASzB,CAAU,EACxB,KAAK,IAAK2B,CAAK,EACf,KAAK,IAAKT,CAAO,EACjB,KAAK,QAASU,CAAS,EACvB,KAAK,SAAUX,CAAM,EACrB,KAAK,OAAQ,MAAM,EACnB,KAAK,SAAUnB,CAAU,EAK9B,IAAMsC,EAAehB,EAAWM,EAAa,EACvCW,EAAe9C,EAAK,EAC1BiB,EAAQ,KACN,YACA,aAAa4B,CAAY,KAAKC,CAAY,2BAA2B,CAAC1B,EAAK,MAAQ,CAAC,KAAK,CAACA,EAAK,OAAS,CAAC,GAC3G,CACF,KAAO,CAEL,IAAM2B,EAAkB,KAAK,IAAI,EAAGjB,EAAaH,CAAO,EAClDqB,EAAc,KAAK,IAAIhB,EAAkBe,CAAe,EAMxDE,EAAQtB,EAAUqB,EAClBE,EAAgB,KAAK,IAAI,EAAGtB,EAAaqB,CAAK,EAE9CE,EAAInD,EAAK,EAAIyB,EAAQ,EAE3B,GAAIzB,EAAK,OAAS,YAAa,CAE7B,IAAMsC,EAAKC,EAAM,IAAI1B,CAAQ,EACvB2B,EAAeC,EAAkBzC,EAAM,CAC3C,UAAW,GACX,KAAMK,EACN,OAAQE,EACR,WAAY,EACZ,KAAMH,CACR,CAAC,EACKsC,EAAcD,EAAkBzC,EAAM,CAC1C,UAAW,GACX,KAAM,OACN,OAAQO,EACR,KAAMH,CACR,CAAC,EAEKuC,GAAaL,EAAG,UAAUa,EAAGxB,EAASF,EAAOuB,EAAaR,CAAY,EAC5EP,EAAYpB,EAAS,OAAO,IAAM8B,GAAY,cAAc,EAC5D,IAAMC,GAAYN,EAAG,UAAUa,EAAGF,EAAOxB,EAAOyB,EAAeR,CAAW,EAC1ER,EAAWrB,EAAS,OAAO,IAAM+B,GAAW,cAAc,EAE1DX,EAAU,OAAO,mBAAmB,EAAE,KAAK,QAASvB,EAAa,KAAK,GAAG,CAAC,EAC1EuB,EAAU,OAAO,MAAM,EAAE,KAAK,QAAStB,EAAiB,KAAK,GAAG,EAAE,QAAQ,OAAQ,QAAQ,CAAC,CAC7F,MACEsB,EAAYpB,EAAS,OAAO,OAAQ,cAAc,EAClDqB,EAAWrB,EAAS,OAAO,OAAQ,cAAc,EAEjDoB,EACG,KAAK,QAAS,gBAAgB,EAC9B,KAAK,QAASxB,CAAU,EACxB,KAAK,IAAK0C,CAAC,EACX,KAAK,IAAKxB,CAAO,EACjB,KAAK,QAASF,CAAK,EACnB,KAAK,SAAUuB,CAAW,EAC1B,KAAK,OAAQ3C,CAAU,EACvB,KAAK,SAAUE,CAAU,EAE5B2B,EACG,KAAK,QAAS,eAAe,EAC7B,KAAK,QAASzB,CAAU,EACxB,KAAK,IAAK0C,CAAC,EACX,KAAK,IAAKF,CAAK,EACf,KAAK,QAASxB,CAAK,EACnB,KAAK,SAAUyB,CAAa,EAC5B,KAAK,OAAQ,MAAM,EACnB,KAAK,SAAU3C,CAAU,EAI9B,IAAM6C,EAASpD,EAAK,EAAIoB,EAAK,MAAQ,EAC/BiC,EAAS1B,GAAWqB,EAAc5B,EAAK,QAAU,EACvDH,EAAQ,KAAK,YAAa,aAAamC,CAAM,KAAKC,CAAM,GAAG,CAC7D,CAIA,GAFAC,EAAI,MAAM,iBAAkBtD,EAAM,KAAK,UAAUA,CAAI,CAAC,EAElDQ,EAAa,CACf,IAAM+C,EAAOtC,EAAQ,OAAO,MAAM,EAC9BsC,GACFA,EAAK,KAAK,QAAS/C,CAAW,CAElC,CAEA,OAAAR,EAAK,QAAU,EACfA,EAAK,MAAQyB,EACbzB,EAAK,OAAS0B,EAEd1B,EAAK,QAAUoB,EAAK,OAASI,EAAU,EAEvCxB,EAAK,UAAY,SAAUwD,EAAO,CAChC,OAAOC,EAAczD,EAAMwD,CAAK,CAClC,EAEO,CAAE,QAAS3C,EAAU,UAAWO,CAAK,CAC9C,EAjOwB,YCDxB,IAAMsC,GAAOC,EAAA,MAAOC,EAAQC,IAAS,CACnCC,EAAI,KAAK,8BAA+BD,EAAK,GAAIA,CAAI,EACrD,IAAME,EAAaC,EAAU,EACvB,CAAE,eAAAC,EAAgB,cAAAC,CAAc,EAAIH,EACpC,CAAE,WAAAI,EAAY,cAAAC,CAAc,EAAIH,EAEhC,CAAE,YAAAI,EAAa,WAAAC,EAAY,aAAAC,EAAc,iBAAAC,CAAiB,EAAIC,EAAcZ,CAAI,EAGhFa,EAAWd,EACd,OAAO,GAAG,EACV,KAAK,QAAS,WAAaC,EAAK,UAAU,EAC1C,KAAK,KAAMA,EAAK,KAAK,EACrB,KAAK,YAAaA,EAAK,IAAI,EAExBc,EAAgBC,EAAuBb,CAAU,EAGjDc,EAAUH,EAAS,OAAO,GAAG,EAAE,KAAK,QAAS,gBAAgB,EAE/DI,EACAjB,EAAK,YAAc,WACrBiB,EAAO,MAAMC,EAAWF,EAAShB,EAAK,MAAO,CAC3C,MAAOA,EAAK,WACZ,cAAAc,EACA,OAAQ,GACR,MAAOd,EAAK,KACd,CAAC,EAEDiB,EAAO,MAAME,EAAYH,EAAShB,EAAK,MAAOA,EAAK,YAAc,GAAI,GAAO,EAAI,EAIlF,IAAIoB,EAAOH,EAAK,QAAQ,EAExB,GAAIF,EAAuBb,CAAU,EAAG,CACtC,IAAMmB,EAAMJ,EAAK,SAAS,CAAC,EACrBK,EAAKC,EAAON,CAAI,EACtBG,EAAOC,EAAI,sBAAsB,EACjCC,EAAG,KAAK,QAASF,EAAK,KAAK,EAC3BE,EAAG,KAAK,SAAUF,EAAK,MAAM,CAC/B,CAEA,IAAMI,EAAQxB,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAAUoB,EAAK,MAAQpB,EAAK,QAAUA,EAAK,MACrFA,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAClCA,EAAK,MAAQwB,EAAQxB,EAAK,OAAS,EAAIA,EAAK,QAE5CA,EAAK,KAAO,CAACA,EAAK,QAGpB,IAAMyB,EAASzB,EAAK,OACd0B,EAAI1B,EAAK,EAAIwB,EAAQ,EACrBG,EAAI3B,EAAK,EAAIyB,EAAS,EAE5BxB,EAAI,MAAM,QAASD,EAAM,KAAK,UAAUA,CAAI,CAAC,EAC7C,IAAIH,EACJ,GAAIG,EAAK,OAAS,YAAa,CAE7B,IAAM4B,EAAKC,EAAM,IAAIhB,CAAQ,EACvBiB,EAAUC,EAAkB/B,EAAM,CACtC,UAAW,GACX,KAAMM,EAEN,OAAQC,EACR,WAAY,EACZ,KAAMF,CACR,CAAC,EACK2B,EAAYJ,EAAG,KAAKK,EAAuBP,EAAGC,EAAGH,EAAOC,EAAQ,CAAC,EAAGK,CAAO,EACjFjC,EAAOgB,EAAS,OAAO,KACrBZ,EAAI,MAAM,wBAAyB+B,CAAS,EACrCA,GACN,cAAc,EAEjBnC,EAAK,OAAO,mBAAmB,EAAE,KAAK,QAASa,EAAa,KAAK,GAAG,CAAC,EACrEb,EAAK,OAAO,MAAM,EAAE,KAAK,QAASc,EAAiB,KAAK,GAAG,EAAE,QAAQ,OAAQ,QAAQ,CAAC,CACxF,MAEEd,EAAOgB,EAAS,OAAO,OAAQ,cAAc,EAE7ChB,EACG,KAAK,QAASY,CAAU,EACxB,KAAK,KAAMT,EAAK,EAAE,EAClB,KAAK,KAAMA,EAAK,EAAE,EAClB,KAAK,IAAK0B,CAAC,EACX,KAAK,IAAKC,CAAC,EACX,KAAK,QAASH,CAAK,EACnB,KAAK,SAAUC,CAAM,EAE1B,GAAM,CAAE,uBAAAS,CAAuB,EAAIC,EAAwBjC,CAAU,EAOrE,GANAc,EAAQ,KACN,YAEA,aAAahB,EAAK,EAAIoB,EAAK,MAAQ,CAAC,KAAKpB,EAAK,EAAIA,EAAK,OAAS,EAAIkC,CAAsB,GAC5F,EAEI1B,EAAa,CACf,IAAM4B,EAAOpB,EAAQ,OAAO,MAAM,EAC9BoB,GACFA,EAAK,KAAK,QAAS5B,CAAW,CAElC,CAGA,IAAM6B,EAAUxC,EAAK,KAAK,EAAE,QAAQ,EACpC,OAAAG,EAAK,QAAU,EACfA,EAAK,MAAQqC,EAAQ,MACrBrC,EAAK,OAASqC,EAAQ,OAEtBrC,EAAK,QAAUoB,EAAK,OAASpB,EAAK,QAAU,EAE5CA,EAAK,UAAY,SAAUsC,EAAO,CAChC,OAAOC,EAAcvC,EAAMsC,CAAK,CAClC,EAEO,CAAE,QAASzB,EAAU,UAAWO,CAAK,CAC9C,EAnHa,QA4HPoB,GAAY1C,EAAA,CAACC,EAAQC,IAAS,CAElC,IAAMa,EAAWd,EAAO,OAAO,GAAG,EAAE,KAAK,QAAS,cAAc,EAAE,KAAK,KAAMC,EAAK,KAAK,EAGjFH,EAAOgB,EAAS,OAAO,OAAQ,cAAc,EAE7C4B,EAAU,EAAIzC,EAAK,QACnB0C,EAAcD,EAAU,EAG9B5C,EACG,KAAK,KAAMG,EAAK,EAAE,EAClB,KAAK,KAAMA,EAAK,EAAE,EAClB,KAAK,IAAKA,EAAK,EAAIA,EAAK,MAAQ,EAAI0C,CAAW,EAC/C,KAAK,IAAK1C,EAAK,EAAIA,EAAK,OAAS,EAAI0C,CAAW,EAChD,KAAK,QAAS1C,EAAK,MAAQyC,CAAO,EAClC,KAAK,SAAUzC,EAAK,OAASyC,CAAO,EACpC,KAAK,OAAQ,MAAM,EAEtB,IAAMJ,EAAUxC,EAAK,KAAK,EAAE,QAAQ,EACpC,OAAAG,EAAK,MAAQqC,EAAQ,MACrBrC,EAAK,OAASqC,EAAQ,OAEtBrC,EAAK,UAAY,SAAUsC,EAAO,CAChC,OAAOC,EAAcvC,EAAMsC,CAAK,CAClC,EAEO,CAAE,QAASzB,EAAU,UAAW,CAAE,MAAO,EAAG,OAAQ,CAAE,CAAE,CACjE,EA7BkB,aA+BZ8B,GAAmB7C,EAAA,MAAOC,EAAQC,IAAS,CAC/C,IAAME,EAAaC,EAAU,EAEvB,CAAE,eAAAC,EAAgB,cAAAC,CAAc,EAAIH,EACpC,CAAE,cAAA0C,EAAe,oBAAAC,EAAqB,yBAAAC,EAA0B,WAAAC,CAAW,EAC/E3C,EAGIS,EAAWd,EACd,OAAO,GAAG,EACV,KAAK,QAASC,EAAK,UAAU,EAC7B,KAAK,KAAMA,EAAK,KAAK,EACrB,KAAK,UAAWA,EAAK,EAAE,EACvB,KAAK,YAAaA,EAAK,IAAI,EAGxBgD,EAAanC,EAAS,OAAO,IAAK,cAAc,EAGhDoC,EAAQpC,EAAS,OAAO,GAAG,EAAE,KAAK,QAAS,eAAe,EAC5DqC,EAAYrC,EAAS,OAAO,MAAM,EAEhCI,EAAO,MAAME,EAAY8B,EAAOjD,EAAK,MAAOA,EAAK,WAAY,OAAW,EAAI,EAG9EoB,EAAOH,EAAK,QAAQ,EAExB,GAAIF,EAAuBb,CAAU,EAAG,CACtC,IAAMmB,EAAMJ,EAAK,SAAS,CAAC,EACrBK,EAAKC,EAAON,CAAI,EACtBG,EAAOC,EAAI,sBAAsB,EACjCC,EAAG,KAAK,QAASF,EAAK,KAAK,EAC3BE,EAAG,KAAK,SAAUF,EAAK,MAAM,CAC/B,CAGA,IAAMqB,EAAU,EAAIzC,EAAK,QACnB0C,EAAcD,EAAU,EAExBjB,GACHxB,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAAUoB,EAAK,MAAQpB,EAAK,QAAUA,EAAK,OAASyC,EACnFzC,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAClCA,EAAK,MAAQwB,EAAQxB,EAAK,OAAS,EAAIA,EAAK,QAE5CA,EAAK,KAAO,CAACA,EAAK,QAGpB,IAAMyB,EAASzB,EAAK,OAASyC,EAEvBU,EAAcnD,EAAK,OAASyC,EAAUrB,EAAK,OAAS,EACpDM,EAAI1B,EAAK,EAAIwB,EAAQ,EACrBG,EAAI3B,EAAK,EAAIyB,EAAS,EAC5BzB,EAAK,MAAQwB,EACb,IAAM4B,EAASpD,EAAK,EAAIA,EAAK,OAAS,EAAI0C,EAActB,EAAK,OAAS,EAGlEvB,EACJ,GAAIG,EAAK,OAAS,YAAa,CAC7B,IAAMqD,EAAQrD,EAAK,WAAW,SAAS,0BAA0B,EAC3D4B,EAAKC,EAAM,IAAIhB,CAAQ,EACvByC,EACJtD,EAAK,IAAMA,EAAK,GACZ4B,EAAG,KAAKK,EAAuBP,EAAGC,EAAGH,EAAOC,EAAQ,EAAE,EAAG,CACvD,UAAW,GACX,KAAMqB,EACN,UAAW,QACX,OAAQC,EACR,KAAM1C,CACR,CAAC,EACDuB,EAAG,UAAUF,EAAGC,EAAGH,EAAOC,EAAQ,CAAE,KAAMpB,CAAc,CAAC,EAE/DR,EAAOgB,EAAS,OAAO,IAAMyC,EAAgB,cAAc,EAC3D,IAAMC,EAAiB3B,EAAG,UAAUF,EAAG0B,EAAQ5B,EAAO2B,EAAa,CACjE,KAAME,EAAQT,EAAgBC,EAC9B,UAAWQ,EAAQ,UAAY,QAC/B,OAAQN,EACR,KAAM1C,CACR,CAAC,EAEDR,EAAOgB,EAAS,OAAO,IAAMyC,EAAgB,cAAc,EAC3DJ,EAAYrC,EAAS,OAAO,IAAM0C,CAAc,CAClD,MACE1D,EAAOmD,EAAW,OAAO,OAAQ,cAAc,EAI/CnD,EACG,KAAK,QAJe,OAIQ,EAC5B,KAAK,IAAK6B,CAAC,EACX,KAAK,IAAKC,CAAC,EACX,KAAK,QAASH,CAAK,EACnB,KAAK,SAAUC,CAAM,EACrB,KAAK,YAAazB,EAAK,IAAI,EAC9BkD,EACG,KAAK,QAAS,OAAO,EACrB,KAAK,IAAKxB,CAAC,EACX,KAAK,IAAK0B,CAAM,EAChB,KAAK,QAAS5B,CAAK,EACnB,KAAK,SAAU2B,CAAW,EAG/BF,EAAM,KACJ,YACA,aAAajD,EAAK,EAAIoB,EAAK,MAAQ,CAAC,KAAKO,EAAI,GAAKZ,EAAuBb,CAAU,EAAI,EAAI,EAAE,GAC/F,EAEA,IAAMmC,EAAUxC,EAAK,KAAK,EAAE,QAAQ,EACpC,OAAAG,EAAK,OAASqC,EAAQ,OACtBrC,EAAK,QAAU,EAEfA,EAAK,QAAUoB,EAAK,OAASpB,EAAK,QAAU,EAC5CA,EAAK,UAAYoB,EAEjBpB,EAAK,UAAY,SAAUsC,EAAO,CAChC,OAAOC,EAAcvC,EAAMsC,CAAK,CAClC,EAEO,CAAE,QAASzB,EAAU,UAAWO,CAAK,CAC9C,EAtHyB,oBAuHnBoC,GAAgB1D,EAAA,MAAOC,EAAQC,IAAS,CAC5CC,EAAI,KAAK,8BAA+BD,EAAK,GAAIA,CAAI,EACrD,IAAME,EAAaC,EAAU,EACvB,CAAE,eAAAC,EAAgB,cAAAC,CAAc,EAAIH,EACpC,CAAE,WAAAI,EAAY,cAAAC,CAAc,EAAIH,EAEhC,CAAE,YAAAI,EAAa,WAAAC,EAAY,aAAAC,EAAc,iBAAAC,CAAiB,EAAIC,EAAcZ,CAAI,EAGhFa,EAAWd,EACd,OAAO,GAAG,EACV,KAAK,QAAS,WAAaC,EAAK,UAAU,EAC1C,KAAK,KAAMA,EAAK,KAAK,EACrB,KAAK,YAAaA,EAAK,IAAI,EAExBc,EAAgBC,EAAuBb,CAAU,EAGjDc,EAAUH,EAAS,OAAO,GAAG,EAAE,KAAK,QAAS,gBAAgB,EAE7DI,EAAO,MAAMC,EAAWF,EAAShB,EAAK,MAAO,CACjD,MAAOA,EAAK,WACZ,cAAAc,EACA,OAAQ,GACR,MAAOd,EAAK,KACd,CAAC,EAGGoB,EAAOH,EAAK,QAAQ,EAExB,GAAIF,EAAuBb,CAAU,EAAG,CACtC,IAAMmB,EAAMJ,EAAK,SAAS,CAAC,EACrBK,EAAKC,EAAON,CAAI,EACtBG,EAAOC,EAAI,sBAAsB,EACjCC,EAAG,KAAK,QAASF,EAAK,KAAK,EAC3BE,EAAG,KAAK,SAAUF,EAAK,MAAM,CAC/B,CAEA,IAAMI,EAAQxB,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAAUoB,EAAK,MAAQpB,EAAK,QAAUA,EAAK,MACrFA,EAAK,OAASoB,EAAK,MAAQpB,EAAK,QAClCA,EAAK,MAAQwB,EAAQxB,EAAK,OAAS,EAAIA,EAAK,QAE5CA,EAAK,KAAO,CAACA,EAAK,QAGpB,IAAMyB,EAASzB,EAAK,OACd0B,EAAI1B,EAAK,EAAIwB,EAAQ,EACrBG,EAAI3B,EAAK,EAAIyB,EAAS,EAE5BxB,EAAI,MAAM,QAASD,EAAM,KAAK,UAAUA,CAAI,CAAC,EAC7C,IAAIH,EACJ,GAAIG,EAAK,OAAS,YAAa,CAE7B,IAAM4B,EAAKC,EAAM,IAAIhB,CAAQ,EACvBiB,EAAUC,EAAkB/B,EAAM,CACtC,UAAW,GACX,KAAMM,EAEN,OAAQC,EACR,WAAY,EACZ,KAAMF,CACR,CAAC,EACK2B,EAAYJ,EAAG,KAAKK,EAAuBP,EAAGC,EAAGH,EAAOC,EAAQzB,EAAK,EAAE,EAAG8B,CAAO,EACvFjC,EAAOgB,EAAS,OAAO,KACrBZ,EAAI,MAAM,wBAAyB+B,CAAS,EACrCA,GACN,cAAc,EAEjBnC,EAAK,OAAO,mBAAmB,EAAE,KAAK,QAASa,EAAa,KAAK,GAAG,CAAC,EACrEb,EAAK,OAAO,MAAM,EAAE,KAAK,QAASc,EAAiB,KAAK,GAAG,EAAE,QAAQ,OAAQ,QAAQ,CAAC,CACxF,MAEEd,EAAOgB,EAAS,OAAO,OAAQ,cAAc,EAE7ChB,EACG,KAAK,QAASY,CAAU,EACxB,KAAK,KAAMT,EAAK,EAAE,EAClB,KAAK,KAAMA,EAAK,EAAE,EAClB,KAAK,IAAK0B,CAAC,EACX,KAAK,IAAKC,CAAC,EACX,KAAK,QAASH,CAAK,EACnB,KAAK,SAAUC,CAAM,EAE1B,GAAM,CAAE,uBAAAS,CAAuB,EAAIC,EAAwBjC,CAAU,EAOrE,GANAc,EAAQ,KACN,YAEA,aAAahB,EAAK,EAAIoB,EAAK,MAAQ,CAAC,KAAKpB,EAAK,EAAIA,EAAK,OAAS,EAAIkC,CAAsB,GAC5F,EAEI1B,EAAa,CACf,IAAM4B,EAAOpB,EAAQ,OAAO,MAAM,EAC9BoB,GACFA,EAAK,KAAK,QAAS5B,CAAW,CAElC,CAGA,IAAM6B,EAAUxC,EAAK,KAAK,EAAE,QAAQ,EACpC,OAAAG,EAAK,QAAU,EACfA,EAAK,MAAQqC,EAAQ,MACrBrC,EAAK,OAASqC,EAAQ,OAEtBrC,EAAK,QAAUoB,EAAK,OAASpB,EAAK,QAAU,EAE5CA,EAAK,UAAY,SAAUsC,EAAO,CAChC,OAAOC,EAAcvC,EAAMsC,CAAK,CAClC,EAEO,CAAE,QAASzB,EAAU,UAAWO,CAAK,CAC9C,EA9GsB,iBA+GhBqC,GAAU3D,EAAA,CAACC,EAAQC,IAAS,CAChC,IAAME,EAAaC,EAAU,EAEvB,CAAE,eAAAC,EAAgB,cAAAC,CAAc,EAAIH,EACpC,CAAE,WAAA6C,CAAW,EAAI3C,EAGjBS,EAAWd,EACd,OAAO,GAAG,EACV,KAAK,QAASC,EAAK,UAAU,EAC7B,KAAK,KAAMA,EAAK,KAAK,EACrB,KAAK,YAAaA,EAAK,IAAI,EAGxBgD,EAAanC,EAAS,OAAO,IAAK,cAAc,EAEhD4B,EAAU,EAAIzC,EAAK,QAEnBwB,EAAQxB,EAAK,MAAQyC,EAE3BzC,EAAK,KAAO,CAACA,EAAK,QAElB,IAAMyB,EAASzB,EAAK,OAASyC,EAEvBf,EAAI1B,EAAK,EAAIwB,EAAQ,EACrBG,EAAI3B,EAAK,EAAIyB,EAAS,EAC5BzB,EAAK,MAAQwB,EAGb,IAAI3B,EACJ,GAAIG,EAAK,OAAS,YAAa,CAE7B,IAAMsD,EADKzB,EAAM,IAAIhB,CAAQ,EACH,UAAUa,EAAGC,EAAGH,EAAOC,EAAQ,CACvD,KAAM,YACN,UAAW,GACX,eAAgB,CAAC,CAAC,EAClB,OAAQsB,EACR,KAAM1C,CACR,CAAC,EAEDR,EAAOgB,EAAS,OAAO,IAAMyC,EAAgB,cAAc,CAC7D,KAAO,CACLzD,EAAOmD,EAAW,OAAO,OAAQ,cAAc,EAC/C,IAAIU,EAAiB,QACjB1D,EAAK,KACP0D,EAAiB,UAMnB7D,EACG,KAAK,QAAS6D,CAAc,EAC5B,KAAK,IAAKhC,CAAC,EACX,KAAK,IAAKC,CAAC,EACX,KAAK,QAASH,CAAK,EACnB,KAAK,SAAUC,CAAM,EACrB,KAAK,YAAazB,EAAK,IAAI,CAChC,CAEA,IAAMqC,EAAUxC,EAAK,KAAK,EAAE,QAAQ,EACpC,OAAAG,EAAK,OAASqC,EAAQ,OACtBrC,EAAK,QAAU,EAEfA,EAAK,QAAU,EAEfA,EAAK,UAAY,SAAUsC,EAAO,CAChC,OAAOC,EAAcvC,EAAMsC,CAAK,CAClC,EAEO,CAAE,QAASzB,EAAU,UAAW,CAAC,CAAE,CAC5C,EAvEgB,WAyEV8C,GAAa9D,GACb+D,GAAS,CACb,KAAA/D,GACA,WAAA8D,GACA,iBAAAhB,GACA,UAAAH,GACA,QAAAiB,GACA,cAAAD,GACA,SAAAK,CACF,EAEIC,GAAe,IAAI,IASVC,GAAgBjE,EAAA,MAAOkE,EAAMhE,IAAS,CACjD,IAAMiE,EAAQjE,EAAK,OAAS,OACtBkE,EAAU,MAAMN,GAAOK,CAAK,EAAED,EAAMhE,CAAI,EAC9C,OAAA8D,GAAa,IAAI9D,EAAK,GAAIkE,CAAO,EAC1BA,CACT,EAL6B,iBAetB,IAAMC,GAAQC,EAAA,IAAM,CACzBC,GAAe,IAAI,GACrB,EAFqB", "names": ["swimlane", "__name", "parent", "node", "siteConfig", "getConfig", "themeVariables", "handDrawnSeed", "clusterBkg", "clusterBorder", "laneStroke", "labelStyles", "nodeStyles", "borderStyles", "backgroundStyles", "styles2String", "shapeSvg", "useHtmlLabels", "evaluate", "isLR", "labelEl", "text", "createText", "bbox", "div", "dv", "select_default", "padding", "width", "height", "laneTop", "laneBottom", "laneLeft", "contentTop", "titlePaddingY", "desiredTitleSize", "titleRect", "bodyRect", "titleWidth", "bodyX", "bodyWidth", "rc", "at", "titleOptions", "userNodeOverrides", "bodyOptions", "roughTitle", "roughBody", "labelCenterX", "labelCenterY", "headerMaxHeight", "titleHeight", "bodyY", "contentHeight", "x", "labelX", "labelY", "log", "span", "point", "intersect_rect_default", "rect", "__name", "parent", "node", "log", "siteConfig", "getConfig", "themeVariables", "handDrawnSeed", "clusterBkg", "clusterBorder", "labelStyles", "nodeStyles", "borderStyles", "backgroundStyles", "styles2String", "shapeSvg", "useHtmlLabels", "getEffectiveHtmlLabels", "labelEl", "text", "createText", "createLabel_default", "bbox", "div", "dv", "select_default", "width", "height", "x", "y", "rc", "at", "options", "userNodeOverrides", "roughNode", "createRoundedRectPathD", "subGraphTitleTopMargin", "getSubGraphTitleMargins", "span", "rectBox", "point", "intersect_rect_default", "noteGroup", "padding", "halfPadding", "roundedWithTitle", "altBackground", "compositeBackground", "compositeTitleBackground", "nodeBorder", "outerRectG", "label", "innerRect", "innerHeight", "innerY", "isAlt", "roughOuterNode", "roughInnerNode", "kanbanSection", "divider", "outerRectClass", "squareRect", "shapes", "swimlane", "clusterElems", "insertCluster", "elem", "shape", "cluster", "clear", "__name", "clusterElems"] }