@tldraw/mermaid 5.4.2 → 5.5.0-canary.0241f11f2e99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist-cjs/colors.js +15 -14
  2. package/dist-cjs/colors.js.map +2 -2
  3. package/dist-cjs/createMermaidDiagram.js +6 -4
  4. package/dist-cjs/createMermaidDiagram.js.map +2 -2
  5. package/dist-cjs/defaultMermaidNodeRenderSpec.js +13 -40
  6. package/dist-cjs/defaultMermaidNodeRenderSpec.js.map +2 -2
  7. package/dist-cjs/flowchartDiagram.js +22 -63
  8. package/dist-cjs/flowchartDiagram.js.map +2 -2
  9. package/dist-cjs/index.js +1 -1
  10. package/dist-cjs/mermaidNodeCreateShape.js +9 -25
  11. package/dist-cjs/mermaidNodeCreateShape.js.map +2 -2
  12. package/dist-cjs/mindmapDiagram.js +42 -66
  13. package/dist-cjs/mindmapDiagram.js.map +2 -2
  14. package/dist-cjs/renderBlueprint.js +108 -169
  15. package/dist-cjs/renderBlueprint.js.map +2 -2
  16. package/dist-cjs/sequenceDiagram.js +117 -163
  17. package/dist-cjs/sequenceDiagram.js.map +3 -3
  18. package/dist-cjs/stateDiagram.js +80 -157
  19. package/dist-cjs/stateDiagram.js.map +3 -3
  20. package/dist-cjs/svgParsing.js +50 -26
  21. package/dist-cjs/svgParsing.js.map +2 -2
  22. package/dist-cjs/utils.js +5 -0
  23. package/dist-cjs/utils.js.map +2 -2
  24. package/dist-esm/colors.mjs +15 -14
  25. package/dist-esm/colors.mjs.map +2 -2
  26. package/dist-esm/createMermaidDiagram.mjs +7 -5
  27. package/dist-esm/createMermaidDiagram.mjs.map +2 -2
  28. package/dist-esm/defaultMermaidNodeRenderSpec.mjs +13 -40
  29. package/dist-esm/defaultMermaidNodeRenderSpec.mjs.map +2 -2
  30. package/dist-esm/flowchartDiagram.mjs +33 -66
  31. package/dist-esm/flowchartDiagram.mjs.map +2 -2
  32. package/dist-esm/index.mjs +1 -1
  33. package/dist-esm/mermaidNodeCreateShape.mjs +9 -25
  34. package/dist-esm/mermaidNodeCreateShape.mjs.map +2 -2
  35. package/dist-esm/mindmapDiagram.mjs +44 -68
  36. package/dist-esm/mindmapDiagram.mjs.map +2 -2
  37. package/dist-esm/renderBlueprint.mjs +108 -169
  38. package/dist-esm/renderBlueprint.mjs.map +2 -2
  39. package/dist-esm/sequenceDiagram.mjs +117 -163
  40. package/dist-esm/sequenceDiagram.mjs.map +3 -3
  41. package/dist-esm/stateDiagram.mjs +84 -159
  42. package/dist-esm/stateDiagram.mjs.map +3 -3
  43. package/dist-esm/svgParsing.mjs +50 -26
  44. package/dist-esm/svgParsing.mjs.map +2 -2
  45. package/dist-esm/utils.mjs +5 -0
  46. package/dist-esm/utils.mjs.map +2 -2
  47. package/package.json +4 -4
  48. package/src/colors.ts +18 -17
  49. package/src/createMermaidDiagram.test.ts +0 -18
  50. package/src/createMermaidDiagram.ts +8 -6
  51. package/src/defaultMermaidNodeRenderSpec.ts +14 -40
  52. package/src/flowchartDiagram.ts +33 -76
  53. package/src/mermaidDiagrams.test.ts +113 -111
  54. package/src/mermaidNodeCreateShape.ts +13 -26
  55. package/src/mindmapDiagram.ts +48 -89
  56. package/src/renderBlueprint.ts +128 -189
  57. package/src/sequenceDiagram.ts +133 -182
  58. package/src/stateDiagram.ts +106 -198
  59. package/src/svgParsing.test.ts +33 -13
  60. package/src/svgParsing.ts +90 -47
  61. package/src/utils.ts +10 -0
  62. package/src/layoutParsing.test.ts +0 -71
@@ -21,7 +21,8 @@ __export(colors_exports, {
21
21
  buildClassDefColorMap: () => buildClassDefColorMap,
22
22
  parseCssStyles: () => parseCssStyles,
23
23
  parseNodeInlineColor: () => parseNodeInlineColor,
24
- parseRgbToTldrawColor: () => parseRgbToTldrawColor
24
+ parseRgbToTldrawColor: () => parseRgbToTldrawColor,
25
+ toNodeColorProps: () => toNodeColorProps
25
26
  });
26
27
  module.exports = __toCommonJS(colors_exports);
27
28
  var import_tldraw = require("tldraw");
