UNPKG

mermaid

Version:

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

8 lines (7 loc) 35.7 kB
{ "version": 3, "sources": ["../../../src/diagrams/treeView/boxDrawingPreprocessor.ts", "../../../src/diagrams/treeView/db.ts", "../../../src/diagrams/treeView/parser.ts", "../../../src/diagrams/treeView/icons.ts", "../../../src/diagrams/treeView/renderer.ts", "../../../src/diagrams/treeView/styles.ts", "../../../src/diagrams/treeView/diagram.ts"], "sourcesContent": ["/**\n * Box-drawing pre-processor for treeView diagrams.\n *\n * Converts box-drawing character input (\u251C\u2500\u2500, \u2514\u2500\u2500, \u2502) to indent-based input\n * before Langium parsing. Supports both standard and heavy Unicode variants.\n */\n\n// Character class regexes\nconst ALL_BOX_CHARS = /[\u2500\u2501\u2502\u2503\u2514\u2517\u251C\u2523]/;\nconst BRANCH_CHAR = /[\u2514\u2517\u251C\u2523]/;\nconst DASH_CHAR = /[\u2500\u2501]/;\nconst DECORATION_ONLY = /^[\\s\u2502\u2503]+$/;\nconst METADATA_LINE = /^\\s*(title[\\t ]|accTitle[\\t ]*:|accDescr[\\t ]*[:{])/;\nconst COMMENT_LINE = /^\\s*%%/;\n\nconst INDENT_UNIT = ' '; // 4 spaces per depth level in output\n\nexport interface PreprocessResult {\n /** The (possibly transformed) input text */\n text: string;\n /** Maps output line numbers (1-based) \u2192 original line numbers (1-based). Empty if no transformation. */\n lineMap: Map<number, number>;\n}\n\n/**\n * Detects whether any of the given lines contain box-drawing characters.\n */\nexport function isBoxDrawingFormat(lines: string[]): boolean {\n return lines.some((line) => ALL_BOX_CHARS.test(line));\n}\n\n/**\n * Infers the segment width (chars per depth level) by finding the first\n * branch character (\u251C/\u2514/\u2523/\u2517) at a column position \\> 0.\n * Falls back to 4 if all branches are at column 0 or none exist.\n */\nfunction inferSegmentWidth(contentLines: string[]): number {\n for (const line of contentLines) {\n const match = BRANCH_CHAR.exec(line);\n if (match?.index && match.index > 0) {\n return match.index;\n }\n }\n return 4;\n}\n\n/**\n * Remaps line numbers in an error message from output line numbers to original line numbers.\n */\nexport function remapErrorLines(message: string, lineMap: Map<number, number>): string {\n return message.replace(/\\bline\\s+(\\d+)\\b/gi, (match, lineStr: string) => {\n const line = parseInt(lineStr, 10);\n const original = lineMap.get(line);\n return original ? `line ${original}` : match;\n });\n}\n\n/**\n * Pre-processes box-drawing formatted treeView input into indent-based format.\n *\n * If the input uses box-drawing characters (\u251C\u2500\u2500 \u2514\u2500\u2500 \u2502 or heavy variants \u2523\u2501\u2501 \u2517\u2501\u2501 \u2503),\n * it is converted to indentation-based format that Langium can parse directly.\n * If the input is already indent-based, it is returned unchanged.\n *\n * @returns The transformed text and a line mapping for error remapping.\n */\nexport function preprocessBoxDrawing(input: string): PreprocessResult {\n const lines = input.split('\\n');\n const lineMap = new Map<number, number>();\n\n // Find keyword line\n let keywordIdx = -1;\n for (const [i, line] of lines.entries()) {\n if (line.trim() === 'treeView-beta') {\n keywordIdx = i;\n break;\n }\n }\n\n if (keywordIdx === -1) {\n // No keyword found \u2014 return as-is (let Langium handle the error)\n return { text: input, lineMap };\n }\n\n // Collect content line texts for format detection (skip blanks, comments, metadata, decoration)\n const contentLineTexts: string[] = [];\n for (let i = keywordIdx + 1; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n if (trimmed === '' || COMMENT_LINE.test(line) || METADATA_LINE.test(line)) {\n continue;\n }\n if (DECORATION_ONLY.test(line)) {\n continue;\n }\n // Normalize tabs early so segment-width inference uses consistent column positions\n contentLineTexts.push(line.replace(/\\t/g, ' '));\n }\n\n // If no box-drawing characters found \u2192 return unchanged\n if (!isBoxDrawingFormat(contentLineTexts)) {\n return { text: input, lineMap };\n }\n\n // Infer segment width\n const segmentWidth = inferSegmentWidth(contentLineTexts);\n\n // Build output\n const outputLines: string[] = [];\n let outLineNo = 0;\n\n // Pass through all lines up to and including keyword\n for (let i = 0; i <= keywordIdx; i++) {\n outputLines.push(lines[i]);\n outLineNo++;\n lineMap.set(outLineNo, i + 1);\n }\n\n // Process lines after keyword\n for (let i = keywordIdx + 1; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n const origLineNo = i + 1;\n\n // Blank lines \u2192 pass through\n if (trimmed === '') {\n outputLines.push(line);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n continue;\n }\n\n // Comments \u2192 pass through\n if (COMMENT_LINE.test(line)) {\n outputLines.push(line);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n continue;\n }\n\n // Metadata (title, accTitle, accDescr) \u2192 pass through\n if (METADATA_LINE.test(line)) {\n outputLines.push(line);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n continue;\n }\n\n // Decoration-only lines (\u2502 + whitespace, no actual content) \u2192 skip\n if (DECORATION_ONLY.test(line)) {\n continue;\n }\n\n // Normalize tabs to spaces for consistent column-position math\n const normalized = line.replace(/\\t/g, ' ');\n\n // Find branch character (\u251C, \u2514, \u2523, \u2517)\n const branchMatch = BRANCH_CHAR.exec(normalized);\n\n if (branchMatch?.index !== undefined) {\n // Has branch char \u2192 compute depth from column position\n const branchCol = branchMatch.index;\n const depth = Math.round(branchCol / segmentWidth) + 1;\n\n // Extract content: skip branch char, then dashes, then spaces\n let pos = branchCol + 1;\n while (pos < normalized.length && DASH_CHAR.test(normalized[pos])) {\n pos++;\n }\n while (pos < normalized.length && normalized[pos] === ' ') {\n pos++;\n }\n const content = normalized.slice(pos).trimEnd();\n\n if (!content) {\n throw new Error(\n `Line ${origLineNo}: Empty node \u2014 expected a filename or directory name after the box-drawing prefix`\n );\n }\n\n const indent = INDENT_UNIT.repeat(depth);\n outputLines.push(indent + content);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n } else if (/^[\\s\u2500\u2501\u2502\u2503\u2514\u2517\u251C\u2523]+$/.test(normalized)) {\n // Entire line is box-drawing decoration and whitespace \u2014 skip\n continue;\n } else if (ALL_BOX_CHARS.test(normalized)) {\n // Has box chars but no branch char \u2014 likely content containing a box char (e.g. \"Section \u2500 A.txt\")\n // Treat as root-level item\n outputLines.push(line);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n } else if (/^\\s+/.test(normalized)) {\n // Leading whitespace without box chars in box mode \u2192 likely mixed format\n throw new Error(\n `Line ${origLineNo}: Unexpected indentation without box-drawing characters. ` +\n `In box-drawing format, use \u251C\u2500\u2500 or \u2514\u2500\u2500 prefixes for indented nodes.`\n );\n } else {\n // No box chars, no leading whitespace \u2192 root-level item (depth 0)\n outputLines.push(line);\n outLineNo++;\n lineMap.set(outLineNo, origLineNo);\n }\n }\n\n return { text: outputLines.join('\\n'), lineMap };\n}\n", "import { getConfig as getCommonConfig } from '../../config.js';\nimport type { TreeViewDiagramConfig } from '../../config.type.js';\nimport DEFAULT_CONFIG from '../../defaultConfig.js';\nimport { cleanAndMerge } from '../../utils.js';\nimport { ImperativeState } from '../../utils/imperativeState.js';\nimport {\n clear as commonClear,\n getAccDescription,\n getAccTitle,\n getDiagramTitle,\n setAccDescription,\n setAccTitle,\n setDiagramTitle,\n} from '../common/commonDb.js';\nimport type { Node, NodeType, TreeViewDB } from './types.js';\n\ninterface TreeViewState {\n cnt: number;\n stack: Node[];\n}\n\nconst state = new ImperativeState<TreeViewState>(() => ({\n cnt: 1,\n stack: [\n {\n id: 0,\n level: -1,\n name: '/',\n nodeType: 'directory' as NodeType,\n children: [],\n },\n ],\n}));\n\nconst clear = () => {\n state.reset();\n commonClear();\n};\n\nconst getRoot = () => {\n return state.records.stack[0];\n};\n\nconst getCount = () => state.records.cnt;\n\nconst defaultConfig: Required<TreeViewDiagramConfig> = DEFAULT_CONFIG.treeView;\n\nconst getConfig = (): Required<TreeViewDiagramConfig> => {\n return cleanAndMerge(defaultConfig, getCommonConfig().treeView);\n};\n\nconst addNode = (\n level: number,\n name: string,\n nodeType: NodeType,\n cssClass?: string,\n icon?: string,\n description?: string\n) => {\n while (level <= state.records.stack[state.records.stack.length - 1].level) {\n state.records.stack.pop();\n }\n const node: Node = {\n id: state.records.cnt++,\n level,\n name,\n nodeType,\n icon,\n cssClass,\n description,\n children: [],\n };\n state.records.stack[state.records.stack.length - 1].children.push(node);\n state.records.stack.push(node);\n};\n\nconst db: TreeViewDB = {\n clear,\n addNode,\n getRoot,\n getCount,\n getConfig,\n getAccTitle,\n getAccDescription,\n getDiagramTitle,\n setAccDescription,\n setAccTitle,\n setDiagramTitle,\n};\n\nexport default db;\n", "import { parse, type TreeView } from '@mermaid-js/parser';\nimport { getConfig } from '../../config.js';\nimport type { ParserDefinition } from '../../diagram-api/types.js';\nimport { log } from '../../logger.js';\nimport { sanitizeText } from '../common/common.js';\nimport { populateCommonDb } from '../common/populateCommonDb.js';\nimport { preprocessBoxDrawing, remapErrorLines } from './boxDrawingPreprocessor.js';\nimport db from './db.js';\nimport type { NodeType } from './types.js';\n\nconst populate = (ast: TreeView) => {\n populateCommonDb(ast, db);\n for (const node of ast.nodes) {\n const level = typeof node.indent === 'number' ? node.indent : 0;\n\n // Name comes pre-cleaned from value converter (quotes stripped, etc.)\n let name = node.name as unknown as string;\n\n // Detect directory: trailing / on the name\n const isDirectory = name.endsWith('/');\n if (isDirectory) {\n name = name.slice(0, -1);\n }\n const nodeType: NodeType = isDirectory ? 'directory' : 'file';\n\n // Read annotations directly from AST fields (cleaned by value converter)\n const cssClass = (node.classAnnotation as unknown as string) || undefined;\n\n // Icon: value converter extracts the iconify name from icon(name).\n // Empty string from icon() means suppress icon. Without an annotation the\n // icon stays undefined \u2014 defaults are resolved at render time (showIcons).\n const rawIcon = node.iconAnnotation as unknown as string | undefined;\n const icon = rawIcon !== undefined ? rawIcon || 'none' : undefined;\n\n // Description comes pre-trimmed from value converter; sanitize for defense in depth\n const rawDesc = (node.descAnnotation as unknown as string) || undefined;\n const description = rawDesc ? sanitizeText(rawDesc, getConfig()) : undefined;\n\n db.addNode(level, name, nodeType, cssClass, icon, description);\n }\n};\n\nexport const parser: ParserDefinition = {\n parse: async (input: string): Promise<void> => {\n const { text, lineMap } = preprocessBoxDrawing(input);\n try {\n const ast = await parse('treeView', text);\n log.debug(ast);\n populate(ast);\n } catch (error) {\n if (lineMap.size > 0 && error instanceof Error) {\n error.message = remapErrorLines(error.message, lineMap);\n }\n throw error;\n }\n },\n};\n", "import type { IconifyJSON } from '@iconify/types';\nimport type { NodeType } from './types.js';\n\n/**\n * Built-in icon pack for treeView nodes.\n *\n * Contains only the two default icons (file and folder), drawn as original\n * shapes for this project. Any other icon must come from a user-registered\n * iconify pack (see `registerIconPacks`) and is referenced from the diagram\n * text as `icon(pack:name)`, or as `icon(name)` together with the\n * `defaultIconPack` config option.\n *\n * Icons use `currentColor` so they can be themed via CSS `color`.\n */\nexport const treeViewIcons: IconifyJSON = {\n prefix: 'mermaid-treeview',\n height: 24,\n width: 24,\n icons: {\n folder: {\n body: '<path fill=\"currentColor\" d=\"M10.59 4.59A2 2 0 0 0 9.17 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.17z\"/>',\n },\n file: {\n body: '<path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M6 2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8.83a2 2 0 0 0-.59-1.42l-4.82-4.82A2 2 0 0 0 13.17 2H6Zm7.5 1.9l4.6 4.6h-3.6a1 1 0 0 1-1-1V3.9Z\" clip-rule=\"evenodd\"/>',\n },\n },\n};\n\ninterface IconDetectionConfig {\n /** Exact-filename \u2192 icon map used to pick file icons when `showIcons` is enabled */\n filenameIcons?: Record<string, string>;\n /** Extension \u2192 icon map (lowercase keys, with or without leading dot) */\n extensionIcons?: Record<string, string>;\n}\n\n/**\n * Detect a file-type icon name from the user-configured maps.\n * There is no built-in mapping \u2014 without `filenameIcons`/`extensionIcons`\n * config, files get the built-in `file` icon. Filename matches win over\n * extension matches; extensions match case-insensitively.\n * Returns `undefined` when nothing matches.\n */\nexport function detectIcon(name: string, config?: IconDetectionConfig): string | undefined {\n const filenameIcon = config?.filenameIcons?.[name];\n if (filenameIcon) {\n return filenameIcon;\n }\n const dotIdx = name.lastIndexOf('.');\n if (dotIdx > 0) {\n const ext = name.substring(dotIdx).toLowerCase();\n const extensionIcons = config?.extensionIcons;\n return extensionIcons?.[ext] ?? extensionIcons?.[ext.slice(1)];\n }\n return undefined;\n}\n\n/** Qualify an unprefixed icon reference: built-ins win, then the defaultIconPack */\nfunction qualifyIcon(icon: string, defaultIconPack: string): string {\n if (icon.includes(':')) {\n return icon;\n }\n if (icon in treeViewIcons.icons || !defaultIconPack) {\n return `${treeViewIcons.prefix}:${icon}`;\n }\n return `${defaultIconPack}:${icon}`;\n}\n\n/**\n * Resolve the (fully-qualified) iconify reference to render for a node.\n *\n * An explicit `icon()` annotation always wins (with `none` hiding the icon);\n * otherwise, when `showIcons` is enabled, files are matched against the\n * user-configured `filenameIcons`/`extensionIcons` maps, falling back to the\n * built-in file/folder icon. Returns `undefined` when no icon should be\n * rendered.\n */\nexport function getNodeIcon(\n node: { icon?: string; name: string; nodeType: NodeType },\n config: { showIcons: boolean; defaultIconPack: string } & IconDetectionConfig\n): string | undefined {\n if (node.icon === 'none') {\n return undefined;\n }\n if (node.icon) {\n return qualifyIcon(node.icon, config.defaultIconPack);\n }\n if (!config.showIcons) {\n return undefined;\n }\n if (node.nodeType === 'file') {\n const detected = detectIcon(node.name, config);\n if (detected === 'none') {\n return undefined;\n }\n if (detected) {\n return qualifyIcon(detected, config.defaultIconPack);\n }\n }\n return `${treeViewIcons.prefix}:${node.nodeType === 'directory' ? 'folder' : 'file'}`;\n}\n", "import type { TreeViewDiagramConfig } from '../../config.type.js';\nimport type { DiagramRenderer, DrawDefinition } from '../../diagram-api/types.js';\nimport { log } from '../../logger.js';\nimport { getIconSVG, registerIconPacks } from '../../rendering-util/icons.js';\nimport { selectSvgElement } from '../../rendering-util/selectSvgElement.js';\nimport { configureSvgSize } from '../../setupGraphViewbox.js';\nimport { getNodeIcon, treeViewIcons } from './icons.js';\nimport type { D3SVGElement, Node, TreeViewDB } from './types.js';\n\nregisterIconPacks([\n {\n name: treeViewIcons.prefix,\n icons: treeViewIcons,\n },\n]);\n\nconst ICON_SIZE = 14;\nconst ICON_GAP = 4;\nconst DESC_GAP = 16;\n\ninterface RenderInfo {\n node: Node;\n nodeGroup: D3SVGElement<SVGGElement>;\n labelRightEdge: number;\n centerY: number;\n}\n\nconst resolveNodeIcons = async (root: Node, config: Required<TreeViewDiagramConfig>) => {\n const nodeIcons: { icon: string; node: Node }[] = [];\n const collect = (node: Node) => {\n const icon = getNodeIcon(node, config);\n if (icon) {\n nodeIcons.push({ icon, node });\n }\n node.children.forEach(collect);\n };\n collect(root);\n\n const resolvedIcons = await Promise.all(\n nodeIcons.map(async ({ icon, node }) => ({\n id: node.id,\n svg: await getIconSVG(icon, {\n height: ICON_SIZE,\n width: ICON_SIZE,\n }),\n }))\n );\n\n return new Map(resolvedIcons.map(({ id, svg }) => [id, svg]));\n};\n\nconst positionLabel = (\n x: number,\n y: number,\n node: Node,\n domElem: D3SVGElement<SVGGElement>,\n config: Required<TreeViewDiagramConfig>,\n iconSVGs: Map<number, string>\n): RenderInfo => {\n const nodeGroup = domElem.append('g');\n let cssClasses = 'treeView-node-label';\n if (node.nodeType === 'directory') {\n cssClasses += ' treeView-node-dir';\n }\n if (node.cssClass) {\n cssClasses += ` ${node.cssClass}`;\n }\n\n // Explicit icon() annotations always render; defaults only when showIcons is on\n const iconOffset = ICON_SIZE + ICON_GAP;\n const icon = getNodeIcon(node, config);\n const showIcon = icon !== undefined;\n if (icon) {\n nodeGroup\n .append('g')\n .attr('class', 'treeView-node-icon')\n .attr('transform', `translate(${x + config.paddingX}, ${y + config.paddingY})`)\n .html(iconSVGs.get(node.id) ?? '');\n }\n\n // Label text\n const label = nodeGroup\n .append('text')\n .text(node.name)\n .attr('dominant-baseline', 'middle')\n .attr('class', cssClasses);\n const { height: labelHeight, width: labelWidth } = label.node()!.getBBox();\n const height = labelHeight + config.paddingY * 2;\n const labelX = x + config.paddingX + (showIcon ? iconOffset : 0);\n label.attr('x', labelX);\n label.attr('y', y + height / 2);\n\n const labelRightEdge = labelX + labelWidth;\n const width = labelWidth + config.paddingX * 2 + (showIcon ? iconOffset : 0);\n node.BBox = { x, y, width, height };\n\n // Highlight background rect (sized later in drawTree)\n if (node.cssClass?.split(/\\s+/).includes('highlight')) {\n nodeGroup\n .insert('rect', ':first-child')\n .attr('x', x)\n .attr('y', y + 1)\n .attr('width', 0)\n .attr('height', height - 2)\n .attr('rx', 3)\n .attr('class', 'treeView-highlight-bg');\n }\n\n return { node, nodeGroup, labelRightEdge, centerY: y + height / 2 };\n};\n\nconst positionLine = (\n domElem: D3SVGElement<SVGGElement>,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n lineThickness: number\n) => {\n return domElem\n .append('line')\n .attr('x1', x1)\n .attr('y1', y1)\n .attr('x2', x2)\n .attr('y2', y2)\n .attr('stroke-width', lineThickness)\n .attr('class', 'treeView-node-line');\n};\n\nconst drawTree = (\n elem: D3SVGElement<SVGGElement>,\n root: Node,\n config: Required<TreeViewDiagramConfig>,\n iconSVGs: Map<number, string>\n) => {\n let totalHeight = 0;\n let totalWidth = 0;\n const renderInfos: RenderInfo[] = [];\n\n const drawNode = (\n elem: D3SVGElement<SVGGElement>,\n node: Node,\n config: Required<TreeViewDiagramConfig>,\n depth: number\n ) => {\n const indent = depth * (config.rowIndent + config.paddingX);\n const info = positionLabel(indent, totalHeight, node, elem, config, iconSVGs);\n renderInfos.push(info);\n const { height, width } = node.BBox!;\n positionLine(\n elem,\n indent - config.rowIndent,\n totalHeight + height / 2,\n indent,\n totalHeight + height / 2,\n config.lineThickness\n );\n\n totalWidth = Math.max(totalWidth, indent + width);\n totalHeight += height;\n };\n\n const processNode = (node: Node, depth = 0) => {\n drawNode(elem, node, config, depth);\n node.children.forEach((child) => {\n processNode(child, depth + 1);\n });\n const { x, y, height } = node.BBox!;\n if (node.children.length) {\n const { y: endY, height: endHeight } = node.children[node.children.length - 1].BBox!;\n positionLine(\n elem,\n x + config.paddingX,\n y + height,\n x + config.paddingX,\n endY + endHeight / 2 + config.lineThickness / 2,\n config.lineThickness\n );\n }\n };\n\n processNode(root);\n\n // Phase 2: Add descriptions, aligned to a common column\n const nodesWithDesc = renderInfos.filter((ri) => ri.node.description);\n if (nodesWithDesc.length > 0) {\n const maxLabelRight = Math.max(...renderInfos.map((ri) => ri.labelRightEdge));\n const descX = maxLabelRight + DESC_GAP;\n for (const ri of nodesWithDesc) {\n const desc = ri.nodeGroup\n .append('text')\n .text(ri.node.description!)\n .attr('dominant-baseline', 'middle')\n .attr('class', 'treeView-node-description')\n .attr('x', descX)\n .attr('y', ri.centerY);\n const descBBox = desc.node()!.getBBox();\n totalWidth = Math.max(totalWidth, descX + descBBox.width + config.paddingX);\n }\n }\n\n // Phase 3: Size highlight background rects to full tree width\n for (const ri of renderInfos) {\n if (ri.node.cssClass?.split(/\\s+/).includes('highlight')) {\n const rect = ri.nodeGroup.select('.treeView-highlight-bg');\n if (!rect.empty()) {\n const rectWidth = totalWidth - ri.node.BBox!.x + 8;\n rect.attr('width', rectWidth);\n // Expand totalWidth to ensure the viewBox includes the highlight rect + stroke\n totalWidth = Math.max(totalWidth, ri.node.BBox!.x + rectWidth + 2);\n }\n }\n }\n\n return { totalHeight, totalWidth };\n};\n\nconst draw: DrawDefinition = async (text, id, _ver, diagObj) => {\n log.debug('Rendering treeView diagram\\n' + text);\n\n const db = diagObj.db as TreeViewDB;\n const root = db.getRoot();\n const config = db.getConfig();\n\n const svg = selectSvgElement(id);\n\n const treeElem = svg.append('g');\n treeElem.attr('class', 'tree-view');\n\n const iconSVGs = await resolveNodeIcons(root, config);\n const { totalHeight, totalWidth } = drawTree(treeElem, root, config, iconSVGs);\n /* -${config.lineThickness/2} is required for a line with x coordinate = 0\n as there is overflow to the left due to the line being centered */\n svg.attr('viewBox', `-${config.lineThickness / 2} 0 ${totalWidth} ${totalHeight}`);\n configureSvgSize(svg, totalHeight, totalWidth, config.useMaxWidth);\n};\n\nconst renderer: DiagramRenderer = {\n draw,\n};\n\nexport default renderer;\n", "import type { DiagramStylesProvider } from '../../diagram-api/types.js';\nimport { cleanAndMerge } from '../../utils.js';\nimport type { TreeViewDiagramStyles } from './types.js';\n\nconst defaultTreeViewDiagramStyles: Required<TreeViewDiagramStyles> = {\n labelFontSize: '16px',\n labelColor: 'black',\n lineColor: 'black',\n iconColor: '#546e7a',\n descriptionColor: '#6a9955',\n highlightBg: 'rgba(255, 193, 7, 0.15)',\n highlightStroke: '#ffc107',\n};\n\nconst styles: DiagramStylesProvider = ({\n treeView,\n}: {\n treeView?: TreeViewDiagramStyles;\n}): string => {\n const {\n labelFontSize,\n labelColor,\n lineColor,\n iconColor,\n descriptionColor,\n highlightBg,\n highlightStroke,\n } = cleanAndMerge(defaultTreeViewDiagramStyles, treeView);\n return `\n .treeView-node-label {\n font-size: ${labelFontSize};\n fill: ${labelColor};\n white-space: pre;\n }\n .treeView-node-dir {\n font-weight: bold;\n }\n .treeView-node-line {\n stroke: ${lineColor};\n }\n .treeView-node-icon {\n color: ${iconColor};\n }\n .treeView-node-description {\n font-size: ${labelFontSize};\n fill: ${descriptionColor};\n font-style: italic;\n white-space: pre;\n }\n .treeView-highlight-bg {\n fill: ${highlightBg};\n stroke: ${highlightStroke};\n stroke-width: 1;\n }\n `;\n};\n\nexport default styles;\n", "import type { DiagramDefinition } from '../../diagram-api/types.js';\nimport { parser } from './parser.js';\nimport db from './db.js';\nimport renderer from './renderer.js';\nimport styles from './styles.js';\n\nexport const diagram: DiagramDefinition = {\n db,\n renderer,\n parser,\n styles,\n};\n"], "mappings": "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", "names": ["clear", "getConfig", "elem", "config", "db"] }