@@ -29,23 +30,23 @@ function buildClassDefColorMap(classDefs, items) {
29
30
  const result = /* @__PURE__ */ new Map();
30
31
  if (classDefs.size === 0) return result;
31
32
  for (const [nodeId, item] of items) {
32
- if (!item.classes || item.classes.length === 0) continue;
33
- for (const className of item.classes) {
34
- const classDef = classDefs.get(className);
35
- if (!classDef || classDef.styles.length === 0) continue;
36
- const props = parseCssProps(classDef.styles);
37
- const fill = toColor(props.get("fill"));
38
- const stroke = toColor(props.get("stroke"));
39
- if (!fill && !stroke) continue;
40
- const colors = {};
41
- if (fill) colors.fillColor = nearestTldrawColor(fill);
42
- if (stroke) colors.strokeColor = nearestTldrawColor(stroke);
43
- result.set(nodeId, colors);
44
- break;
33
+ for (const className of item.classes ?? []) {
34
+ const colors = parseNodeInlineColor(classDefs.get(className)?.styles);
35
+ if (colors) {
36
+ result.set(nodeId, colors);
37
+ break;
38
+ }
45
39
  }
46
40
  }
47
41
  return result;
48
42
  }
43
+ function toNodeColorProps(colors) {
44
+ if (!colors) return {};
45
+ return {
46
+ ...colors.fillColor && { fill: "solid" },
47
+ color: colors.strokeColor ?? colors.fillColor
48
+ };
49
+ }
49
50
  function parseRgbToTldrawColor(text) {
50
51
  const color = toColor(text);
51
52
  if (!color) return null;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/colors.ts"],
4
- "sourcesContent": ["import { DEFAULT_THEME, TLDefaultColorStyle, TLDefaultDashStyle, TLDefaultSizeStyle } from 'tldraw'\n\ntype Color = [number, number, number, number]\n\nexport interface ParsedNodeColors {\n\tfillColor?: TLDefaultColorStyle\n\tstrokeColor?: TLDefaultColorStyle\n}\n\n/**\n * Build a map of node id \u2192 parsed fill/stroke colors from Mermaid's classDef definitions.\n *\n * Uses the structured data from `db.getClasses()` and each node's `classes`\n * array. For each node, looks up its applied classDef styles and maps fill and\n * stroke independently to the nearest tldraw palette color.\n */\nexport function buildClassDefColorMap(\n\tclassDefs: Map<string, { styles: string[] }>,\n\titems: Iterable<[string, { classes?: string[] }]>\n): Map<string, ParsedNodeColors> {\n\tconst result = new Map<string, ParsedNodeColors>()\n\tif (classDefs.size === 0) return result\n\n\tfor (const [nodeId, item] of items) {\n\t\tif (!item.classes || item.classes.length === 0) continue\n\n\t\tfor (const className of item.classes) {\n\t\t\tconst classDef = classDefs.get(className)\n\t\t\tif (!classDef || classDef.styles.length === 0) continue\n\n\t\t\tconst props = parseCssProps(classDef.styles)\n\t\t\tconst fill = toColor(props.get('fill'))\n\t\t\tconst stroke = toColor(props.get('stroke'))\n\n\t\t\tif (!fill && !stroke) continue\n\n\t\t\tconst colors: ParsedNodeColors = {}\n\t\t\tif (fill) colors.fillColor = nearestTldrawColor(fill)\n\t\t\tif (stroke) colors.strokeColor = nearestTldrawColor(stroke)\n\t\t\tresult.set(nodeId, colors)\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn result\n}\n\nexport function parseRgbToTldrawColor(\n\ttext: string\n): { color: TLDefaultColorStyle; hasAlpha: boolean } | null {\n\tconst color = toColor(text)\n\tif (!color) return null\n\treturn { color: nearestTldrawColor(color), hasAlpha: color[3] < 255 }\n}\n\ninterface ParsedCssOverrides {\n\tcolor?: TLDefaultColorStyle\n\tdashOverride?: TLDefaultDashStyle\n\tsizeOverride?: TLDefaultSizeStyle\n}\n\nfunction parseCssProps(styles: string[]): Map<string, string> {\n\tconst props = new Map<string, string>()\n\tfor (const entry of styles) {\n\t\tfor (const part of entry.split(';')) {\n\t\t\tconst colon = part.indexOf(':')\n\t\t\tif (colon < 0) continue\n\t\t\tconst key = part.slice(0, colon).trim().toLowerCase()\n\t\t\tconst value = part.slice(colon + 1).trim()\n\t\t\tif (key && value) props.set(key, value)\n\t\t}\n\t}\n\treturn props\n}\n\n/**\n * Parse a Mermaid CSS style array from an edge (FlowEdge.style / linkStyle)\n * and return tldraw-compatible overrides.\n */\nexport function parseCssStyles(styles: string[] | undefined): ParsedCssOverrides {\n\tif (!styles || styles.length === 0) return {}\n\n\tconst props = parseCssProps(styles)\n\tconst result: ParsedCssOverrides = {}\n\n\tconst stroke = toColor(props.get('stroke'))\n\tif (stroke) {\n\t\tresult.color = nearestTldrawColor(stroke)\n\t}\n\n\tif (props.has('stroke-dasharray')) {\n\t\tresult.dashOverride = 'dashed'\n\t}\n\n\tconst strokeWidth = props.get('stroke-width')\n\tif (strokeWidth) {\n\t\tconst pixels = parseFloat(strokeWidth)\n\t\tif (Number.isFinite(pixels)) {\n\t\t\tif (pixels <= 1) result.sizeOverride = 's'\n\t\t\telse if (pixels <= 2) result.sizeOverride = 'm'\n\t\t\telse result.sizeOverride = 'l'\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Parse inline `style nodeId fill:\u2026,stroke:\u2026` directives from a FlowVertex.styles\n * array and return fill and stroke as independent tldraw colors.\n */\nexport function parseNodeInlineColor(styles: string[] | undefined): ParsedNodeColors | undefined {\n\tif (!styles || styles.length === 0) return undefined\n\n\tconst props = parseCssProps(styles)\n\tconst fill = toColor(props.get('fill'))\n\tconst stroke = toColor(props.get('stroke'))\n\n\tif (!fill && !stroke) return undefined\n\n\tconst colors: ParsedNodeColors = {}\n\tif (fill) colors.fillColor = nearestTldrawColor(fill)\n\tif (stroke) colors.strokeColor = nearestTldrawColor(stroke)\n\treturn colors\n}\n\nfunction parseHexToRgb(hex: string): [number, number, number] | null {\n\tconst stripped = hex.replace(/^#/, '')\n\tif (stripped.length === 3 || stripped.length === 4) {\n\t\treturn [\n\t\t\tparseInt(stripped[0] + stripped[0], 16),\n\t\t\tparseInt(stripped[1] + stripped[1], 16),\n\t\t\tparseInt(stripped[2] + stripped[2], 16),\n\t\t]\n\t}\n\tif (stripped.length === 6 || stripped.length === 8) {\n\t\treturn [\n\t\t\tparseInt(stripped.slice(0, 2), 16),\n\t\t\tparseInt(stripped.slice(2, 4), 16),\n\t\t\tparseInt(stripped.slice(4, 6), 16),\n\t\t]\n\t}\n\treturn null\n}\n\nconst defaultColorNames: TLDefaultColorStyle[] = [\n\t'black',\n\t'grey',\n\t'light-violet',\n\t'violet',\n\t'blue',\n\t'light-blue',\n\t'yellow',\n\t'orange',\n\t'green',\n\t'light-green',\n\t'light-red',\n\t'red',\n\t'white',\n]\n\nconst TLDRAW_PALETTE: [TLDefaultColorStyle, number, number, number][] = defaultColorNames.map(\n\t(name) => {\n\t\tconst { solid } = DEFAULT_THEME.colors.light[name]!\n\t\tconst rgb = parseHexToRgb(solid)!\n\t\treturn [name, rgb[0], rgb[1], rgb[2]]\n\t}\n)\n\n/** Map an arbitrary Color tuple to the nearest tldraw named color (best-effort). */\nfunction nearestTldrawColor(rgb: Color): TLDefaultColorStyle {\n\tlet [r, g, b] = rgb\n\n\tconst max = Math.max(r, g, b)\n\tconst min = Math.min(r, g, b)\n\tconst lightness = (max + min) / 2 / 255\n\tconst chroma = max - min\n\n\t// For very light pastels, strip the white base and amplify the\n\t// chromatic signal so the distance metric can see the hue.\n\tif (lightness > 0.75 && chroma > 5) {\n\t\tconst target = 200\n\t\tr = Math.round(((r - min) / chroma) * target)\n\t\tg = Math.round(((g - min) / chroma) * target)\n\t\tb = Math.round(((b - min) / chroma) * target)\n\t}\n\n\tlet best: TLDefaultColorStyle = 'black'\n\tlet bestDistance = Infinity\n\tfor (const [name, red, green, blue] of TLDRAW_PALETTE) {\n\t\t// \"Redmean\" weighted Euclidean distance (Compuphase approximation).\n\t\t// Weights RGB channels by the average red value of the two colors to\n\t\t// approximate human perception, which is more sensitive to green and\n\t\t// varies in red/blue sensitivity depending on the color's warmth.\n\t\tconst rMean = (r + red) / 2\n\t\tconst dR = r - red\n\t\tconst dG = g - green\n\t\tconst dB = b - blue\n\t\tconst distance = (2 + rMean / 256) * dR * dR + 4 * dG * dG + (2 + (255 - rMean) / 256) * dB * dB\n\t\tif (distance < bestDistance) {\n\t\t\tbestDistance = distance\n\t\t\tbest = name\n\t\t}\n\t}\n\treturn best\n}\n\nfunction toColor(value: string | undefined): Color | undefined {\n\tif (!value) return undefined\n\n\tconst trimmed = value.trim()\n\tif (!trimmed || trimmed === 'none' || trimmed === 'transparent') return undefined\n\n\tif (trimmed.startsWith('rgb')) {\n\t\tconst match = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)/)\n\t\tif (!match) return undefined\n\t\treturn [\n\t\t\tparseInt(match[1], 10),\n\t\t\tparseInt(match[2], 10),\n\t\t\tparseInt(match[3], 10),\n\t\t\tmatch[4] !== undefined ? Math.round(parseFloat(match[4]) * 255) : 255,\n\t\t]\n\t}\n\tif (trimmed.startsWith('#')) {\n\t\tconst rgb = parseHexToRgb(trimmed)\n\t\tif (!rgb) return undefined\n\t\treturn [rgb[0], rgb[1], rgb[2], 255]\n\t}\n\treturn undefined\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { DEFAULT_THEME, TLDefaultColorStyle, TLDefaultDashStyle, TLDefaultSizeStyle } from 'tldraw'\nimport type { MermaidBlueprintNode } from './blueprint'\n\ntype Color = [number, number, number, number]\n\nexport interface ParsedNodeColors {\n\tfillColor?: TLDefaultColorStyle\n\tstrokeColor?: TLDefaultColorStyle\n}\n\n/**\n * Build a map of node id \u2192 parsed fill/stroke colors from Mermaid's classDef definitions.\n *\n * Uses the structured data from `db.getClasses()` and each node's `classes`\n * array. For each node, looks up its applied classDef styles and maps fill and\n * stroke independently to the nearest tldraw palette color.\n */\nexport function buildClassDefColorMap(\n\tclassDefs: Map<string, { styles: string[] }>,\n\titems: Iterable<[string, { classes?: string[] }]>\n): Map<string, ParsedNodeColors> {\n\tconst result = new Map<string, ParsedNodeColors>()\n\tif (classDefs.size === 0) return result\n\n\tfor (const [nodeId, item] of items) {\n\t\tfor (const className of item.classes ?? []) {\n\t\t\tconst colors = parseNodeInlineColor(classDefs.get(className)?.styles)\n\t\t\tif (colors) {\n\t\t\t\tresult.set(nodeId, colors)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\n/** Blueprint node style props for parsed fill/stroke colors: solid fill when a fill was set, stroke color preferred. */\nexport function toNodeColorProps(\n\tcolors: ParsedNodeColors | undefined\n): Pick<MermaidBlueprintNode, 'fill' | 'color'> {\n\tif (!colors) return {}\n\treturn {\n\t\t...(colors.fillColor && { fill: 'solid' as const }),\n\t\tcolor: colors.strokeColor ?? colors.fillColor,\n\t}\n}\n\nexport function parseRgbToTldrawColor(\n\ttext: string\n): { color: TLDefaultColorStyle; hasAlpha: boolean } | null {\n\tconst color = toColor(text)\n\tif (!color) return null\n\treturn { color: nearestTldrawColor(color), hasAlpha: color[3] < 255 }\n}\n\ninterface ParsedCssOverrides {\n\tcolor?: TLDefaultColorStyle\n\tdashOverride?: TLDefaultDashStyle\n\tsizeOverride?: TLDefaultSizeStyle\n}\n\nfunction parseCssProps(styles: string[]): Map<string, string> {\n\tconst props = new Map<string, string>()\n\tfor (const entry of styles) {\n\t\tfor (const part of entry.split(';')) {\n\t\t\tconst colon = part.indexOf(':')\n\t\t\tif (colon < 0) continue\n\t\t\tconst key = part.slice(0, colon).trim().toLowerCase()\n\t\t\tconst value = part.slice(colon + 1).trim()\n\t\t\tif (key && value) props.set(key, value)\n\t\t}\n\t}\n\treturn props\n}\n\n/**\n * Parse a Mermaid CSS style array from an edge (FlowEdge.style / linkStyle)\n * and return tldraw-compatible overrides.\n */\nexport function parseCssStyles(styles: string[] | undefined): ParsedCssOverrides {\n\tif (!styles || styles.length === 0) return {}\n\n\tconst props = parseCssProps(styles)\n\tconst result: ParsedCssOverrides = {}\n\n\tconst stroke = toColor(props.get('stroke'))\n\tif (stroke) {\n\t\tresult.color = nearestTldrawColor(stroke)\n\t}\n\n\tif (props.has('stroke-dasharray')) {\n\t\tresult.dashOverride = 'dashed'\n\t}\n\n\tconst strokeWidth = props.get('stroke-width')\n\tif (strokeWidth) {\n\t\tconst pixels = parseFloat(strokeWidth)\n\t\tif (Number.isFinite(pixels)) {\n\t\t\tif (pixels <= 1) result.sizeOverride = 's'\n\t\t\telse if (pixels <= 2) result.sizeOverride = 'm'\n\t\t\telse result.sizeOverride = 'l'\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Parse inline `style nodeId fill:\u2026,stroke:\u2026` directives from a FlowVertex.styles\n * array and return fill and stroke as independent tldraw colors.\n */\nexport function parseNodeInlineColor(styles: string[] | undefined): ParsedNodeColors | undefined {\n\tif (!styles || styles.length === 0) return undefined\n\n\tconst props = parseCssProps(styles)\n\tconst fill = toColor(props.get('fill'))\n\tconst stroke = toColor(props.get('stroke'))\n\n\tif (!fill && !stroke) return undefined\n\n\tconst colors: ParsedNodeColors = {}\n\tif (fill) colors.fillColor = nearestTldrawColor(fill)\n\tif (stroke) colors.strokeColor = nearestTldrawColor(stroke)\n\treturn colors\n}\n\nfunction parseHexToRgb(hex: string): [number, number, number] | null {\n\tconst stripped = hex.replace(/^#/, '')\n\tif (stripped.length === 3 || stripped.length === 4) {\n\t\treturn [\n\t\t\tparseInt(stripped[0] + stripped[0], 16),\n\t\t\tparseInt(stripped[1] + stripped[1], 16),\n\t\t\tparseInt(stripped[2] + stripped[2], 16),\n\t\t]\n\t}\n\tif (stripped.length === 6 || stripped.length === 8) {\n\t\treturn [\n\t\t\tparseInt(stripped.slice(0, 2), 16),\n\t\t\tparseInt(stripped.slice(2, 4), 16),\n\t\t\tparseInt(stripped.slice(4, 6), 16),\n\t\t]\n\t}\n\treturn null\n}\n\nconst defaultColorNames: TLDefaultColorStyle[] = [\n\t'black',\n\t'grey',\n\t'light-violet',\n\t'violet',\n\t'blue',\n\t'light-blue',\n\t'yellow',\n\t'orange',\n\t'green',\n\t'light-green',\n\t'light-red',\n\t'red',\n\t'white',\n]\n\nconst TLDRAW_PALETTE: [TLDefaultColorStyle, number, number, number][] = defaultColorNames.map(\n\t(name) => {\n\t\tconst { solid } = DEFAULT_THEME.colors.light[name]!\n\t\tconst rgb = parseHexToRgb(solid)!\n\t\treturn [name, rgb[0], rgb[1], rgb[2]]\n\t}\n)\n\n/** Map an arbitrary Color tuple to the nearest tldraw named color (best-effort). */\nfunction nearestTldrawColor(rgb: Color): TLDefaultColorStyle {\n\tlet [r, g, b] = rgb\n\n\tconst max = Math.max(r, g, b)\n\tconst min = Math.min(r, g, b)\n\tconst lightness = (max + min) / 2 / 255\n\tconst chroma = max - min\n\n\t// For very light pastels, strip the white base and amplify the\n\t// chromatic signal so the distance metric can see the hue.\n\tif (lightness > 0.75 && chroma > 5) {\n\t\tconst target = 200\n\t\tr = Math.round(((r - min) / chroma) * target)\n\t\tg = Math.round(((g - min) / chroma) * target)\n\t\tb = Math.round(((b - min) / chroma) * target)\n\t}\n\n\tlet best: TLDefaultColorStyle = 'black'\n\tlet bestDistance = Infinity\n\tfor (const [name, red, green, blue] of TLDRAW_PALETTE) {\n\t\t// \"Redmean\" weighted Euclidean distance (Compuphase approximation).\n\t\t// Weights RGB channels by the average red value of the two colors to\n\t\t// approximate human perception, which is more sensitive to green and\n\t\t// varies in red/blue sensitivity depending on the color's warmth.\n\t\tconst rMean = (r + red) / 2\n\t\tconst dR = r - red\n\t\tconst dG = g - green\n\t\tconst dB = b - blue\n\t\tconst distance = (2 + rMean / 256) * dR * dR + 4 * dG * dG + (2 + (255 - rMean) / 256) * dB * dB\n\t\tif (distance < bestDistance) {\n\t\t\tbestDistance = distance\n\t\t\tbest = name\n\t\t}\n\t}\n\treturn best\n}\n\nfunction toColor(value: string | undefined): Color | undefined {\n\tif (!value) return undefined\n\n\tconst trimmed = value.trim()\n\tif (!trimmed || trimmed === 'none' || trimmed === 'transparent') return undefined\n\n\tif (trimmed.startsWith('rgb')) {\n\t\tconst match = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)/)\n\t\tif (!match) return undefined\n\t\treturn [\n\t\t\tparseInt(match[1], 10),\n\t\t\tparseInt(match[2], 10),\n\t\t\tparseInt(match[3], 10),\n\t\t\tmatch[4] !== undefined ? Math.round(parseFloat(match[4]) * 255) : 255,\n\t\t]\n\t}\n\tif (trimmed.startsWith('#')) {\n\t\tconst rgb = parseHexToRgb(trimmed)\n\t\tif (!rgb) return undefined\n\t\treturn [rgb[0], rgb[1], rgb[2], 255]\n\t}\n\treturn undefined\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -73,10 +73,12 @@ async function createMermaidDiagram(editor, text, options = {}) {
73
73
  throw new MermaidDiagramError("not a mermaid diagram", "parse");
74
74
  }
75
75
  const offscreen = document.createElement("div");
76
- offscreen.style.position = "absolute";
77
- offscreen.style.left = "-9999px";
78
- offscreen.style.top = "-9999px";
79
- offscreen.style.overflow = "hidden";
76
+ Object.assign(offscreen.style, {
77
+ position: "absolute",
78
+ left: "-9999px",
79
+ top: "-9999px",
80
+ overflow: "hidden"
81
+ });
80
82
  document.body.appendChild(offscreen);
81
83
  try {
82
84
  const parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/createMermaidDiagram.ts"],
4
- "sourcesContent": ["let nextMermaidId = 0\n\nimport type { FlowDB } from 'mermaid/dist/diagrams/flowchart/flowDb.d.ts'\nimport type { FlowEdge, FlowSubGraph, FlowVertex } from 'mermaid/dist/diagrams/flowchart/types.js'\nimport type { MindmapDB } from 'mermaid/dist/diagrams/mindmap/mindmapDb.d.ts'\nimport type { SequenceDB } from 'mermaid/dist/diagrams/sequence/sequenceDb.d.ts'\nimport type { StateDB } from 'mermaid/dist/diagrams/state/stateDb.d.ts'\nimport { Editor } from 'tldraw'\nimport { flowchartToBlueprint, parseFlowchartLayout } from './flowchartDiagram'\nimport { mindmapToBlueprint, parseMindmapLayout } from './mindmapDiagram'\nimport { BlueprintRenderingOptions, renderBlueprint } from './renderBlueprint'\nimport { countSequenceEvents, parseSequenceLayout, sequenceToBlueprint } from './sequenceDiagram'\nimport { parseStateDiagramLayout, stateToBlueprint } from './stateDiagram'\n\n/** @public */\nexport class MermaidDiagramError extends Error {\n\tconstructor(\n\t\tpublic diagramType: string,\n\t\tpublic type: 'parse' | 'unsupported'\n\t) {\n\t\tsuper(`mermaid diagram error: ${diagramType}`)\n\t\tthis.name = 'MermaidDiagramError'\n\t}\n}\n\n// Inflate the font size so Mermaid's layout engine allocates larger nodes,\n// compensating for tldraw's hand-drawn font being wider than Mermaid's default.\nconst FONT_INFLATE = 1.4\n\nconst MERMAID_CONFIG = {\n\tstartOnLoad: false,\n\tflowchart: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tstate: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tmindmap: { padding: 20 },\n\tsequence: { actorMargin: 50, noteMargin: 20 },\n\tthemeVariables: { fontSize: `${18 * FONT_INFLATE}px` },\n}\n\n/** @public */\nexport interface MermaidDiagramOptions {\n\tmermaidConfig?: Record<string, any>\n\tblueprintRender?: BlueprintRenderingOptions\n\tonUnsupportedDiagram?(svg: string): Promise<void>\n}\n\n/**\n * Parse mermaid text and create tldraw shapes for supported diagram types.\n * Returns the SVG string for supported diagrams, or `null` when the diagram type\n * is unsupported (after calling `onUnsupportedDiagram` if provided).\n * Throws {@link MermaidDiagramError} if parsing fails.\n * @public\n */\nexport async function createMermaidDiagram(\n\teditor: Editor,\n\ttext: string,\n\toptions: MermaidDiagramOptions = {}\n): Promise<void> {\n\t// load mermaid lazily: it's a large, ESM-only dependency only needed when a\n\t// diagram is actually created. a dynamic import() works from CommonJS (unlike\n\t// a static import, which compiles to require(<esm>) and throws\n\t// ERR_REQUIRE_ESM on Node <20.19, Jest, and ts-node) and avoids pulling\n\t// mermaid in when @tldraw/mermaid is merely imported.\n\tconst mermaid = (await import('mermaid')).default\n\n\tmermaid.initialize({\n\t\t...MERMAID_CONFIG,\n\t\t...(options.mermaidConfig ?? {}),\n\t\tflowchart: { ...MERMAID_CONFIG.flowchart, ...options.mermaidConfig?.flowchart },\n\t\tstate: { ...MERMAID_CONFIG.state, ...options.mermaidConfig?.state },\n\t\tmindmap: { ...MERMAID_CONFIG.mindmap, ...options.mermaidConfig?.mindmap },\n\t\tsequence: { ...MERMAID_CONFIG.sequence, ...options.mermaidConfig?.sequence },\n\t\tthemeVariables: { ...MERMAID_CONFIG.themeVariables, ...options.mermaidConfig?.themeVariables },\n\t})\n\n\tconst parsedResult = await mermaid.parse(text, { suppressErrors: true })\n\n\tif (!parsedResult) {\n\t\tthrow new MermaidDiagramError('not a mermaid diagram', 'parse')\n\t}\n\n\tconst offscreen = document.createElement('div')\n\toffscreen.style.position = 'absolute'\n\toffscreen.style.left = '-9999px'\n\toffscreen.style.top = '-9999px'\n\toffscreen.style.overflow = 'hidden'\n\tdocument.body.appendChild(offscreen)\n\n\ttry {\n\t\tconst parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg\n\n\t\t// Reuse the live SVG that mermaid.render() already mounted into the\n\t\t// offscreen container. This avoids a second DOM mount and ensures\n\t\t// getBBox() works for every diagram type (state diagrams in particular\n\t\t// lack explicit dimension attributes and rely on live layout).\n\t\tlet liveSvg = offscreen.querySelector('svg')\n\n\t\tif (!liveSvg) {\n\t\t\toffscreen.innerHTML = parsedSvg\n\t\t\tliveSvg = offscreen.querySelector('svg')\n\t\t\tif (!liveSvg) {\n\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t\t\t}\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tconst diagramResult = await mermaid.mermaidAPI.getDiagramFromText(text)\n\n\t\tlet blueprint\n\t\tswitch (parsedResult.diagramType) {\n\t\t\tcase 'flowchart-v2': {\n\t\t\t\tconst db = diagramResult.db as FlowDB\n\t\t\t\tconst vertices = db.getVertices() as Map<string, FlowVertex>\n\t\t\t\tconst edges = db.getEdges() as FlowEdge[]\n\t\t\t\tconst subGraphs = db.getSubGraphs() as FlowSubGraph[]\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseFlowchartLayout(liveSvg)\n\t\t\t\tblueprint = flowchartToBlueprint(layout, vertices, edges, subGraphs, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'sequence': {\n\t\t\t\tconst db = diagramResult.db as SequenceDB\n\t\t\t\tconst actors = db.getActors()\n\t\t\t\tconst actorKeys = db.getActorKeys()\n\t\t\t\tconst messages = db.getMessages()\n\t\t\t\tconst layout = parseSequenceLayout(liveSvg, actorKeys.length, countSequenceEvents(messages))\n\t\t\t\tblueprint = sequenceToBlueprint(\n\t\t\t\t\tlayout,\n\t\t\t\t\tactors,\n\t\t\t\t\tactorKeys,\n\t\t\t\t\tmessages,\n\t\t\t\t\tdb.getCreatedActors(),\n\t\t\t\t\tdb.getDestroyedActors()\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'state':\n\t\t\tcase 'stateDiagram': {\n\t\t\t\tconst db = diagramResult.db as StateDB\n\t\t\t\tconst states = db.getStates()\n\t\t\t\tconst relations = db.getRelations()\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseStateDiagramLayout(liveSvg)\n\t\t\t\tblueprint = stateToBlueprint(layout, states, relations, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'mindmap': {\n\t\t\t\tconst db = diagramResult.db as MindmapDB\n\t\t\t\tconst tree = db.getMindmap()\n\t\t\t\tif (tree) {\n\t\t\t\t\tdb.assignSections(tree)\n\t\t\t\t\tconst layout = parseMindmapLayout(liveSvg)\n\t\t\t\t\tblueprint = mindmapToBlueprint(layout, tree, liveSvg)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif (options.onUnsupportedDiagram) {\n\t\t\t\t\tawait options.onUnsupportedDiagram(parsedSvg)\n\t\t\t\t} else {\n\t\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'unsupported')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (blueprint) {\n\t\t\trenderBlueprint(editor, blueprint, options.blueprintRender)\n\t\t}\n\t} catch (e) {\n\t\tif (e instanceof MermaidDiagramError) throw e\n\t\tconsole.error(e)\n\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t} finally {\n\t\toffscreen.remove()\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { FlowDB } from 'mermaid/dist/diagrams/flowchart/flowDb.d.ts'\nimport type { FlowEdge, FlowSubGraph, FlowVertex } from 'mermaid/dist/diagrams/flowchart/types.js'\nimport type { MindmapDB } from 'mermaid/dist/diagrams/mindmap/mindmapDb.d.ts'\nimport type { SequenceDB } from 'mermaid/dist/diagrams/sequence/sequenceDb.d.ts'\nimport type { StateDB } from 'mermaid/dist/diagrams/state/stateDb.d.ts'\nimport { Editor } from 'tldraw'\nimport { flowchartToBlueprint, parseFlowchartLayout } from './flowchartDiagram'\nimport { mindmapToBlueprint, parseMindmapLayout } from './mindmapDiagram'\nimport { BlueprintRenderingOptions, renderBlueprint } from './renderBlueprint'\nimport { countSequenceEvents, parseSequenceLayout, sequenceToBlueprint } from './sequenceDiagram'\nimport { parseStateDiagramLayout, stateToBlueprint } from './stateDiagram'\n\nlet nextMermaidId = 0\n\n/** @public */\nexport class MermaidDiagramError extends Error {\n\tconstructor(\n\t\tpublic diagramType: string,\n\t\tpublic type: 'parse' | 'unsupported'\n\t) {\n\t\tsuper(`mermaid diagram error: ${diagramType}`)\n\t\tthis.name = 'MermaidDiagramError'\n\t}\n}\n\n// Inflate the font size so Mermaid's layout engine allocates larger nodes,\n// compensating for tldraw's hand-drawn font being wider than Mermaid's default.\nconst FONT_INFLATE = 1.4\n\nconst MERMAID_CONFIG = {\n\tstartOnLoad: false,\n\tflowchart: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tstate: { nodeSpacing: 80, rankSpacing: 80, padding: 20 },\n\tmindmap: { padding: 20 },\n\tsequence: { actorMargin: 50, noteMargin: 20 },\n\tthemeVariables: { fontSize: `${18 * FONT_INFLATE}px` },\n}\n\n/** @public */\nexport interface MermaidDiagramOptions {\n\tmermaidConfig?: Record<string, any>\n\tblueprintRender?: BlueprintRenderingOptions\n\tonUnsupportedDiagram?(svg: string): Promise<void>\n}\n\n/**\n * Parse mermaid text and create tldraw shapes for supported diagram types.\n * Returns the SVG string for supported diagrams, or `null` when the diagram type\n * is unsupported (after calling `onUnsupportedDiagram` if provided).\n * Throws {@link MermaidDiagramError} if parsing fails.\n * @public\n */\nexport async function createMermaidDiagram(\n\teditor: Editor,\n\ttext: string,\n\toptions: MermaidDiagramOptions = {}\n): Promise<void> {\n\t// load mermaid lazily: it's a large, ESM-only dependency only needed when a\n\t// diagram is actually created. a dynamic import() works from CommonJS (unlike\n\t// a static import, which compiles to require(<esm>) and throws\n\t// ERR_REQUIRE_ESM on Node <20.19, Jest, and ts-node) and avoids pulling\n\t// mermaid in when @tldraw/mermaid is merely imported.\n\tconst mermaid = (await import('mermaid')).default\n\n\tmermaid.initialize({\n\t\t...MERMAID_CONFIG,\n\t\t...(options.mermaidConfig ?? {}),\n\t\tflowchart: { ...MERMAID_CONFIG.flowchart, ...options.mermaidConfig?.flowchart },\n\t\tstate: { ...MERMAID_CONFIG.state, ...options.mermaidConfig?.state },\n\t\tmindmap: { ...MERMAID_CONFIG.mindmap, ...options.mermaidConfig?.mindmap },\n\t\tsequence: { ...MERMAID_CONFIG.sequence, ...options.mermaidConfig?.sequence },\n\t\tthemeVariables: { ...MERMAID_CONFIG.themeVariables, ...options.mermaidConfig?.themeVariables },\n\t})\n\n\tconst parsedResult = await mermaid.parse(text, { suppressErrors: true })\n\n\tif (!parsedResult) {\n\t\tthrow new MermaidDiagramError('not a mermaid diagram', 'parse')\n\t}\n\n\tconst offscreen = document.createElement('div')\n\tObject.assign(offscreen.style, {\n\t\tposition: 'absolute',\n\t\tleft: '-9999px',\n\t\ttop: '-9999px',\n\t\toverflow: 'hidden',\n\t})\n\tdocument.body.appendChild(offscreen)\n\n\ttry {\n\t\tconst parsedSvg = (await mermaid.render(`mermaid-${nextMermaidId++}`, text, offscreen)).svg\n\n\t\t// Reuse the live SVG that mermaid.render() already mounted into the\n\t\t// offscreen container. This avoids a second DOM mount and ensures\n\t\t// getBBox() works for every diagram type (state diagrams in particular\n\t\t// lack explicit dimension attributes and rely on live layout).\n\t\tlet liveSvg = offscreen.querySelector('svg')\n\n\t\tif (!liveSvg) {\n\t\t\toffscreen.innerHTML = parsedSvg\n\t\t\tliveSvg = offscreen.querySelector('svg')\n\t\t\tif (!liveSvg) {\n\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t\t\t}\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tconst diagramResult = await mermaid.mermaidAPI.getDiagramFromText(text)\n\n\t\tlet blueprint\n\t\tswitch (parsedResult.diagramType) {\n\t\t\tcase 'flowchart-v2': {\n\t\t\t\tconst db = diagramResult.db as FlowDB\n\t\t\t\tconst vertices = db.getVertices() as Map<string, FlowVertex>\n\t\t\t\tconst edges = db.getEdges() as FlowEdge[]\n\t\t\t\tconst subGraphs = db.getSubGraphs() as FlowSubGraph[]\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseFlowchartLayout(liveSvg)\n\t\t\t\tblueprint = flowchartToBlueprint(layout, vertices, edges, subGraphs, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'sequence': {\n\t\t\t\tconst db = diagramResult.db as SequenceDB\n\t\t\t\tconst actors = db.getActors()\n\t\t\t\tconst actorKeys = db.getActorKeys()\n\t\t\t\tconst messages = db.getMessages()\n\t\t\t\tconst layout = parseSequenceLayout(liveSvg, actorKeys.length, countSequenceEvents(messages))\n\t\t\t\tblueprint = sequenceToBlueprint(\n\t\t\t\t\tlayout,\n\t\t\t\t\tactors,\n\t\t\t\t\tactorKeys,\n\t\t\t\t\tmessages,\n\t\t\t\t\tdb.getCreatedActors(),\n\t\t\t\t\tdb.getDestroyedActors()\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'state':\n\t\t\tcase 'stateDiagram': {\n\t\t\t\tconst db = diagramResult.db as StateDB\n\t\t\t\tconst states = db.getStates()\n\t\t\t\tconst relations = db.getRelations()\n\t\t\t\tconst classes = db.getClasses()\n\t\t\t\tconst layout = parseStateDiagramLayout(liveSvg)\n\t\t\t\tblueprint = stateToBlueprint(layout, states, relations, classes)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'mindmap': {\n\t\t\t\tconst db = diagramResult.db as MindmapDB\n\t\t\t\tconst tree = db.getMindmap()\n\t\t\t\tif (tree) {\n\t\t\t\t\tdb.assignSections(tree)\n\t\t\t\t\tconst layout = parseMindmapLayout(liveSvg)\n\t\t\t\t\tblueprint = mindmapToBlueprint(layout, tree, liveSvg)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif (options.onUnsupportedDiagram) {\n\t\t\t\t\tawait options.onUnsupportedDiagram(parsedSvg)\n\t\t\t\t} else {\n\t\t\t\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'unsupported')\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (blueprint) {\n\t\t\trenderBlueprint(editor, blueprint, options.blueprintRender)\n\t\t}\n\t} catch (e) {\n\t\tif (e instanceof MermaidDiagramError) throw e\n\t\tconsole.error(e)\n\t\tthrow new MermaidDiagramError(parsedResult.diagramType, 'parse')\n\t} finally {\n\t\toffscreen.remove()\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,8BAA2D;AAC3D,4BAAuD;AACvD,6BAA2D;AAC3D,6BAA8E;AAC9E,0BAA0D;AAE1D,IAAI,gBAAgB;AAGb,MAAM,4BAA4B,MAAM;AAAA,EAC9C,YACQ,aACA,MACN;AACD,UAAM,0BAA0B,WAAW,EAAE;AAHtC;AACA;AAGP,SAAK,OAAO;AAAA,EACb;AAAA,EALQ;AAAA,EACA;AAKT;AAIA,MAAM,eAAe;AAErB,MAAM,iBAAiB;AAAA,EACtB,aAAa;AAAA,EACb,WAAW,EAAE,aAAa,IAAI,aAAa,IAAI,SAAS,GAAG;AAAA,EAC3D,OAAO,EAAE,aAAa,IAAI,aAAa,IAAI,SAAS,GAAG;AAAA,EACvD,SAAS,EAAE,SAAS,GAAG;AAAA,EACvB,UAAU,EAAE,aAAa,IAAI,YAAY,GAAG;AAAA,EAC5C,gBAAgB,EAAE,UAAU,GAAG,KAAK,YAAY,KAAK;AACtD;AAgBA,eAAsB,qBACrB,QACA,MACA,UAAiC,CAAC,GAClB;AAMhB,QAAM,WAAW,MAAM,OAAO,SAAS,GAAG;AAE1C,UAAQ,WAAW;AAAA,IAClB,GAAG;AAAA,IACH,GAAI,QAAQ,iBAAiB,CAAC;AAAA,IAC9B,WAAW,EAAE,GAAG,eAAe,WAAW,GAAG,QAAQ,eAAe,UAAU;AAAA,IAC9E,OAAO,EAAE,GAAG,eAAe,OAAO,GAAG,QAAQ,eAAe,MAAM;AAAA,IAClE,SAAS,EAAE,GAAG,eAAe,SAAS,GAAG,QAAQ,eAAe,QAAQ;AAAA,IACxE,UAAU,EAAE,GAAG,eAAe,UAAU,GAAG,QAAQ,eAAe,SAAS;AAAA,IAC3E,gBAAgB,EAAE,GAAG,eAAe,gBAAgB,GAAG,QAAQ,eAAe,eAAe;AAAA,EAC9F,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,MAAM,MAAM,EAAE,gBAAgB,KAAK,CAAC;AAEvE,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,oBAAoB,yBAAyB,OAAO;AAAA,EAC/D;AAEA,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,SAAO,OAAO,UAAU,OAAO;AAAA,IAC9B,UAAU;AAAA,IACV,MAAM;AAAA,IACN,KAAK;AAAA,IACL,UAAU;AAAA,EACX,CAAC;AACD,WAAS,KAAK,YAAY,SAAS;AAEnC,MAAI;AACH,UAAM,aAAa,MAAM,QAAQ,OAAO,WAAW,eAAe,IAAI,MAAM,SAAS,GAAG;AAMxF,QAAI,UAAU,UAAU,cAAc,KAAK;AAE3C,QAAI,CAAC,SAAS;AACb,gBAAU,YAAY;AACtB,gBAAU,UAAU,cAAc,KAAK;AACvC,UAAI,CAAC,SAAS;AACb,cAAM,IAAI,oBAAoB,aAAa,aAAa,OAAO;AAAA,MAChE;AAAA,IACD;AAGA,UAAM,gBAAgB,MAAM,QAAQ,WAAW,mBAAmB,IAAI;AAEtE,QAAI;AACJ,YAAQ,aAAa,aAAa;AAAA,MACjC,KAAK,gBAAgB;AACpB,cAAM,KAAK,cAAc;AACzB,cAAM,WAAW,GAAG,YAAY;AAChC,cAAM,QAAQ,GAAG,SAAS;AAC1B,cAAM,YAAY,GAAG,aAAa;AAClC,cAAM,UAAU,GAAG,WAAW;AAC9B,cAAM,aAAS,8CAAqB,OAAO;AAC3C,wBAAY,8CAAqB,QAAQ,UAAU,OAAO,WAAW,OAAO;AAC5E;AAAA,MACD;AAAA,MACA,KAAK,YAAY;AAChB,cAAM,KAAK,cAAc;AACzB,cAAM,SAAS,GAAG,UAAU;AAC5B,cAAM,YAAY,GAAG,aAAa;AAClC,cAAM,WAAW,GAAG,YAAY;AAChC,cAAM,aAAS,4CAAoB,SAAS,UAAU,YAAQ,4CAAoB,QAAQ,CAAC;AAC3F,wBAAY;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG,iBAAiB;AAAA,UACpB,GAAG,mBAAmB;AAAA,QACvB;AACA;AAAA,MACD;AAAA,MACA,KAAK;AAAA,MACL,KAAK,gBAAgB;AACpB,cAAM,KAAK,cAAc;AACzB,cAAM,SAAS,GAAG,UAAU;AAC5B,cAAM,YAAY,GAAG,aAAa;AAClC,cAAM,UAAU,GAAG,WAAW;AAC9B,cAAM,aAAS,6CAAwB,OAAO;AAC9C,wBAAY,sCAAiB,QAAQ,QAAQ,WAAW,OAAO;AAC/D;AAAA,MACD;AAAA,MACA,KAAK,WAAW;AACf,cAAM,KAAK,cAAc;AACzB,cAAM,OAAO,GAAG,WAAW;AAC3B,YAAI,MAAM;AACT,aAAG,eAAe,IAAI;AACtB,gBAAM,aAAS,0CAAmB,OAAO;AACzC,0BAAY,0CAAmB,QAAQ,MAAM,OAAO;AAAA,QACrD;AACA;AAAA,MACD;AAAA,MACA;AACC,YAAI,QAAQ,sBAAsB;AACjC,gBAAM,QAAQ,qBAAqB,SAAS;AAAA,QAC7C,OAAO;AACN,gBAAM,IAAI,oBAAoB,aAAa,aAAa,aAAa;AAAA,QACtE;AACA;AAAA,IACF;AAEA,QAAI,WAAW;AACd,kDAAgB,QAAQ,WAAW,QAAQ,eAAe;AAAA,IAC3D;AAAA,EACD,SAAS,GAAG;AACX,QAAI,aAAa,oBAAqB,OAAM;AAC5C,YAAQ,MAAM,CAAC;AACf,UAAM,IAAI,oBAAoB,aAAa,aAAa,OAAO;AAAA,EAChE,UAAE;AACD,cAAU,OAAO;AAAA,EAClB;AACD;",
6
6
  "names": []
7
7
  }
@@ -22,6 +22,7 @@ __export(defaultMermaidNodeRenderSpec_exports, {
22
22
  resolveMermaidNodeRender: () => resolveMermaidNodeRender
23
23
  });
24
24
  module.exports = __toCommonJS(defaultMermaidNodeRenderSpec_exports);
25
+ var import_mindmapDiagram = require("./mindmapDiagram");
25
26
  function flowchartKindToGeo(kind) {
26
27
  switch (kind) {
27
28
  case "diamond":
@@ -41,11 +42,6 @@ function flowchartKindToGeo(kind) {
41
42
  return "rhombus";
42
43
  case "lean_left":
43
44
  return "rhombus-2";
44
- case "subgraph":
45
- case "square":
46
- case "rect":
47
- case "round":
48
- case "subroutine":
49
45
  default:
50
46
  return "rectangle";
51
47
  }
@@ -58,10 +54,6 @@ function stateKindToGeo(kind) {
58
54
  case "end":
59
55
  case "end_inner":
60
56
  return "ellipse";
61
- case "compound":
62
- case "note":
63
- case "fork":
64
- case "join":
65
57
  default:
66
58
  return "rectangle";
67
59
  }
@@ -72,51 +64,32 @@ function sequenceKindToGeo(kind) {
72
64
  return "ellipse";
73
65
  case "database":
74
66
  return "oval";
75
- case "sequence_activation":
76
- case "sequence_fragment":
77
- case "sequence_fragment_section":
78
- case "sequence_note":
79
67
  default:
80
68
  return "rectangle";
81
69
  }
82
70
  }
83
71
  function mindmapKindToGeo(kind) {
84
- const type = Number(kind);
85
- switch (type) {
86
- case 3:
72
+ switch (Number(kind)) {
73
+ case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.CIRCLE:
87
74
  return "ellipse";
88
- case 4:
75
+ case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.CLOUD:
89
76
  return "cloud";
90
- case 6:
77
+ case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.HEXAGON:
91
78
  return "hexagon";
92
- case 5:
79
+ case import_mindmapDiagram.MERMAID_MINDMAP_NODE_TYPE.BANG:
93
80
  return "star";
94
- case 2:
95
- case 1:
96
- case 0:
97
81
  default:
98
82
  return "rectangle";
99
83
  }
100
84
  }
85
+ const KIND_TO_GEO = {
86
+ flowchart: flowchartKindToGeo,
87
+ state: stateKindToGeo,
88
+ sequence: sequenceKindToGeo,
89
+ mindmap: mindmapKindToGeo
90
+ };
101
91
  function defaultMermaidNodeRenderSpec(diagramKind, kind) {
102
- let geo;
103
- switch (diagramKind) {
104
- case "flowchart":
105
- geo = flowchartKindToGeo(kind);
106
- break;
107
- case "state":
108
- geo = stateKindToGeo(kind);
109
- break;
110
- case "sequence":
111
- geo = sequenceKindToGeo(kind);
112
- break;
113
- case "mindmap":
114
- geo = mindmapKindToGeo(kind);
115
- break;
116
- default:
117
- geo = "rectangle";
118
- }
119
- return { variant: "geo", geo };
92
+ return { variant: "geo", geo: KIND_TO_GEO[diagramKind]?.(kind) ?? "rectangle" };
120
93
  }
121
94
  function resolveMermaidNodeRender(diagramKind, node, mapper) {
122
95
  return mapper?.({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/defaultMermaidNodeRenderSpec.ts"],
4
- "sourcesContent": ["import type { TLGeoShapeGeoStyle } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n\tMermaidNodeRenderMapper,\n} from './blueprint'\n\nfunction flowchartKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'diamond':\n\t\t\treturn 'diamond'\n\t\tcase 'ellipse':\n\t\tcase 'circle':\n\t\tcase 'doublecircle':\n\t\tcase 'stadium':\n\t\tcase 'cylinder':\n\t\t\treturn 'ellipse'\n\t\tcase 'hexagon':\n\t\t\treturn 'hexagon'\n\t\tcase 'trapezoid':\n\t\tcase 'inv_trapezoid':\n\t\t\treturn 'trapezoid'\n\t\tcase 'lean_right':\n\t\t\treturn 'rhombus'\n\t\tcase 'lean_left':\n\t\t\treturn 'rhombus-2'\n\t\tcase 'subgraph':\n\t\tcase 'square':\n\t\tcase 'rect':\n\t\tcase 'round':\n\t\tcase 'subroutine':\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction stateKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'choice':\n\t\t\treturn 'diamond'\n\t\tcase 'start':\n\t\tcase 'end':\n\t\tcase 'end_inner':\n\t\t\treturn 'ellipse'\n\t\tcase 'compound':\n\t\tcase 'note':\n\t\tcase 'fork':\n\t\tcase 'join':\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction sequenceKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'actor':\n\t\t\treturn 'ellipse'\n\t\tcase 'database':\n\t\t\treturn 'oval'\n\t\tcase 'sequence_activation':\n\t\tcase 'sequence_fragment':\n\t\tcase 'sequence_fragment_section':\n\t\tcase 'sequence_note':\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction mindmapKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tconst type = Number(kind)\n\tswitch (type) {\n\t\tcase 3:\n\t\t\treturn 'ellipse'\n\t\tcase 4:\n\t\t\treturn 'cloud'\n\t\tcase 6:\n\t\t\treturn 'hexagon'\n\t\tcase 5:\n\t\t\treturn 'star'\n\t\tcase 2:\n\t\tcase 1:\n\t\tcase 0:\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\n/**\n * Default built-in mapping from {@link MermaidDiagramKind} + semantic `kind` to a geo {@link MermaidBlueprintNodeRenderSpec}.\n * Used when `mapNodeToRenderSpec` is omitted from `renderBlueprint` options, or when the mapper returns `undefined`.\n * @public\n */\nexport function defaultMermaidNodeRenderSpec(\n\tdiagramKind: MermaidDiagramKind,\n\tkind: string\n): MermaidBlueprintNodeRenderSpec {\n\tlet geo: TLGeoShapeGeoStyle\n\tswitch (diagramKind) {\n\t\tcase 'flowchart':\n\t\t\tgeo = flowchartKindToGeo(kind)\n\t\t\tbreak\n\t\tcase 'state':\n\t\t\tgeo = stateKindToGeo(kind)\n\t\t\tbreak\n\t\tcase 'sequence':\n\t\t\tgeo = sequenceKindToGeo(kind)\n\t\t\tbreak\n\t\tcase 'mindmap':\n\t\t\tgeo = mindmapKindToGeo(kind)\n\t\t\tbreak\n\t\tdefault:\n\t\t\tgeo = 'rectangle'\n\t}\n\treturn { variant: 'geo', geo }\n}\n\n/**\n * Uses the optional mapper when it returns a value; otherwise {@link defaultMermaidNodeRenderSpec}.\n * @public\n */\nexport function resolveMermaidNodeRender(\n\tdiagramKind: MermaidDiagramKind,\n\tnode: MermaidBlueprintNode,\n\tmapper?: MermaidNodeRenderMapper | undefined\n): MermaidBlueprintNodeRenderSpec {\n\treturn (\n\t\tmapper?.({\n\t\t\tdiagramKind,\n\t\t\tnodeId: node.id,\n\t\t\tkind: node.kind,\n\t\t\tnode,\n\t\t}) ?? defaultMermaidNodeRenderSpec(diagramKind, node.kind)\n\t)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,SAAS,mBAAmB,MAAkC;AAC7D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,eAAe,MAAkC;AACzD,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,kBAAkB,MAAkC;AAC5D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,iBAAiB,MAAkC;AAC3D,QAAM,OAAO,OAAO,IAAI;AACxB,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAOO,SAAS,6BACf,aACA,MACiC;AACjC,MAAI;AACJ,UAAQ,aAAa;AAAA,IACpB,KAAK;AACJ,YAAM,mBAAmB,IAAI;AAC7B;AAAA,IACD,KAAK;AACJ,YAAM,eAAe,IAAI;AACzB;AAAA,IACD,KAAK;AACJ,YAAM,kBAAkB,IAAI;AAC5B;AAAA,IACD,KAAK;AACJ,YAAM,iBAAiB,IAAI;AAC3B;AAAA,IACD;AACC,YAAM;AAAA,EACR;AACA,SAAO,EAAE,SAAS,OAAO,IAAI;AAC9B;AAMO,SAAS,yBACf,aACA,MACA,QACiC;AACjC,SACC,SAAS;AAAA,IACR;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX;AAAA,EACD,CAAC,KAAK,6BAA6B,aAAa,KAAK,IAAI;AAE3D;",
4
+ "sourcesContent": ["import type { TLGeoShapeGeoStyle } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n\tMermaidNodeRenderMapper,\n} from './blueprint'\nimport { MERMAID_MINDMAP_NODE_TYPE } from './mindmapDiagram'\n\nfunction flowchartKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'diamond':\n\t\t\treturn 'diamond'\n\t\tcase 'ellipse':\n\t\tcase 'circle':\n\t\tcase 'doublecircle':\n\t\tcase 'stadium':\n\t\tcase 'cylinder':\n\t\t\treturn 'ellipse'\n\t\tcase 'hexagon':\n\t\t\treturn 'hexagon'\n\t\tcase 'trapezoid':\n\t\tcase 'inv_trapezoid':\n\t\t\treturn 'trapezoid'\n\t\tcase 'lean_right':\n\t\t\treturn 'rhombus'\n\t\tcase 'lean_left':\n\t\t\treturn 'rhombus-2'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction stateKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'choice':\n\t\t\treturn 'diamond'\n\t\tcase 'start':\n\t\tcase 'end':\n\t\tcase 'end_inner':\n\t\t\treturn 'ellipse'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction sequenceKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (kind) {\n\t\tcase 'actor':\n\t\t\treturn 'ellipse'\n\t\tcase 'database':\n\t\t\treturn 'oval'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nfunction mindmapKindToGeo(kind: string): TLGeoShapeGeoStyle {\n\tswitch (Number(kind)) {\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.CIRCLE:\n\t\t\treturn 'ellipse'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.CLOUD:\n\t\t\treturn 'cloud'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.HEXAGON:\n\t\t\treturn 'hexagon'\n\t\tcase MERMAID_MINDMAP_NODE_TYPE.BANG:\n\t\t\treturn 'star'\n\t\tdefault:\n\t\t\treturn 'rectangle'\n\t}\n}\n\nconst KIND_TO_GEO: Record<MermaidDiagramKind, (kind: string) => TLGeoShapeGeoStyle> = {\n\tflowchart: flowchartKindToGeo,\n\tstate: stateKindToGeo,\n\tsequence: sequenceKindToGeo,\n\tmindmap: mindmapKindToGeo,\n}\n\n/**\n * Default built-in mapping from {@link MermaidDiagramKind} + semantic `kind` to a geo {@link MermaidBlueprintNodeRenderSpec}.\n * Used when `mapNodeToRenderSpec` is omitted from `renderBlueprint` options, or when the mapper returns `undefined`.\n * @public\n */\nexport function defaultMermaidNodeRenderSpec(\n\tdiagramKind: MermaidDiagramKind,\n\tkind: string\n): MermaidBlueprintNodeRenderSpec {\n\treturn { variant: 'geo', geo: KIND_TO_GEO[diagramKind]?.(kind) ?? 'rectangle' }\n}\n\n/**\n * Uses the optional mapper when it returns a value; otherwise {@link defaultMermaidNodeRenderSpec}.\n * @public\n */\nexport function resolveMermaidNodeRender(\n\tdiagramKind: MermaidDiagramKind,\n\tnode: MermaidBlueprintNode,\n\tmapper?: MermaidNodeRenderMapper | undefined\n): MermaidBlueprintNodeRenderSpec {\n\treturn (\n\t\tmapper?.({\n\t\t\tdiagramKind,\n\t\t\tnodeId: node.id,\n\t\t\tkind: node.kind,\n\t\t\tnode,\n\t\t}) ?? defaultMermaidNodeRenderSpec(diagramKind, node.kind)\n\t)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,4BAA0C;AAE1C,SAAS,mBAAmB,MAAkC;AAC7D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,eAAe,MAAkC;AACzD,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,kBAAkB,MAAkC;AAC5D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,iBAAiB,MAAkC;AAC3D,UAAQ,OAAO,IAAI,GAAG;AAAA,IACrB,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR,KAAK,gDAA0B;AAC9B,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEA,MAAM,cAAgF;AAAA,EACrF,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACV;AAOO,SAAS,6BACf,aACA,MACiC;AACjC,SAAO,EAAE,SAAS,OAAO,KAAK,YAAY,WAAW,IAAI,IAAI,KAAK,YAAY;AAC/E;AAMO,SAAS,yBACf,aACA,MACA,QACiC;AACjC,SACC,SAAS;AAAA,IACR;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX;AAAA,EACD,CAAC,KAAK,6BAA6B,aAAa,KAAK,IAAI;AAE3D;",
6
6
  "names": []
7
7
  }
@@ -26,19 +26,13 @@ var import_colors = require("./colors");
26
26
  var import_svgParsing = require("./svgParsing");
27
27
  var import_utils = require("./utils");
28
28
  function mapEdgeTypeToArrowhead(type) {
29
- if (!type) return "arrow";
30
- if (type.includes("point")) return "arrow";
31
- if (type.includes("circle")) return "dot";
32
- if (type.includes("cross")) return "bar";
33
- if (type.includes("open")) return "none";
29
+ if (type?.includes("circle")) return "dot";
30
+ if (type?.includes("cross")) return "bar";
31
+ if (type?.includes("open")) return "none";
34
32
  return "arrow";
35
33
  }
36
- function mapEdgeStrokeToDash(stroke) {
37
- if (!stroke) return "solid";
38
- if (stroke === "dotted") return "dotted";
39
- return "solid";
40
- }
41
34
  const FRAME_TOP_PAD = 14;
35
+ const NODE_ID = /^flowchart-(.+)-\d+$/;
42
36
  function buildHierarchy(subGraphs) {
43
37
  const subGraphIds = new Set(subGraphs.map((subGraph) => subGraph.id));
44
38
  const nodeToSubGraph = /* @__PURE__ */ new Map();
@@ -55,15 +49,8 @@ function buildHierarchy(subGraphs) {
55
49
  return { nodeToSubGraph, subGraphParent };
56
50
  }
57
51
  function parseFlowchartLayout(root) {
58
- const nodes = (0, import_svgParsing.parseNodesFromSvg)(root, ".node", (domId) => {
59
- const match = domId.match(/^(?:mermaid-\d+-)?flowchart-(.+)-\d+$/);
60
- return match ? match[1] : domId;
61
- });
62
- const clusters = (0, import_svgParsing.parseClustersFromSvg)(
63
- root,
64
- ".cluster",
65
- (domId) => domId.replace(/^mermaid-\d+-/, "")
66
- );
52
+ const nodes = (0, import_svgParsing.parseNodesFromSvg)(root, ".node", (domId) => (0, import_svgParsing.parseDomId)(domId, NODE_ID));
53
+ const clusters = (0, import_svgParsing.parseClustersFromSvg)(root, ".cluster", import_svgParsing.stripDiagramIdPrefix);
67
54
  const edges = (0, import_svgParsing.parseAllEdgePointsFromSvg)(root, (dataId) => {
68
55
  const match = dataId.match(/(?:^|-)L_(.+)_([^_]+)_\d+$/);
69
56
  return match ? { start: match[1], end: match[2] } : null;
@@ -72,7 +59,7 @@ function parseFlowchartLayout(root) {
72
59
  return { nodes, clusters, edges };
73
60
  }
74
61
  function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
75
- const nodeColorMap = classDefs ? (0, import_colors.buildClassDefColorMap)(classDefs, vertices) : /* @__PURE__ */ new Map();
62
+ const nodeColorMap = (0, import_colors.buildClassDefColorMap)(classDefs ?? /* @__PURE__ */ new Map(), vertices);
76
63
  const { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout;
77
64
  const nodeCenters = (0, import_svgParsing.buildNodeCentersFromSvg)(svgNodes, svgClusters);
78
65
  const allSubGraphs = subGraphs || [];
@@ -86,11 +73,9 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
86
73
  )) {
87
74
  const cluster = svgClusters.get(subGraph.id);
88
75
  if (!cluster) continue;
89
- const id = subGraph.id;
90
- const kind = "subgraph";
91
76
  nodes.push({
92
- id,
93
- kind,
77
+ id: subGraph.id,
78
+ kind: "subgraph",
94
79
  x: cluster.topLeft.x,
95
80
  y: cluster.topLeft.y - FRAME_TOP_PAD,
96
81
  w: cluster.width,
@@ -108,23 +93,20 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
108
93
  for (const [id, vertex] of vertices) {
109
94
  const svgNode = svgNodes.get(id);
110
95
  if (!svgNode) continue;
111
- const kind = vertex.type ?? "rect";
112
- const colors = nodeColorMap.get(id) ?? (0, import_colors.parseNodeInlineColor)(vertex.styles);
113
96
  let { width: w, height: h } = svgNode;
114
97
  if (vertex.type === "circle" || vertex.type === "doublecircle") {
115
98
  w = h = Math.max(w, h);
116
99
  }
117
100
  nodes.push({
118
101
  id,
119
- kind,
102
+ kind: vertex.type ?? "rect",
120
103
  x: svgNode.center.x - w / 2,
121
104
  y: svgNode.center.y - h / 2,
122
105
  w,
123
106
  h,
124
107
  parentId: nodeToSubGraph.get(id),
125
108
  label: vertex.text || void 0,
126
- ...colors?.fillColor && { fill: "solid" },
127
- ...colors && { color: colors.strokeColor ?? colors.fillColor },
109
+ ...(0, import_colors.toNodeColorProps)(nodeColorMap.get(id) ?? (0, import_colors.parseNodeInlineColor)(vertex.styles)),
128
110
  align: "middle",
129
111
  verticalAlign: "middle",
130
112
  size: "m"
@@ -132,33 +114,14 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
132
114
  }
133
115
  const claimed = /* @__PURE__ */ new Set();
134
116
  for (const edge of edges) {
135
- const startCenter = nodeCenters.get(edge.start);
136
- const endCenter = nodeCenters.get(edge.end);
137
- let bend = 0;
138
- if (startCenter && endCenter) {
139
- let bestIndex = -1;
140
- let bestDist = Infinity;
141
- for (let i = 0; i < svgEdges.length; i++) {
142
- if (claimed.has(i) || svgEdges[i].points.length < 2) continue;
143
- const points = svgEdges[i].points;
144
- const distance = Math.hypot(points[0].x - startCenter.x, points[0].y - startCenter.y) + Math.hypot(
145
- points[points.length - 1].x - endCenter.x,
146
- points[points.length - 1].y - endCenter.y
147
- );
148
- if (distance < bestDist) {
149
- bestDist = distance;
150
- bestIndex = i;
151
- }
152
- }
153
- if (bestIndex >= 0) {
154
- claimed.add(bestIndex);
155
- bend = (0, import_utils.getArrowBend)(svgEdges[bestIndex]);
156
- }
157
- }
158
- const cssOverrides = edge.style ? (0, import_colors.parseCssStyles)(edge.style) : void 0;
117
+ const bend = (0, import_svgParsing.claimNearestEdgeBend)(
118
+ svgEdges,
119
+ claimed,
120
+ nodeCenters.get(edge.start),
121
+ nodeCenters.get(edge.end)
122
+ );
123
+ const cssOverrides = (0, import_colors.parseCssStyles)(edge.style);
159
124
  const arrowheadEnd = mapEdgeTypeToArrowhead(edge.type);
160
- const dash = cssOverrides?.dashOverride ?? mapEdgeStrokeToDash(edge.stroke);
161
- const size = cssOverrides?.sizeOverride ?? (edge.stroke === "thick" ? "l" : "s");
162
125
  blueprintEdges.push({
163
126
  startNodeId: edge.start,
164
127
  endNodeId: edge.end,
@@ -166,15 +129,11 @@ function flowchartToBlueprint(layout, vertices, edges, subGraphs, classDefs) {
166
129
  bend,
167
130
  arrowheadEnd,
168
131
  arrowheadStart: edge.type?.includes("double_arrow") ? arrowheadEnd : void 0,
169
- dash,
170
- size,
171
- color: cssOverrides?.color
132
+ dash: cssOverrides.dashOverride ?? (edge.stroke === "dotted" ? "dotted" : "solid"),
133
+ size: cssOverrides.sizeOverride ?? (edge.stroke === "thick" ? "l" : "s"),
134
+ color: cssOverrides.color
172
135
  });
173
136
  }
174
- const nodeIds = new Set(nodes.map((n) => n.id));
175
- const validEdges = blueprintEdges.filter(
176
- (e) => nodeIds.has(e.startNodeId) && nodeIds.has(e.endNodeId)
177
- );
178
- return { diagramKind: "flowchart", nodes, edges: validEdges };
137
+ return { diagramKind: "flowchart", nodes, edges: (0, import_utils.dropDanglingEdges)(nodes, blueprintEdges) };
179
138
  }
180
139
  //# sourceMappingURL=flowchartDiagram.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/flowchartDiagram.ts"],
4
- "sourcesContent": ["import type {\n\tFlowClass,\n\tFlowEdge,\n\tFlowSubGraph,\n\tFlowVertex,\n} from 'mermaid/dist/diagrams/flowchart/types.js'\nimport { TLArrowShapeArrowheadStyle, TLDefaultDashStyle } from 'tldraw'\nimport type {\n\tDiagramMermaidBlueprint,\n\tMermaidBlueprintEdge,\n\tMermaidBlueprintNode,\n} from './blueprint'\nimport { buildClassDefColorMap, parseCssStyles, parseNodeInlineColor } from './colors'\nimport {\n\tbuildNodeCentersFromSvg,\n\tparseAllEdgePointsFromSvg,\n\tparseClustersFromSvg,\n\ttype ParsedDiagramLayout,\n\tparseNodesFromSvg,\n\tscaleLayout,\n} from './svgParsing'\nimport { getArrowBend, LAYOUT_SCALE, orderTopDown } from './utils'\n\nfunction mapEdgeTypeToArrowhead(type: string | undefined): TLArrowShapeArrowheadStyle {\n\tif (!type) return 'arrow'\n\n\tif (type.includes('point')) return 'arrow'\n\tif (type.includes('circle')) return 'dot'\n\tif (type.includes('cross')) return 'bar'\n\tif (type.includes('open')) return 'none'\n\n\treturn 'arrow'\n}\n\nfunction mapEdgeStrokeToDash(stroke: string | undefined): TLDefaultDashStyle {\n\tif (!stroke) return 'solid'\n\tif (stroke === 'dotted') return 'dotted'\n\treturn 'solid'\n}\n\nconst FRAME_TOP_PAD = 14\n\nfunction buildHierarchy(subGraphs: FlowSubGraph[]) {\n\tconst subGraphIds = new Set(subGraphs.map((subGraph) => subGraph.id))\n\tconst nodeToSubGraph = new Map<string, string>()\n\tconst subGraphParent = new Map<string, string>()\n\tfor (const subGraph of subGraphs) {\n\t\tfor (const nodeId of subGraph.nodes) {\n\t\t\tif (subGraphIds.has(nodeId)) {\n\t\t\t\tsubGraphParent.set(nodeId, subGraph.id)\n\t\t\t} else if (!nodeToSubGraph.has(nodeId)) {\n\t\t\t\tnodeToSubGraph.set(nodeId, subGraph.id)\n\t\t\t}\n\t\t}\n\t}\n\treturn { nodeToSubGraph, subGraphParent }\n}\n\n/** Parse flowchart-specific SVG layout data for use by {@link flowchartToBlueprint}. */\nexport function parseFlowchartLayout(root: Element): ParsedDiagramLayout {\n\t// Mermaid 11.15 prefixes node and cluster dom ids with the diagram id (e.g.\n\t// `mermaid-0-flowchart-s1-0` instead of `flowchart-s1-0`), so tolerate that\n\t// optional `mermaid-<n>-` prefix when reading the clean id.\n\tconst nodes = parseNodesFromSvg(root, '.node', (domId) => {\n\t\tconst match = domId.match(/^(?:mermaid-\\d+-)?flowchart-(.+)-\\d+$/)\n\t\treturn match ? match[1] : domId\n\t})\n\tconst clusters = parseClustersFromSvg(root, '.cluster', (domId) =>\n\t\tdomId.replace(/^mermaid-\\d+-/, '')\n\t)\n\tconst edges = parseAllEdgePointsFromSvg(root, (dataId) => {\n\t\tconst match = dataId.match(/(?:^|-)L_(.+)_([^_]+)_\\d+$/)\n\t\treturn match ? { start: match[1], end: match[2] } : null\n\t})\n\tscaleLayout(nodes, clusters, edges, LAYOUT_SCALE)\n\treturn { nodes, clusters, edges }\n}\n\n/** Convert a parsed Mermaid flowchart into a tldraw blueprint of nodes and edges. */\nexport function flowchartToBlueprint(\n\tlayout: ParsedDiagramLayout,\n\tvertices: Map<string, FlowVertex>,\n\tedges: FlowEdge[],\n\tsubGraphs?: FlowSubGraph[],\n\tclassDefs?: Map<string, FlowClass>\n): DiagramMermaidBlueprint {\n\tconst nodeColorMap = classDefs ? buildClassDefColorMap(classDefs, vertices) : new Map()\n\tconst { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout\n\tconst nodeCenters = buildNodeCentersFromSvg(svgNodes, svgClusters)\n\n\tconst allSubGraphs = subGraphs || []\n\tconst { nodeToSubGraph, subGraphParent } = buildHierarchy(allSubGraphs)\n\n\tconst nodes: MermaidBlueprintNode[] = []\n\tconst blueprintEdges: MermaidBlueprintEdge[] = []\n\n\t// Frames for subgraphs\n\tfor (const subGraph of orderTopDown(\n\t\tallSubGraphs,\n\t\t(subGraph) => subGraph.id,\n\t\t(subGraph) => subGraphParent.get(subGraph.id)\n\t)) {\n\t\tconst cluster = svgClusters.get(subGraph.id)\n\t\tif (!cluster) continue\n\n\t\tconst id = subGraph.id\n\t\tconst kind = 'subgraph'\n\t\tnodes.push({\n\t\t\tid,\n\t\t\tkind,\n\t\t\tx: cluster.topLeft.x,\n\t\t\ty: cluster.topLeft.y - FRAME_TOP_PAD,\n\t\t\tw: cluster.width,\n\t\t\th: cluster.height + FRAME_TOP_PAD,\n\t\t\tparentId: subGraphParent.get(subGraph.id),\n\t\t\tlabel: subGraph.title || subGraph.id,\n\t\t\tfill: 'semi',\n\t\t\tcolor: 'black',\n\t\t\tdash: 'draw',\n\t\t\tsize: 's',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'start',\n\t\t})\n\t}\n\n\t// Node shapes\n\tfor (const [id, vertex] of vertices) {\n\t\tconst svgNode = svgNodes.get(id)\n\t\tif (!svgNode) continue\n\n\t\tconst kind = vertex.type ?? 'rect'\n\t\tconst colors = nodeColorMap.get(id) ?? parseNodeInlineColor(vertex.styles)\n\n\t\tlet { width: w, height: h } = svgNode\n\t\tif (vertex.type === 'circle' || vertex.type === 'doublecircle') {\n\t\t\tw = h = Math.max(w, h)\n\t\t}\n\n\t\tnodes.push({\n\t\t\tid,\n\t\t\tkind,\n\t\t\tx: svgNode.center.x - w / 2,\n\t\t\ty: svgNode.center.y - h / 2,\n\t\t\tw,\n\t\t\th,\n\t\t\tparentId: nodeToSubGraph.get(id),\n\t\t\tlabel: vertex.text || undefined,\n\t\t\t...(colors?.fillColor && { fill: 'solid' as const }),\n\t\t\t...(colors && { color: colors.strokeColor ?? colors.fillColor }),\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tsize: 'm',\n\t\t})\n\t}\n\n\t// Edges: match DB edges to SVG edges by proximity, compute bends\n\tconst claimed = new Set<number>()\n\tfor (const edge of edges) {\n\t\tconst startCenter = nodeCenters.get(edge.start)\n\t\tconst endCenter = nodeCenters.get(edge.end)\n\n\t\tlet bend = 0\n\t\tif (startCenter && endCenter) {\n\t\t\tlet bestIndex = -1\n\t\t\tlet bestDist = Infinity\n\t\t\tfor (let i = 0; i < svgEdges.length; i++) {\n\t\t\t\tif (claimed.has(i) || svgEdges[i].points.length < 2) continue\n\n\t\t\t\tconst points = svgEdges[i].points\n\t\t\t\tconst distance =\n\t\t\t\t\tMath.hypot(points[0].x - startCenter.x, points[0].y - startCenter.y) +\n\t\t\t\t\tMath.hypot(\n\t\t\t\t\t\tpoints[points.length - 1].x - endCenter.x,\n\t\t\t\t\t\tpoints[points.length - 1].y - endCenter.y\n\t\t\t\t\t)\n\t\t\t\tif (distance < bestDist) {\n\t\t\t\t\tbestDist = distance\n\t\t\t\t\tbestIndex = i\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bestIndex >= 0) {\n\t\t\t\tclaimed.add(bestIndex)\n\t\t\t\tbend = getArrowBend(svgEdges[bestIndex])\n\t\t\t}\n\t\t}\n\n\t\tconst cssOverrides = edge.style ? parseCssStyles(edge.style) : undefined\n\t\tconst arrowheadEnd = mapEdgeTypeToArrowhead(edge.type)\n\t\tconst dash = cssOverrides?.dashOverride ?? mapEdgeStrokeToDash(edge.stroke)\n\t\tconst size = cssOverrides?.sizeOverride ?? (edge.stroke === 'thick' ? 'l' : 's')\n\n\t\tblueprintEdges.push({\n\t\t\tstartNodeId: edge.start,\n\t\t\tendNodeId: edge.end,\n\t\t\tlabel: edge.text,\n\t\t\tbend,\n\t\t\tarrowheadEnd,\n\t\t\tarrowheadStart: edge.type?.includes('double_arrow') ? arrowheadEnd : undefined,\n\t\t\tdash,\n\t\t\tsize,\n\t\t\tcolor: cssOverrides?.color,\n\t\t})\n\t}\n\n\tconst nodeIds = new Set(nodes.map((n) => n.id))\n\tconst validEdges = blueprintEdges.filter(\n\t\t(e) => nodeIds.has(e.startNodeId) && nodeIds.has(e.endNodeId)\n\t)\n\treturn { diagramKind: 'flowchart', nodes, edges: validEdges }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n\tFlowClass,\n\tFlowEdge,\n\tFlowSubGraph,\n\tFlowVertex,\n} from 'mermaid/dist/diagrams/flowchart/types.js'\nimport { TLArrowShapeArrowheadStyle } from 'tldraw'\nimport type {\n\tDiagramMermaidBlueprint,\n\tMermaidBlueprintEdge,\n\tMermaidBlueprintNode,\n} from './blueprint'\nimport {\n\tbuildClassDefColorMap,\n\tparseCssStyles,\n\tparseNodeInlineColor,\n\ttoNodeColorProps,\n} from './colors'\nimport {\n\tbuildNodeCentersFromSvg,\n\tclaimNearestEdgeBend,\n\tparseAllEdgePointsFromSvg,\n\tparseClustersFromSvg,\n\tparseDomId,\n\ttype ParsedDiagramLayout,\n\tparseNodesFromSvg,\n\tscaleLayout,\n\tstripDiagramIdPrefix,\n} from './svgParsing'\nimport { dropDanglingEdges, LAYOUT_SCALE, orderTopDown } from './utils'\n\nfunction mapEdgeTypeToArrowhead(type: string | undefined): TLArrowShapeArrowheadStyle {\n\tif (type?.includes('circle')) return 'dot'\n\tif (type?.includes('cross')) return 'bar'\n\tif (type?.includes('open')) return 'none'\n\treturn 'arrow'\n}\n\nconst FRAME_TOP_PAD = 14\nconst NODE_ID = /^flowchart-(.+)-\\d+$/\n\nfunction buildHierarchy(subGraphs: FlowSubGraph[]) {\n\tconst subGraphIds = new Set(subGraphs.map((subGraph) => subGraph.id))\n\tconst nodeToSubGraph = new Map<string, string>()\n\tconst subGraphParent = new Map<string, string>()\n\tfor (const subGraph of subGraphs) {\n\t\tfor (const nodeId of subGraph.nodes) {\n\t\t\tif (subGraphIds.has(nodeId)) {\n\t\t\t\tsubGraphParent.set(nodeId, subGraph.id)\n\t\t\t} else if (!nodeToSubGraph.has(nodeId)) {\n\t\t\t\tnodeToSubGraph.set(nodeId, subGraph.id)\n\t\t\t}\n\t\t}\n\t}\n\treturn { nodeToSubGraph, subGraphParent }\n}\n\n/** Parse flowchart-specific SVG layout data for use by {@link flowchartToBlueprint}. */\nexport function parseFlowchartLayout(root: Element): ParsedDiagramLayout {\n\tconst nodes = parseNodesFromSvg(root, '.node', (domId) => parseDomId(domId, NODE_ID))\n\tconst clusters = parseClustersFromSvg(root, '.cluster', stripDiagramIdPrefix)\n\tconst edges = parseAllEdgePointsFromSvg(root, (dataId) => {\n\t\tconst match = dataId.match(/(?:^|-)L_(.+)_([^_]+)_\\d+$/)\n\t\treturn match ? { start: match[1], end: match[2] } : null\n\t})\n\tscaleLayout(nodes, clusters, edges, LAYOUT_SCALE)\n\treturn { nodes, clusters, edges }\n}\n\n/** Convert a parsed Mermaid flowchart into a tldraw blueprint of nodes and edges. */\nexport function flowchartToBlueprint(\n\tlayout: ParsedDiagramLayout,\n\tvertices: Map<string, FlowVertex>,\n\tedges: FlowEdge[],\n\tsubGraphs?: FlowSubGraph[],\n\tclassDefs?: Map<string, FlowClass>\n): DiagramMermaidBlueprint {\n\tconst nodeColorMap = buildClassDefColorMap(classDefs ?? new Map(), vertices)\n\tconst { nodes: svgNodes, clusters: svgClusters, edges: svgEdges } = layout\n\tconst nodeCenters = buildNodeCentersFromSvg(svgNodes, svgClusters)\n\n\tconst allSubGraphs = subGraphs || []\n\tconst { nodeToSubGraph, subGraphParent } = buildHierarchy(allSubGraphs)\n\n\tconst nodes: MermaidBlueprintNode[] = []\n\tconst blueprintEdges: MermaidBlueprintEdge[] = []\n\n\t// Frames for subgraphs\n\tfor (const subGraph of orderTopDown(\n\t\tallSubGraphs,\n\t\t(subGraph) => subGraph.id,\n\t\t(subGraph) => subGraphParent.get(subGraph.id)\n\t)) {\n\t\tconst cluster = svgClusters.get(subGraph.id)\n\t\tif (!cluster) continue\n\n\t\tnodes.push({\n\t\t\tid: subGraph.id,\n\t\t\tkind: 'subgraph',\n\t\t\tx: cluster.topLeft.x,\n\t\t\ty: cluster.topLeft.y - FRAME_TOP_PAD,\n\t\t\tw: cluster.width,\n\t\t\th: cluster.height + FRAME_TOP_PAD,\n\t\t\tparentId: subGraphParent.get(subGraph.id),\n\t\t\tlabel: subGraph.title || subGraph.id,\n\t\t\tfill: 'semi',\n\t\t\tcolor: 'black',\n\t\t\tdash: 'draw',\n\t\t\tsize: 's',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'start',\n\t\t})\n\t}\n\n\t// Node shapes\n\tfor (const [id, vertex] of vertices) {\n\t\tconst svgNode = svgNodes.get(id)\n\t\tif (!svgNode) continue\n\n\t\tlet { width: w, height: h } = svgNode\n\t\tif (vertex.type === 'circle' || vertex.type === 'doublecircle') {\n\t\t\tw = h = Math.max(w, h)\n\t\t}\n\n\t\tnodes.push({\n\t\t\tid,\n\t\t\tkind: vertex.type ?? 'rect',\n\t\t\tx: svgNode.center.x - w / 2,\n\t\t\ty: svgNode.center.y - h / 2,\n\t\t\tw,\n\t\t\th,\n\t\t\tparentId: nodeToSubGraph.get(id),\n\t\t\tlabel: vertex.text || undefined,\n\t\t\t...toNodeColorProps(nodeColorMap.get(id) ?? parseNodeInlineColor(vertex.styles)),\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tsize: 'm',\n\t\t})\n\t}\n\n\t// Edges: match DB edges to SVG edges by proximity, compute bends\n\tconst claimed = new Set<number>()\n\tfor (const edge of edges) {\n\t\tconst bend = claimNearestEdgeBend(\n\t\t\tsvgEdges,\n\t\t\tclaimed,\n\t\t\tnodeCenters.get(edge.start),\n\t\t\tnodeCenters.get(edge.end)\n\t\t)\n\t\tconst cssOverrides = parseCssStyles(edge.style)\n\t\tconst arrowheadEnd = mapEdgeTypeToArrowhead(edge.type)\n\n\t\tblueprintEdges.push({\n\t\t\tstartNodeId: edge.start,\n\t\t\tendNodeId: edge.end,\n\t\t\tlabel: edge.text,\n\t\t\tbend,\n\t\t\tarrowheadEnd,\n\t\t\tarrowheadStart: edge.type?.includes('double_arrow') ? arrowheadEnd : undefined,\n\t\t\tdash: cssOverrides.dashOverride ?? (edge.stroke === 'dotted' ? 'dotted' : 'solid'),\n\t\t\tsize: cssOverrides.sizeOverride ?? (edge.stroke === 'thick' ? 'l' : 's'),\n\t\t\tcolor: cssOverrides.color,\n\t\t})\n\t}\n\n\treturn { diagramKind: 'flowchart', nodes, edges: dropDanglingEdges(nodes, blueprintEdges) }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["subGraph"]
7
7
  }
package/dist-cjs/index.js CHANGED
@@ -35,7 +35,7 @@ var import_mermaidNodeCreateShape = require("./mermaidNodeCreateShape");
35
35
  var import_renderBlueprint = require("./renderBlueprint");
36
36
  (0, import_utils.registerTldrawLibraryVersion)(
37
37
  "@tldraw/mermaid",
38
- "5.4.2",
38
+ "5.5.0-canary.0241f11f2e99",
39
39
  "cjs"
40
40
  );
41
41
  //# sourceMappingURL=index.js.map
@@ -36,31 +36,15 @@ function defaultCreateMermaidNodeFromBlueprint(args) {
36
36
  ...node.align && { align: node.align },
37
37
  ...node.verticalAlign && { verticalAlign: node.verticalAlign }
38
38
  };
39
- if (render.variant === "geo") {
40
- editor.createShape({
41
- id: shapeId,
42
- type: "geo",
43
- x,
44
- y,
45
- parentId: parentShapeId,
46
- props: {
47
- ...baseProps,
48
- geo: render.geo
49
- }
50
- });
51
- } else {
52
- editor.createShape({
53
- id: shapeId,
54
- type: render.type,
55
- x,
56
- y,
57
- parentId: parentShapeId,
58
- props: {
59
- ...baseProps,
60
- ...render.props
61
- }
62
- });
63
- }
39
+ const { type, props } = render.variant === "geo" ? { type: "geo", props: { geo: render.geo } } : { type: render.type, props: render.props };
40
+ editor.createShape({
41
+ id: shapeId,
42
+ type,
43
+ x,
44
+ y,
45
+ parentId: parentShapeId,
46
+ props: { ...baseProps, ...props }
47
+ });
64
48
  return editor.getShape(shapeId);
65
49
  }
66
50
  //# sourceMappingURL=mermaidNodeCreateShape.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/mermaidNodeCreateShape.ts"],
4
- "sourcesContent": ["import type { Editor, TLGeoShape, TLShape, TLShapeId } from 'tldraw'\nimport { toRichText } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n} from './blueprint'\nimport { sanitizeDiagramText } from './utils'\n\n/**\n * Arguments for {@link defaultCreateMermaidNodeFromBlueprint}. `x` / `y` are in shape space (parent-relative when\n * `parentShapeId` is set), matching {@link renderBlueprint}.\n * @public\n */\nexport interface MermaidNodeCreateFunctionArgs {\n\teditor: Editor\n\tnode: MermaidBlueprintNode\n\tshapeId: TLShapeId\n\tx: number\n\ty: number\n\tparentShapeId?: TLShapeId\n\tdiagramKind: MermaidDiagramKind\n\t/** Materialization spec (from {@link resolveMermaidNodeRender} or your mapper). */\n\trender: MermaidBlueprintNodeRenderSpec\n}\n\n/**\n * Creates the tldraw shape for one Mermaid blueprint node using `render` and layout-derived props.\n * @public\n */\nexport function defaultCreateMermaidNodeFromBlueprint(\n\targs: MermaidNodeCreateFunctionArgs\n): TLShape {\n\tconst { editor, node, shapeId, x, y, parentShapeId, render } = args\n\tconst baseProps = {\n\t\tw: node.w,\n\t\th: node.h,\n\t\tfill: node.fill ?? 'none',\n\t\tcolor: node.color ?? 'black',\n\t\tdash: node.dash ?? 'draw',\n\t\tsize: node.size ?? 'm',\n\t\t...(node.label && { richText: toRichText(sanitizeDiagramText(node.label)) }),\n\t\t...(node.align && { align: node.align }),\n\t\t...(node.verticalAlign && { verticalAlign: node.verticalAlign }),\n\t}\n\n\tif (render.variant === 'geo') {\n\t\teditor.createShape<TLGeoShape>({\n\t\t\tid: shapeId,\n\t\t\ttype: 'geo',\n\t\t\tx,\n\t\t\ty,\n\t\t\tparentId: parentShapeId,\n\t\t\tprops: {\n\t\t\t\t...baseProps,\n\t\t\t\tgeo: render.geo,\n\t\t\t},\n\t\t})\n\t} else {\n\t\teditor.createShape({\n\t\t\tid: shapeId,\n\t\t\ttype: render.type as any,\n\t\t\tx,\n\t\t\ty,\n\t\t\tparentId: parentShapeId,\n\t\t\tprops: {\n\t\t\t\t...baseProps,\n\t\t\t\t...render.props,\n\t\t\t},\n\t\t})\n\t}\n\treturn editor.getShape(shapeId)!\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAM3B,mBAAoC;AAuB7B,SAAS,sCACf,MACU;AACV,QAAM,EAAE,QAAQ,MAAM,SAAS,GAAG,GAAG,eAAe,OAAO,IAAI;AAC/D,QAAM,YAAY;AAAA,IACjB,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,IACR,MAAM,KAAK,QAAQ;AAAA,IACnB,OAAO,KAAK,SAAS;AAAA,IACrB,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB,GAAI,KAAK,SAAS,EAAE,cAAU,8BAAW,kCAAoB,KAAK,KAAK,CAAC,EAAE;AAAA,IAC1E,GAAI,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM;AAAA,IACtC,GAAI,KAAK,iBAAiB,EAAE,eAAe,KAAK,cAAc;AAAA,EAC/D;AAEA,MAAI,OAAO,YAAY,OAAO;AAC7B,WAAO,YAAwB;AAAA,MAC9B,IAAI;AAAA,MACJ,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACN,GAAG;AAAA,QACH,KAAK,OAAO;AAAA,MACb;AAAA,IACD,CAAC;AAAA,EACF,OAAO;AACN,WAAO,YAAY;AAAA,MAClB,IAAI;AAAA,MACJ,MAAM,OAAO;AAAA,MACb;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACN,GAAG;AAAA,QACH,GAAG,OAAO;AAAA,MACX;AAAA,IACD,CAAC;AAAA,EACF;AACA,SAAO,OAAO,SAAS,OAAO;AAC/B;",
4
+ "sourcesContent": ["import type { Editor, TLShape, TLShapeId } from 'tldraw'\nimport { toRichText } from 'tldraw'\nimport type {\n\tMermaidBlueprintNode,\n\tMermaidBlueprintNodeRenderSpec,\n\tMermaidDiagramKind,\n} from './blueprint'\nimport { sanitizeDiagramText } from './utils'\n\n/**\n * Arguments for {@link defaultCreateMermaidNodeFromBlueprint}. `x` / `y` are in shape space (parent-relative when\n * `parentShapeId` is set), matching {@link renderBlueprint}.\n * @public\n */\nexport interface MermaidNodeCreateFunctionArgs {\n\teditor: Editor\n\tnode: MermaidBlueprintNode\n\tshapeId: TLShapeId\n\tx: number\n\ty: number\n\tparentShapeId?: TLShapeId\n\tdiagramKind: MermaidDiagramKind\n\t/** Materialization spec (from {@link resolveMermaidNodeRender} or your mapper). */\n\trender: MermaidBlueprintNodeRenderSpec\n}\n\n/**\n * Creates the tldraw shape for one Mermaid blueprint node using `render` and layout-derived props.\n * @public\n */\nexport function defaultCreateMermaidNodeFromBlueprint(\n\targs: MermaidNodeCreateFunctionArgs\n): TLShape {\n\tconst { editor, node, shapeId, x, y, parentShapeId, render } = args\n\tconst baseProps = {\n\t\tw: node.w,\n\t\th: node.h,\n\t\tfill: node.fill ?? 'none',\n\t\tcolor: node.color ?? 'black',\n\t\tdash: node.dash ?? 'draw',\n\t\tsize: node.size ?? 'm',\n\t\t...(node.label && { richText: toRichText(sanitizeDiagramText(node.label)) }),\n\t\t...(node.align && { align: node.align }),\n\t\t...(node.verticalAlign && { verticalAlign: node.verticalAlign }),\n\t}\n\n\tconst { type, props } =\n\t\trender.variant === 'geo'\n\t\t\t? { type: 'geo', props: { geo: render.geo } }\n\t\t\t: { type: render.type, props: render.props }\n\teditor.createShape({\n\t\tid: shapeId,\n\t\ttype: type as any,\n\t\tx,\n\t\ty,\n\t\tparentId: parentShapeId,\n\t\tprops: { ...baseProps, ...props },\n\t})\n\treturn editor.getShape(shapeId)!\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAM3B,mBAAoC;AAuB7B,SAAS,sCACf,MACU;AACV,QAAM,EAAE,QAAQ,MAAM,SAAS,GAAG,GAAG,eAAe,OAAO,IAAI;AAC/D,QAAM,YAAY;AAAA,IACjB,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,IACR,MAAM,KAAK,QAAQ;AAAA,IACnB,OAAO,KAAK,SAAS;AAAA,IACrB,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB,GAAI,KAAK,SAAS,EAAE,cAAU,8BAAW,kCAAoB,KAAK,KAAK,CAAC,EAAE;AAAA,IAC1E,GAAI,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM;AAAA,IACtC,GAAI,KAAK,iBAAiB,EAAE,eAAe,KAAK,cAAc;AAAA,EAC/D;AAEA,QAAM,EAAE,MAAM,MAAM,IACnB,OAAO,YAAY,QAChB,EAAE,MAAM,OAAO,OAAO,EAAE,KAAK,OAAO,IAAI,EAAE,IAC1C,EAAE,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM;AAC7C,SAAO,YAAY;AAAA,IAClB,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,EAAE,GAAG,WAAW,GAAG,MAAM;AAAA,EACjC,CAAC;AACD,SAAO,OAAO,SAAS,OAAO;AAC/B;",
6
6
  "names": []
7
7
  }